From 4e459e92798130cfb43d88935c4db284e25f132b Mon Sep 17 00:00:00 2001
From: pkupczyk <pkupczyk>
Date: Thu, 2 Apr 2015 14:12:38 +0000
Subject: [PATCH] V3 API refactoring: - translators are now Spring beans -
 logic from ApplicationServerApi moved to method executors

SVN: 33787
---
 .../server/api/v3/ApplicationServerApi.java   | 447 ++++--------------
 .../api/v3/ApplicationServerApiLogger.java    |   9 -
 .../method/AbstractCreateMethodExecutor.java  |  61 +++
 .../method/AbstractMapMethodExecutor.java     |  86 ++++
 .../method/AbstractMethodExecutor.java        |  39 ++
 .../method/AbstractSearchMethodExecutor.java  |  74 +++
 .../method/AbstractUpdateMethodExecutor.java  |  61 +++
 .../CreateExperimentMethodExecutor.java       |  44 ++
 .../method/CreateMaterialMethodExecutor.java  |  44 ++
 .../method/CreateProjectMethodExecutor.java   |  43 ++
 .../method/CreateSampleMethodExecutor.java    |  44 ++
 .../method/CreateSpaceMethodExecutor.java     |  43 ++
 .../ICreateExperimentMethodExecutor.java      |  28 ++
 .../method/ICreateMaterialMethodExecutor.java |  28 ++
 .../method/ICreateMethodExecutor.java}        |  15 +-
 .../method/ICreateProjectMethodExecutor.java  |  28 ++
 .../method/ICreateSampleMethodExecutor.java   |  28 ++
 .../method/ICreateSpaceMethodExecutor.java    |  28 ++
 .../method/IListDeletionMethodExecutor.java   |  32 ++
 .../method/IMapDataSetMethodExecutor.java     |  29 ++
 .../method/IMapExperimentMethodExecutor.java  |  29 ++
 .../method/IMapMaterialMethodExecutor.java    |  29 ++
 .../executor/method/IMapMethodExecutor.java   |  30 ++
 .../method/IMapProjectMethodExecutor.java     |  29 ++
 .../method/IMapSampleMethodExecutor.java      |  29 ++
 .../method/IMapSpaceMethodExecutor.java       |  29 ++
 .../method/ISearchDataSetMethodExecutor.java  |  30 ++
 .../ISearchExperimentMethodExecutor.java      |  30 ++
 .../method/ISearchMaterialMethodExecutor.java |  30 ++
 .../method/ISearchMethodExecutor.java         |  29 ++
 .../method/ISearchProjectMethodExecutor.java  |  29 ++
 .../method/ISearchSampleMethodExecutor.java   |  29 ++
 .../method/ISearchSpaceMethodExecutor.java    |  29 ++
 .../method/IUpdateDataSetMethodExecutor.java  |  27 ++
 .../IUpdateExperimentMethodExecutor.java      |  27 ++
 .../method/IUpdateMaterialMethodExecutor.java |  27 ++
 .../method/IUpdateMethodExecutor.java         |  29 ++
 .../method/IUpdateProjectMethodExecutor.java  |  27 ++
 .../method/IUpdateSampleMethodExecutor.java   |  27 ++
 .../method/IUpdateSpaceMethodExecutor.java    |  27 ++
 .../method/ListDeletionMethodExecutor.java    |  67 +++
 .../method/MapDataSetMethodExecutor.java      |  56 +++
 .../method/MapExperimentMethodExecutor.java   |  57 +++
 .../method/MapMaterialMethodExecutor.java     |  57 +++
 .../method/MapProjectMethodExecutor.java      |  57 +++
 .../method/MapSampleMethodExecutor.java       |  56 +++
 .../method/MapSpaceMethodExecutor.java        |  56 +++
 .../method/SearchDataSetMethodExecutor.java   |  58 +++
 .../SearchExperimentMethodExecutor.java       |  58 +++
 .../method/SearchMaterialMethodExecutor.java  |  58 +++
 .../method/SearchProjectMethodExecutor.java   |  57 +++
 .../method/SearchSampleMethodExecutor.java    |  58 +++
 .../method/SearchSpaceMethodExecutor.java     |  57 +++
 .../method/UpdateDataSetMethodExecutor.java   |  43 ++
 .../UpdateExperimentMethodExecutor.java       |  43 ++
 .../method/UpdateMaterialMethodExecutor.java  |  43 ++
 .../method/UpdateProjectMethodExecutor.java   |  43 ++
 .../method/UpdateSampleMethodExecutor.java    |  43 ++
 .../method/UpdateSpaceMethodExecutor.java     |  43 ++
 .../project/UpdateProjectExecutor.java        |   4 -
 .../project/UpdateProjectLeaderExecutor.java  |  82 ----
 .../translator/AbstractCachingTranslator.java |  88 ++--
 .../api/v3/translator/AbstractTranslator.java |  16 +-
 .../server/api/v3/translator/ITranslator.java |   6 +-
 .../api/v3/translator/ToManyRelation.java     |  18 +-
 .../api/v3/translator/ToOneRelation.java      |  18 +-
 .../api/v3/translator/TranslationContext.java |  11 +-
 .../common/AbstractCollectionTranslator.java  |  52 --
 .../v3/translator/common/MapTranslator.java   |  65 ---
 .../attachment/AttachmentTranslator.java      |  41 +-
 .../attachment/IAttachmentTranslator.java     |  37 ++
 .../entity/dataset/DataSetTranslator.java     | 185 ++++----
 .../entity/dataset/DataSetTypeTranslator.java |  16 +-
 .../dataset/ExternalDataTranslator.java       |  49 +-
 .../dataset/FileFormatTypeTranslator.java     |  16 +-
 .../entity/dataset/IDataSetTranslator.java    |  30 ++
 .../dataset/IDataSetTypeTranslator.java       |  30 ++
 .../dataset/IExternalDataTranslator.java      |  30 ++
 .../dataset/IFileFormatTypeTranslator.java    |  30 ++
 .../dataset/ILocatorTypeTranslator.java       |  30 ++
 .../entity/dataset/LocatorTypeTranslator.java |  15 +-
 .../entity/deletion/DeletionTranslator.java   |  27 +-
 .../entity/deletion/IDeletionTranslator.java  |  29 ++
 .../experiment/ExperimentTranslator.java      | 149 +++---
 .../experiment/ExperimentTypeTranslator.java  |  16 +-
 .../experiment/IExperimentTranslator.java}    |  25 +-
 .../experiment/IExperimentTypeTranslator.java |  30 ++
 .../IMaterialPropertyTranslator.java}         |  25 +-
 .../entity/material/IMaterialTranslator.java  |  30 ++
 .../material/IMaterialTypeTranslator.java     |  30 ++
 .../material/MaterialPropertyTranslator.java  |  21 +-
 .../entity/material/MaterialTranslator.java   |  69 +--
 .../material/MaterialTypeTranslator.java      |  17 +-
 .../entity/person/IPersonTranslator.java      |  30 ++
 .../entity/person/PersonTranslator.java       |  35 +-
 .../entity/project/IProjectTranslator.java}   |  11 +-
 .../entity/project/ProjectTranslator.java     |  87 ++--
 .../entity/property/IPropertyTranslator.java  |  31 ++
 .../entity/property/PropertyTranslator.java   |  29 +-
 .../entity/sample/ISampleTranslator.java      |  30 ++
 .../entity/sample/ISampleTypeTranslator.java  |  30 ++
 .../entity/sample/SampleTranslator.java       | 215 +++++----
 .../entity/sample/SampleTypeTranslator.java   |  15 +-
 .../entity/space/ISpaceTranslator.java        |  30 ++
 .../entity/space/SpaceTranslator.java         |  60 +--
 .../translator/entity/tag/ITagTranslator.java |  30 ++
 .../translator/entity/tag/TagTranslator.java  |  29 +-
 .../vocabulary/IVocabularyTermTranslator.java |  30 ++
 .../vocabulary/IVocabularyTranslator.java     |  30 ++
 .../vocabulary/VocabularyTermTranslator.java  |  38 +-
 .../vocabulary/VocabularyTranslator.java      |  28 +-
 .../systemtest/api/v3/UpdateProjectTest.java  |  57 ---
 .../shared/api/v3/IApplicationServerApi.java  |  63 ---
 .../v3/dto/entity/project/ProjectUpdate.java  |  16 -
 114 files changed, 3664 insertions(+), 1390 deletions(-)
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractCreateMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractMapMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractSearchMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractUpdateMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateExperimentMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateMaterialMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateProjectMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateSampleMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateSpaceMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateExperimentMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateMaterialMethodExecutor.java
 rename openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/{translator/common/IdentityTranslator.java => executor/method/ICreateMethodExecutor.java} (62%)
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateProjectMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateSampleMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateSpaceMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IListDeletionMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapDataSetMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapExperimentMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapMaterialMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapProjectMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapSampleMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapSpaceMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchDataSetMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchExperimentMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchMaterialMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchProjectMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchSampleMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchSpaceMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateDataSetMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateExperimentMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateMaterialMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateProjectMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateSampleMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateSpaceMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ListDeletionMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapDataSetMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapExperimentMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapMaterialMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapProjectMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapSampleMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapSpaceMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchDataSetMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchExperimentMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchMaterialMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchProjectMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchSampleMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchSpaceMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateDataSetMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateExperimentMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateMaterialMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateProjectMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateSampleMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateSpaceMethodExecutor.java
 delete mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/UpdateProjectLeaderExecutor.java
 delete mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/common/AbstractCollectionTranslator.java
 delete mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/common/MapTranslator.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/attachment/IAttachmentTranslator.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/IDataSetTranslator.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/IDataSetTypeTranslator.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/IExternalDataTranslator.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/IFileFormatTypeTranslator.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/ILocatorTypeTranslator.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/deletion/IDeletionTranslator.java
 rename openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/{common/SetTranslator.java => entity/experiment/IExperimentTranslator.java} (54%)
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/experiment/IExperimentTypeTranslator.java
 rename openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/{common/ListTranslator.java => entity/material/IMaterialPropertyTranslator.java} (54%)
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/IMaterialTranslator.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/IMaterialTypeTranslator.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/person/IPersonTranslator.java
 rename openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/{executor/project/IUpdateProjectLeaderExecutor.java => translator/entity/project/IProjectTranslator.java} (68%)
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/property/IPropertyTranslator.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/sample/ISampleTranslator.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/sample/ISampleTypeTranslator.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/space/ISpaceTranslator.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/tag/ITagTranslator.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/vocabulary/IVocabularyTermTranslator.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/vocabulary/IVocabularyTranslator.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 063fb1c0aca..71d25594d47 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,59 +16,46 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3;
 
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
-import javax.annotation.Resource;
-
 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.executor.OperationContext;
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.dataset.IDeleteDataSetExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.dataset.IMapDataSetByIdExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.dataset.ISearchDataSetExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.dataset.IUpdateDataSetExecutor;
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.deletion.IConfirmDeletionExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.deletion.IListDeletionExecutor;
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.deletion.IRevertDeletionExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.experiment.ICreateExperimentExecutor;
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.experiment.IDeleteExperimentExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.experiment.IMapExperimentByIdExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.experiment.ISearchExperimentExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.experiment.IUpdateExperimentExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.material.ICreateMaterialExecutor;
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.material.IDeleteMaterialExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.material.IMapMaterialByIdExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.material.ISearchMaterialExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.material.IUpdateMaterialExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.project.ICreateProjectExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.ICreateExperimentMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.ICreateMaterialMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.ICreateProjectMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.ICreateSampleMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.ICreateSpaceMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.IListDeletionMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.IMapDataSetMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.IMapExperimentMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.IMapMaterialMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.IMapProjectMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.IMapSampleMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.IMapSpaceMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.ISearchDataSetMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.ISearchExperimentMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.ISearchMaterialMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.ISearchProjectMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.ISearchSampleMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.ISearchSpaceMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.IUpdateDataSetMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.IUpdateExperimentMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.IUpdateMaterialMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.IUpdateProjectMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.IUpdateSampleMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.method.IUpdateSpaceMethodExecutor;
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.project.IDeleteProjectExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.project.IMapProjectByIdExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.project.ISearchProjectExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.project.IUpdateProjectExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.sample.ICreateSampleExecutor;
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.sample.IDeleteSampleExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.sample.IMapSampleByIdExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.sample.ISearchSampleExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.sample.IUpdateSampleExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.space.ICreateSpaceExecutor;
 import ch.ethz.sis.openbis.generic.server.api.v3.executor.space.IDeleteSpaceExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.space.IMapSpaceByIdExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.space.ISearchSpaceExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.space.IUpdateSpaceExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.common.IdentityTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.common.MapTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.dataset.DataSetTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.deletion.DeletionTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.experiment.ExperimentTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.material.MaterialTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.project.ProjectTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.sample.SampleTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.space.SpaceTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.utils.ExceptionUtils;
 import ch.ethz.sis.openbis.generic.shared.api.v3.IApplicationServerApi;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.deletion.Deletion;
@@ -114,8 +101,6 @@ 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.space.ISpaceId;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.SpacePermId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.operation.IOperation;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.operation.IOperationResult;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.DataSetSearchCriterion;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.ExperimentSearchCriterion;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.MaterialSearchCriterion;
@@ -124,7 +109,6 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SampleSearchCriterio
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SpaceSearchCriterion;
 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.Capability;
 import ch.systemsx.cisd.openbis.generic.server.authorization.annotation.RolesAllowed;
 import ch.systemsx.cisd.openbis.generic.server.business.IPropertiesBatchManager;
@@ -136,14 +120,8 @@ import ch.systemsx.cisd.openbis.generic.shared.DatabaseUpdateModification;
 import ch.systemsx.cisd.openbis.generic.shared.IOpenBisSessionManager;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.ObjectKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SessionContextDTO;
-import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
 import ch.systemsx.cisd.openbis.generic.shared.managed_property.IManagedPropertyEvaluatorFactory;
 
 /**
@@ -153,77 +131,74 @@ import ch.systemsx.cisd.openbis.generic.shared.managed_property.IManagedProperty
 public class ApplicationServerApi extends AbstractServer<IApplicationServerApi> implements
         IApplicationServerApi
 {
-    @Resource(name = ComponentNames.MANAGED_PROPERTY_EVALUATOR_FACTORY)
-    private IManagedPropertyEvaluatorFactory managedPropertyEvaluatorFactory;
-
     @Autowired
-    private ICreateSpaceExecutor createSpaceExecutor;
+    private ICreateSpaceMethodExecutor createSpaceExecutor;
 
     @Autowired
-    private ICreateProjectExecutor createProjectExecutor;
+    private ICreateProjectMethodExecutor createProjectExecutor;
 
     @Autowired
-    private ICreateExperimentExecutor createExperimentExecutor;
+    private ICreateExperimentMethodExecutor createExperimentExecutor;
 
     @Autowired
-    private ICreateSampleExecutor createSampleExecutor;
+    private ICreateSampleMethodExecutor createSampleExecutor;
 
     @Autowired
-    private ICreateMaterialExecutor createMaterialExecutor;
+    private ICreateMaterialMethodExecutor createMaterialExecutor;
 
     @Autowired
-    private IUpdateSpaceExecutor updateSpaceExecutor;
+    private IUpdateSpaceMethodExecutor updateSpaceExecutor;
 
     @Autowired
-    private IUpdateProjectExecutor updateProjectExecutor;
+    private IUpdateProjectMethodExecutor updateProjectExecutor;
 
     @Autowired
-    private IUpdateExperimentExecutor updateExperimentExecutor;
+    private IUpdateExperimentMethodExecutor updateExperimentExecutor;
 
     @Autowired
-    private IUpdateSampleExecutor updateSampleExecutor;
+    private IUpdateSampleMethodExecutor updateSampleExecutor;
 
     @Autowired
-    private IUpdateDataSetExecutor updateDataSetExecutor;
+    private IUpdateDataSetMethodExecutor updateDataSetExecutor;
 
     @Autowired
-    private IUpdateMaterialExecutor updateMaterialExecutor;
+    private IUpdateMaterialMethodExecutor updateMaterialExecutor;
 
     @Autowired
-    private IMapSpaceByIdExecutor mapSpaceByIdExecutor;
+    private IMapSpaceMethodExecutor mapSpaceExecutor;
 
     @Autowired
-    private IMapProjectByIdExecutor mapProjectByIdExecutor;
+    private IMapProjectMethodExecutor mapProjectExecutor;
 
     @Autowired
-    private IMapExperimentByIdExecutor mapExperimentByIdExecutor;
+    private IMapExperimentMethodExecutor mapExperimentExecutor;
 
     @Autowired
-    private IMapSampleByIdExecutor mapSampleByIdExecutor;
+    private IMapSampleMethodExecutor mapSampleExecutor;
 
     @Autowired
-    private IMapDataSetByIdExecutor mapDataSetByIdExecutor;
+    private IMapDataSetMethodExecutor mapDataSetExecutor;
 
     @Autowired
-    private IMapMaterialByIdExecutor mapMaterialByIdExecutor;
+    private IMapMaterialMethodExecutor mapMaterialExecutor;
 
     @Autowired
-    private ISearchSpaceExecutor searchSpaceExecutor;
+    private ISearchSpaceMethodExecutor searchSpaceExecutor;
 
     @Autowired
-    private ISearchProjectExecutor searchProjectExecutor;
+    private ISearchProjectMethodExecutor searchProjectExecutor;
 
     @Autowired
-    private ISearchExperimentExecutor searchExperimentExecutor;
+    private ISearchExperimentMethodExecutor searchExperimentExecutor;
 
     @Autowired
-    private ISearchSampleExecutor searchSampleExecutor;
+    private ISearchSampleMethodExecutor searchSampleExecutor;
 
     @Autowired
-    private ISearchDataSetExecutor searchDataSetExecutor;
+    private ISearchDataSetMethodExecutor searchDataSetExecutor;
 
     @Autowired
-    private ISearchMaterialExecutor searchMaterialExecutor;
+    private ISearchMaterialMethodExecutor searchMaterialExecutor;
 
     @Autowired
     private IDeleteSpaceExecutor deleteSpaceExecutor;
@@ -244,7 +219,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     private IDeleteMaterialExecutor deleteMaterialExecutor;
 
     @Autowired
-    private IListDeletionExecutor listDeletionExecutor;
+    private IListDeletionMethodExecutor listDeletionExecutor;
 
     @Autowired
     private IRevertDeletionExecutor revertDeletionExecutor;
@@ -265,7 +240,6 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     {
         super(sessionManager, daoFactory, propertiesBatchManager, sampleTypeSlaveServerPlugin,
                 dataSetTypeSlaveServerPlugin);
-        this.managedPropertyEvaluatorFactory = managedPropertyEvaluatorFactory;
     }
 
     @Override
@@ -284,15 +258,6 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
         return session == null ? null : session.getSessionToken();
     }
 
-    @Override
-    @Transactional
-    public List<? extends IOperationResult> performOperations(String sessionToken,
-            List<? extends IOperation> operations)
-    {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
     @Override
     @Transactional
     @RolesAllowed({ RoleWithHierarchy.SPACE_ADMIN, RoleWithHierarchy.SPACE_ETL_SERVER })
@@ -300,34 +265,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @DatabaseCreateOrDeleteModification(value = ObjectKind.SPACE)
     public List<SpacePermId> createSpaces(String sessionToken, List<SpaceCreation> creations)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        try
-        {
-            return createSpaceExecutor.create(context, creations);
-        } catch (Throwable t)
-        {
-            throw ExceptionUtils.create(context, t);
-        }
-    }
-
-    @Override
-    @Transactional
-    @RolesAllowed({ RoleWithHierarchy.INSTANCE_ADMIN, RoleWithHierarchy.SPACE_ETL_SERVER })
-    @Capability("WRITE_MATERIAL")
-    @DatabaseCreateOrDeleteModification(value = ObjectKind.MATERIAL)
-    public List<MaterialPermId> createMaterials(String sessionToken, List<MaterialCreation> newMaterials)
-    {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-        try
-        {
-            return createMaterialExecutor.create(context, newMaterials);
-        } catch (Throwable t)
-        {
-            throw ExceptionUtils.create(context, t);
-        }
+        return createSpaceExecutor.create(sessionToken, creations);
     }
 
     @Override
@@ -337,16 +275,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @DatabaseCreateOrDeleteModification(value = ObjectKind.PROJECT)
     public List<ProjectPermId> createProjects(String sessionToken, List<ProjectCreation> creations)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        try
-        {
-            return createProjectExecutor.create(context, creations);
-        } catch (Throwable t)
-        {
-            throw ExceptionUtils.create(context, t);
-        }
+        return createProjectExecutor.create(sessionToken, creations);
     }
 
     @Override
@@ -357,19 +286,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     public List<ExperimentPermId> createExperiments(String sessionToken,
             List<ExperimentCreation> creations)
     {
-        // REPLACES:
-        // - ServiceForDataStoreServer.registerExperiment()
-
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        try
-        {
-            return createExperimentExecutor.create(context, creations);
-        } catch (Throwable t)
-        {
-            throw ExceptionUtils.create(context, t);
-        }
+        return createExperimentExecutor.create(sessionToken, creations);
     }
 
     @Override
@@ -380,20 +297,17 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     public List<SamplePermId> createSamples(String sessionToken,
             List<SampleCreation> creations)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
+        return createSampleExecutor.create(sessionToken, creations);
+    }
 
-        try
-        {
-            return createSampleExecutor.create(context, creations);
-        } catch (Throwable t)
-        {
-            throw ExceptionUtils.create(context, t);
-        } finally
-        {
-            // the clear is necessary, as registering samples involves sql queries, that are not visible to cached PE objects
-            getDAOFactory().getSessionFactory().getCurrentSession().clear();
-        }
+    @Override
+    @Transactional
+    @RolesAllowed({ RoleWithHierarchy.INSTANCE_ADMIN, RoleWithHierarchy.SPACE_ETL_SERVER })
+    @Capability("WRITE_MATERIAL")
+    @DatabaseCreateOrDeleteModification(value = ObjectKind.MATERIAL)
+    public List<MaterialPermId> createMaterials(String sessionToken, List<MaterialCreation> creations)
+    {
+        return createMaterialExecutor.create(sessionToken, creations);
     }
 
     @Override
@@ -401,18 +315,9 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @RolesAllowed({ RoleWithHierarchy.SPACE_ADMIN, RoleWithHierarchy.SPACE_ETL_SERVER })
     @Capability("UPDATE_SPACE")
     @DatabaseUpdateModification(value = ObjectKind.SPACE)
-    public void updateSpaces(String sessionToken, List<SpaceUpdate> spaceUpdates)
+    public void updateSpaces(String sessionToken, List<SpaceUpdate> updates)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        try
-        {
-            updateSpaceExecutor.update(context, spaceUpdates);
-        } catch (Throwable t)
-        {
-            throw ExceptionUtils.create(context, t);
-        }
+        updateSpaceExecutor.update(sessionToken, updates);
     }
 
     @Override
@@ -420,18 +325,9 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @RolesAllowed({ RoleWithHierarchy.SPACE_POWER_USER, RoleWithHierarchy.SPACE_ETL_SERVER })
     @Capability("WRITE_PROJECT")
     @DatabaseUpdateModification(value = ObjectKind.PROJECT)
-    public void updateProjects(String sessionToken, List<ProjectUpdate> projectUpdates)
+    public void updateProjects(String sessionToken, List<ProjectUpdate> updates)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        try
-        {
-            updateProjectExecutor.update(context, projectUpdates);
-        } catch (Throwable t)
-        {
-            throw ExceptionUtils.create(context, t);
-        }
+        updateProjectExecutor.update(sessionToken, updates);
     }
 
     @Override
@@ -439,22 +335,9 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @RolesAllowed({ RoleWithHierarchy.SPACE_USER, RoleWithHierarchy.SPACE_ETL_SERVER })
     @Capability("WRITE_EXPERIMENT")
     @DatabaseUpdateModification(value = ObjectKind.EXPERIMENT)
-    public void updateExperiments(String sessionToken, List<ExperimentUpdate> experimentUpdates)
+    public void updateExperiments(String sessionToken, List<ExperimentUpdate> updates)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        try
-        {
-            updateExperimentExecutor.update(context, experimentUpdates);
-        } catch (Throwable t)
-        {
-            throw ExceptionUtils.create(context, t);
-        } finally
-        {
-            // the clear is necessary, as updating experiments involves sql queries, that are not visible to cached PE objects
-            getDAOFactory().getSessionFactory().getCurrentSession().clear();
-        }
+        updateExperimentExecutor.update(sessionToken, updates);
     }
 
     @Override
@@ -464,20 +347,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @DatabaseUpdateModification(value = ObjectKind.SAMPLE)
     public void updateSamples(String sessionToken, List<SampleUpdate> updates)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        try
-        {
-            updateSampleExecutor.update(context, updates);
-        } catch (Throwable t)
-        {
-            throw ExceptionUtils.create(context, t);
-        } finally
-        {
-            // the clear is necessary, as registering samples involves sql queries, that are not visible to cached PE objects
-            getDAOFactory().getSessionFactory().getCurrentSession().clear();
-        }
+        updateSampleExecutor.update(sessionToken, updates);
     }
 
     @Override
@@ -487,16 +357,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @DatabaseUpdateModification(value = ObjectKind.MATERIAL)
     public void updateMaterials(String sessionToken, List<MaterialUpdate> updates)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        try
-        {
-            updateMaterialExecutor.update(context, updates);
-        } catch (Throwable t)
-        {
-            throw ExceptionUtils.create(context, t);
-        }
+        updateMaterialExecutor.update(sessionToken, updates);
     }
 
     @Override
@@ -506,16 +367,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @DatabaseUpdateModification(value = ObjectKind.DATA_SET)
     public void updateDataSets(String sessionToken, List<DataSetUpdate> updates)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        try
-        {
-            updateDataSetExecutor.update(context, updates);
-        } catch (Throwable t)
-        {
-            throw ExceptionUtils.create(context, t);
-        }
+        updateDataSetExecutor.update(sessionToken, updates);
     }
 
     @Override
@@ -523,14 +375,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @RolesAllowed({ RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public Map<ISpaceId, Space> mapSpaces(String sessionToken, List<? extends ISpaceId> spaceIds, SpaceFetchOptions fetchOptions)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        Map<ISpaceId, SpacePE> map = mapSpaceByIdExecutor.map(context, spaceIds);
-
-        return new MapTranslator<ISpaceId, ISpaceId, SpacePE, Space>().translate(map, new IdentityTranslator<ISpaceId>(),
-                new SpaceTranslator(new TranslationContext(session, managedPropertyEvaluatorFactory),
-                        fetchOptions));
+        return mapSpaceExecutor.map(sessionToken, spaceIds, fetchOptions);
     }
 
     @Override
@@ -538,14 +383,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @RolesAllowed({ RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public Map<IProjectId, Project> mapProjects(String sessionToken, List<? extends IProjectId> projectIds, ProjectFetchOptions fetchOptions)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        Map<IProjectId, ProjectPE> map = mapProjectByIdExecutor.map(context, projectIds);
-
-        return new MapTranslator<IProjectId, IProjectId, ProjectPE, Project>().translate(map, new IdentityTranslator<IProjectId>(),
-                new ProjectTranslator(new TranslationContext(session, managedPropertyEvaluatorFactory),
-                        fetchOptions));
+        return mapProjectExecutor.map(sessionToken, projectIds, fetchOptions);
     }
 
     @Override
@@ -554,14 +392,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     public Map<IExperimentId, Experiment> mapExperiments(String sessionToken,
             List<? extends IExperimentId> experimentIds, ExperimentFetchOptions fetchOptions)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        Map<IExperimentId, ExperimentPE> map = mapExperimentByIdExecutor.map(context, experimentIds);
-
-        return new MapTranslator<IExperimentId, IExperimentId, ExperimentPE, Experiment>().translate(map, new IdentityTranslator<IExperimentId>(),
-                new ExperimentTranslator(new TranslationContext(session, managedPropertyEvaluatorFactory),
-                        fetchOptions));
+        return mapExperimentExecutor.map(sessionToken, experimentIds, fetchOptions);
     }
 
     @Override
@@ -570,14 +401,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     public Map<ISampleId, Sample> mapSamples(String sessionToken, List<? extends ISampleId> sampleIds,
             SampleFetchOptions fetchOptions)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        Map<ISampleId, SamplePE> map = mapSampleByIdExecutor.map(context, sampleIds);
-
-        return new MapTranslator<ISampleId, ISampleId, SamplePE, Sample>().translate(map, new IdentityTranslator<ISampleId>(),
-                new SampleTranslator(new TranslationContext(session, managedPropertyEvaluatorFactory),
-                        fetchOptions));
+        return mapSampleExecutor.map(sessionToken, sampleIds, fetchOptions);
     }
 
     @Override
@@ -585,14 +409,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @RolesAllowed({ RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public Map<IDataSetId, DataSet> mapDataSets(String sessionToken, List<? extends IDataSetId> dataSetIds, DataSetFetchOptions fetchOptions)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        Map<IDataSetId, DataPE> map = mapDataSetByIdExecutor.map(context, dataSetIds);
-
-        return new MapTranslator<IDataSetId, IDataSetId, DataPE, DataSet>().translate(map, new IdentityTranslator<IDataSetId>(),
-                new DataSetTranslator(new TranslationContext(session, managedPropertyEvaluatorFactory),
-                        fetchOptions));
+        return mapDataSetExecutor.map(sessionToken, dataSetIds, fetchOptions);
     }
 
     @Override
@@ -600,14 +417,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @RolesAllowed({ RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public Map<IMaterialId, Material> mapMaterials(String sessionToken, List<? extends IMaterialId> materialIds, MaterialFetchOptions fetchOptions)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        Map<IMaterialId, MaterialPE> map = mapMaterialByIdExecutor.map(context, materialIds);
-
-        return new MapTranslator<IMaterialId, IMaterialId, MaterialPE, Material>().translate(map, new IdentityTranslator<IMaterialId>(),
-                new MaterialTranslator(new TranslationContext(session, managedPropertyEvaluatorFactory),
-                        fetchOptions));
+        return mapMaterialExecutor.map(sessionToken, materialIds, fetchOptions);
     }
 
     @Override
@@ -615,20 +425,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @RolesAllowed({ RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public List<Space> searchSpaces(String sessionToken, SpaceSearchCriterion searchCriterion, SpaceFetchOptions fetchOptions)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        try
-        {
-            List<SpacePE> spaces = searchSpaceExecutor.search(context, searchCriterion);
-
-            Map<SpacePE, Space> translatedMap =
-                    new SpaceTranslator(new TranslationContext(session, managedPropertyEvaluatorFactory), fetchOptions).translate(spaces);
-            return new ArrayList<Space>(translatedMap.values());
-        } catch (Throwable t)
-        {
-            throw ExceptionUtils.create(context, t);
-        }
+        return searchSpaceExecutor.search(sessionToken, searchCriterion, fetchOptions);
     }
 
     @Override
@@ -636,20 +433,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @RolesAllowed({ RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public List<Project> searchProjects(String sessionToken, ProjectSearchCriterion searchCriterion, ProjectFetchOptions fetchOptions)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        try
-        {
-            List<ProjectPE> projects = searchProjectExecutor.search(context, searchCriterion);
-
-            Map<ProjectPE, Project> translatedMap =
-                    new ProjectTranslator(new TranslationContext(session, managedPropertyEvaluatorFactory), fetchOptions).translate(projects);
-            return new ArrayList<Project>(translatedMap.values());
-        } catch (Throwable t)
-        {
-            throw ExceptionUtils.create(context, t);
-        }
+        return searchProjectExecutor.search(sessionToken, searchCriterion, fetchOptions);
     }
 
     @Override
@@ -658,20 +442,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     public List<Experiment> searchExperiments(String sessionToken, ExperimentSearchCriterion searchCriterion,
             ExperimentFetchOptions fetchOptions)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        try
-        {
-            List<ExperimentPE> experiments = searchExperimentExecutor.search(context, searchCriterion);
-
-            Map<ExperimentPE, Experiment> translatedMap =
-                    new ExperimentTranslator(new TranslationContext(session, managedPropertyEvaluatorFactory), fetchOptions).translate(experiments);
-            return new ArrayList<Experiment>(translatedMap.values());
-        } catch (Throwable t)
-        {
-            throw ExceptionUtils.create(context, t);
-        }
+        return searchExperimentExecutor.search(sessionToken, searchCriterion, fetchOptions);
     }
 
     @Override
@@ -679,20 +450,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @RolesAllowed({ RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public List<Sample> searchSamples(String sessionToken, SampleSearchCriterion searchCriterion, SampleFetchOptions fetchOptions)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        try
-        {
-            List<SamplePE> samples = searchSampleExecutor.search(context, searchCriterion);
-
-            Map<SamplePE, Sample> translatedMap =
-                    new SampleTranslator(new TranslationContext(session, managedPropertyEvaluatorFactory), fetchOptions).translate(samples);
-            return new ArrayList<Sample>(translatedMap.values());
-        } catch (Throwable t)
-        {
-            throw ExceptionUtils.create(context, t);
-        }
+        return searchSampleExecutor.search(sessionToken, searchCriterion, fetchOptions);
     }
 
     @Override
@@ -700,20 +458,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @RolesAllowed({ RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public List<DataSet> searchDataSets(String sessionToken, DataSetSearchCriterion searchCriterion, DataSetFetchOptions fetchOptions)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        try
-        {
-            List<DataPE> dataSets = searchDataSetExecutor.search(context, searchCriterion);
-
-            Map<DataPE, DataSet> translatedMap =
-                    new DataSetTranslator(new TranslationContext(session, managedPropertyEvaluatorFactory), fetchOptions).translate(dataSets);
-            return new ArrayList<DataSet>(translatedMap.values());
-        } catch (Throwable t)
-        {
-            throw ExceptionUtils.create(context, t);
-        }
+        return searchDataSetExecutor.search(sessionToken, searchCriterion, fetchOptions);
     }
 
     @Override
@@ -721,20 +466,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @RolesAllowed({ RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public List<Material> searchMaterials(String sessionToken, MaterialSearchCriterion searchCriterion, MaterialFetchOptions fetchOptions)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        try
-        {
-            List<MaterialPE> materials = searchMaterialExecutor.search(context, searchCriterion);
-
-            Map<MaterialPE, Material> translatedMap =
-                    new MaterialTranslator(new TranslationContext(session, managedPropertyEvaluatorFactory), fetchOptions).translate(materials);
-            return new ArrayList<Material>(translatedMap.values());
-        } catch (Throwable t)
-        {
-            throw ExceptionUtils.create(context, t);
-        }
+        return searchMaterialExecutor.search(sessionToken, searchCriterion, fetchOptions);
     }
 
     @Override
@@ -868,20 +600,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @RolesAllowed({ RoleWithHierarchy.SPACE_USER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public List<Deletion> listDeletions(String sessionToken, DeletionFetchOptions fetchOptions)
     {
-        Session session = getSession(sessionToken);
-        OperationContext context = new OperationContext(session);
-
-        try
-        {
-            List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Deletion> deletions = listDeletionExecutor.list(context, fetchOptions);
-            Map<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Deletion, Deletion> translatedMap =
-                    new DeletionTranslator(new TranslationContext(session, managedPropertyEvaluatorFactory), fetchOptions, getDAOFactory())
-                            .translate(deletions);
-            return new ArrayList<Deletion>(translatedMap.values());
-        } catch (Throwable t)
-        {
-            throw ExceptionUtils.create(context, t);
-        }
+        return listDeletionExecutor.listDeletions(sessionToken, fetchOptions);
     }
 
     @Override
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/ApplicationServerApiLogger.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/ApplicationServerApiLogger.java
index 9e7de0099f7..f5fe5a24fc1 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/ApplicationServerApiLogger.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/ApplicationServerApiLogger.java
@@ -63,8 +63,6 @@ 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.space.ISpaceId;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.SpacePermId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.operation.IOperation;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.operation.IOperationResult;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.DataSetSearchCriterion;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.ExperimentSearchCriterion;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.MaterialSearchCriterion;
@@ -112,13 +110,6 @@ public class ApplicationServerApiLogger extends AbstractServerLogger implements
         return null;
     }
 
-    @Override
-    public List<? extends IOperationResult> performOperations(String sessionToken, List<? extends IOperation> operations)
-    {
-        logAccess(sessionToken, "perform-operations", "OPERATIONS(%s)", operations);
-        return null;
-    }
-
     @Override
     public List<SpacePermId> createSpaces(String sessionToken, List<SpaceCreation> newSpaces)
     {
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractCreateMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractCreateMethodExecutor.java
new file mode 100644
index 00000000000..949abb5bc97
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractCreateMethodExecutor.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.OperationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.entity.ICreateEntityExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.utils.ExceptionUtils;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+
+/**
+ * @author pkupczyk
+ */
+public abstract class AbstractCreateMethodExecutor<PERM_ID, CREATION> extends AbstractMethodExecutor implements
+        ICreateMethodExecutor<PERM_ID, CREATION>
+{
+
+    @Autowired
+    private IDAOFactory daoFactory;
+
+    @Override
+    public List<PERM_ID> create(String sessionToken, List<CREATION> creations)
+    {
+        Session session = getSession(sessionToken);
+        OperationContext context = new OperationContext(session);
+
+        try
+        {
+            List<PERM_ID> permIds = getCreateExecutor().create(context, creations);
+            daoFactory.getSessionFactory().getCurrentSession().flush();
+            return permIds;
+        } catch (Throwable t)
+        {
+            throw ExceptionUtils.create(context, t);
+        } finally
+        {
+            daoFactory.getSessionFactory().getCurrentSession().clear();
+        }
+    }
+
+    protected abstract ICreateEntityExecutor<CREATION, PERM_ID> getCreateExecutor();
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractMapMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractMapMethodExecutor.java
new file mode 100644
index 00000000000..0dab0672cd9
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractMapMethodExecutor.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.OperationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IMapObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.utils.ExceptionUtils;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.IObjectId;
+import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+
+/**
+ * @author pkupczyk
+ */
+public abstract class AbstractMapMethodExecutor<OBJECT_ID extends IObjectId, OBJECT_PE, OBJECT, FETCH_OPTIONS> extends AbstractMethodExecutor
+{
+
+    public Map<OBJECT_ID, OBJECT> map(String sessionToken, List<? extends OBJECT_ID> objectIds, FETCH_OPTIONS fetchOptions)
+    {
+        Session session = getSession(sessionToken);
+        return translate(session, map(session, objectIds), fetchOptions);
+    }
+
+    private Map<OBJECT_ID, OBJECT_PE> map(Session session, List<? extends OBJECT_ID> objectIds)
+    {
+        OperationContext context = new OperationContext(session);
+        try
+        {
+            return getMapExecutor().map(context, objectIds);
+        } catch (Throwable t)
+        {
+            throw ExceptionUtils.create(context, t);
+        }
+    }
+
+    private Map<OBJECT_ID, OBJECT> translate(Session session, Map<OBJECT_ID, OBJECT_PE> idToPeMap, FETCH_OPTIONS fetchOptions)
+    {
+        if (idToPeMap == null || idToPeMap.isEmpty())
+        {
+            return Collections.emptyMap();
+        }
+
+        TranslationContext context = new TranslationContext(session);
+        Map<OBJECT_PE, OBJECT> peToObjectMap = getTranslator().translate(context, idToPeMap.values(), fetchOptions);
+        Map<OBJECT_ID, OBJECT> idToObjectMap = new LinkedHashMap<OBJECT_ID, OBJECT>();
+
+        for (Map.Entry<OBJECT_ID, OBJECT_PE> entry : idToPeMap.entrySet())
+        {
+            OBJECT_ID id = entry.getKey();
+            OBJECT_PE pe = entry.getValue();
+            OBJECT object = peToObjectMap.get(pe);
+
+            if (object != null)
+            {
+                idToObjectMap.put(id, object);
+            }
+        }
+
+        return idToObjectMap;
+    }
+
+    protected abstract IMapObjectByIdExecutor<OBJECT_ID, OBJECT_PE> getMapExecutor();
+
+    protected abstract ITranslator<OBJECT_PE, OBJECT, FETCH_OPTIONS> getTranslator();
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractMethodExecutor.java
new file mode 100644
index 00000000000..901056051f3
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractMethodExecutor.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import javax.annotation.Resource;
+
+import ch.systemsx.cisd.openbis.generic.server.ComponentNames;
+import ch.systemsx.cisd.openbis.generic.shared.IOpenBisSessionManager;
+import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+
+/**
+ * @author pkupczyk
+ */
+public class AbstractMethodExecutor
+{
+
+    @Resource(name = ComponentNames.SESSION_MANAGER)
+    protected IOpenBisSessionManager sessionManager;
+
+    protected Session getSession(String sessionToken)
+    {
+        return sessionManager.getSession(sessionToken);
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractSearchMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractSearchMethodExecutor.java
new file mode 100644
index 00000000000..5f58e17de97
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractSearchMethodExecutor.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.OperationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.ISearchObjectExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.utils.ExceptionUtils;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.AbstractObjectSearchCriterion;
+import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+
+/**
+ * @author pkupczyk
+ */
+public abstract class AbstractSearchMethodExecutor<OBJECT, OBJECT_PE, CRITERION extends AbstractObjectSearchCriterion<?>, FETCH_OPTIONS> extends
+        AbstractMethodExecutor implements ISearchMethodExecutor<OBJECT, CRITERION, FETCH_OPTIONS>
+{
+
+    @Override
+    public List<OBJECT> search(String sessionToken, CRITERION criterion, FETCH_OPTIONS fetchOptions)
+    {
+        Session session = getSession(sessionToken);
+        return translate(session, search(session, criterion), fetchOptions);
+    }
+
+    private List<OBJECT_PE> search(Session session, CRITERION criterion)
+    {
+        OperationContext context = new OperationContext(session);
+        try
+        {
+            return getSearchExecutor().search(context, criterion);
+        } catch (Throwable t)
+        {
+            throw ExceptionUtils.create(context, t);
+        }
+    }
+
+    private List<OBJECT> translate(Session session, List<OBJECT_PE> peList, FETCH_OPTIONS fetchOptions)
+    {
+        if (peList == null || peList.isEmpty())
+        {
+            return Collections.emptyList();
+        }
+
+        TranslationContext context = new TranslationContext(session);
+        Map<OBJECT_PE, OBJECT> peToObjectMap = getTranslator().translate(context, peList, fetchOptions);
+        return new ArrayList<OBJECT>(peToObjectMap.values());
+    }
+
+    protected abstract ISearchObjectExecutor<CRITERION, OBJECT_PE> getSearchExecutor();
+
+    protected abstract ITranslator<OBJECT_PE, OBJECT, FETCH_OPTIONS> getTranslator();
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractUpdateMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractUpdateMethodExecutor.java
new file mode 100644
index 00000000000..a7438797278
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractUpdateMethodExecutor.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.OperationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.entity.IUpdateEntityExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.utils.ExceptionUtils;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+
+/**
+ * @author pkupczyk
+ */
+public abstract class AbstractUpdateMethodExecutor<UPDATE> extends AbstractMethodExecutor implements
+        IUpdateMethodExecutor<UPDATE>
+{
+
+    @Autowired
+    private IDAOFactory daoFactory;
+
+    @Override
+    public void update(String sessionToken, List<UPDATE> updates)
+    {
+        Session session = getSession(sessionToken);
+        OperationContext context = new OperationContext(session);
+
+        try
+        {
+            getUpdateExecutor().update(context, updates);
+            daoFactory.getSessionFactory().getCurrentSession().flush();
+        } catch (Throwable t)
+        {
+            throw ExceptionUtils.create(context, t);
+        } finally
+        {
+
+            daoFactory.getSessionFactory().getCurrentSession().clear();
+        }
+    }
+
+    protected abstract IUpdateEntityExecutor<UPDATE> getUpdateExecutor();
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateExperimentMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateExperimentMethodExecutor.java
new file mode 100644
index 00000000000..3a26364f127
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateExperimentMethodExecutor.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.entity.ICreateEntityExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.experiment.ICreateExperimentExecutor;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.ExperimentCreation;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.ExperimentPermId;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class CreateExperimentMethodExecutor extends AbstractCreateMethodExecutor<ExperimentPermId, ExperimentCreation> implements
+        ICreateExperimentMethodExecutor
+{
+
+    @Autowired
+    private ICreateExperimentExecutor createExecutor;
+
+    @Override
+    protected ICreateEntityExecutor<ExperimentCreation, ExperimentPermId> getCreateExecutor()
+    {
+        return createExecutor;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateMaterialMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateMaterialMethodExecutor.java
new file mode 100644
index 00000000000..db5e073d8ef
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateMaterialMethodExecutor.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.entity.ICreateEntityExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.material.ICreateMaterialExecutor;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.material.MaterialCreation;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.material.MaterialPermId;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class CreateMaterialMethodExecutor extends AbstractCreateMethodExecutor<MaterialPermId, MaterialCreation> implements
+        ICreateMaterialMethodExecutor
+{
+
+    @Autowired
+    private ICreateMaterialExecutor createExecutor;
+
+    @Override
+    protected ICreateEntityExecutor<MaterialCreation, MaterialPermId> getCreateExecutor()
+    {
+        return createExecutor;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateProjectMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateProjectMethodExecutor.java
new file mode 100644
index 00000000000..9aca9fded59
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateProjectMethodExecutor.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.entity.ICreateEntityExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.project.ICreateProjectExecutor;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.project.ProjectCreation;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.ProjectPermId;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class CreateProjectMethodExecutor extends AbstractCreateMethodExecutor<ProjectPermId, ProjectCreation> implements ICreateProjectMethodExecutor
+{
+
+    @Autowired
+    private ICreateProjectExecutor createExecutor;
+
+    @Override
+    protected ICreateEntityExecutor<ProjectCreation, ProjectPermId> getCreateExecutor()
+    {
+        return createExecutor;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateSampleMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateSampleMethodExecutor.java
new file mode 100644
index 00000000000..0667f9ab041
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateSampleMethodExecutor.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.entity.ICreateEntityExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.sample.ICreateSampleExecutor;
+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.SamplePermId;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class CreateSampleMethodExecutor extends AbstractCreateMethodExecutor<SamplePermId, SampleCreation> implements
+        ICreateSampleMethodExecutor
+{
+
+    @Autowired
+    private ICreateSampleExecutor createExecutor;
+
+    @Override
+    protected ICreateEntityExecutor<SampleCreation, SamplePermId> getCreateExecutor()
+    {
+        return createExecutor;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateSpaceMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateSpaceMethodExecutor.java
new file mode 100644
index 00000000000..4017f8df210
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/CreateSpaceMethodExecutor.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.entity.ICreateEntityExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.space.ICreateSpaceExecutor;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.space.SpaceCreation;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.SpacePermId;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class CreateSpaceMethodExecutor extends AbstractCreateMethodExecutor<SpacePermId, SpaceCreation> implements ICreateSpaceMethodExecutor
+{
+
+    @Autowired
+    private ICreateSpaceExecutor createExecutor;
+
+    @Override
+    protected ICreateEntityExecutor<SpaceCreation, SpacePermId> getCreateExecutor()
+    {
+        return createExecutor;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateExperimentMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateExperimentMethodExecutor.java
new file mode 100644
index 00000000000..9bc72025120
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateExperimentMethodExecutor.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.ExperimentCreation;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.ExperimentPermId;
+
+/**
+ * @author pkupczyk
+ */
+public interface ICreateExperimentMethodExecutor extends ICreateMethodExecutor<ExperimentPermId, ExperimentCreation>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateMaterialMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateMaterialMethodExecutor.java
new file mode 100644
index 00000000000..8b5ca0635bd
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateMaterialMethodExecutor.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.material.MaterialCreation;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.material.MaterialPermId;
+
+/**
+ * @author pkupczyk
+ */
+public interface ICreateMaterialMethodExecutor extends ICreateMethodExecutor<MaterialPermId, MaterialCreation>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/common/IdentityTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateMethodExecutor.java
similarity index 62%
rename from openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/common/IdentityTranslator.java
rename to openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateMethodExecutor.java
index c04af7aa822..13cf5e2cea0 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/common/IdentityTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateMethodExecutor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 ETH Zuerich, Scientific IT Services
+ * Copyright 2015 ETH Zuerich, CISD
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,19 +14,16 @@
  * limitations under the License.
  */
 
-package ch.ethz.sis.openbis.generic.server.api.v3.translator.common;
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
 
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractTranslator;
+import java.util.List;
 
 /**
  * @author pkupczyk
  */
-public class IdentityTranslator<T> extends AbstractTranslator<T, T>
+public interface ICreateMethodExecutor<PERM_ID, CREATION>
 {
 
-    @Override
-    protected T doTranslate(T object)
-    {
-        return object;
-    }
+    public List<PERM_ID> create(String sessionToken, List<CREATION> creations);
+
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateProjectMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateProjectMethodExecutor.java
new file mode 100644
index 00000000000..10d690207af
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateProjectMethodExecutor.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.project.ProjectCreation;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.ProjectPermId;
+
+/**
+ * @author pkupczyk
+ */
+public interface ICreateProjectMethodExecutor extends ICreateMethodExecutor<ProjectPermId, ProjectCreation>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateSampleMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateSampleMethodExecutor.java
new file mode 100644
index 00000000000..47e730c22b1
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateSampleMethodExecutor.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+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.SamplePermId;
+
+/**
+ * @author pkupczyk
+ */
+public interface ICreateSampleMethodExecutor extends ICreateMethodExecutor<SamplePermId, SampleCreation>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateSpaceMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateSpaceMethodExecutor.java
new file mode 100644
index 00000000000..b1999ebb661
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ICreateSpaceMethodExecutor.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.space.SpaceCreation;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.SpacePermId;
+
+/**
+ * @author pkupczyk
+ */
+public interface ICreateSpaceMethodExecutor extends ICreateMethodExecutor<SpacePermId, SpaceCreation>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IListDeletionMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IListDeletionMethodExecutor.java
new file mode 100644
index 00000000000..868579a6821
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IListDeletionMethodExecutor.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import java.util.List;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.deletion.Deletion;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.deletion.DeletionFetchOptions;
+
+/**
+ * @author pkupczyk
+ */
+public interface IListDeletionMethodExecutor
+{
+
+    public List<Deletion> listDeletions(String sessionToken, DeletionFetchOptions fetchOptions);
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapDataSetMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapDataSetMethodExecutor.java
new file mode 100644
index 00000000000..9a4dfc389f7
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapDataSetMethodExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.DataSet;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.dataset.DataSetFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.dataset.IDataSetId;
+
+/**
+ * @author pkupczyk
+ */
+public interface IMapDataSetMethodExecutor extends IMapMethodExecutor<IDataSetId, DataSet, DataSetFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapExperimentMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapExperimentMethodExecutor.java
new file mode 100644
index 00000000000..6d9395d8040
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapExperimentMethodExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.Experiment;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.experiment.ExperimentFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.IExperimentId;
+
+/**
+ * @author pkupczyk
+ */
+public interface IMapExperimentMethodExecutor extends IMapMethodExecutor<IExperimentId, Experiment, ExperimentFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapMaterialMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapMaterialMethodExecutor.java
new file mode 100644
index 00000000000..d5f9947c175
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapMaterialMethodExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.material.Material;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.material.MaterialFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.material.IMaterialId;
+
+/**
+ * @author pkupczyk
+ */
+public interface IMapMaterialMethodExecutor extends IMapMethodExecutor<IMaterialId, Material, MaterialFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapMethodExecutor.java
new file mode 100644
index 00000000000..3b8ed95a82b
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapMethodExecutor.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author pkupczyk
+ */
+public interface IMapMethodExecutor<OBJECT_ID, OBJECT, FETCH_OPTIONS>
+{
+
+    public Map<OBJECT_ID, OBJECT> map(String sessionToken, List<? extends OBJECT_ID> objectIds, FETCH_OPTIONS fetchOptions);
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapProjectMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapProjectMethodExecutor.java
new file mode 100644
index 00000000000..6cc78893c9c
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapProjectMethodExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.project.Project;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.project.ProjectFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.IProjectId;
+
+/**
+ * @author pkupczyk
+ */
+public interface IMapProjectMethodExecutor extends IMapMethodExecutor<IProjectId, Project, ProjectFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapSampleMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapSampleMethodExecutor.java
new file mode 100644
index 00000000000..03538346918
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapSampleMethodExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.Sample;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sample.SampleFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
+
+/**
+ * @author pkupczyk
+ */
+public interface IMapSampleMethodExecutor extends IMapMethodExecutor<ISampleId, Sample, SampleFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapSpaceMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapSpaceMethodExecutor.java
new file mode 100644
index 00000000000..140d43811ef
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IMapSpaceMethodExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.space.Space;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.space.SpaceFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.ISpaceId;
+
+/**
+ * @author pkupczyk
+ */
+public interface IMapSpaceMethodExecutor extends IMapMethodExecutor<ISpaceId, Space, SpaceFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchDataSetMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchDataSetMethodExecutor.java
new file mode 100644
index 00000000000..9231273a86c
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchDataSetMethodExecutor.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.DataSet;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.dataset.DataSetFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.DataSetSearchCriterion;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISearchDataSetMethodExecutor extends
+        ISearchMethodExecutor<DataSet, DataSetSearchCriterion, DataSetFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchExperimentMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchExperimentMethodExecutor.java
new file mode 100644
index 00000000000..c5fc82fafd5
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchExperimentMethodExecutor.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.Experiment;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.experiment.ExperimentFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.ExperimentSearchCriterion;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISearchExperimentMethodExecutor extends
+        ISearchMethodExecutor<Experiment, ExperimentSearchCriterion, ExperimentFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchMaterialMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchMaterialMethodExecutor.java
new file mode 100644
index 00000000000..9c92731df30
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchMaterialMethodExecutor.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.material.Material;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.material.MaterialFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.MaterialSearchCriterion;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISearchMaterialMethodExecutor extends
+        ISearchMethodExecutor<Material, MaterialSearchCriterion, MaterialFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchMethodExecutor.java
new file mode 100644
index 00000000000..0367622f1ca
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchMethodExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import java.util.List;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISearchMethodExecutor<OBJECT, CRITERION, FETCH_OPTIONS>
+{
+
+    public List<OBJECT> search(String sessionToken, CRITERION searchCriterion, FETCH_OPTIONS fetchOptions);
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchProjectMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchProjectMethodExecutor.java
new file mode 100644
index 00000000000..449a4068ab8
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchProjectMethodExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.project.Project;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.project.ProjectFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.ProjectSearchCriterion;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISearchProjectMethodExecutor extends ISearchMethodExecutor<Project, ProjectSearchCriterion, ProjectFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchSampleMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchSampleMethodExecutor.java
new file mode 100644
index 00000000000..c49f37dd1c2
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchSampleMethodExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.Sample;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sample.SampleFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SampleSearchCriterion;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISearchSampleMethodExecutor extends ISearchMethodExecutor<Sample, SampleSearchCriterion, SampleFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchSpaceMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchSpaceMethodExecutor.java
new file mode 100644
index 00000000000..bfbbcc0e676
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchSpaceMethodExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.space.Space;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.space.SpaceFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SpaceSearchCriterion;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISearchSpaceMethodExecutor extends ISearchMethodExecutor<Space, SpaceSearchCriterion, SpaceFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateDataSetMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateDataSetMethodExecutor.java
new file mode 100644
index 00000000000..b6503d6e254
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateDataSetMethodExecutor.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.DataSetUpdate;
+
+/**
+ * @author pkupczyk
+ */
+public interface IUpdateDataSetMethodExecutor extends IUpdateMethodExecutor<DataSetUpdate>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateExperimentMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateExperimentMethodExecutor.java
new file mode 100644
index 00000000000..065b3ef81bd
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateExperimentMethodExecutor.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.ExperimentUpdate;
+
+/**
+ * @author pkupczyk
+ */
+public interface IUpdateExperimentMethodExecutor extends IUpdateMethodExecutor<ExperimentUpdate>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateMaterialMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateMaterialMethodExecutor.java
new file mode 100644
index 00000000000..121ab089d22
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateMaterialMethodExecutor.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.material.MaterialUpdate;
+
+/**
+ * @author pkupczyk
+ */
+public interface IUpdateMaterialMethodExecutor extends IUpdateMethodExecutor<MaterialUpdate>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateMethodExecutor.java
new file mode 100644
index 00000000000..f720025cd34
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateMethodExecutor.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import java.util.List;
+
+/**
+ * @author pkupczyk
+ */
+public interface IUpdateMethodExecutor<UPDATE>
+{
+
+    public void update(String sessionToken, List<UPDATE> updates);
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateProjectMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateProjectMethodExecutor.java
new file mode 100644
index 00000000000..15ac2a1f45e
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateProjectMethodExecutor.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.project.ProjectUpdate;
+
+/**
+ * @author pkupczyk
+ */
+public interface IUpdateProjectMethodExecutor extends IUpdateMethodExecutor<ProjectUpdate>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateSampleMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateSampleMethodExecutor.java
new file mode 100644
index 00000000000..8bef53f4cb2
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateSampleMethodExecutor.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleUpdate;
+
+/**
+ * @author pkupczyk
+ */
+public interface IUpdateSampleMethodExecutor extends IUpdateMethodExecutor<SampleUpdate>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateSpaceMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateSpaceMethodExecutor.java
new file mode 100644
index 00000000000..a3ff0925286
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/IUpdateSpaceMethodExecutor.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.space.SpaceUpdate;
+
+/**
+ * @author pkupczyk
+ */
+public interface IUpdateSpaceMethodExecutor extends IUpdateMethodExecutor<SpaceUpdate>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ListDeletionMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ListDeletionMethodExecutor.java
new file mode 100644
index 00000000000..7e6849474f2
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ListDeletionMethodExecutor.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import java.util.ArrayList;
+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.OperationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.deletion.IListDeletionExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.deletion.IDeletionTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.utils.ExceptionUtils;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.deletion.Deletion;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.deletion.DeletionFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class ListDeletionMethodExecutor extends AbstractMethodExecutor implements IListDeletionMethodExecutor
+{
+
+    @Autowired
+    private IListDeletionExecutor listExecutor;
+
+    @Autowired
+    private IDeletionTranslator translator;
+
+    @Override
+    public List<Deletion> listDeletions(String sessionToken, DeletionFetchOptions fetchOptions)
+    {
+        Session session = getSession(sessionToken);
+        OperationContext context = new OperationContext(session);
+        try
+        {
+            List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Deletion> deletions = listExecutor.list(context, fetchOptions);
+
+            Map<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Deletion, Deletion> translatedMap =
+                    translator.translate(new TranslationContext(session), deletions, fetchOptions);
+
+            return new ArrayList<Deletion>(translatedMap.values());
+        } catch (Throwable t)
+        {
+            throw ExceptionUtils.create(context, t);
+        }
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapDataSetMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapDataSetMethodExecutor.java
new file mode 100644
index 00000000000..c35c7582843
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapDataSetMethodExecutor.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IMapObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.dataset.IMapDataSetByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.dataset.IDataSetTranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.DataSet;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.dataset.DataSetFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.dataset.IDataSetId;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class MapDataSetMethodExecutor extends AbstractMapMethodExecutor<IDataSetId, DataPE, DataSet, DataSetFetchOptions> implements IMapDataSetMethodExecutor
+{
+
+    @Autowired
+    private IMapDataSetByIdExecutor mapExecutor;
+
+    @Autowired
+    private IDataSetTranslator translator;
+
+    @Override
+    protected IMapObjectByIdExecutor<IDataSetId, DataPE> getMapExecutor()
+    {
+        return mapExecutor;
+    }
+
+    @Override
+    protected ITranslator<DataPE, DataSet, DataSetFetchOptions> getTranslator()
+    {
+        return translator;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapExperimentMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapExperimentMethodExecutor.java
new file mode 100644
index 00000000000..243bbedff58
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapExperimentMethodExecutor.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IMapObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.experiment.IMapExperimentByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.experiment.IExperimentTranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.Experiment;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.experiment.ExperimentFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.experiment.IExperimentId;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class MapExperimentMethodExecutor extends AbstractMapMethodExecutor<IExperimentId, ExperimentPE, Experiment, ExperimentFetchOptions> implements
+        IMapExperimentMethodExecutor
+{
+
+    @Autowired
+    private IMapExperimentByIdExecutor mapExecutor;
+
+    @Autowired
+    private IExperimentTranslator translator;
+
+    @Override
+    protected IMapObjectByIdExecutor<IExperimentId, ExperimentPE> getMapExecutor()
+    {
+        return mapExecutor;
+    }
+
+    @Override
+    protected ITranslator<ExperimentPE, Experiment, ExperimentFetchOptions> getTranslator()
+    {
+        return translator;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapMaterialMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapMaterialMethodExecutor.java
new file mode 100644
index 00000000000..311ed37167f
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapMaterialMethodExecutor.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IMapObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.material.IMapMaterialByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.material.IMaterialTranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.material.Material;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.material.MaterialFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.material.IMaterialId;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class MapMaterialMethodExecutor extends AbstractMapMethodExecutor<IMaterialId, MaterialPE, Material, MaterialFetchOptions> implements
+        IMapMaterialMethodExecutor
+{
+
+    @Autowired
+    private IMapMaterialByIdExecutor mapExecutor;
+
+    @Autowired
+    private IMaterialTranslator translator;
+
+    @Override
+    protected IMapObjectByIdExecutor<IMaterialId, MaterialPE> getMapExecutor()
+    {
+        return mapExecutor;
+    }
+
+    @Override
+    protected ITranslator<MaterialPE, Material, MaterialFetchOptions> getTranslator()
+    {
+        return translator;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapProjectMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapProjectMethodExecutor.java
new file mode 100644
index 00000000000..62f410b958a
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapProjectMethodExecutor.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IMapObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.project.IMapProjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.project.IProjectTranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.project.Project;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.project.ProjectFetchOptions;
+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 MapProjectMethodExecutor extends AbstractMapMethodExecutor<IProjectId, ProjectPE, Project, ProjectFetchOptions> implements
+        IMapProjectMethodExecutor
+{
+
+    @Autowired
+    private IMapProjectByIdExecutor mapExecutor;
+
+    @Autowired
+    private IProjectTranslator translator;
+
+    @Override
+    protected IMapObjectByIdExecutor<IProjectId, ProjectPE> getMapExecutor()
+    {
+        return mapExecutor;
+    }
+
+    @Override
+    protected ITranslator<ProjectPE, Project, ProjectFetchOptions> getTranslator()
+    {
+        return translator;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapSampleMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapSampleMethodExecutor.java
new file mode 100644
index 00000000000..8276b488e6c
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapSampleMethodExecutor.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IMapObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.sample.IMapSampleByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.sample.ISampleTranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.Sample;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sample.SampleFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.sample.ISampleId;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class MapSampleMethodExecutor extends AbstractMapMethodExecutor<ISampleId, SamplePE, Sample, SampleFetchOptions> implements IMapSampleMethodExecutor
+{
+
+    @Autowired
+    private IMapSampleByIdExecutor mapExecutor;
+
+    @Autowired
+    private ISampleTranslator translator;
+
+    @Override
+    protected IMapObjectByIdExecutor<ISampleId, SamplePE> getMapExecutor()
+    {
+        return mapExecutor;
+    }
+
+    @Override
+    protected ITranslator<SamplePE, Sample, SampleFetchOptions> getTranslator()
+    {
+        return translator;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapSpaceMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapSpaceMethodExecutor.java
new file mode 100644
index 00000000000..699e9219cf0
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/MapSpaceMethodExecutor.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.IMapObjectByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.space.IMapSpaceByIdExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.space.ISpaceTranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.space.Space;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.space.SpaceFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.ISpaceId;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class MapSpaceMethodExecutor extends AbstractMapMethodExecutor<ISpaceId, SpacePE, Space, SpaceFetchOptions> implements IMapSpaceMethodExecutor
+{
+
+    @Autowired
+    private IMapSpaceByIdExecutor mapExecutor;
+
+    @Autowired
+    private ISpaceTranslator translator;
+
+    @Override
+    protected IMapObjectByIdExecutor<ISpaceId, SpacePE> getMapExecutor()
+    {
+        return mapExecutor;
+    }
+
+    @Override
+    protected ITranslator<SpacePE, Space, SpaceFetchOptions> getTranslator()
+    {
+        return translator;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchDataSetMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchDataSetMethodExecutor.java
new file mode 100644
index 00000000000..7e067900098
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchDataSetMethodExecutor.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.ISearchObjectExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.dataset.ISearchDataSetExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.dataset.IDataSetTranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.DataSet;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.dataset.DataSetFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.DataSetSearchCriterion;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class SearchDataSetMethodExecutor extends
+        AbstractSearchMethodExecutor<DataSet, DataPE, DataSetSearchCriterion, DataSetFetchOptions>
+        implements ISearchDataSetMethodExecutor
+{
+
+    @Autowired
+    private ISearchDataSetExecutor searchExecutor;
+
+    @Autowired
+    private IDataSetTranslator translator;
+
+    @Override
+    protected ISearchObjectExecutor<DataSetSearchCriterion, DataPE> getSearchExecutor()
+    {
+        return searchExecutor;
+    }
+
+    @Override
+    protected ITranslator<DataPE, DataSet, DataSetFetchOptions> getTranslator()
+    {
+        return translator;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchExperimentMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchExperimentMethodExecutor.java
new file mode 100644
index 00000000000..e9c2b95a38d
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchExperimentMethodExecutor.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.ISearchObjectExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.experiment.ISearchExperimentExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.experiment.IExperimentTranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.Experiment;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.experiment.ExperimentFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.ExperimentSearchCriterion;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class SearchExperimentMethodExecutor extends
+        AbstractSearchMethodExecutor<Experiment, ExperimentPE, ExperimentSearchCriterion, ExperimentFetchOptions>
+        implements ISearchExperimentMethodExecutor
+{
+
+    @Autowired
+    private ISearchExperimentExecutor searchExecutor;
+
+    @Autowired
+    private IExperimentTranslator translator;
+
+    @Override
+    protected ISearchObjectExecutor<ExperimentSearchCriterion, ExperimentPE> getSearchExecutor()
+    {
+        return searchExecutor;
+    }
+
+    @Override
+    protected ITranslator<ExperimentPE, Experiment, ExperimentFetchOptions> getTranslator()
+    {
+        return translator;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchMaterialMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchMaterialMethodExecutor.java
new file mode 100644
index 00000000000..32bf0b76905
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchMaterialMethodExecutor.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.ISearchObjectExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.material.ISearchMaterialExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.material.IMaterialTranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.material.Material;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.material.MaterialFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.MaterialSearchCriterion;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class SearchMaterialMethodExecutor extends
+        AbstractSearchMethodExecutor<Material, MaterialPE, MaterialSearchCriterion, MaterialFetchOptions>
+        implements ISearchMaterialMethodExecutor
+{
+
+    @Autowired
+    private ISearchMaterialExecutor searchExecutor;
+
+    @Autowired
+    private IMaterialTranslator translator;
+
+    @Override
+    protected ISearchObjectExecutor<MaterialSearchCriterion, MaterialPE> getSearchExecutor()
+    {
+        return searchExecutor;
+    }
+
+    @Override
+    protected ITranslator<MaterialPE, Material, MaterialFetchOptions> getTranslator()
+    {
+        return translator;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchProjectMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchProjectMethodExecutor.java
new file mode 100644
index 00000000000..8e2b33bf47d
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchProjectMethodExecutor.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.ISearchObjectExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.project.ISearchProjectExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.project.IProjectTranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.project.Project;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.project.ProjectFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.ProjectSearchCriterion;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class SearchProjectMethodExecutor extends AbstractSearchMethodExecutor<Project, ProjectPE, ProjectSearchCriterion, ProjectFetchOptions>
+        implements ISearchProjectMethodExecutor
+{
+
+    @Autowired
+    private ISearchProjectExecutor searchExecutor;
+
+    @Autowired
+    private IProjectTranslator translator;
+
+    @Override
+    protected ISearchObjectExecutor<ProjectSearchCriterion, ProjectPE> getSearchExecutor()
+    {
+        return searchExecutor;
+    }
+
+    @Override
+    protected ITranslator<ProjectPE, Project, ProjectFetchOptions> getTranslator()
+    {
+        return translator;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchSampleMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchSampleMethodExecutor.java
new file mode 100644
index 00000000000..41e3c2d8ea6
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchSampleMethodExecutor.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.ISearchObjectExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.sample.ISearchSampleExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.sample.ISampleTranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.Sample;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sample.SampleFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SampleSearchCriterion;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class SearchSampleMethodExecutor extends
+        AbstractSearchMethodExecutor<Sample, SamplePE, SampleSearchCriterion, SampleFetchOptions>
+        implements ISearchSampleMethodExecutor
+{
+
+    @Autowired
+    private ISearchSampleExecutor searchExecutor;
+
+    @Autowired
+    private ISampleTranslator translator;
+
+    @Override
+    protected ISearchObjectExecutor<SampleSearchCriterion, SamplePE> getSearchExecutor()
+    {
+        return searchExecutor;
+    }
+
+    @Override
+    protected ITranslator<SamplePE, Sample, SampleFetchOptions> getTranslator()
+    {
+        return translator;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchSpaceMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchSpaceMethodExecutor.java
new file mode 100644
index 00000000000..042e2cd7fef
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchSpaceMethodExecutor.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.ISearchObjectExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.space.ISearchSpaceExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.space.ISpaceTranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.space.Space;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.space.SpaceFetchOptions;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SpaceSearchCriterion;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class SearchSpaceMethodExecutor extends AbstractSearchMethodExecutor<Space, SpacePE, SpaceSearchCriterion, SpaceFetchOptions> implements
+        ISearchSpaceMethodExecutor
+{
+
+    @Autowired
+    private ISearchSpaceExecutor searchExecutor;
+
+    @Autowired
+    private ISpaceTranslator translator;
+
+    @Override
+    protected ISearchObjectExecutor<SpaceSearchCriterion, SpacePE> getSearchExecutor()
+    {
+        return searchExecutor;
+    }
+
+    @Override
+    protected ITranslator<SpacePE, Space, SpaceFetchOptions> getTranslator()
+    {
+        return translator;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateDataSetMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateDataSetMethodExecutor.java
new file mode 100644
index 00000000000..ccaad567516
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateDataSetMethodExecutor.java
@@ -0,0 +1,43 @@
+/*
+
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.dataset.IUpdateDataSetExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.entity.IUpdateEntityExecutor;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.DataSetUpdate;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class UpdateDataSetMethodExecutor extends AbstractUpdateMethodExecutor<DataSetUpdate> implements IUpdateDataSetMethodExecutor
+{
+
+    @Autowired
+    private IUpdateDataSetExecutor updateExecutor;
+
+    @Override
+    protected IUpdateEntityExecutor<DataSetUpdate> getUpdateExecutor()
+    {
+        return updateExecutor;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateExperimentMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateExperimentMethodExecutor.java
new file mode 100644
index 00000000000..91f5025a892
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateExperimentMethodExecutor.java
@@ -0,0 +1,43 @@
+/*
+
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.entity.IUpdateEntityExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.experiment.IUpdateExperimentExecutor;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.ExperimentUpdate;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class UpdateExperimentMethodExecutor extends AbstractUpdateMethodExecutor<ExperimentUpdate> implements IUpdateExperimentMethodExecutor
+{
+
+    @Autowired
+    private IUpdateExperimentExecutor updateExecutor;
+
+    @Override
+    protected IUpdateEntityExecutor<ExperimentUpdate> getUpdateExecutor()
+    {
+        return updateExecutor;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateMaterialMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateMaterialMethodExecutor.java
new file mode 100644
index 00000000000..4126eba18b7
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateMaterialMethodExecutor.java
@@ -0,0 +1,43 @@
+/*
+
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.entity.IUpdateEntityExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.material.IUpdateMaterialExecutor;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.material.MaterialUpdate;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class UpdateMaterialMethodExecutor extends AbstractUpdateMethodExecutor<MaterialUpdate> implements IUpdateMaterialMethodExecutor
+{
+
+    @Autowired
+    private IUpdateMaterialExecutor updateExecutor;
+
+    @Override
+    protected IUpdateEntityExecutor<MaterialUpdate> getUpdateExecutor()
+    {
+        return updateExecutor;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateProjectMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateProjectMethodExecutor.java
new file mode 100644
index 00000000000..36c8774f936
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateProjectMethodExecutor.java
@@ -0,0 +1,43 @@
+/*
+
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.entity.IUpdateEntityExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.project.IUpdateProjectExecutor;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.project.ProjectUpdate;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class UpdateProjectMethodExecutor extends AbstractUpdateMethodExecutor<ProjectUpdate> implements IUpdateProjectMethodExecutor
+{
+
+    @Autowired
+    private IUpdateProjectExecutor updateExecutor;
+
+    @Override
+    protected IUpdateEntityExecutor<ProjectUpdate> getUpdateExecutor()
+    {
+        return updateExecutor;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateSampleMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateSampleMethodExecutor.java
new file mode 100644
index 00000000000..f907b67fbf6
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateSampleMethodExecutor.java
@@ -0,0 +1,43 @@
+/*
+
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.entity.IUpdateEntityExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.sample.IUpdateSampleExecutor;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleUpdate;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class UpdateSampleMethodExecutor extends AbstractUpdateMethodExecutor<SampleUpdate> implements IUpdateSampleMethodExecutor
+{
+
+    @Autowired
+    private IUpdateSampleExecutor updateExecutor;
+
+    @Override
+    protected IUpdateEntityExecutor<SampleUpdate> getUpdateExecutor()
+    {
+        return updateExecutor;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateSpaceMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateSpaceMethodExecutor.java
new file mode 100644
index 00000000000..0bc123a0f5f
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/UpdateSpaceMethodExecutor.java
@@ -0,0 +1,43 @@
+/*
+
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.executor.method;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.entity.IUpdateEntityExecutor;
+import ch.ethz.sis.openbis.generic.server.api.v3.executor.space.IUpdateSpaceExecutor;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.space.SpaceUpdate;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class UpdateSpaceMethodExecutor extends AbstractUpdateMethodExecutor<SpaceUpdate> implements IUpdateSpaceMethodExecutor
+{
+
+    @Autowired
+    private IUpdateSpaceExecutor updateExecutor;
+
+    @Override
+    protected IUpdateEntityExecutor<SpaceUpdate> getUpdateExecutor()
+    {
+        return updateExecutor;
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/UpdateProjectExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/UpdateProjectExecutor.java
index 143b5a70dcf..f9539480701 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/UpdateProjectExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/UpdateProjectExecutor.java
@@ -54,9 +54,6 @@ public class UpdateProjectExecutor extends AbstractUpdateEntityExecutor<ProjectU
     @Autowired
     private IUpdateProjectSpaceExecutor updateProjectSpaceExecutor;
 
-    @Autowired
-    private IUpdateProjectLeaderExecutor updateProjectLeaderExecutor;
-
     @Autowired
     private IUpdateAttachmentForEntityExecutor updateAttachmentForEntityExecutor;
 
@@ -94,7 +91,6 @@ public class UpdateProjectExecutor extends AbstractUpdateEntityExecutor<ProjectU
     protected void updateBatch(IOperationContext context, Map<ProjectUpdate, ProjectPE> entitiesMap)
     {
         updateProjectSpaceExecutor.update(context, entitiesMap);
-        updateProjectLeaderExecutor.update(context, entitiesMap);
 
         for (Map.Entry<ProjectUpdate, ProjectPE> entry : entitiesMap.entrySet())
         {
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/UpdateProjectLeaderExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/UpdateProjectLeaderExecutor.java
deleted file mode 100644
index 1bd4187a800..00000000000
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/UpdateProjectLeaderExecutor.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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.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.AbstractUpdateEntityFieldUpdateValueRelationExecutor;
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.person.IMapPersonByIdExecutor;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.FieldUpdateValue;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.project.ProjectUpdate;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.person.IPersonId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.person.PersonPermId;
-import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
-
-/**
- * @author pkupczyk
- */
-@Component
-public class UpdateProjectLeaderExecutor extends AbstractUpdateEntityFieldUpdateValueRelationExecutor<ProjectUpdate, ProjectPE, IPersonId, PersonPE>
-        implements IUpdateProjectLeaderExecutor
-{
-
-    @Autowired
-    private IMapPersonByIdExecutor mapPersonByIdExecutor;
-
-    @Override
-    protected IPersonId getRelatedId(PersonPE related)
-    {
-        return new PersonPermId(related.getUserId());
-    }
-
-    @Override
-    protected PersonPE getCurrentlyRelated(ProjectPE entity)
-    {
-        return entity.getProjectLeader();
-    }
-
-    @Override
-    protected FieldUpdateValue<IPersonId> getRelatedUpdate(ProjectUpdate update)
-    {
-        return update.getLeaderId();
-    }
-
-    @Override
-    protected Map<IPersonId, PersonPE> map(IOperationContext context, List<IPersonId> relatedIds)
-    {
-        return mapPersonByIdExecutor.map(context, relatedIds);
-    }
-
-    @Override
-    protected void check(IOperationContext context, ProjectPE entity, IPersonId relatedId, PersonPE related)
-    {
-        // nothing to do
-    }
-
-    @Override
-    protected void update(IOperationContext context, ProjectPE entity, PersonPE related)
-    {
-        entity.setProjectLeader(related);
-    }
-
-}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/AbstractCachingTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/AbstractCachingTranslator.java
index 82fd57b3fcf..20c3cc9a9ab 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/AbstractCachingTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/AbstractCachingTranslator.java
@@ -31,25 +31,15 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.IIdHolder;
 /**
  * @author pkupczyk
  */
-public abstract class AbstractCachingTranslator<I extends IIdHolder, O, F> extends AbstractTranslator<I, O>
+public abstract class AbstractCachingTranslator<I extends IIdHolder, O, F> extends AbstractTranslator<I, O, F>
 {
 
     private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, AbstractCachingTranslator.class);
 
-    protected TranslationContext translationContext;
-
-    private F fetchOptions;
-
-    public AbstractCachingTranslator(TranslationContext translationContext, F fetchOptions)
-    {
-        this.translationContext = translationContext;
-        this.fetchOptions = fetchOptions;
-    }
-
     @Override
-    protected final O doTranslate(I object)
+    protected final O doTranslate(TranslationContext context, I object, F fetchOptions)
     {
-        Map<I, O> translated = doTranslate(Collections.singleton(object));
+        Map<I, O> translated = doTranslate(context, Collections.singleton(object), fetchOptions);
         if (translated.isEmpty())
         {
             return null;
@@ -60,30 +50,31 @@ public abstract class AbstractCachingTranslator<I extends IIdHolder, O, F> exten
     }
 
     @Override
-    protected final Map<I, O> doTranslate(Collection<I> inputs)
+    protected final Map<I, O> doTranslate(TranslationContext context, Collection<I> inputs, F fetchOptions)
     {
         Map<I, O> translated = new LinkedHashMap<I, O>();
         Map<I, O> updated = new HashMap<I, O>();
+        TranslationCache cache = context.getTranslationCache();
 
         for (I input : inputs)
         {
-            if (getTranslationCache().hasTranslatedObject(getClass().getName(), input.getId()))
+            if (cache.hasTranslatedObject(getClass().getName(), input.getId()))
             {
-                handleAlreadyTranslatedInput(input, translated, updated);
+                handleAlreadyTranslatedInput(context, input, translated, updated, fetchOptions);
             } else
             {
-                handleNewInput(input, translated, updated);
+                handleNewInput(context, input, translated, updated, fetchOptions);
             }
         }
 
         if (false == updated.isEmpty())
         {
-            Relations relations = getObjectsRelations(updated.keySet());
+            Relations relations = getObjectsRelations(context, updated.keySet(), fetchOptions);
             relations.load();
 
             for (Map.Entry<I, O> updatedEntry : updated.entrySet())
             {
-                updateObject(updatedEntry.getKey(), updatedEntry.getValue(), relations);
+                updateObject(context, updatedEntry.getKey(), updatedEntry.getValue(), relations, fetchOptions);
             }
         }
 
@@ -91,10 +82,12 @@ public abstract class AbstractCachingTranslator<I extends IIdHolder, O, F> exten
     }
 
     @SuppressWarnings("unchecked")
-    private final void handleAlreadyTranslatedInput(I input, Map<I, O> translated, Map<I, O> updated)
+    private final void handleAlreadyTranslatedInput(TranslationContext context, I input, Map<I, O> translated, Map<I, O> updated, F fetchOptions)
     {
         Long id = input.getId();
-        O output = (O) getTranslationCache().getTranslatedObject(getClass().getName(), id);
+        TranslationCache cache = context.getTranslationCache();
+
+        O output = (O) cache.getTranslatedObject(getClass().getName(), id);
 
         if (output == null)
         {
@@ -109,7 +102,7 @@ public abstract class AbstractCachingTranslator<I extends IIdHolder, O, F> exten
                 operationLog.debug("Found in cache: " + output.getClass() + " with id: " + id);
             }
 
-            if (getTranslationCache().isFetchedWithOptions(output, getFetchOptions()))
+            if (cache.isFetchedWithOptions(output, fetchOptions))
             {
                 translated.put(input, output);
             } else
@@ -119,27 +112,28 @@ public abstract class AbstractCachingTranslator<I extends IIdHolder, O, F> exten
                     operationLog.debug("Updating from cache: " + output.getClass() + " with id: " + id);
                 }
 
-                getTranslationCache().setFetchedWithOptions(output, getFetchOptions());
+                cache.setFetchedWithOptions(output, fetchOptions);
                 updated.put(input, output);
                 translated.put(input, output);
             }
         }
     }
 
-    private void handleNewInput(I input, Map<I, O> translated, Map<I, O> updated)
+    private void handleNewInput(TranslationContext context, I input, Map<I, O> translated, Map<I, O> updated, F fetchOptions)
     {
         Long id = input.getId();
-        if (shouldTranslate(input))
+        if (shouldTranslate(context, input, fetchOptions))
         {
-            O output = createObject(input);
+            O output = createObject(context, input, fetchOptions);
+            TranslationCache cache = context.getTranslationCache();
 
             if (operationLog.isDebugEnabled())
             {
                 operationLog.debug("Created: " + output.getClass() + " with id: " + id);
             }
 
-            getTranslationCache().putTranslatedObject(getClass().getName(), id, output);
-            getTranslationCache().setFetchedWithOptions(output, getFetchOptions());
+            cache.putTranslatedObject(getClass().getName(), id, output);
+            cache.setFetchedWithOptions(output, fetchOptions);
             updated.put(input, output);
             translated.put(input, output);
 
@@ -157,46 +151,30 @@ public abstract class AbstractCachingTranslator<I extends IIdHolder, O, F> exten
      * Override this method if you want to conditionally skip translation (e.g. when the input object is not visible for a user the translation is
      * performed for)
      */
-    protected boolean shouldTranslate(I input)
+    protected boolean shouldTranslate(TranslationContext context, I input, F fetchOptions)
     {
         return true;
     }
 
-    /**
-     * Override this method if you want to fetch related objects for all the inputs at once. This way you can greatly improve the performance of the
-     * translation.
-     */
-    protected Relations getObjectsRelations(Collection<I> inputs)
-    {
-        return new Relations();
-    }
-
     /**
      * Implementation of this method should create a translated version of the input object. Only basic attributes of the input object should be
      * translated here. Parts that have a corresponding fetch option should be translated in the
-     * {@link AbstractCachingTranslator#updateObject(IIdHolder, Object, Relations)} method.
+     * {@link AbstractCachingTranslator#updateObject(TranslationContext, IIdHolder, Object, Relations, Object)} method.
      */
-    protected abstract O createObject(I input);
+    protected abstract O createObject(TranslationContext context, I input, F fetchOptions);
 
     /**
-     * Implementation of this method should update the translated version of the input object to meet the fetch options (see
-     * {@link AbstractCachingTranslator#getFetchOptions()}.
+     * Override this method if you want to fetch related objects for all the inputs at once. This way you can greatly improve the performance of the
+     * translation.
      */
-    protected abstract void updateObject(I input, O output, Relations relations);
-
-    protected final TranslationContext getTranslationContext()
-    {
-        return translationContext;
-    }
-
-    protected final TranslationCache getTranslationCache()
+    protected Relations getObjectsRelations(TranslationContext context, Collection<I> inputs, F fetchOptions)
     {
-        return getTranslationContext().getTranslationCache();
+        return new Relations();
     }
 
-    protected final F getFetchOptions()
-    {
-        return fetchOptions;
-    }
+    /**
+     * Implementation of this method should update the translated version of the input object to meet the fetch options.
+     */
+    protected abstract void updateObject(TranslationContext context, I input, O output, Relations relations, F fetchOptions);
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/AbstractTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/AbstractTranslator.java
index 1d651fd9804..2c4e769e7a5 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/AbstractTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/AbstractTranslator.java
@@ -23,37 +23,37 @@ import java.util.Map;
 /**
  * @author pkupczyk
  */
-public abstract class AbstractTranslator<I, O> implements ITranslator<I, O>
+public abstract class AbstractTranslator<I, O, F> implements ITranslator<I, O, F>
 {
 
     @Override
-    public O translate(I object)
+    public O translate(TranslationContext context, I object, F fetchOptions)
     {
         if (object == null)
         {
             return null;
         }
 
-        return doTranslate(object);
+        return doTranslate(context, object, fetchOptions);
     }
 
     @Override
-    public final Map<I, O> translate(Collection<I> objects)
+    public final Map<I, O> translate(TranslationContext context, Collection<I> objects, F fetchOptions)
     {
         if (objects == null)
         {
             return null;
         }
 
-        return doTranslate(objects);
+        return doTranslate(context, objects, fetchOptions);
     }
 
-    protected Map<I, O> doTranslate(Collection<I> objects)
+    protected Map<I, O> doTranslate(TranslationContext context, Collection<I> objects, F fetchOptions)
     {
         Map<I, O> translatedMap = new LinkedHashMap<I, O>();
         for (I object : objects)
         {
-            O translated = doTranslate(object);
+            O translated = doTranslate(context, object, fetchOptions);
             if (translated != null)
             {
                 translatedMap.put(object, translated);
@@ -62,6 +62,6 @@ public abstract class AbstractTranslator<I, O> implements ITranslator<I, O>
         return translatedMap;
     }
 
-    protected abstract O doTranslate(I object);
+    protected abstract O doTranslate(TranslationContext context, I object, F fetchOptions);
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/ITranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/ITranslator.java
index 397c0ed5871..cbb38e57a15 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/ITranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/ITranslator.java
@@ -22,11 +22,11 @@ import java.util.Map;
 /**
  * @author pkupczyk
  */
-public interface ITranslator<I, O>
+public interface ITranslator<I, O, F>
 {
 
-    public O translate(I object);
+    public O translate(TranslationContext context, I object, F fetchOptions);
 
-    public Map<I, O> translate(Collection<I> objects);
+    public Map<I, O> translate(TranslationContext context, Collection<I> objects, F fetchOptions);
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/ToManyRelation.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/ToManyRelation.java
index 62ff5108acf..125ef78d269 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/ToManyRelation.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/ToManyRelation.java
@@ -28,11 +28,21 @@ import java.util.Set;
 /**
  * @author pkupczyk
  */
-public abstract class ToManyRelation<OWNER, ORIGINAL, TRANSLATED> implements Relation
+public abstract class ToManyRelation<OWNER, ORIGINAL, TRANSLATED, FETCH_OPTIONS> implements Relation
 {
 
+    private TranslationContext context;
+
+    private FETCH_OPTIONS fetchOptions;
+
     private Map<OWNER, Collection<TRANSLATED>> translatedMap;
 
+    public ToManyRelation(TranslationContext context, FETCH_OPTIONS fetchOptions)
+    {
+        this.context = context;
+        this.fetchOptions = fetchOptions;
+    }
+
     @Override
     public void load()
     {
@@ -58,7 +68,7 @@ public abstract class ToManyRelation<OWNER, ORIGINAL, TRANSLATED> implements Rel
             }
         }
 
-        Map<ORIGINAL, TRANSLATED> originalToTranslatedMap = getTranslatedMap(originalSet);
+        Map<ORIGINAL, TRANSLATED> originalToTranslatedMap = getTranslatedMap(context, originalSet, fetchOptions);
         Map<OWNER, Collection<TRANSLATED>> result = new HashMap<OWNER, Collection<TRANSLATED>>();
 
         for (Map.Entry<OWNER, Collection<ORIGINAL>> ownerToOriginalCollectionEntry : ownerToOriginalCollectionMap.entrySet())
@@ -118,6 +128,8 @@ public abstract class ToManyRelation<OWNER, ORIGINAL, TRANSLATED> implements Rel
 
     protected abstract Map<OWNER, Collection<ORIGINAL>> getOriginalMap();
 
-    protected abstract Map<ORIGINAL, TRANSLATED> getTranslatedMap(Collection<ORIGINAL> originalCollection);
+    @SuppressWarnings("hiding")
+    protected abstract Map<ORIGINAL, TRANSLATED> getTranslatedMap(TranslationContext context, Collection<ORIGINAL> originalCollection,
+            FETCH_OPTIONS fetchOptions);
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/ToOneRelation.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/ToOneRelation.java
index afcf13535a1..373b47c5cfb 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/ToOneRelation.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/ToOneRelation.java
@@ -25,11 +25,21 @@ import java.util.Set;
 /**
  * @author pkupczyk
  */
-public abstract class ToOneRelation<OWNER, ORIGINAL, TRANSLATED> implements Relation
+public abstract class ToOneRelation<OWNER, ORIGINAL, TRANSLATED, FETCH_OPTIONS> implements Relation
 {
 
+    private TranslationContext context;
+
+    private FETCH_OPTIONS fetchOptions;
+
     private Map<OWNER, TRANSLATED> translatedMap;
 
+    public ToOneRelation(TranslationContext context, FETCH_OPTIONS fetchOptions)
+    {
+        this.context = context;
+        this.fetchOptions = fetchOptions;
+    }
+
     @Override
     public void load()
     {
@@ -49,7 +59,7 @@ public abstract class ToOneRelation<OWNER, ORIGINAL, TRANSLATED> implements Rela
             }
         }
 
-        Map<ORIGINAL, TRANSLATED> originalToTranslatedMap = getTranslatedMap(originalSet);
+        Map<ORIGINAL, TRANSLATED> originalToTranslatedMap = getTranslatedMap(context, originalSet, fetchOptions);
         Map<OWNER, TRANSLATED> ownerToTranslatedMap = new LinkedHashMap<OWNER, TRANSLATED>();
 
         for (Map.Entry<OWNER, ORIGINAL> entry : ownerToOriginalMap.entrySet())
@@ -70,6 +80,8 @@ public abstract class ToOneRelation<OWNER, ORIGINAL, TRANSLATED> implements Rela
 
     protected abstract Map<OWNER, ORIGINAL> getOriginalMap();
 
-    protected abstract Map<ORIGINAL, TRANSLATED> getTranslatedMap(Collection<ORIGINAL> originalCollection);
+    @SuppressWarnings("hiding")
+    protected abstract Map<ORIGINAL, TRANSLATED> getTranslatedMap(TranslationContext context, Collection<ORIGINAL> originalCollection,
+            FETCH_OPTIONS fetchOptions);
 
 }
\ No newline at end of file
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/TranslationContext.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/TranslationContext.java
index ce57ae8f142..3749ac1ffb8 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/TranslationContext.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/TranslationContext.java
@@ -2,19 +2,15 @@ package ch.ethz.sis.openbis.generic.server.api.v3.translator;
 
 import ch.ethz.sis.openbis.generic.server.api.v3.context.Context;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
-import ch.systemsx.cisd.openbis.generic.shared.managed_property.IManagedPropertyEvaluatorFactory;
 
 public class TranslationContext extends Context
 {
     private final TranslationCache translationCache;
 
-    private IManagedPropertyEvaluatorFactory managedPropertyEvaluatorFactory;
-
-    public TranslationContext(Session session, IManagedPropertyEvaluatorFactory managedPropertyEvaluatorFactory)
+    public TranslationContext(Session session)
     {
         super(session);
         this.translationCache = new TranslationCache();
-        this.managedPropertyEvaluatorFactory = managedPropertyEvaluatorFactory;
     }
 
     public TranslationCache getTranslationCache()
@@ -22,9 +18,4 @@ public class TranslationContext extends Context
         return translationCache;
     }
 
-    public IManagedPropertyEvaluatorFactory getManagedPropertyEvaluatorFactory()
-    {
-        return managedPropertyEvaluatorFactory;
-    }
-
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/common/AbstractCollectionTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/common/AbstractCollectionTranslator.java
deleted file mode 100644
index 70657084d99..00000000000
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/common/AbstractCollectionTranslator.java
+++ /dev/null
@@ -1,52 +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.common;
-
-import java.util.Collection;
-
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
-
-/**
- * @author pkupczyk
- */
-public abstract class AbstractCollectionTranslator
-{
-
-    public <I, O> Collection<O> translate(Collection<? extends I> collection, ITranslator<I, O> itemTranslator)
-    {
-        if (collection == null)
-        {
-            return null;
-        }
-
-        Collection<O> result = createCollection();
-
-        for (I item : collection)
-        {
-            O translationResult = itemTranslator.translate(item);
-            if (translationResult != null)
-            {
-                result.add(translationResult);
-            }
-        }
-
-        return result;
-    }
-
-    protected abstract <O> Collection<O> createCollection();
-
-}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/common/MapTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/common/MapTranslator.java
deleted file mode 100644
index 07e2b2c86c4..00000000000
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/common/MapTranslator.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.translator.common;
-
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
-
-/**
- * @author pkupczyk
- */
-public class MapTranslator<ORIGINAL_KEY, TRANSLATED_KEY, ORIGINAL_VALUE, TRANSLATED_VALUE>
-{
-
-    public Map<TRANSLATED_KEY, TRANSLATED_VALUE> translate(Map<ORIGINAL_KEY, ORIGINAL_VALUE> map,
-            ITranslator<ORIGINAL_KEY, TRANSLATED_KEY> keyTranslator, ITranslator<ORIGINAL_VALUE, TRANSLATED_VALUE> valueTranslator)
-    {
-        if (map == null || map.isEmpty())
-        {
-            return Collections.emptyMap();
-        }
-
-        Map<ORIGINAL_KEY, TRANSLATED_KEY> translatedKeyMap = keyTranslator.translate(map.keySet());
-        Map<ORIGINAL_VALUE, TRANSLATED_VALUE> translatedValueMap = valueTranslator.translate(map.values());
-        Map<TRANSLATED_KEY, TRANSLATED_VALUE> result = new LinkedHashMap<TRANSLATED_KEY, TRANSLATED_VALUE>();
-
-        for (Map.Entry<ORIGINAL_KEY, ORIGINAL_VALUE> entry : map.entrySet())
-        {
-            ORIGINAL_KEY originalKey = entry.getKey();
-            ORIGINAL_VALUE originalValue = entry.getValue();
-            TRANSLATED_KEY translatedKey = translatedKeyMap.get(originalKey);
-            TRANSLATED_VALUE translatedValue = translatedValueMap.get(originalValue);
-
-            if (originalKey != null && translatedKey == null)
-            {
-                continue;
-            }
-            if (originalValue != null && translatedValue == null)
-            {
-                continue;
-            }
-
-            result.put(translatedKey, translatedValue);
-        }
-
-        return result;
-    }
-
-}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/attachment/AttachmentTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/attachment/AttachmentTranslator.java
index 6ad884ff8fe..6f449c963aa 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/attachment/AttachmentTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/attachment/AttachmentTranslator.java
@@ -8,11 +8,15 @@ import java.util.HashMap;
 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.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.PersonTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.IPersonTranslator;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.attachment.Attachment;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.person.Person;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.attachment.AttachmentFetchOptions;
 import ch.systemsx.cisd.openbis.generic.shared.basic.PermlinkUtilities;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AttachmentHolderKind;
@@ -20,15 +24,16 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentHolderPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
 
-public class AttachmentTranslator extends AbstractCachingTranslator<AttachmentPE, Attachment, AttachmentFetchOptions>
+@Component
+public class AttachmentTranslator extends AbstractCachingTranslator<AttachmentPE, Attachment, AttachmentFetchOptions> implements
+        IAttachmentTranslator
 {
-    public AttachmentTranslator(TranslationContext translationContext, AttachmentFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
+
+    @Autowired
+    private IPersonTranslator personTranslator;
 
     @Override
-    protected Attachment createObject(AttachmentPE attachment)
+    protected Attachment createObject(TranslationContext context, AttachmentPE attachment, AttachmentFetchOptions fetchOptions)
     {
         Attachment result = new Attachment();
 
@@ -38,7 +43,7 @@ public class AttachmentTranslator extends AbstractCachingTranslator<AttachmentPE
         result.setRegistrationDate(attachment.getRegistrationDate());
         result.setVersion(attachment.getVersion());
 
-        String baseIndexURL = translationContext.getSession().getBaseIndexURL();
+        String baseIndexURL = context.getSession().getBaseIndexURL();
         result.setPermlink(createPermlink(attachment, baseIndexURL, false));
         result.setLatestVersionPermlink(createPermlink(attachment, baseIndexURL, true));
 
@@ -64,22 +69,24 @@ public class AttachmentTranslator extends AbstractCachingTranslator<AttachmentPE
     }
 
     @Override
-    protected void updateObject(AttachmentPE attachment, Attachment result, Relations relations)
+    protected void updateObject(TranslationContext context, AttachmentPE attachment, Attachment result, Relations relations,
+            AttachmentFetchOptions fetchOptions)
     {
-        if (getFetchOptions().hasRegistrator())
+        if (fetchOptions.hasRegistrator())
         {
-            result.setRegistrator(new PersonTranslator(getTranslationContext(), getFetchOptions().withRegistrator()).translate(attachment
-                    .getRegistrator()));
-            result.getFetchOptions().withRegistratorUsing(getFetchOptions().withRegistrator());
+            Person registrator = personTranslator.translate(context, attachment.getRegistrator(), fetchOptions.withRegistrator());
+            result.setRegistrator(registrator);
+            result.getFetchOptions().withRegistratorUsing(fetchOptions.withRegistrator());
         }
 
-        if (getFetchOptions().hasContent())
+        if (fetchOptions.hasContent())
         {
             result.setContent(attachment.getAttachmentContent().getValue());
         }
     }
 
-    public static ArrayList<Attachment> translate(TranslationContext translationContext, AttachmentHolderPE attachmentHolder,
+    @Override
+    public List<Attachment> translate(TranslationContext translationContext, AttachmentHolderPE attachmentHolder,
             AttachmentFetchOptions attachmentFetchOptions)
     {
         List<List<AttachmentPE>> attachmentsIntoVersionGroups =
@@ -92,11 +99,11 @@ public class AttachmentTranslator extends AbstractCachingTranslator<AttachmentPE
         return attachments;
     }
 
-    private static Attachment translate(TranslationContext translationContext, List<AttachmentPE> group, AttachmentFetchOptions fetchOptions)
+    private Attachment translate(TranslationContext translationContext, List<AttachmentPE> group, AttachmentFetchOptions fetchOptions)
     {
         assert group.isEmpty() == false;
 
-        Attachment attachment = new AttachmentTranslator(translationContext, fetchOptions).translate(group.get(0));
+        Attachment attachment = translate(translationContext, group.get(0), fetchOptions);
 
         if (fetchOptions.hasPreviousVersion() && group.size() > 0)
         {
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/attachment/IAttachmentTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/attachment/IAttachmentTranslator.java
new file mode 100644
index 00000000000..c5fbe8fa8c0
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/attachment/IAttachmentTranslator.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.attachment;
+
+import java.util.List;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.attachment.Attachment;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.attachment.AttachmentFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentHolderPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentPE;
+
+/**
+ * @author pkupczyk
+ */
+public interface IAttachmentTranslator extends ITranslator<AttachmentPE, Attachment, AttachmentFetchOptions>
+{
+
+    public List<Attachment> translate(TranslationContext translationContext, AttachmentHolderPE attachmentHolder,
+            AttachmentFetchOptions attachmentFetchOptions);
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/DataSetTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/DataSetTranslator.java
index 6cf41bdf0bf..2018b2e6a6e 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/DataSetTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/DataSetTranslator.java
@@ -16,51 +16,70 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.dataset;
 
+import java.util.ArrayList;
 import java.util.HashSet;
-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.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.common.ListTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.experiment.ExperimentTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.material.MaterialPropertyTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.PersonTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.property.PropertyTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.sample.SampleTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.tag.TagTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.experiment.IExperimentTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.material.IMaterialPropertyTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.IPersonTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.property.IPropertyTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.sample.ISampleTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.tag.ITagTranslator;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.DataSet;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.DataSetType;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.ExternalData;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.Experiment;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.person.Person;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.Sample;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.tag.Tag;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.dataset.DataSetFetchOptions;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.dataset.DataSetPermId;
 import ch.systemsx.cisd.openbis.generic.server.authorization.validator.DataSetPEByExperimentOrSampleIdentifierValidator;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 
 /**
  * @author Jakub Straszewski
  */
-public class DataSetTranslator extends AbstractCachingTranslator<DataPE, DataSet, DataSetFetchOptions>
+@Component
+public class DataSetTranslator extends AbstractCachingTranslator<DataPE, DataSet, DataSetFetchOptions> implements IDataSetTranslator
 {
 
-    public DataSetTranslator(TranslationContext translationContext, DataSetFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
+    @Autowired
+    private IExperimentTranslator experimentTranslator;
+
+    @Autowired
+    private ISampleTranslator sampleTranslator;
+
+    @Autowired
+    private IPropertyTranslator propertyTranslator;
+
+    @Autowired
+    private IMaterialPropertyTranslator materialPropertyTranslator;
+
+    @Autowired
+    private IDataSetTypeTranslator typeTranslator;
+
+    @Autowired
+    private ITagTranslator tagTranslator;
+
+    @Autowired
+    private IPersonTranslator personTranslator;
+
+    @Autowired
+    private IExternalDataTranslator externalDataTranslator;
 
     @Override
-    protected boolean shouldTranslate(DataPE input)
+    protected boolean shouldTranslate(TranslationContext context, DataPE input, DataSetFetchOptions fetchOptions)
     {
-        return new DataSetPEByExperimentOrSampleIdentifierValidator().doValidation(getTranslationContext().getSession().tryGetPerson(), input);
+        return new DataSetPEByExperimentOrSampleIdentifierValidator().doValidation(context.getSession().tryGetPerson(), input);
     }
 
     @Override
-    protected DataSet createObject(DataPE dataPe)
+    protected DataSet createObject(TranslationContext context, DataPE dataPe, DataSetFetchOptions fetchOptions)
     {
         final DataSet dataSet = new DataSet();
         dataSet.setCode(dataPe.getCode());
@@ -75,126 +94,98 @@ public class DataSetTranslator extends AbstractCachingTranslator<DataPE, DataSet
     }
 
     @Override
-    protected void updateObject(DataPE dataPe, DataSet result, Relations relations)
+    protected void updateObject(TranslationContext context, DataPE dataPe, DataSet result, Relations relations, DataSetFetchOptions fetchOptions)
     {
-        if (getFetchOptions().hasChildren())
+        if (fetchOptions.hasChildren())
         {
-            List<DataSet> children =
-                    new ListTranslator().translate(dataPe.getChildren(), new DataSetTranslator(getTranslationContext(),
-                            getFetchOptions()
-                                    .withChildren()));
-            result.setChildren(children);
-            result.getFetchOptions().withChildrenUsing(getFetchOptions().withChildren());
+            Map<DataPE, DataSet> children = translate(context, dataPe.getChildren(), fetchOptions.withChildren());
+            result.setChildren(new ArrayList<DataSet>(children.values()));
+            result.getFetchOptions().withChildrenUsing(fetchOptions.withChildren());
         }
 
-        if (getFetchOptions().hasParents())
+        if (fetchOptions.hasParents())
         {
-            List<DataSet> parents =
-                    new ListTranslator().translate(dataPe.getParents(), new DataSetTranslator(getTranslationContext(),
-                            getFetchOptions()
-                                    .withParents()));
-            result.setParents(parents);
-            result.getFetchOptions().withParentsUsing(getFetchOptions().withParents());
+            Map<DataPE, DataSet> parents = translate(context, dataPe.getParents(), fetchOptions.withParents());
+            result.setParents(new ArrayList<DataSet>(parents.values()));
+            result.getFetchOptions().withParentsUsing(fetchOptions.withParents());
         }
 
-        if (getFetchOptions().hasContained())
+        if (fetchOptions.hasContained())
         {
-            List<DataSet> contained =
-                    new ListTranslator().translate(dataPe.getContainedDataSets(), new DataSetTranslator(getTranslationContext(),
-                            getFetchOptions()
-                                    .withContained()));
-            result.setContained(contained);
-            result.getFetchOptions().withContainedUsing(getFetchOptions().withContained());
+            Map<DataPE, DataSet> contained = translate(context, dataPe.getContainedDataSets(), fetchOptions.withContained());
+            result.setContained(new ArrayList<DataSet>(contained.values()));
+            result.getFetchOptions().withContainedUsing(fetchOptions.withContained());
         }
 
-        if (getFetchOptions().hasContainers())
+        if (fetchOptions.hasContainers())
         {
-            List<DataSet> containers =
-                    new ListTranslator().translate(dataPe.getContainers(), new DataSetTranslator(getTranslationContext(),
-                            getFetchOptions()
-                                    .withContainers()));
-            result.setContainers(containers);
-            result.getFetchOptions().withContainersUsing(getFetchOptions().withContainers());
+            Map<DataPE, DataSet> containers = translate(context, dataPe.getContainers(), fetchOptions.withContainers());
+            result.setContainers(new ArrayList<DataSet>(containers.values()));
+            result.getFetchOptions().withContainersUsing(fetchOptions.withContainers());
         }
 
-        if (getFetchOptions().hasExperiment() && dataPe.getExperiment() != null)
+        if (fetchOptions.hasExperiment())
         {
-            Experiment experiment =
-                    new ExperimentTranslator(getTranslationContext(), getFetchOptions().withExperiment())
-                            .translate(dataPe.getExperiment());
-            result.setExperiment(experiment);
-            result.getFetchOptions().withExperimentUsing(getFetchOptions().withExperiment());
+            if (dataPe.getExperiment() != null)
+            {
+                result.setExperiment(experimentTranslator.translate(context, dataPe.getExperiment(), fetchOptions.withExperiment()));
+            }
+            result.getFetchOptions().withExperimentUsing(fetchOptions.withExperiment());
         }
 
-        if (getFetchOptions().hasSample())
+        if (fetchOptions.hasSample())
         {
             if (dataPe.tryGetSample() != null)
             {
-                Sample sample =
-                        new SampleTranslator(getTranslationContext(), getFetchOptions().withSample())
-                                .translate(dataPe.tryGetSample());
-                result.setSample(sample);
+                result.setSample(sampleTranslator.translate(context, dataPe.tryGetSample(), fetchOptions.withSample()));
             }
-            result.getFetchOptions().withSampleUsing(getFetchOptions().withSample());
+            result.getFetchOptions().withSampleUsing(fetchOptions.withSample());
         }
 
-        if (getFetchOptions().hasProperties())
+        if (fetchOptions.hasProperties())
         {
-            result.setProperties(new PropertyTranslator(getTranslationContext(), getFetchOptions().withProperties())
-                    .translate(dataPe));
-            result.getFetchOptions().withPropertiesUsing(getFetchOptions().withProperties());
+            result.setProperties(propertyTranslator.translate(context, dataPe, fetchOptions.withProperties()));
+            result.getFetchOptions().withPropertiesUsing(fetchOptions.withProperties());
         }
 
-        if (getFetchOptions().hasMaterialProperties())
+        if (fetchOptions.hasMaterialProperties())
         {
-            result.setMaterialProperties(new MaterialPropertyTranslator(getTranslationContext(), getFetchOptions().withMaterialProperties())
-                    .translate(dataPe));
-            result.getFetchOptions().withMaterialPropertiesUsing(getFetchOptions().withMaterialProperties());
+            result.setMaterialProperties(materialPropertyTranslator.translate(context, dataPe, fetchOptions.withMaterialProperties()));
+            result.getFetchOptions().withMaterialPropertiesUsing(fetchOptions.withMaterialProperties());
         }
 
-        if (getFetchOptions().hasType())
+        if (fetchOptions.hasType())
         {
-            DataSetType dataSetType =
-                    new DataSetTypeTranslator(getTranslationContext(),
-                            getFetchOptions().withType()).translate(dataPe.getDataSetType());
-            result.setType(dataSetType);
-            result.getFetchOptions().withTypeUsing(getFetchOptions().withType());
+            result.setType(typeTranslator.translate(context, dataPe.getDataSetType(), fetchOptions.withType()));
+            result.getFetchOptions().withTypeUsing(fetchOptions.withType());
         }
 
-        if (getFetchOptions().hasTags())
+        if (fetchOptions.hasTags())
         {
-            List<Tag> tags =
-                    new ListTranslator().translate(dataPe.getMetaprojects(), new TagTranslator(getTranslationContext(), getFetchOptions()
-                            .withTags()));
-            result.setTags(new HashSet<Tag>(tags));
-            result.getFetchOptions().withTagsUsing(getFetchOptions().withTags());
+            Map<MetaprojectPE, Tag> tags = tagTranslator.translate(context, dataPe.getMetaprojects(), fetchOptions.withTags());
+            result.setTags(new HashSet<Tag>(tags.values()));
+            result.getFetchOptions().withTagsUsing(fetchOptions.withTags());
         }
 
-        if (getFetchOptions().hasRegistrator())
+        if (fetchOptions.hasRegistrator())
         {
-            Person registrator =
-                    new PersonTranslator(getTranslationContext(), getFetchOptions().withRegistrator()).translate(dataPe.getRegistrator());
-            result.setRegistrator(registrator);
-            result.getFetchOptions().withRegistratorUsing(getFetchOptions().withRegistrator());
+            result.setRegistrator(personTranslator.translate(context, dataPe.getRegistrator(), fetchOptions.withRegistrator()));
+            result.getFetchOptions().withRegistratorUsing(fetchOptions.withRegistrator());
         }
 
-        if (getFetchOptions().hasModifier())
+        if (fetchOptions.hasModifier())
         {
-            Person modifier =
-                    new PersonTranslator(getTranslationContext(), getFetchOptions().withModifier()).translate(dataPe.getModifier());
-            result.setModifier(modifier);
-            result.getFetchOptions().withModifierUsing(getFetchOptions().withModifier());
+            result.setModifier(personTranslator.translate(context, dataPe.getModifier(), fetchOptions.withModifier()));
+            result.getFetchOptions().withModifierUsing(fetchOptions.withModifier());
         }
 
-        if (getFetchOptions().hasExternalData())
+        if (fetchOptions.hasExternalData())
         {
             if (dataPe instanceof ExternalDataPE)
             {
-                ExternalData externalData =
-                        new ExternalDataTranslator(getTranslationContext(), getFetchOptions().withExternalData()).translate((ExternalDataPE) dataPe);
-                result.setExternalData(externalData);
+                result.setExternalData(externalDataTranslator.translate(context, (ExternalDataPE) dataPe, fetchOptions.withExternalData()));
             }
-            result.getFetchOptions().withExternalDataUsing(getFetchOptions().withExternalData());
+            result.getFetchOptions().withExternalDataUsing(fetchOptions.withExternalData());
         }
     }
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/DataSetTypeTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/DataSetTypeTranslator.java
index 77f7cc04746..a52d66f4827 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/DataSetTypeTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/DataSetTypeTranslator.java
@@ -16,6 +16,8 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.dataset;
 
+import org.springframework.stereotype.Component;
+
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
@@ -28,16 +30,13 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
 /**
  * @author Jakub Straszewski
  */
-public class DataSetTypeTranslator extends AbstractCachingTranslator<DataSetTypePE, DataSetType, DataSetTypeFetchOptions>
+@Component
+public class DataSetTypeTranslator extends AbstractCachingTranslator<DataSetTypePE, DataSetType, DataSetTypeFetchOptions> implements
+        IDataSetTypeTranslator
 {
 
-    public DataSetTypeTranslator(TranslationContext translationContext, DataSetTypeFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
-
     @Override
-    protected DataSetType createObject(DataSetTypePE input)
+    protected DataSetType createObject(TranslationContext context, DataSetTypePE input, DataSetTypeFetchOptions fetchOptions)
     {
         final DataSetType dataSetType = new DataSetType();
         dataSetType.setCode(input.getCode());
@@ -50,7 +49,8 @@ public class DataSetTypeTranslator extends AbstractCachingTranslator<DataSetType
     }
 
     @Override
-    protected void updateObject(DataSetTypePE input, DataSetType output, Relations relations)
+    protected void updateObject(TranslationContext context, DataSetTypePE input, DataSetType output, Relations relations,
+            DataSetTypeFetchOptions fetchOptions)
     {
     }
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/ExternalDataTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/ExternalDataTranslator.java
index bfa7530faf5..12e0c5e0aaa 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/ExternalDataTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/ExternalDataTranslator.java
@@ -16,10 +16,13 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.dataset;
 
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.vocabulary.VocabularyTermTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.vocabulary.IVocabularyTermTranslator;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.ArchivingStatus;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.Complete;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.ExternalData;
@@ -31,15 +34,22 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 /**
  * @author pkupczyk
  */
-public class ExternalDataTranslator extends AbstractCachingTranslator<ExternalDataPE, ExternalData, ExternalDataFetchOptions>
+@Component
+public class ExternalDataTranslator extends AbstractCachingTranslator<ExternalDataPE, ExternalData, ExternalDataFetchOptions> implements
+        IExternalDataTranslator
 {
-    public ExternalDataTranslator(TranslationContext translationContext, ExternalDataFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
+
+    @Autowired
+    private IFileFormatTypeTranslator fileFormatTypeTranslator;
+
+    @Autowired
+    private ILocatorTypeTranslator locatorTypeTranslator;
+
+    @Autowired
+    private IVocabularyTermTranslator vocabularyTermTranslator;
 
     @Override
-    protected ExternalData createObject(ExternalDataPE data)
+    protected ExternalData createObject(TranslationContext context, ExternalDataPE data, ExternalDataFetchOptions fetchOptions)
     {
         ExternalData result = new ExternalData();
 
@@ -103,27 +113,26 @@ public class ExternalDataTranslator extends AbstractCachingTranslator<ExternalDa
     }
 
     @Override
-    protected void updateObject(ExternalDataPE data, ExternalData result, Relations relations)
+    protected void updateObject(TranslationContext context, ExternalDataPE data, ExternalData result, Relations relations,
+            ExternalDataFetchOptions fetchOptions)
     {
-        if (getFetchOptions().hasFileFormatType())
+        if (fetchOptions.hasFileFormatType())
         {
-            result.setFileFormatType(new FileFormatTypeTranslator(getTranslationContext(), getFetchOptions().withFileFormatType()).translate(data
-                    .getFileFormatType()));
-            result.getFetchOptions().withFileFormatTypeUsing(getFetchOptions().withFileFormatType());
+            result.setFileFormatType(fileFormatTypeTranslator.translate(context, data.getFileFormatType(), fetchOptions.withFileFormatType()));
+            result.getFetchOptions().withFileFormatTypeUsing(fetchOptions.withFileFormatType());
         }
 
-        if (getFetchOptions().hasLocatorType())
+        if (fetchOptions.hasLocatorType())
         {
-            result.setLocatorType(new LocatorTypeTranslator(getTranslationContext(), getFetchOptions().withLocatorType()).translate(data
-                    .getLocatorType()));
-            result.getFetchOptions().withLocatorTypeUsing(getFetchOptions().withLocatorType());
+            result.setLocatorType(locatorTypeTranslator.translate(context, data.getLocatorType(), fetchOptions.withLocatorType()));
+            result.getFetchOptions().withLocatorTypeUsing(fetchOptions.withLocatorType());
         }
 
-        if (getFetchOptions().hasStorageFormat())
+        if (fetchOptions.hasStorageFormat())
         {
-            result.setStorageFormat(new VocabularyTermTranslator(getTranslationContext(), getFetchOptions()
-                    .withStorageFormat()).translate(data.getStorageFormatVocabularyTerm()));
-            result.getFetchOptions().withStorageFormatUsing(getFetchOptions().withStorageFormat());
+            result.setStorageFormat(vocabularyTermTranslator.translate(context, data.getStorageFormatVocabularyTerm(),
+                    fetchOptions.withStorageFormat()));
+            result.getFetchOptions().withStorageFormatUsing(fetchOptions.withStorageFormat());
         }
     }
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/FileFormatTypeTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/FileFormatTypeTranslator.java
index f56fbf6bf02..0c86db90204 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/FileFormatTypeTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/FileFormatTypeTranslator.java
@@ -16,6 +16,8 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.dataset;
 
+import org.springframework.stereotype.Component;
+
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
@@ -26,15 +28,12 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.FileFormatTypePE;
 /**
  * @author pkupczyk
  */
-public class FileFormatTypeTranslator extends AbstractCachingTranslator<FileFormatTypePE, FileFormatType, FileFormatTypeFetchOptions>
+@Component
+public class FileFormatTypeTranslator extends AbstractCachingTranslator<FileFormatTypePE, FileFormatType, FileFormatTypeFetchOptions> implements
+        IFileFormatTypeTranslator
 {
-    public FileFormatTypeTranslator(TranslationContext translationContext, FileFormatTypeFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
-
     @Override
-    protected FileFormatType createObject(FileFormatTypePE type)
+    protected FileFormatType createObject(TranslationContext context, FileFormatTypePE type, FileFormatTypeFetchOptions fetchOptions)
     {
         FileFormatType result = new FileFormatType();
 
@@ -46,7 +45,8 @@ public class FileFormatTypeTranslator extends AbstractCachingTranslator<FileForm
     }
 
     @Override
-    protected void updateObject(FileFormatTypePE type, FileFormatType result, Relations relations)
+    protected void updateObject(TranslationContext context, FileFormatTypePE type, FileFormatType result, Relations relations,
+            FileFormatTypeFetchOptions fetchOptions)
     {
     }
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/IDataSetTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/IDataSetTranslator.java
new file mode 100644
index 00000000000..a60228aa007
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/IDataSetTranslator.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.dataset;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.DataSet;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.dataset.DataSetFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
+
+/**
+ * @author pkupczyk
+ */
+public interface IDataSetTranslator extends ITranslator<DataPE, DataSet, DataSetFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/IDataSetTypeTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/IDataSetTypeTranslator.java
new file mode 100644
index 00000000000..88458311b4b
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/IDataSetTypeTranslator.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.dataset;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.DataSetType;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.dataset.DataSetTypeFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
+
+/**
+ * @author pkupczyk
+ */
+public interface IDataSetTypeTranslator extends ITranslator<DataSetTypePE, DataSetType, DataSetTypeFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/IExternalDataTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/IExternalDataTranslator.java
new file mode 100644
index 00000000000..90430f5d207
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/IExternalDataTranslator.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.dataset;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.ExternalData;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.dataset.ExternalDataFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
+
+/**
+ * @author pkupczyk
+ */
+public interface IExternalDataTranslator extends ITranslator<ExternalDataPE, ExternalData, ExternalDataFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/IFileFormatTypeTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/IFileFormatTypeTranslator.java
new file mode 100644
index 00000000000..83dddfacb34
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/IFileFormatTypeTranslator.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.dataset;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.FileFormatType;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.dataset.FileFormatTypeFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.FileFormatTypePE;
+
+/**
+ * @author pkupczyk
+ */
+public interface IFileFormatTypeTranslator extends ITranslator<FileFormatTypePE, FileFormatType, FileFormatTypeFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/ILocatorTypeTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/ILocatorTypeTranslator.java
new file mode 100644
index 00000000000..493c8e2b607
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/ILocatorTypeTranslator.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.dataset;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.LocatorType;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.dataset.LocatorTypeFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.LocatorTypePE;
+
+/**
+ * @author pkupczyk
+ */
+public interface ILocatorTypeTranslator extends ITranslator<LocatorTypePE, LocatorType, LocatorTypeFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/LocatorTypeTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/LocatorTypeTranslator.java
index 0b7436c6b0d..f9d3330a9be 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/LocatorTypeTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/dataset/LocatorTypeTranslator.java
@@ -16,6 +16,8 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.dataset;
 
+import org.springframework.stereotype.Component;
+
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
@@ -26,15 +28,13 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.LocatorTypePE;
 /**
  * @author pkupczyk
  */
-public class LocatorTypeTranslator extends AbstractCachingTranslator<LocatorTypePE, LocatorType, LocatorTypeFetchOptions>
+@Component
+public class LocatorTypeTranslator extends AbstractCachingTranslator<LocatorTypePE, LocatorType, LocatorTypeFetchOptions> implements
+        ILocatorTypeTranslator
 {
-    public LocatorTypeTranslator(TranslationContext translationContext, LocatorTypeFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
 
     @Override
-    protected LocatorType createObject(LocatorTypePE type)
+    protected LocatorType createObject(TranslationContext context, LocatorTypePE type, LocatorTypeFetchOptions fetchOptions)
     {
         LocatorType result = new LocatorType();
 
@@ -46,7 +46,8 @@ public class LocatorTypeTranslator extends AbstractCachingTranslator<LocatorType
     }
 
     @Override
-    protected void updateObject(LocatorTypePE type, LocatorType result, Relations relations)
+    protected void updateObject(TranslationContext context, LocatorTypePE input, LocatorType output, Relations relations,
+            LocatorTypeFetchOptions fetchOptions)
     {
     }
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/deletion/DeletionTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/deletion/DeletionTranslator.java
index a8e3a201cfa..215d6a59e61 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/deletion/DeletionTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/deletion/DeletionTranslator.java
@@ -19,6 +19,9 @@ package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.deletion;
 import java.util.ArrayList;
 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.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
@@ -38,28 +41,27 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolderWit
 /**
  * @author pkupczyk
  */
+@Component
 public class DeletionTranslator extends
-        AbstractCachingTranslator<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Deletion, Deletion, DeletionFetchOptions>
+        AbstractCachingTranslator<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Deletion, Deletion, DeletionFetchOptions> implements
+        IDeletionTranslator
 {
 
+    @Autowired
     private IDAOFactory daoFactory;
 
-    public DeletionTranslator(TranslationContext translationContext, DeletionFetchOptions fetchOptions, IDAOFactory daoFactory)
-    {
-        super(translationContext, fetchOptions);
-        this.daoFactory = daoFactory;
-    }
-
     @Override
-    protected boolean shouldTranslate(ch.systemsx.cisd.openbis.generic.shared.basic.dto.Deletion input)
+    protected boolean shouldTranslate(TranslationContext context, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Deletion input,
+            DeletionFetchOptions fetchOptions)
     {
         DeletionValidator validator = new DeletionValidator();
         validator.init(new AuthorizationDataProvider(daoFactory));
-        return validator.doValidation(getTranslationContext().getSession().tryGetPerson(), input);
+        return validator.doValidation(context.getSession().tryGetPerson(), input);
     }
 
     @Override
-    protected Deletion createObject(ch.systemsx.cisd.openbis.generic.shared.basic.dto.Deletion input)
+    protected Deletion createObject(TranslationContext context, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Deletion input,
+            DeletionFetchOptions fetchOptions)
     {
         Deletion deletion = new Deletion();
         deletion.setId(new DeletionTechId(input.getId()));
@@ -69,9 +71,10 @@ public class DeletionTranslator extends
     }
 
     @Override
-    protected void updateObject(ch.systemsx.cisd.openbis.generic.shared.basic.dto.Deletion input, Deletion output, Relations relations)
+    protected void updateObject(TranslationContext context, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Deletion input, Deletion output,
+            Relations relations, DeletionFetchOptions fetchOptions)
     {
-        if (getFetchOptions().hasDeletedObjects())
+        if (fetchOptions.hasDeletedObjects())
         {
             output.getFetchOptions().fetchDeletedObjects();
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/deletion/IDeletionTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/deletion/IDeletionTranslator.java
new file mode 100644
index 00000000000..4a69cae303f
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/deletion/IDeletionTranslator.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.deletion;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.deletion.Deletion;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.deletion.DeletionFetchOptions;
+
+/**
+ * @author pkupczyk
+ */
+public interface IDeletionTranslator extends ITranslator<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Deletion, Deletion, DeletionFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/experiment/ExperimentTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/experiment/ExperimentTranslator.java
index f1bb873a15b..97393c27055 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/experiment/ExperimentTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/experiment/ExperimentTranslator.java
@@ -17,49 +17,81 @@
 package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.experiment;
 
 import java.util.ArrayList;
+import java.util.HashSet;
+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.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.common.ListTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.common.SetTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.attachment.AttachmentTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.dataset.DataSetTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.material.MaterialPropertyTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.PersonTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.project.ProjectTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.property.PropertyTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.sample.SampleTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.tag.TagTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.attachment.IAttachmentTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.dataset.IDataSetTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.material.IMaterialPropertyTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.IPersonTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.project.IProjectTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.property.IPropertyTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.sample.ISampleTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.tag.ITagTranslator;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.attachment.Attachment;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.DataSet;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.Experiment;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.ExperimentType;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.Sample;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.tag.Tag;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.experiment.ExperimentFetchOptions;
 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.ExperimentPermId;
 import ch.systemsx.cisd.openbis.generic.server.authorization.validator.ExperimentByIdentiferValidator;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
 /**
  * @author pkupczyk
  */
-public class ExperimentTranslator extends AbstractCachingTranslator<ExperimentPE, Experiment, ExperimentFetchOptions>
+@Component
+public class ExperimentTranslator extends AbstractCachingTranslator<ExperimentPE, Experiment, ExperimentFetchOptions> implements
+        IExperimentTranslator
 {
 
-    public ExperimentTranslator(TranslationContext translationContext, ExperimentFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
+    @Autowired
+    private IExperimentTypeTranslator typeTranslator;
+
+    @Autowired
+    private IProjectTranslator projectTranslator;
+
+    @Autowired
+    private ISampleTranslator sampleTranslator;
+
+    @Autowired
+    private IPersonTranslator personTranslator;
+
+    @Autowired
+    private IAttachmentTranslator attachmentTranslator;
+
+    @Autowired
+    private IPropertyTranslator propertyTranslator;
+
+    @Autowired
+    private IMaterialPropertyTranslator materialPropertyTranslator;
+
+    @Autowired
+    private IDataSetTranslator dataSetTranslator;
+
+    @Autowired
+    private ITagTranslator tagTranslator;
 
     @Override
-    protected boolean shouldTranslate(ExperimentPE input)
+    protected boolean shouldTranslate(TranslationContext context, ExperimentPE input, ExperimentFetchOptions fetchOptions)
     {
-        return new ExperimentByIdentiferValidator().doValidation(getTranslationContext().getSession().tryGetPerson(), input);
+        return new ExperimentByIdentiferValidator().doValidation(context.getSession().tryGetPerson(), input);
     }
 
     @Override
-    protected Experiment createObject(ExperimentPE experiment)
+    protected Experiment createObject(TranslationContext context, ExperimentPE experiment, ExperimentFetchOptions fetchOptions)
     {
         Experiment result = new Experiment();
 
@@ -74,80 +106,71 @@ public class ExperimentTranslator extends AbstractCachingTranslator<ExperimentPE
     }
 
     @Override
-    protected void updateObject(ExperimentPE experiment, Experiment result, Relations relations)
+    protected void updateObject(TranslationContext context, ExperimentPE experiment, Experiment result, Relations relations,
+            ExperimentFetchOptions fetchOptions)
     {
-        if (getFetchOptions().hasType())
+        if (fetchOptions.hasType())
         {
-            ExperimentType type =
-                    new ExperimentTypeTranslator(getTranslationContext(), getFetchOptions().withType()).translate(experiment.getExperimentType());
-            result.setType(type);
-            result.getFetchOptions().withTypeUsing(getFetchOptions().withType());
+            result.setType(typeTranslator.translate(context, experiment.getExperimentType(), fetchOptions.withType()));
+            result.getFetchOptions().withTypeUsing(fetchOptions.withType());
         }
 
-        if (getFetchOptions().hasProperties())
+        if (fetchOptions.hasProperties())
         {
-            Map<String, String> properties =
-                    new PropertyTranslator(getTranslationContext(), getFetchOptions().withProperties())
-                            .translate(experiment);
-            result.setProperties(properties);
-            result.getFetchOptions().withPropertiesUsing(getFetchOptions().withProperties());
+            result.setProperties(propertyTranslator.translate(context, experiment, fetchOptions.withProperties()));
+            result.getFetchOptions().withPropertiesUsing(fetchOptions.withProperties());
         }
 
-        if (getFetchOptions().hasMaterialProperties())
+        if (fetchOptions.hasMaterialProperties())
         {
-            result.setMaterialProperties(new MaterialPropertyTranslator(getTranslationContext(), getFetchOptions().withMaterialProperties())
-                    .translate(experiment));
-            result.getFetchOptions().withMaterialPropertiesUsing(getFetchOptions().withMaterialProperties());
+            result.setMaterialProperties(materialPropertyTranslator.translate(context, experiment, fetchOptions.withMaterialProperties()));
+            result.getFetchOptions().withMaterialPropertiesUsing(fetchOptions.withMaterialProperties());
         }
 
-        if (getFetchOptions().hasProject())
+        if (fetchOptions.hasProject())
         {
-            result.setProject(new ProjectTranslator(getTranslationContext(), getFetchOptions().withProject())
-                    .translate(experiment.getProject()));
-            result.getFetchOptions().withProjectUsing(getFetchOptions().withProject());
+            result.setProject(projectTranslator.translate(context, experiment.getProject(), fetchOptions.withProject()));
+            result.getFetchOptions().withProjectUsing(fetchOptions.withProject());
         }
 
-        if (getFetchOptions().hasSamples())
+        if (fetchOptions.hasSamples())
         {
-            result.setSamples(new ListTranslator().translate(experiment.getSamples(), new SampleTranslator(getTranslationContext(),
-                    getFetchOptions().withSamples())));
-            result.getFetchOptions().withSamplesUsing(getFetchOptions().withSamples());
+            Map<SamplePE, Sample> samples = sampleTranslator.translate(context, experiment.getSamples(), fetchOptions.withSamples());
+            result.setSamples(new ArrayList<Sample>(samples.values()));
+            result.getFetchOptions().withSamplesUsing(fetchOptions.withSamples());
         }
 
-        if (getFetchOptions().hasDataSets())
+        if (fetchOptions.hasDataSets())
         {
-            result.setDataSets(new ListTranslator().translate(experiment.getDataSets(), new DataSetTranslator(getTranslationContext(),
-                    getFetchOptions().withDataSets())));
-            result.getFetchOptions().withDataSetsUsing(getFetchOptions().withDataSets());
+            Map<DataPE, DataSet> dataSets = dataSetTranslator.translate(context, experiment.getDataSets(), fetchOptions.withDataSets());
+            result.setDataSets(new ArrayList<DataSet>(dataSets.values()));
+            result.getFetchOptions().withDataSetsUsing(fetchOptions.withDataSets());
         }
 
-        if (getFetchOptions().hasRegistrator())
+        if (fetchOptions.hasRegistrator())
         {
-            result.setRegistrator(new PersonTranslator(getTranslationContext(), getFetchOptions().withRegistrator()).translate(experiment
-                    .getRegistrator()));
-            result.getFetchOptions().withRegistratorUsing(getFetchOptions().withRegistrator());
+            result.setRegistrator(personTranslator.translate(context, experiment.getRegistrator(), fetchOptions.withRegistrator()));
+            result.getFetchOptions().withRegistratorUsing(fetchOptions.withRegistrator());
         }
 
-        if (getFetchOptions().hasModifier())
+        if (fetchOptions.hasModifier())
         {
-            result.setModifier(new PersonTranslator(getTranslationContext(), getFetchOptions().withModifier()).translate(experiment
-                    .getModifier()));
-            result.getFetchOptions().withModifierUsing(getFetchOptions().withModifier());
+            result.setModifier(personTranslator.translate(context, experiment.getModifier(), fetchOptions.withModifier()));
+            result.getFetchOptions().withModifierUsing(fetchOptions.withModifier());
         }
 
-        if (getFetchOptions().hasTags())
+        if (fetchOptions.hasTags())
         {
-            result.setTags(new SetTranslator().translate(experiment.getMetaprojects(), new TagTranslator(getTranslationContext(), getFetchOptions()
-                    .withTags())));
-            result.getFetchOptions().withTagsUsing(getFetchOptions().withTags());
+            Map<MetaprojectPE, Tag> tags = tagTranslator.translate(context, experiment.getMetaprojects(), fetchOptions.withTags());
+            result.setTags(new HashSet<Tag>(tags.values()));
+            result.getFetchOptions().withTagsUsing(fetchOptions.withTags());
         }
 
-        if (getFetchOptions().hasAttachments())
+        if (fetchOptions.hasAttachments())
         {
-            ArrayList<Attachment> attachments =
-                    AttachmentTranslator.translate(getTranslationContext(), experiment, getFetchOptions().withAttachments());
+            List<Attachment> attachments = attachmentTranslator.translate(context, experiment, fetchOptions.withAttachments());
             result.setAttachments(attachments);
-            result.getFetchOptions().withAttachmentsUsing(getFetchOptions().withAttachments());
+            result.getFetchOptions().withAttachmentsUsing(fetchOptions.withAttachments());
         }
 
     }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/experiment/ExperimentTypeTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/experiment/ExperimentTypeTranslator.java
index 82049bfe081..dbf5587149e 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/experiment/ExperimentTypeTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/experiment/ExperimentTypeTranslator.java
@@ -16,6 +16,8 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.experiment;
 
+import org.springframework.stereotype.Component;
+
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
@@ -27,16 +29,13 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
 /**
  * @author pkupczyk
  */
-public class ExperimentTypeTranslator extends AbstractCachingTranslator<ExperimentTypePE, ExperimentType, ExperimentTypeFetchOptions>
+@Component
+public class ExperimentTypeTranslator extends AbstractCachingTranslator<ExperimentTypePE, ExperimentType, ExperimentTypeFetchOptions> implements
+        IExperimentTypeTranslator
 {
 
-    public ExperimentTypeTranslator(TranslationContext translationContext, ExperimentTypeFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
-
     @Override
-    protected ExperimentType createObject(ExperimentTypePE type)
+    protected ExperimentType createObject(TranslationContext context, ExperimentTypePE type, ExperimentTypeFetchOptions fetchOptions)
     {
         ExperimentType result = new ExperimentType();
         result.setPermId(new EntityTypePermId(type.getCode()));
@@ -48,7 +47,8 @@ public class ExperimentTypeTranslator extends AbstractCachingTranslator<Experime
     }
 
     @Override
-    protected void updateObject(ExperimentTypePE input, ExperimentType output, Relations relations)
+    protected void updateObject(TranslationContext context, ExperimentTypePE input, ExperimentType output, Relations relations,
+            ExperimentTypeFetchOptions fetchOptions)
     {
     }
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/common/SetTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/experiment/IExperimentTranslator.java
similarity index 54%
rename from openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/common/SetTranslator.java
rename to openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/experiment/IExperimentTranslator.java
index 11f10252bc7..67f238be01e 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/common/SetTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/experiment/IExperimentTranslator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2013 ETH Zuerich, CISD
+ * Copyright 2015 ETH Zuerich, CISD
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,30 +14,17 @@
  * limitations under the License.
  */
 
-package ch.ethz.sis.openbis.generic.server.api.v3.translator.common;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.experiment;
 
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.Experiment;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.experiment.ExperimentFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 
 /**
  * @author pkupczyk
  */
-public class SetTranslator extends AbstractCollectionTranslator
+public interface IExperimentTranslator extends ITranslator<ExperimentPE, Experiment, ExperimentFetchOptions>
 {
 
-    @Override
-    public <I, O> Set<O> translate(Collection<? extends I> collection, ITranslator<I, O> itemTranslator)
-    {
-        return (Set<O>) super.translate(collection, itemTranslator);
-    }
-
-    @Override
-    protected <O> Collection<O> createCollection()
-    {
-        return new HashSet<O>();
-    }
-
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/experiment/IExperimentTypeTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/experiment/IExperimentTypeTranslator.java
new file mode 100644
index 00000000000..e1c5d4da2c5
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/experiment/IExperimentTypeTranslator.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.experiment;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.ExperimentType;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.experiment.ExperimentTypeFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
+
+/**
+ * @author pkupczyk
+ */
+public interface IExperimentTypeTranslator extends ITranslator<ExperimentTypePE, ExperimentType, ExperimentTypeFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/common/ListTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/IMaterialPropertyTranslator.java
similarity index 54%
rename from openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/common/ListTranslator.java
rename to openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/IMaterialPropertyTranslator.java
index a5c163caa7c..001bbc0cfd7 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/common/ListTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/IMaterialPropertyTranslator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2013 ETH Zuerich, CISD
+ * Copyright 2015 ETH Zuerich, CISD
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,30 +14,19 @@
  * limitations under the License.
  */
 
-package ch.ethz.sis.openbis.generic.server.api.v3.translator.common;
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.material;
 
-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.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.material.Material;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.material.MaterialFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityPropertiesHolder;
 
 /**
  * @author pkupczyk
  */
-public class ListTranslator extends AbstractCollectionTranslator
+public interface IMaterialPropertyTranslator extends ITranslator<IEntityPropertiesHolder, Map<String, Material>, MaterialFetchOptions>
 {
 
-    @Override
-    public <I, O> List<O> translate(Collection<? extends I> collection, ITranslator<I, O> itemTranslator)
-    {
-        return (List<O>) super.translate(collection, itemTranslator);
-    }
-
-    @Override
-    protected <O> Collection<O> createCollection()
-    {
-        return new ArrayList<O>();
-    }
-
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/IMaterialTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/IMaterialTranslator.java
new file mode 100644
index 00000000000..55839049228
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/IMaterialTranslator.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.material;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.material.Material;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.material.MaterialFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+
+/**
+ * @author pkupczyk
+ */
+public interface IMaterialTranslator extends ITranslator<MaterialPE, Material, MaterialFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/IMaterialTypeTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/IMaterialTypeTranslator.java
new file mode 100644
index 00000000000..7525d4d9e50
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/IMaterialTypeTranslator.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.material;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.material.MaterialType;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.material.MaterialTypeFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
+
+/**
+ * @author pkupczyk
+ */
+public interface IMaterialTypeTranslator extends ITranslator<MaterialTypePE, MaterialType, MaterialTypeFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/MaterialPropertyTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/MaterialPropertyTranslator.java
index 77bdeec5e25..e7882107f0d 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/MaterialPropertyTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/MaterialPropertyTranslator.java
@@ -19,6 +19,9 @@ package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.material;
 import java.util.HashMap;
 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.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
@@ -32,17 +35,16 @@ import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils;
 /**
  * @author Jakub Straszewski
  */
+@Component
 public class MaterialPropertyTranslator extends
-        AbstractCachingTranslator<IEntityPropertiesHolder, Map<String, Material>, MaterialFetchOptions>
+        AbstractCachingTranslator<IEntityPropertiesHolder, Map<String, Material>, MaterialFetchOptions> implements IMaterialPropertyTranslator
 {
 
-    public MaterialPropertyTranslator(TranslationContext translationContext, MaterialFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
+    @Autowired
+    private IMaterialTranslator materialTranslator;
 
     @Override
-    protected Map<String, Material> createObject(IEntityPropertiesHolder entity)
+    protected Map<String, Material> createObject(TranslationContext context, IEntityPropertiesHolder entity, MaterialFetchOptions fetchOptions)
     {
         if (false == entity.isPropertiesInitialized())
         {
@@ -58,8 +60,7 @@ public class MaterialPropertyTranslator extends
                 String code = property.getEntityTypePropertyType().getPropertyType().getCode();
                 MaterialPE materialPe = property.getMaterialValue();
 
-                Material material =
-                        new MaterialTranslator(getTranslationContext(), getFetchOptions()).translate(materialPe);
+                Material material = materialTranslator.translate(context, materialPe, fetchOptions);
                 properties.put(code, material);
             }
         }
@@ -67,9 +68,9 @@ public class MaterialPropertyTranslator extends
     }
 
     @Override
-    protected void updateObject(IEntityPropertiesHolder input, Map<String, Material> output, Relations relations)
+    protected void updateObject(TranslationContext context, IEntityPropertiesHolder input, Map<String, Material> output, Relations relations,
+            MaterialFetchOptions fetchOptions)
     {
-
     }
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/MaterialTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/MaterialTranslator.java
index 70aa2511323..8e994142241 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/MaterialTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/MaterialTranslator.java
@@ -17,35 +17,45 @@
 package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.material;
 
 import java.util.HashSet;
-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.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.common.ListTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.PersonTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.property.PropertyTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.tag.TagTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.IPersonTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.property.IPropertyTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.tag.ITagTranslator;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.material.Material;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.person.Person;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.tag.Tag;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.material.MaterialFetchOptions;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.material.MaterialPermId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 
 /**
  * @author Jakub Straszewski
  */
-public class MaterialTranslator extends AbstractCachingTranslator<MaterialPE, Material, MaterialFetchOptions>
+@Component
+public class MaterialTranslator extends AbstractCachingTranslator<MaterialPE, Material, MaterialFetchOptions> implements IMaterialTranslator
 {
 
-    public MaterialTranslator(TranslationContext translationContext, MaterialFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
+    @Autowired
+    private IPropertyTranslator propertyTranslator;
+
+    @Autowired
+    private IMaterialPropertyTranslator materialPropertyTranslator;
+
+    @Autowired
+    private IPersonTranslator personTranslator;
+
+    @Autowired
+    private ITagTranslator tagTranslator;
 
     @Override
-    protected Material createObject(MaterialPE materialPE)
+    protected Material createObject(TranslationContext context, MaterialPE materialPE, MaterialFetchOptions fetchOptions)
     {
         final Material material = new Material();
         material.setPermId(new MaterialPermId(materialPE.getCode(), materialPE.getMaterialType().getCode()));
@@ -57,37 +67,32 @@ public class MaterialTranslator extends AbstractCachingTranslator<MaterialPE, Ma
     }
 
     @Override
-    protected void updateObject(MaterialPE materialPe, Material result, Relations relations)
+    protected void updateObject(TranslationContext context, MaterialPE materialPe, Material result, Relations relations,
+            MaterialFetchOptions fetchOptions)
     {
-        if (getFetchOptions().hasProperties())
+        if (fetchOptions.hasProperties())
         {
-            result.setProperties(new PropertyTranslator(getTranslationContext(), getFetchOptions().withProperties())
-                    .translate(materialPe));
-            result.getFetchOptions().withPropertiesUsing(getFetchOptions().withProperties());
+            result.setProperties(propertyTranslator.translate(context, materialPe, fetchOptions.withProperties()));
+            result.getFetchOptions().withPropertiesUsing(fetchOptions.withProperties());
         }
 
-        if (getFetchOptions().hasMaterialProperties())
+        if (fetchOptions.hasMaterialProperties())
         {
-            result.setMaterialProperties(new MaterialPropertyTranslator(getTranslationContext(), getFetchOptions().withMaterialProperties())
-                    .translate(materialPe));
-            result.getFetchOptions().withMaterialPropertiesUsing(getFetchOptions().withMaterialProperties());
+            result.setMaterialProperties(materialPropertyTranslator.translate(context, materialPe, fetchOptions.withMaterialProperties()));
+            result.getFetchOptions().withMaterialPropertiesUsing(fetchOptions.withMaterialProperties());
         }
 
-        if (getFetchOptions().hasTags())
+        if (fetchOptions.hasTags())
         {
-            List<Tag> tags =
-                    new ListTranslator().translate(materialPe.getMetaprojects(), new TagTranslator(getTranslationContext(), getFetchOptions()
-                            .withTags()));
-            result.setTags(new HashSet<Tag>(tags));
-            result.getFetchOptions().withTagsUsing(getFetchOptions().withTags());
+            Map<MetaprojectPE, Tag> tags = tagTranslator.translate(context, materialPe.getMetaprojects(), fetchOptions.withTags());
+            result.setTags(new HashSet<Tag>(tags.values()));
+            result.getFetchOptions().withTagsUsing(fetchOptions.withTags());
         }
 
-        if (getFetchOptions().hasRegistrator())
+        if (fetchOptions.hasRegistrator())
         {
-            Person registrator =
-                    new PersonTranslator(getTranslationContext(), getFetchOptions().withRegistrator()).translate(materialPe.getRegistrator());
-            result.setRegistrator(registrator);
-            result.getFetchOptions().withRegistratorUsing(getFetchOptions().withRegistrator());
+            result.setRegistrator(personTranslator.translate(context, materialPe.getRegistrator(), fetchOptions.withRegistrator()));
+            result.getFetchOptions().withRegistratorUsing(fetchOptions.withRegistrator());
         }
     }
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/MaterialTypeTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/MaterialTypeTranslator.java
index ac6247f6fea..d022fa8964e 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/MaterialTypeTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/material/MaterialTypeTranslator.java
@@ -16,6 +16,8 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.material;
 
+import org.springframework.stereotype.Component;
+
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
@@ -27,16 +29,13 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
 /**
  * @author Jakub Straszewski
  */
-public class MaterialTypeTranslator extends AbstractCachingTranslator<MaterialTypePE, MaterialType, MaterialTypeFetchOptions>
+@Component
+public class MaterialTypeTranslator extends AbstractCachingTranslator<MaterialTypePE, MaterialType, MaterialTypeFetchOptions> implements
+        IMaterialTypeTranslator
 {
 
-    public MaterialTypeTranslator(TranslationContext translationContext, MaterialTypeFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
-
     @Override
-    protected MaterialType createObject(MaterialTypePE input)
+    protected MaterialType createObject(TranslationContext context, MaterialTypePE input, MaterialTypeFetchOptions fetchOptions)
     {
         final MaterialType materialType = new MaterialType();
         materialType.setPermId(new EntityTypePermId(input.getCode()));
@@ -47,9 +46,9 @@ public class MaterialTypeTranslator extends AbstractCachingTranslator<MaterialTy
     }
 
     @Override
-    protected void updateObject(MaterialTypePE input, MaterialType output, Relations relations)
+    protected void updateObject(TranslationContext context, MaterialTypePE input, MaterialType output, Relations relations,
+            MaterialTypeFetchOptions fetchOptions)
     {
-
     }
 
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/person/IPersonTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/person/IPersonTranslator.java
new file mode 100644
index 00000000000..1b6b076d6b2
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/person/IPersonTranslator.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.person.Person;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.person.PersonFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+
+/**
+ * @author pkupczyk
+ */
+public interface IPersonTranslator extends ITranslator<PersonPE, Person, PersonFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/person/PersonTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/person/PersonTranslator.java
index 60c40f32e6c..a7b41f50d1e 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/person/PersonTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/person/PersonTranslator.java
@@ -16,10 +16,13 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person;
 
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.space.SpaceTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.space.ISpaceTranslator;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.person.Person;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.person.PersonFetchOptions;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.person.PersonPermId;
@@ -28,15 +31,15 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 /**
  * @author pkupczyk
  */
-public class PersonTranslator extends AbstractCachingTranslator<PersonPE, Person, PersonFetchOptions>
+@Component
+public class PersonTranslator extends AbstractCachingTranslator<PersonPE, Person, PersonFetchOptions> implements IPersonTranslator
 {
-    public PersonTranslator(TranslationContext translationContext, PersonFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
+
+    @Autowired
+    private ISpaceTranslator spaceTranslator;
 
     @Override
-    protected Person createObject(PersonPE person)
+    protected Person createObject(TranslationContext context, PersonPE person, PersonFetchOptions fetchOptions)
     {
         Person result = new Person();
 
@@ -53,22 +56,18 @@ public class PersonTranslator extends AbstractCachingTranslator<PersonPE, Person
     }
 
     @Override
-    protected void updateObject(PersonPE person, Person result, Relations relations)
+    protected void updateObject(TranslationContext context, PersonPE person, Person result, Relations relations, PersonFetchOptions fetchOptions)
     {
-        if (getFetchOptions().hasSpace())
+        if (fetchOptions.hasSpace())
         {
-            result.setSpace(new SpaceTranslator(getTranslationContext(), getFetchOptions().withSpace())
-                    .translate(person.getHomeSpace()));
-            result.getFetchOptions().withSpaceUsing(getFetchOptions().withSpace());
+            result.setSpace(spaceTranslator.translate(context, person.getHomeSpace(), fetchOptions.withSpace()));
+            result.getFetchOptions().withSpaceUsing(fetchOptions.withSpace());
         }
 
-        if (getFetchOptions().hasRegistrator())
+        if (fetchOptions.hasRegistrator())
         {
-            result.setRegistrator(new PersonTranslator(getTranslationContext(), getFetchOptions().withRegistrator())
-                    .translate(person
-                            .getRegistrator()));
-            result.getFetchOptions().withRegistratorUsing(getFetchOptions().withRegistrator());
+            result.setRegistrator(translate(context, person.getRegistrator(), fetchOptions.withRegistrator()));
+            result.getFetchOptions().withRegistratorUsing(fetchOptions.withRegistrator());
         }
     }
-
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/IUpdateProjectLeaderExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/project/IProjectTranslator.java
similarity index 68%
rename from openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/IUpdateProjectLeaderExecutor.java
rename to openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/project/IProjectTranslator.java
index ab91122843c..83f9dba1696 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/project/IUpdateProjectLeaderExecutor.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/project/IProjectTranslator.java
@@ -14,16 +14,17 @@
  * limitations under the License.
  */
 
-package ch.ethz.sis.openbis.generic.server.api.v3.executor.project;
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.project;
 
-import ch.ethz.sis.openbis.generic.server.api.v3.executor.entity.IUpdateEntityRelationsExecutor;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.project.ProjectUpdate;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.project.Project;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.project.ProjectFetchOptions;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
 
 /**
  * @author pkupczyk
  */
-public interface IUpdateProjectLeaderExecutor extends IUpdateEntityRelationsExecutor<ProjectUpdate, ProjectPE>
+public interface IProjectTranslator extends ITranslator<ProjectPE, Project, ProjectFetchOptions>
 {
 
-}
\ No newline at end of file
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/project/ProjectTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/project/ProjectTranslator.java
index bc54f997ffb..f1e2750c694 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/project/ProjectTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/project/ProjectTranslator.java
@@ -18,15 +18,18 @@ package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.project;
 
 import java.util.ArrayList;
 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.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.common.ListTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.attachment.AttachmentTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.experiment.ExperimentTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.PersonTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.space.SpaceTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.attachment.IAttachmentTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.experiment.IExperimentTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.IPersonTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.space.ISpaceTranslator;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.attachment.Attachment;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.Experiment;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.project.Project;
@@ -34,26 +37,36 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.project.Projec
 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.systemsx.cisd.openbis.generic.server.authorization.validator.ProjectByIdentiferValidator;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
 
 /**
  * @author pkupczyk
  */
-public class ProjectTranslator extends AbstractCachingTranslator<ProjectPE, Project, ProjectFetchOptions>
+@Component
+public class ProjectTranslator extends AbstractCachingTranslator<ProjectPE, Project, ProjectFetchOptions> implements IProjectTranslator
 {
-    public ProjectTranslator(TranslationContext translationContext, ProjectFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
+
+    @Autowired
+    private ISpaceTranslator spaceTranslator;
+
+    @Autowired
+    private IPersonTranslator personTranslator;
+
+    @Autowired
+    private IExperimentTranslator experimentTranslator;
+
+    @Autowired
+    private IAttachmentTranslator attachmentTranslator;
 
     @Override
-    protected boolean shouldTranslate(ProjectPE input)
+    protected boolean shouldTranslate(TranslationContext context, ProjectPE input, ProjectFetchOptions fetchOptions)
     {
-        return new ProjectByIdentiferValidator().doValidation(getTranslationContext().getSession().tryGetPerson(), input);
+        return new ProjectByIdentiferValidator().doValidation(context.getSession().tryGetPerson(), input);
     }
 
     @Override
-    protected Project createObject(ProjectPE project)
+    protected Project createObject(TranslationContext context, ProjectPE project, ProjectFetchOptions fetchOptions)
     {
         Project result = new Project();
 
@@ -69,51 +82,45 @@ public class ProjectTranslator extends AbstractCachingTranslator<ProjectPE, Proj
     }
 
     @Override
-    protected void updateObject(ProjectPE project, Project result, Relations relations)
+    protected void updateObject(TranslationContext context, ProjectPE project, Project result, Relations relations, ProjectFetchOptions fetchOptions)
     {
-        if (getFetchOptions().hasSpace())
+        if (fetchOptions.hasSpace())
         {
-            result.setSpace(new SpaceTranslator(getTranslationContext(), getFetchOptions().withSpace())
-                    .translate(project.getSpace()));
-            result.getFetchOptions().withSpaceUsing(getFetchOptions().withSpace());
+            result.setSpace(spaceTranslator.translate(context, project.getSpace(), fetchOptions.withSpace()));
+            result.getFetchOptions().withSpaceUsing(fetchOptions.withSpace());
         }
 
-        if (getFetchOptions().hasRegistrator())
+        if (fetchOptions.hasRegistrator())
         {
-            result.setRegistrator(new PersonTranslator(getTranslationContext(), getFetchOptions().withRegistrator()).translate(project
-                    .getRegistrator()));
-            result.getFetchOptions().withRegistratorUsing(getFetchOptions().withRegistrator());
+            result.setRegistrator(personTranslator.translate(context, project.getRegistrator(), fetchOptions.withRegistrator()));
+            result.getFetchOptions().withRegistratorUsing(fetchOptions.withRegistrator());
         }
 
-        if (getFetchOptions().hasModifier())
+        if (fetchOptions.hasModifier())
         {
-            result.setModifier(new PersonTranslator(getTranslationContext(), getFetchOptions().withModifier()).translate(project
-                    .getModifier()));
-            result.getFetchOptions().withModifierUsing(getFetchOptions().withModifier());
+            result.setModifier(personTranslator.translate(context, project.getModifier(), fetchOptions.withModifier()));
+            result.getFetchOptions().withModifierUsing(fetchOptions.withModifier());
         }
 
-        if (getFetchOptions().hasLeader())
+        if (fetchOptions.hasLeader())
         {
-            result.setLeader(new PersonTranslator(getTranslationContext(), getFetchOptions().withLeader()).translate(project
-                    .getProjectLeader()));
-            result.getFetchOptions().withLeaderUsing(getFetchOptions().withLeader());
+            result.setLeader(personTranslator.translate(context, project.getProjectLeader(), fetchOptions.withLeader()));
+            result.getFetchOptions().withLeaderUsing(fetchOptions.withLeader());
         }
 
-        if (getFetchOptions().hasExperiments())
+        if (fetchOptions.hasExperiments())
         {
-            List<Experiment> experiments =
-                    new ListTranslator().translate(project.getExperiments(), new ExperimentTranslator(getTranslationContext(),
-                            getFetchOptions().withExperiments()));
-            result.setExperiments(experiments);
-            result.getFetchOptions().withExperimentsUsing(getFetchOptions().withExperiments());
+            Map<ExperimentPE, Experiment> experiments =
+                    experimentTranslator.translate(context, project.getExperiments(), fetchOptions.withExperiments());
+            result.setExperiments(new ArrayList<Experiment>(experiments.values()));
+            result.getFetchOptions().withExperimentsUsing(fetchOptions.withExperiments());
         }
 
-        if (getFetchOptions().hasAttachments())
+        if (fetchOptions.hasAttachments())
         {
-            ArrayList<Attachment> attachments =
-                    AttachmentTranslator.translate(getTranslationContext(), project, getFetchOptions().withAttachments());
+            List<Attachment> attachments = attachmentTranslator.translate(context, project, fetchOptions.withAttachments());
             result.setAttachments(attachments);
-            result.getFetchOptions().withAttachmentsUsing(getFetchOptions().withAttachments());
+            result.getFetchOptions().withAttachmentsUsing(fetchOptions.withAttachments());
         }
 
     }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/property/IPropertyTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/property/IPropertyTranslator.java
new file mode 100644
index 00000000000..781c41da2a1
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/property/IPropertyTranslator.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.property;
+
+import java.util.Map;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.property.PropertyFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityPropertiesHolder;
+
+/**
+ * @author pkupczyk
+ */
+public interface IPropertyTranslator extends ITranslator<IEntityPropertiesHolder, Map<String, String>, PropertyFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/property/PropertyTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/property/PropertyTranslator.java
index bd11295fdcc..d356a938158 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/property/PropertyTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/property/PropertyTranslator.java
@@ -20,30 +20,36 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import javax.annotation.Resource;
+
+import org.springframework.stereotype.Component;
+
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.property.PropertyFetchOptions;
+import ch.systemsx.cisd.openbis.generic.server.ComponentNames;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityPropertiesHolder;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.managed_property.IManagedPropertyEvaluatorFactory;
 import ch.systemsx.cisd.openbis.generic.shared.translator.EntityPropertyTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils;
 
 /**
  * @author pkupczyk
  */
-public class PropertyTranslator extends AbstractCachingTranslator<IEntityPropertiesHolder, Map<String, String>, PropertyFetchOptions>
+@Component
+public class PropertyTranslator extends AbstractCachingTranslator<IEntityPropertiesHolder, Map<String, String>, PropertyFetchOptions> implements
+        IPropertyTranslator
 {
 
-    public PropertyTranslator(TranslationContext translationContext, PropertyFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
+    @Resource(name = ComponentNames.MANAGED_PROPERTY_EVALUATOR_FACTORY)
+    private IManagedPropertyEvaluatorFactory managedPropertyEvaluatorFactory;
 
     @Override
-    protected Map<String, String> createObject(IEntityPropertiesHolder entity)
+    protected Map<String, String> createObject(TranslationContext context, IEntityPropertiesHolder entity, PropertyFetchOptions fetchOptions)
     {
         if (false == entity.isPropertiesInitialized())
         {
@@ -52,10 +58,9 @@ public class PropertyTranslator extends AbstractCachingTranslator<IEntityPropert
 
         HashMap<String, String> properties = new HashMap<String, String>();
 
-        List<IEntityProperty> propertiesPE = EntityPropertyTranslator
-                .translate(entity.getProperties(),
-                        new HashMap<PropertyTypePE, PropertyType>(),
-                        getTranslationContext().getManagedPropertyEvaluatorFactory());
+        List<IEntityProperty> propertiesPE =
+                EntityPropertyTranslator.translate(entity.getProperties(), new HashMap<PropertyTypePE, PropertyType>(),
+                        managedPropertyEvaluatorFactory);
 
         for (IEntityProperty iEntityProperty : propertiesPE)
         {
@@ -67,9 +72,9 @@ public class PropertyTranslator extends AbstractCachingTranslator<IEntityPropert
     }
 
     @Override
-    protected void updateObject(IEntityPropertiesHolder input, Map<String, String> output, Relations relations)
+    protected void updateObject(TranslationContext context, IEntityPropertiesHolder input, Map<String, String> output, Relations relations,
+            PropertyFetchOptions fetchOptions)
     {
 
     }
-
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/sample/ISampleTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/sample/ISampleTranslator.java
new file mode 100644
index 00000000000..1f56e10dacd
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/sample/ISampleTranslator.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.sample;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.Sample;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sample.SampleFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISampleTranslator extends ITranslator<SamplePE, Sample, SampleFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/sample/ISampleTypeTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/sample/ISampleTypeTranslator.java
new file mode 100644
index 00000000000..cce19aae589
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/sample/ISampleTypeTranslator.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.sample;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleType;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sample.SampleTypeFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePE;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISampleTypeTranslator extends ITranslator<SampleTypePE, SampleType, SampleTypeFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/sample/SampleTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/sample/SampleTranslator.java
index 870b29f643e..109a7d6d920 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/sample/SampleTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/sample/SampleTranslator.java
@@ -9,51 +9,75 @@ import java.util.HashSet;
 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.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.ToManyRelation;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.ToOneRelation;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.common.ListTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.attachment.AttachmentTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.dataset.DataSetTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.experiment.ExperimentTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.material.MaterialPropertyTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.PersonTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.property.PropertyTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.space.SpaceTranslator;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.tag.TagTranslator;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.attachment.Attachment;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.attachment.IAttachmentTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.dataset.IDataSetTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.experiment.IExperimentTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.material.IMaterialPropertyTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.IPersonTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.property.IPropertyTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.space.ISpaceTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.tag.ITagTranslator;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.dataset.DataSet;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.experiment.Experiment;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.person.Person;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.Sample;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.SampleType;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.space.Space;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.tag.Tag;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.experiment.ExperimentFetchOptions;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sample.SampleFetchOptions;
 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.systemsx.cisd.openbis.generic.server.authorization.validator.SampleByIdentiferValidator;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
-public class SampleTranslator extends AbstractCachingTranslator<SamplePE, Sample, SampleFetchOptions>
+@Component
+public class SampleTranslator extends AbstractCachingTranslator<SamplePE, Sample, SampleFetchOptions> implements ISampleTranslator
 {
 
-    public SampleTranslator(TranslationContext translationContext, SampleFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
+    @Autowired
+    private ISpaceTranslator spaceTranslator;
+
+    @Autowired
+    private IExperimentTranslator experimentTranslator;
+
+    @Autowired
+    private IAttachmentTranslator attachmentTranslator;
+
+    @Autowired
+    private IPropertyTranslator propertyTranslator;
+
+    @Autowired
+    private IMaterialPropertyTranslator materialPropertyTranslator;
+
+    @Autowired
+    private ISampleTypeTranslator typeTranslator;
+
+    @Autowired
+    private IPersonTranslator personTranslator;
+
+    @Autowired
+    private ITagTranslator tagTranslator;
+
+    @Autowired
+    private IDataSetTranslator dataSetTranslator;
 
     @Override
-    protected boolean shouldTranslate(SamplePE input)
+    protected boolean shouldTranslate(TranslationContext context, SamplePE input, SampleFetchOptions fetchOptions)
     {
-        return new SampleByIdentiferValidator().doValidation(getTranslationContext().getSession().tryGetPerson(), input);
+        return new SampleByIdentiferValidator().doValidation(context.getSession().tryGetPerson(), input);
     }
 
     @Override
-    protected Sample createObject(SamplePE samplePe)
+    protected Sample createObject(TranslationContext context, SamplePE samplePe, SampleFetchOptions fetchOptions)
     {
         final Sample sample = new Sample();
         sample.setPermId(new SamplePermId(samplePe.getPermId()));
@@ -67,148 +91,123 @@ public class SampleTranslator extends AbstractCachingTranslator<SamplePE, Sample
     }
 
     @Override
-    protected Relations getObjectsRelations(final Collection<SamplePE> samples)
+    protected Relations getObjectsRelations(TranslationContext context, final Collection<SamplePE> samples, SampleFetchOptions fetchOptions)
     {
         Relations relations = new Relations();
 
-        if (getFetchOptions().hasExperiment())
+        if (fetchOptions.hasExperiment())
         {
-            relations.add(new SampleExperimentRelation(samples));
+            relations.add(new SampleExperimentRelation(context, samples, fetchOptions.withExperiment()));
         }
 
-        if (getFetchOptions().hasParents())
+        if (fetchOptions.hasParents())
         {
-            relations.add(new SampleParentsRelation(samples));
+            relations.add(new SampleParentsRelation(context, samples, fetchOptions.withParents()));
         }
 
         return relations;
     }
 
     @Override
-    protected void updateObject(SamplePE samplePe, Sample result, Relations relations)
+    protected void updateObject(TranslationContext context, SamplePE samplePe, Sample result, Relations relations, SampleFetchOptions fetchOptions)
     {
-        if (getFetchOptions().hasExperiment())
+        if (fetchOptions.hasExperiment())
         {
             result.setExperiment(relations.get(SampleExperimentRelation.class).getTranslated(samplePe));
-            result.getFetchOptions().withExperimentUsing(getFetchOptions().withExperiment());
+            result.getFetchOptions().withExperimentUsing(fetchOptions.withExperiment());
         }
 
-        if (getFetchOptions().hasSpace())
+        if (fetchOptions.hasSpace())
         {
-            Space space =
-                    new SpaceTranslator(getTranslationContext(), getFetchOptions().withSpace()).translate(samplePe
-                            .getSpace());
-            result.setSpace(space);
-            result.getFetchOptions().withSpaceUsing(getFetchOptions().withSpace());
+            result.setSpace(spaceTranslator.translate(context, samplePe.getSpace(), fetchOptions.withSpace()));
+            result.getFetchOptions().withSpaceUsing(fetchOptions.withSpace());
         }
 
-        if (getFetchOptions().hasProperties())
+        if (fetchOptions.hasProperties())
         {
-            result.setProperties(new PropertyTranslator(getTranslationContext(), getFetchOptions().withProperties())
-                    .translate(samplePe));
-            result.getFetchOptions().withPropertiesUsing(getFetchOptions().withProperties());
+            result.setProperties(propertyTranslator.translate(context, samplePe, fetchOptions.withProperties()));
+            result.getFetchOptions().withPropertiesUsing(fetchOptions.withProperties());
         }
 
-        if (getFetchOptions().hasMaterialProperties())
+        if (fetchOptions.hasMaterialProperties())
         {
-            result.setMaterialProperties(new MaterialPropertyTranslator(getTranslationContext(), getFetchOptions().withMaterialProperties())
-                    .translate(samplePe));
-            result.getFetchOptions().withMaterialPropertiesUsing(getFetchOptions().withMaterialProperties());
+            result.setMaterialProperties(materialPropertyTranslator.translate(context, samplePe, fetchOptions.withMaterialProperties()));
+            result.getFetchOptions().withMaterialPropertiesUsing(fetchOptions.withMaterialProperties());
         }
 
-        if (getFetchOptions().hasParents())
+        if (fetchOptions.hasParents())
         {
             result.setParents(relations.get(SampleParentsRelation.class).getTranslatedList(samplePe));
-            result.getFetchOptions().withParentsUsing(getFetchOptions().withParents());
+            result.getFetchOptions().withParentsUsing(fetchOptions.withParents());
         }
 
-        if (getFetchOptions().hasChildren())
+        if (fetchOptions.hasChildren())
         {
-            List<Sample> children =
-                    new ListTranslator().translate(samplePe.getChildren(), new SampleTranslator(getTranslationContext(),
-                            getFetchOptions()
-                                    .withChildren()));
-            result.setChildren(children);
-            result.getFetchOptions().withChildrenUsing(getFetchOptions().withChildren());
+            Map<SamplePE, Sample> children = translate(context, samplePe.getChildren(), fetchOptions.withChildren());
+            result.setChildren(new ArrayList<Sample>(children.values()));
+            result.getFetchOptions().withChildrenUsing(fetchOptions.withChildren());
         }
 
-        if (getFetchOptions().hasContainer())
+        if (fetchOptions.hasContainer())
         {
-            Sample container =
-                    new SampleTranslator(getTranslationContext(), getFetchOptions().withContainer())
-                            .translate(samplePe.getContainer());
-            result.setContainer(container);
-            result.getFetchOptions().withContainerUsing(getFetchOptions().withContainer());
+            result.setContainer(translate(context, samplePe.getContainer(), fetchOptions.withContainer()));
+            result.getFetchOptions().withContainerUsing(fetchOptions.withContainer());
         }
 
-        if (getFetchOptions().hasContained())
+        if (fetchOptions.hasContained())
         {
-            List<Sample> contained =
-                    new ListTranslator().translate(samplePe.getContained(), new SampleTranslator(getTranslationContext(),
-                            getFetchOptions()
-                                    .withContained()));
-            result.setContained(contained);
-            result.getFetchOptions().withContainedUsing(getFetchOptions().withContained());
+            Map<SamplePE, Sample> contained = translate(context, samplePe.getContained(), fetchOptions.withContained());
+            result.setContained(new ArrayList<Sample>(contained.values()));
+            result.getFetchOptions().withContainedUsing(fetchOptions.withContained());
         }
 
-        if (getFetchOptions().hasDataSets())
+        if (fetchOptions.hasDataSets())
         {
-            List<DataSet> dataSets =
-                    new ListTranslator().translate(samplePe.getDatasets(), new DataSetTranslator(getTranslationContext(),
-                            getFetchOptions().withDataSets()));
-            result.setDataSets(dataSets);
-            result.getFetchOptions().withDataSetsUsing(getFetchOptions().withDataSets());
+            Map<DataPE, DataSet> dataSets = dataSetTranslator.translate(context, samplePe.getDatasets(), fetchOptions.withDataSets());
+            result.setDataSets(new ArrayList<DataSet>(dataSets.values()));
+            result.getFetchOptions().withDataSetsUsing(fetchOptions.withDataSets());
         }
 
-        if (getFetchOptions().hasType())
+        if (fetchOptions.hasType())
         {
-            SampleType sampleType =
-                    new SampleTypeTranslator(getTranslationContext(), getFetchOptions().withType()).translate(samplePe.getSampleType());
-            result.setType(sampleType);
-            result.getFetchOptions().withTypeUsing(getFetchOptions().withType());
+            result.setType(typeTranslator.translate(context, samplePe.getSampleType(), fetchOptions.withType()));
+            result.getFetchOptions().withTypeUsing(fetchOptions.withType());
         }
 
-        if (getFetchOptions().hasTags())
+        if (fetchOptions.hasTags())
         {
-            List<Tag> tags =
-                    new ListTranslator().translate(samplePe.getMetaprojects(), new TagTranslator(getTranslationContext(), getFetchOptions()
-                            .withTags()));
-            result.setTags(new HashSet<Tag>(tags));
-            result.getFetchOptions().withTagsUsing(getFetchOptions().withTags());
+            Map<MetaprojectPE, Tag> tags = tagTranslator.translate(context, samplePe.getMetaprojects(), fetchOptions.withTags());
+            result.setTags(new HashSet<Tag>(tags.values()));
+            result.getFetchOptions().withTagsUsing(fetchOptions.withTags());
         }
 
-        if (getFetchOptions().hasRegistrator())
+        if (fetchOptions.hasRegistrator())
         {
-            Person registrator =
-                    new PersonTranslator(getTranslationContext(), getFetchOptions().withRegistrator()).translate(samplePe.getRegistrator());
-            result.setRegistrator(registrator);
-            result.getFetchOptions().withRegistratorUsing(getFetchOptions().withRegistrator());
+            result.setRegistrator(personTranslator.translate(context, samplePe.getRegistrator(), fetchOptions.withRegistrator()));
+            result.getFetchOptions().withRegistratorUsing(fetchOptions.withRegistrator());
         }
 
-        if (getFetchOptions().hasModifier())
+        if (fetchOptions.hasModifier())
         {
-            Person modifier =
-                    new PersonTranslator(getTranslationContext(), getFetchOptions().withModifier()).translate(samplePe.getModifier());
-            result.setModifier(modifier);
-            result.getFetchOptions().withModifierUsing(getFetchOptions().withModifier());
+            result.setModifier(personTranslator.translate(context, samplePe.getModifier(), fetchOptions.withModifier()));
+            result.getFetchOptions().withModifierUsing(fetchOptions.withModifier());
         }
 
-        if (getFetchOptions().hasAttachments())
+        if (fetchOptions.hasAttachments())
         {
-            ArrayList<Attachment> attachments =
-                    AttachmentTranslator.translate(getTranslationContext(), samplePe, getFetchOptions().withAttachments());
-            result.setAttachments(attachments);
-            result.getFetchOptions().withAttachmentsUsing(getFetchOptions().withAttachments());
+            result.setAttachments(attachmentTranslator.translate(context, samplePe, fetchOptions.withAttachments()));
+            result.getFetchOptions().withAttachmentsUsing(fetchOptions.withAttachments());
         }
     }
 
-    private class SampleExperimentRelation extends ToOneRelation<SamplePE, ExperimentPE, Experiment>
+    private class SampleExperimentRelation extends ToOneRelation<SamplePE, ExperimentPE, Experiment, ExperimentFetchOptions>
     {
 
         private Collection<SamplePE> samples;
 
-        public SampleExperimentRelation(Collection<SamplePE> samples)
+        public SampleExperimentRelation(TranslationContext context, Collection<SamplePE> samples, ExperimentFetchOptions fetchOptions)
         {
+            super(context, fetchOptions);
             this.samples = samples;
         }
 
@@ -225,21 +224,21 @@ public class SampleTranslator extends AbstractCachingTranslator<SamplePE, Sample
         }
 
         @Override
-        protected Map<ExperimentPE, Experiment> getTranslatedMap(Collection<ExperimentPE> originalCollection)
+        protected Map<ExperimentPE, Experiment> getTranslatedMap(TranslationContext context, Collection<ExperimentPE> originalCollection,
+                ExperimentFetchOptions fetchOptions)
         {
-            return new ExperimentTranslator(getTranslationContext(), getFetchOptions()
-                    .withExperiment()).translate(originalCollection);
+            return experimentTranslator.translate(context, originalCollection, fetchOptions);
         }
-
     }
 
-    private class SampleParentsRelation extends ToManyRelation<SamplePE, SamplePE, Sample>
+    private class SampleParentsRelation extends ToManyRelation<SamplePE, SamplePE, Sample, SampleFetchOptions>
     {
 
         private Collection<SamplePE> samples;
 
-        public SampleParentsRelation(Collection<SamplePE> samples)
+        public SampleParentsRelation(TranslationContext context, Collection<SamplePE> samples, SampleFetchOptions fetchOptions)
         {
+            super(context, fetchOptions);
             this.samples = samples;
         }
 
@@ -266,10 +265,10 @@ public class SampleTranslator extends AbstractCachingTranslator<SamplePE, Sample
         }
 
         @Override
-        protected Map<SamplePE, Sample> getTranslatedMap(Collection<SamplePE> originalCollection)
+        protected Map<SamplePE, Sample> getTranslatedMap(TranslationContext context, Collection<SamplePE> originalCollection,
+                SampleFetchOptions fetchOptions)
         {
-            return new SampleTranslator(getTranslationContext(), getFetchOptions()
-                    .withParents()).translate(originalCollection);
+            return translate(context, originalCollection, fetchOptions);
         }
 
     }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/sample/SampleTypeTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/sample/SampleTypeTranslator.java
index 6ebabb37088..4b1ac2f9061 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/sample/SampleTypeTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/sample/SampleTypeTranslator.java
@@ -1,5 +1,7 @@
 package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.sample;
 
+import org.springframework.stereotype.Component;
+
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
@@ -8,15 +10,13 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sample.SampleT
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.entitytype.EntityTypePermId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePE;
 
-public class SampleTypeTranslator extends AbstractCachingTranslator<SampleTypePE, SampleType, SampleTypeFetchOptions>
+@Component
+public class SampleTypeTranslator extends AbstractCachingTranslator<SampleTypePE, SampleType, SampleTypeFetchOptions> implements
+        ISampleTypeTranslator
 {
-    public SampleTypeTranslator(TranslationContext translationContext, SampleTypeFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
 
     @Override
-    protected SampleType createObject(SampleTypePE type)
+    protected SampleType createObject(TranslationContext context, SampleTypePE type, SampleTypeFetchOptions fetchOptions)
     {
         SampleType result = new SampleType();
         result.setPermId(new EntityTypePermId(type.getCode()));
@@ -34,7 +34,8 @@ public class SampleTypeTranslator extends AbstractCachingTranslator<SampleTypePE
     }
 
     @Override
-    protected void updateObject(SampleTypePE input, SampleType output, Relations relations)
+    protected void updateObject(TranslationContext context, SampleTypePE input, SampleType output, Relations relations,
+            SampleTypeFetchOptions fetchOptions)
     {
 
     }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/space/ISpaceTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/space/ISpaceTranslator.java
new file mode 100644
index 00000000000..67551ab0a37
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/space/ISpaceTranslator.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.space;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.space.Space;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.space.SpaceFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
+
+/**
+ * @author pkupczyk
+ */
+public interface ISpaceTranslator extends ITranslator<SpacePE, Space, SpaceFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/space/SpaceTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/space/SpaceTranslator.java
index 9f75a895f21..d4205d85959 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/space/SpaceTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/space/SpaceTranslator.java
@@ -16,12 +16,15 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.space;
 
-import java.util.List;
+import java.util.ArrayList;
+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.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.common.ListTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.PersonTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.project.ProjectTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.sample.SampleTranslator;
@@ -31,26 +34,34 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.space.Space;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.space.SpaceFetchOptions;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.SpacePermId;
 import ch.systemsx.cisd.openbis.generic.server.authorization.validator.SimpleSpaceValidator;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
 
 /**
  * @author pkupczyk
  */
-public class SpaceTranslator extends AbstractCachingTranslator<SpacePE, Space, SpaceFetchOptions>
+@Component
+public class SpaceTranslator extends AbstractCachingTranslator<SpacePE, Space, SpaceFetchOptions> implements ISpaceTranslator
 {
-    public SpaceTranslator(TranslationContext translationContext, SpaceFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
+
+    @Autowired
+    private PersonTranslator personTranslator;
+
+    @Autowired
+    private ProjectTranslator projectTranslator;
+
+    @Autowired
+    private SampleTranslator sampleTranslator;
 
     @Override
-    protected boolean shouldTranslate(SpacePE input)
+    protected boolean shouldTranslate(TranslationContext context, SpacePE input, SpaceFetchOptions fetchOptions)
     {
-        return new SimpleSpaceValidator().doValidation(getTranslationContext().getSession().tryGetPerson(), input);
+        return new SimpleSpaceValidator().doValidation(context.getSession().tryGetPerson(), input);
     }
 
     @Override
-    protected Space createObject(SpacePE space)
+    protected Space createObject(TranslationContext context, SpacePE space, SpaceFetchOptions fetchOptions)
     {
         Space result = new Space();
 
@@ -64,31 +75,26 @@ public class SpaceTranslator extends AbstractCachingTranslator<SpacePE, Space, S
     }
 
     @Override
-    protected void updateObject(SpacePE space, Space result, Relations relations)
+    protected void updateObject(TranslationContext context, SpacePE space, Space result, Relations relations, SpaceFetchOptions fetchOptions)
     {
-        if (getFetchOptions().hasRegistrator())
+        if (fetchOptions.hasRegistrator())
         {
-            result.setRegistrator(new PersonTranslator(getTranslationContext(), getFetchOptions().withRegistrator()).translate(space
-                    .getRegistrator()));
-            result.getFetchOptions().withRegistratorUsing(getFetchOptions().withRegistrator());
+            result.setRegistrator(personTranslator.translate(context, space.getRegistrator(), fetchOptions.withRegistrator()));
+            result.getFetchOptions().withRegistratorUsing(fetchOptions.withRegistrator());
         }
 
-        if (getFetchOptions().hasProjects())
+        if (fetchOptions.hasProjects())
         {
-            List<Project> projects =
-                    new ListTranslator().translate(space.getProjects(), new ProjectTranslator(getTranslationContext(),
-                            getFetchOptions().withProjects()));
-            result.setProjects(projects);
-            result.getFetchOptions().withProjectsUsing(getFetchOptions().withProjects());
+            Map<ProjectPE, Project> projects = projectTranslator.translate(context, space.getProjects(), fetchOptions.withProjects());
+            result.setProjects(new ArrayList<Project>(projects.values()));
+            result.getFetchOptions().withProjectsUsing(fetchOptions.withProjects());
         }
 
-        if (getFetchOptions().hasSamples())
+        if (fetchOptions.hasSamples())
         {
-            List<Sample> samples =
-                    new ListTranslator().translate(space.getSamples(), new SampleTranslator(getTranslationContext(),
-                            getFetchOptions().withSamples()));
-            result.setSamples(samples);
-            result.getFetchOptions().withSamplesUsing(getFetchOptions().withSamples());
+            Map<SamplePE, Sample> samples = sampleTranslator.translate(context, space.getSamples(), fetchOptions.withSamples());
+            result.setSamples(new ArrayList<Sample>(samples.values()));
+            result.getFetchOptions().withSamplesUsing(fetchOptions.withSamples());
         }
     }
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/tag/ITagTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/tag/ITagTranslator.java
new file mode 100644
index 00000000000..9edac7be35b
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/tag/ITagTranslator.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.tag;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.tag.Tag;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.tag.TagFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
+
+/**
+ * @author pkupczyk
+ */
+public interface ITagTranslator extends ITranslator<MetaprojectPE, Tag, TagFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/tag/TagTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/tag/TagTranslator.java
index e1817111abd..e5e22914494 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/tag/TagTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/tag/TagTranslator.java
@@ -16,10 +16,13 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.tag;
 
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.PersonTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.IPersonTranslator;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.tag.Tag;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.tag.TagFetchOptions;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.tag.TagPermId;
@@ -28,23 +31,21 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 /**
  * @author pkupczyk
  */
-public class TagTranslator extends AbstractCachingTranslator<MetaprojectPE, Tag, TagFetchOptions>
+@Component
+public class TagTranslator extends AbstractCachingTranslator<MetaprojectPE, Tag, TagFetchOptions> implements ITagTranslator
 {
-
-    public TagTranslator(TranslationContext translationContext, TagFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
+    @Autowired
+    private IPersonTranslator personTranslator;
 
     @Override
-    public boolean shouldTranslate(MetaprojectPE object)
+    public boolean shouldTranslate(TranslationContext context, MetaprojectPE object, TagFetchOptions fetchOptions)
     {
         boolean isPublic = false == object.isPrivate();
-        return isPublic || object.getOwner().getUserId().equals(translationContext.getSession().tryGetPerson().getUserId());
+        return isPublic || object.getOwner().getUserId().equals(context.getSession().tryGetPerson().getUserId());
     }
 
     @Override
-    protected Tag createObject(MetaprojectPE tag)
+    protected Tag createObject(TranslationContext context, MetaprojectPE tag, TagFetchOptions fetchOptions)
     {
         Tag result = new Tag();
 
@@ -59,12 +60,12 @@ public class TagTranslator extends AbstractCachingTranslator<MetaprojectPE, Tag,
     }
 
     @Override
-    protected void updateObject(MetaprojectPE tag, Tag result, Relations relations)
+    protected void updateObject(TranslationContext context, MetaprojectPE tag, Tag result, Relations relations, TagFetchOptions fetchOptions)
     {
-        if (getFetchOptions().hasOwner())
+        if (fetchOptions.hasOwner())
         {
-            result.setOwner(new PersonTranslator(getTranslationContext(), getFetchOptions().withOwner()).translate(tag.getOwner()));
-            result.getFetchOptions().withOwnerUsing(getFetchOptions().withOwner());
+            result.setOwner(personTranslator.translate(context, tag.getOwner(), fetchOptions.withOwner()));
+            result.getFetchOptions().withOwnerUsing(fetchOptions.withOwner());
         }
     }
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/vocabulary/IVocabularyTermTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/vocabulary/IVocabularyTermTranslator.java
new file mode 100644
index 00000000000..1fa354d5734
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/vocabulary/IVocabularyTermTranslator.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.vocabulary;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.vocabulary.VocabularyTerm;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.vocabulary.VocabularyTermFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermPE;
+
+/**
+ * @author pkupczyk
+ */
+public interface IVocabularyTermTranslator extends ITranslator<VocabularyTermPE, VocabularyTerm, VocabularyTermFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/vocabulary/IVocabularyTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/vocabulary/IVocabularyTranslator.java
new file mode 100644
index 00000000000..5e84144b356
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/vocabulary/IVocabularyTranslator.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.vocabulary;
+
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.vocabulary.Vocabulary;
+import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.vocabulary.VocabularyFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE;
+
+/**
+ * @author pkupczyk
+ */
+public interface IVocabularyTranslator extends ITranslator<VocabularyPE, Vocabulary, VocabularyFetchOptions>
+{
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/vocabulary/VocabularyTermTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/vocabulary/VocabularyTermTranslator.java
index 6d95d0640fa..2bada69d85f 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/vocabulary/VocabularyTermTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/vocabulary/VocabularyTermTranslator.java
@@ -16,10 +16,13 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.vocabulary;
 
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.PersonTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.IPersonTranslator;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.person.Person;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.vocabulary.Vocabulary;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.vocabulary.VocabularyTerm;
@@ -29,15 +32,19 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermPE;
 /**
  * @author pkupczyk
  */
-public class VocabularyTermTranslator extends AbstractCachingTranslator<VocabularyTermPE, VocabularyTerm, VocabularyTermFetchOptions>
+@Component
+public class VocabularyTermTranslator extends AbstractCachingTranslator<VocabularyTermPE, VocabularyTerm, VocabularyTermFetchOptions> implements
+        IVocabularyTermTranslator
 {
-    public VocabularyTermTranslator(TranslationContext translationContext, VocabularyTermFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
+
+    @Autowired
+    private IPersonTranslator personTranslator;
+
+    @Autowired
+    private IVocabularyTranslator vocabularyTranslator;
 
     @Override
-    protected VocabularyTerm createObject(VocabularyTermPE term)
+    protected VocabularyTerm createObject(TranslationContext context, VocabularyTermPE term, VocabularyTermFetchOptions fetchOptions)
     {
         VocabularyTerm result = new VocabularyTerm();
 
@@ -54,22 +61,21 @@ public class VocabularyTermTranslator extends AbstractCachingTranslator<Vocabula
     }
 
     @Override
-    protected void updateObject(VocabularyTermPE term, VocabularyTerm result, Relations relations)
+    protected void updateObject(TranslationContext context, VocabularyTermPE term, VocabularyTerm result, Relations relations,
+            VocabularyTermFetchOptions fetchOptions)
     {
-        if (getFetchOptions().hasRegistrator())
+        if (fetchOptions.hasRegistrator())
         {
-            Person registrator =
-                    new PersonTranslator(getTranslationContext(), getFetchOptions().withRegistrator()).translate(term.getRegistrator());
+            Person registrator = personTranslator.translate(context, term.getRegistrator(), fetchOptions.withRegistrator());
             result.setRegistrator(registrator);
-            result.getFetchOptions().withRegistratorUsing(getFetchOptions().withRegistrator());
+            result.getFetchOptions().withRegistratorUsing(fetchOptions.withRegistrator());
         }
 
-        if (getFetchOptions().hasVocabulary())
+        if (fetchOptions.hasVocabulary())
         {
-            Vocabulary vocabulary =
-                    new VocabularyTranslator(getTranslationContext(), getFetchOptions().withVocabulary()).translate(term.getVocabulary());
+            Vocabulary vocabulary = vocabularyTranslator.translate(context, term.getVocabulary(), fetchOptions.withVocabulary());
             result.setVocabulary(vocabulary);
-            result.getFetchOptions().withVocabularyUsing(getFetchOptions().withVocabulary());
+            result.getFetchOptions().withVocabularyUsing(fetchOptions.withVocabulary());
         }
     }
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/vocabulary/VocabularyTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/vocabulary/VocabularyTranslator.java
index 7991c20d1e5..fb84ff8bbd7 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/vocabulary/VocabularyTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/translator/entity/vocabulary/VocabularyTranslator.java
@@ -16,10 +16,13 @@
 
 package ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.vocabulary;
 
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.AbstractCachingTranslator;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.Relations;
 import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext;
-import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.PersonTranslator;
+import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.person.IPersonTranslator;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.person.Person;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.vocabulary.Vocabulary;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.vocabulary.VocabularyFetchOptions;
@@ -28,15 +31,16 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE;
 /**
  * @author pkupczyk
  */
-public class VocabularyTranslator extends AbstractCachingTranslator<VocabularyPE, Vocabulary, VocabularyFetchOptions>
+@Component
+public class VocabularyTranslator extends AbstractCachingTranslator<VocabularyPE, Vocabulary, VocabularyFetchOptions> implements
+        IVocabularyTranslator
 {
-    public VocabularyTranslator(TranslationContext translationContext, VocabularyFetchOptions fetchOptions)
-    {
-        super(translationContext, fetchOptions);
-    }
+
+    @Autowired
+    private IPersonTranslator personTranslator;
 
     @Override
-    protected Vocabulary createObject(VocabularyPE vocabulary)
+    protected Vocabulary createObject(TranslationContext context, VocabularyPE vocabulary, VocabularyFetchOptions fetchOptions)
     {
         Vocabulary result = new Vocabulary();
 
@@ -50,14 +54,14 @@ public class VocabularyTranslator extends AbstractCachingTranslator<VocabularyPE
     }
 
     @Override
-    protected void updateObject(VocabularyPE vocabulary, Vocabulary result, Relations relations)
+    protected void updateObject(TranslationContext context, VocabularyPE vocabulary, Vocabulary result, Relations relations,
+            VocabularyFetchOptions fetchOptions)
     {
-        if (getFetchOptions().hasRegistrator())
+        if (fetchOptions.hasRegistrator())
         {
-            Person registrator =
-                    new PersonTranslator(getTranslationContext(), getFetchOptions().withRegistrator()).translate(vocabulary.getRegistrator());
+            Person registrator = personTranslator.translate(context, vocabulary.getRegistrator(), fetchOptions.withRegistrator());
             result.setRegistrator(registrator);
-            result.getFetchOptions().withRegistratorUsing(getFetchOptions().withRegistrator());
+            result.getFetchOptions().withRegistratorUsing(fetchOptions.withRegistrator());
         }
     }
 
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/UpdateProjectTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/UpdateProjectTest.java
index b303add001b..e5b841288bb 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/UpdateProjectTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/UpdateProjectTest.java
@@ -30,8 +30,6 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.project.ProjectCreat
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.project.ProjectUpdate;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.sample.Sample;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.project.ProjectFetchOptions;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.person.IPersonId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.person.PersonPermId;
 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;
@@ -210,61 +208,6 @@ public class UpdateProjectTest extends AbstractTest
         }
     }
 
-    @Test
-    public void testUpdateWithLeaderNonexistent()
-    {
-        final String sessionToken = v3api.login(TEST_USER, PASSWORD);
-
-        final IProjectId projectId = new ProjectIdentifier("/TEST-SPACE/TEST-PROJECT");
-        final IPersonId leaderId = new PersonPermId("IDONTEXIST");
-        final ProjectUpdate update = new ProjectUpdate();
-        update.setProjectId(projectId);
-        update.setLeaderId(leaderId);
-
-        assertObjectNotFoundException(new IDelegatedAction()
-            {
-                @Override
-                public void execute()
-                {
-                    v3api.updateProjects(sessionToken, Arrays.asList(update));
-                }
-            }, leaderId);
-    }
-
-    @Test
-    public void testUpdateWithLeader()
-    {
-        final String sessionToken = v3api.login(TEST_USER, PASSWORD);
-
-        final IProjectId projectId = new ProjectIdentifier("/TEST-SPACE/TEST-PROJECT");
-        final ProjectFetchOptions projectFetchOptions = new ProjectFetchOptions();
-        projectFetchOptions.withLeader();
-
-        Map<IProjectId, Project> projectMap = v3api.mapProjects(sessionToken, Arrays.asList(projectId), projectFetchOptions);
-        Project project = projectMap.get(projectId);
-
-        Assert.assertNull(project.getLeader());
-
-        final IPersonId leaderId = new PersonPermId(TEST_SPACE_USER);
-        final ProjectUpdate update = new ProjectUpdate();
-        update.setProjectId(projectId);
-        update.setLeaderId(leaderId);
-
-        v3api.updateProjects(sessionToken, Arrays.asList(update));
-        projectMap = v3api.mapProjects(sessionToken, Arrays.asList(projectId), projectFetchOptions);
-        project = projectMap.get(projectId);
-
-        Assert.assertEquals(project.getLeader().getPermId(), leaderId);
-
-        update.setLeaderId(null);
-
-        v3api.updateProjects(sessionToken, Arrays.asList(update));
-        projectMap = v3api.mapProjects(sessionToken, Arrays.asList(projectId), projectFetchOptions);
-        project = projectMap.get(projectId);
-
-        Assert.assertNull(project.getLeader());
-    }
-
     @Test
     public void testUpdateWithAttachments()
     {
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/IApplicationServerApi.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/IApplicationServerApi.java
index 609b0b2a6b2..c7899d07ee0 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/IApplicationServerApi.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/IApplicationServerApi.java
@@ -62,8 +62,6 @@ 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.space.ISpaceId;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.SpacePermId;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.operation.IOperation;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.operation.IOperationResult;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.DataSetSearchCriterion;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.ExperimentSearchCriterion;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.MaterialSearchCriterion;
@@ -100,21 +98,12 @@ public interface IApplicationServerApi extends IRpcService
 
     public void logout(String sessionToken);
 
-    public List<? extends IOperationResult> performOperations(String sessionToken, List<? extends IOperation> operations);
-
     public List<SpacePermId> createSpaces(String sessionToken, List<SpaceCreation> newSpaces);
 
     public List<ProjectPermId> createProjects(String sessionToken, List<ProjectCreation> newProjects);
 
-    // REPLACES:
-    // - ServiceForDataStoreServer.registerExperiment()
-
     public List<ExperimentPermId> createExperiments(String sessionToken, List<ExperimentCreation> newExperiments);
 
-    // REPLACES:
-    // - ServiceForDataStoreServer.registerSamples()
-    // - ServiceForDataStoreServer.registerSample()
-
     public List<SamplePermId> createSamples(String sessionToken, List<SampleCreation> newSamples);
 
     public List<MaterialPermId> createMaterials(String sessionToken, List<MaterialCreation> newMaterials);
@@ -123,20 +112,10 @@ public interface IApplicationServerApi extends IRpcService
 
     public void updateProjects(String sessionToken, List<ProjectUpdate> projectUpdates);
 
-    // REPLACES:
-    // - ServiceForDataStoreServer.updateExperiment()
-
     public void updateExperiments(String sessionToken, List<ExperimentUpdate> experimentUpdates);
 
-    // REPLACES:
-    // - ServiceForDataStoreServer.updateSamples()
-    // - ServiceForDataStoreServer.updateSample()
-
     public void updateSamples(String sessionToken, List<SampleUpdate> sampleUpdates);
 
-    // REPLACES:
-    // - ServiceForDataStoreServer.updateDataSet()
-
     public void updateDataSets(String sessionToken, List<DataSetUpdate> dataSetUpdates);
 
     public void updateMaterials(String sessionToken, List<MaterialUpdate> materialUpdates);
@@ -147,19 +126,9 @@ public interface IApplicationServerApi extends IRpcService
     public Map<IProjectId, Project> mapProjects(String sessionToken, List<? extends IProjectId> projectIds,
             ProjectFetchOptions fetchOptions);
 
-    // REPLACES:
-    // - ServiceForDataStoreServer.tryGetExperiment(ExperimentIdentifier)
-    // - ServiceForDataStoreServer.listExperiments(List<ExperimentIdentifier>, ExperimentFetchOptions)
-    // - GeneralInformationService.listExperiments(List<String> experimentIdentifiers)
-
     public Map<IExperimentId, Experiment> mapExperiments(String sessionToken, List<? extends IExperimentId> experimentIds,
             ExperimentFetchOptions fetchOptions);
 
-    // REPLACES:
-    // - ServiceForDataStoreServer.tryGetSampleWithExperiment(SampleIdentifier)
-    // - ServiceForDataStoreServer.listSamplesByPermId(List<String>)
-    // - ServiceForDataStoreServer.tryGetPropertiesOfSample(SampleIdentifier)
-
     public Map<ISampleId, Sample> mapSamples(String sessionToken, List<? extends ISampleId> sampleIds, SampleFetchOptions fetchOptions);
 
     public Map<IDataSetId, DataSet> mapDataSets(String sessionToken, List<? extends IDataSetId> dataSetIds, DataSetFetchOptions fetchOptions);
@@ -170,30 +139,8 @@ public interface IApplicationServerApi extends IRpcService
 
     public List<Project> searchProjects(String sessionToken, ProjectSearchCriterion searchCriterion, ProjectFetchOptions fetchOptions);
 
-    // REPLACES:
-    // - ServiceForDataStoreServer.listExperimentsForProjects(List<ProjectIdentifier>, ExperimentFetchOptions)
-    // - ServiceForDataStoreServer.listExperiments(ProjectIdentifier)
-    // - GeneralInformationService.listExperiments(List<Project>, String experimentType)
-    // - GeneralInformationService.listExperimentsHavingDataSets(List<Project>, String experimentType) - TODO add "HAVING_DATASETS" criteria
-    // - GeneralInformationService.listExperimentsHavingSamples(List<Project>, String experimentType) - TODO add "HAVING_SAMPLES" criteria
-    // - GeneralInformationService.searchForExperiments(SearchCriteria)
-
     public List<Experiment> searchExperiments(String sessionToken, ExperimentSearchCriterion searchCriterion, ExperimentFetchOptions fetchOptions);
 
-    // REPLACES:
-    // - ServiceForDataStoreServer.listSamples(ListSampleCriteria)
-    // - ServiceForDataStoreServer.listSamplesByCriteria(ListSamplesByPropertyCriteria)
-    // - ServiceForDataStoreServer.searchForSamples(SearchCriteria)
-    // - GeneralInformationService.searchForSamples(SearchCriteria)
-    // - GeneralInformationService.searchForSamples(SearchCriteria, EnumSet<SampleFetchOption>)
-    // - GeneralInformationService.listSamplesForExperiment(String experimentIdentifier)
-    /**
-     * This is the comment
-     * 
-     * @param sessionToken
-     * @param searchCriterion
-     * @param fetchOptions
-     */
     public List<Sample> searchSamples(String sessionToken, SampleSearchCriterion searchCriterion, SampleFetchOptions fetchOptions);
 
     public List<DataSet> searchDataSets(String sessionToken, DataSetSearchCriterion searchCriterion, DataSetFetchOptions fetchOptions);
@@ -204,28 +151,18 @@ public interface IApplicationServerApi extends IRpcService
 
     public void deleteProjects(String sessionToken, List<? extends IProjectId> projectIds, ProjectDeletionOptions deletionOptions);
 
-    // REPLACES:
-    // - IGeneralInformationChangingService.deleteExperiments(List<Long>, String, DeletionType)
     public IDeletionId deleteExperiments(String sessionToken, List<? extends IExperimentId> experimentIds, ExperimentDeletionOptions deletionOptions);
 
-    // REPLACES:
-    // - IGeneralInformationChangingService.deleteSamples(List<Long>, String, DeletionType)
     public IDeletionId deleteSamples(String sessionToken, List<? extends ISampleId> sampleIds, SampleDeletionOptions deletionOptions);
 
     public IDeletionId deleteDataSets(String sessionToken, List<? extends IDataSetId> dataSetIds, DataSetDeletionOptions deletionOptions);
 
     public void deleteMaterials(String sessionToken, List<? extends IMaterialId> materialIds, MaterialDeletionOptions deletionOptions);
 
-    // REPLACES:
-    // - IGeneralInformationService.listDeletions(EnumSet<DeletionFetchOption>)
     public List<Deletion> listDeletions(String sessionToken, DeletionFetchOptions fetchOptions);
 
-    // REPLACES:
-    // - IGeneralInformationChangingService.revertDeletions(List<Long>)
     public void revertDeletions(String sessionToken, List<? extends IDeletionId> deletionIds);
 
-    // REPLACES:
-    // - IGeneralInformationChangingService.deletePermanently(List<Long>)
     public void confirmDeletions(String sessionToken, List<? extends IDeletionId> deletionIds);
 
 }
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/dto/entity/project/ProjectUpdate.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/dto/entity/project/ProjectUpdate.java
index 0d20472fb31..886c722096d 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/dto/entity/project/ProjectUpdate.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/dto/entity/project/ProjectUpdate.java
@@ -25,7 +25,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.AttachmentListUpdateValue;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.FieldUpdateValue;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.ListUpdateValue.ListUpdateAction;
-import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.person.IPersonId;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.IProjectId;
 import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.ISpaceId;
 import ch.systemsx.cisd.base.annotation.JsonObject;
@@ -48,9 +47,6 @@ public class ProjectUpdate implements Serializable
     @JsonProperty
     private FieldUpdateValue<String> description = new FieldUpdateValue<String>();
 
-    @JsonProperty
-    private FieldUpdateValue<IPersonId> leaderId = new FieldUpdateValue<IPersonId>();
-
     @JsonProperty
     private AttachmentListUpdateValue attachments = new AttachmentListUpdateValue();
 
@@ -90,18 +86,6 @@ public class ProjectUpdate implements Serializable
         return description;
     }
 
-    @JsonIgnore
-    public void setLeaderId(IPersonId leaderId)
-    {
-        this.leaderId.setValue(leaderId);
-    }
-
-    @JsonIgnore
-    public FieldUpdateValue<IPersonId> getLeaderId()
-    {
-        return leaderId;
-    }
-
     @JsonIgnore
     public AttachmentListUpdateValue getAttachments()
     {
-- 
GitLab