From ce15c2bf2be2766afc362a93e1bf1e6574fbe43c Mon Sep 17 00:00:00 2001
From: gpawel <gpawel>
Date: Fri, 19 Oct 2012 11:17:01 +0000
Subject: [PATCH] SP-345 BIS-178: initial, incomplete commit

SVN: 27245
---
 .../generic/server/UploadingCommandTest.java  | 13 ++--
 .../openbis/generic/server/CommonServer.java  | 69 ++++++++++++++---
 .../openbis/generic/server/ETLService.java    | 70 +++++++++++++----
 .../generic/server/MaterialHelper.java        |  5 +-
 .../api/v1/GeneralInformationService.java     | 28 ++++---
 .../server/business/bo/DataSetTable.java      |  4 +-
 .../EntityMetaprojectRelationRecord.java      | 27 +++++++
 .../common/MetaprojectCreator.java            | 41 ++++++++++
 .../common/MetaprojectRecord.java             | 35 +++++++++
 .../datasetlister/DataSetLister.java          | 22 ++++--
 .../samplelister/ISampleListingQuery.java     | 15 ++++
 .../samplelister/SampleLister.java            | 77 +++++++++++++++++--
 .../samplelister/SampleRecord.java            |  3 +
 .../server/dataaccess/IMetaprojectDAO.java    |  9 +++
 .../server/dataaccess/db/MetaprojectDAO.java  | 22 ++++++
 .../generic/shared/basic/dto/Experiment.java  | 13 ++++
 .../basic/dto/ExperimentFetchOption.java      |  2 +-
 .../shared/basic/dto/ExternalData.java        | 13 +++-
 .../generic/shared/basic/dto/Material.java    | 14 +++-
 .../generic/shared/basic/dto/Sample.java      | 13 ++++
 .../shared/translator/DataSetTranslator.java  | 25 ++++--
 .../translator/EntityHistoryTranslator.java   | 13 ++--
 .../translator/EntityPropertyTranslator.java  |  2 +-
 .../translator/ExperimentTranslator.java      | 23 ++++--
 .../shared/translator/MaterialTranslator.java | 22 ++++--
 .../translator/MetaprojectTranslator.java     | 55 ++++++++++++-
 .../shared/translator/SampleTranslator.java   | 38 +++++----
 .../plugin/generic/server/GenericServer.java  | 10 +++
 .../generic/server/CommonServerTest.java      | 17 +++-
 .../api/v1/GeneralInformationServiceTest.java |  9 ++-
 .../validator/ExperimentValidatorTest.java    | 15 ++--
 .../validator/ExternalDataValidatorTest.java  |  5 +-
 .../validator/SampleValidatorTest.java        | 25 +++---
 .../bo/datasetlister/DatasetListerTest.java   |  4 +-
 .../datasetlister/DataSetListerTest.java      | 34 ++++----
 .../dataaccess/db/MetaprojectDAOTest.java     | 23 ++++++
 .../shared/AbstractServerTestCase.java        |  6 ++
 .../translator/DataSetTranslatorTest.java     |  9 ++-
 .../api/v1/GeneralInformationServiceTest.java | 46 +++++++++++
 .../124/042=metaproject_assignments_all.tsv   |  1 +
 .../shared/api/v1/dto/DataSetFetchOption.java |  2 +-
 .../generic/shared/api/v1/dto/Sample.java     | 42 ++++++++++
 .../shared/api/v1/dto/SampleFetchOption.java  | 11 ++-
 .../server/ProteomicsDataServiceInternal.java | 24 ++++--
 .../server/business/ExperimentLoader.java     |  9 +--
 .../server/business/ExperimentLoaderTest.java | 18 ++---
 .../server/logic/LogicalImageLoader.java      |  2 +-
 .../server/logic/PlateContentLoader.java      |  2 +-
 .../server/logic/ScreeningApiImpl.java        | 15 ++--
 .../server/logic/ScreeningUtils.java          |  2 +-
 50 files changed, 819 insertions(+), 185 deletions(-)
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/common/EntityMetaprojectRelationRecord.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/common/MetaprojectCreator.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/common/MetaprojectRecord.java

diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommandTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommandTest.java
index 6b9a4900f58..efd0745a6ae 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommandTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommandTest.java
@@ -240,11 +240,11 @@ public class UploadingCommandTest extends AssertJUnit
         createTestData(LOCATION1);
         ds2 = createTestData(LOCATION2);
         ExternalData dataSet1 =
-                DataSetTranslator.translate(createDataSet("1"), "?",
+                DataSetTranslator.translate(createDataSet("1"), "?", null,
                         ExperimentTranslator.LoadableFields.PROPERTIES);
         System.out.println("ds1:" + dataSet1.getExperiment().getProperties());
         ExternalData dataSet2 =
-                DataSetTranslator.translate(createDataSet("2"), "?",
+                DataSetTranslator.translate(createDataSet("2"), "?", null,
                         ExperimentTranslator.LoadableFields.PROPERTIES);
         dataSets = Arrays.<ExternalData> asList(dataSet1, dataSet2);
         command =
@@ -388,8 +388,7 @@ public class UploadingCommandTest extends AssertJUnit
 
                     one(uploader).upload(
                             Collections.singletonList(new FileWithOverrideName(new File(TMP,
-                                    ZIP_FILENAME + ".zip"), null)),
-                            "id:user", null);
+                                    ZIP_FILENAME + ".zip"), null)), "id:user", null);
                     will(new CustomAction("report 'finish' to listener")
                         {
                             @Override
@@ -447,8 +446,7 @@ public class UploadingCommandTest extends AssertJUnit
 
                     one(uploader).upload(
                             Collections.singletonList(new FileWithOverrideName(new File(TMP,
-                                    ZIP_FILENAME + ".zip"), null)),
-                            "id:user", null);
+                                    ZIP_FILENAME + ".zip"), null)), "id:user", null);
                     will(new CustomAction("report 'finish' to listener")
                         {
                             @Override
@@ -546,8 +544,7 @@ public class UploadingCommandTest extends AssertJUnit
 
                     one(uploader).upload(
                             Collections.singletonList(new FileWithOverrideName(new File(TMP,
-                                    ZIP_FILENAME + ".zip"), null)),
-                            "id:user", null);
+                                    ZIP_FILENAME + ".zip"), null)), "id:user", null);
                     will(new CustomAction("report 'abort' to listener")
                         {
                             @Override
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
index 1f61940f265..7111ca7b595 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
@@ -874,8 +874,17 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
         experimentTable.load(experimentIdentifiers);
 
         List<ExperimentPE> experiments = experimentTable.getExperiments();
+        final Collection<MetaprojectAssignmentPE> assignmentPEs =
+                getDAOFactory()
+                        .getMetaprojectDAO()
+                        .listMetaprojectAssignmentsForEntities(
+                                session.tryGetPerson(),
+                                experiments,
+                                ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind.EXPERIMENT);
+        Map<Long, Set<Metaproject>> assignments =
+                MetaprojectTranslator.translateMetaprojectAssignments(assignmentPEs);
         Collections.sort(experiments);
-        return ExperimentTranslator.translate(experiments, session.getBaseIndexURL());
+        return ExperimentTranslator.translate(experiments, session.getBaseIndexURL(), assignments);
     }
 
     private final List<Experiment> listExperiments(final String sessionToken,
@@ -895,8 +904,17 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
             experimentTable.load(experimentType.getCode(), spaceIdentifierOrNull);
         }
         final List<ExperimentPE> experiments = experimentTable.getExperiments();
+        final Collection<MetaprojectAssignmentPE> assignmentPEs =
+                getDAOFactory()
+                        .getMetaprojectDAO()
+                        .listMetaprojectAssignmentsForEntities(
+                                session.tryGetPerson(),
+                                experiments,
+                                ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind.EXPERIMENT);
+        Map<Long, Set<Metaproject>> assignments =
+                MetaprojectTranslator.translateMetaprojectAssignments(assignmentPEs);
         Collections.sort(experiments);
-        return ExperimentTranslator.translate(experiments, session.getBaseIndexURL());
+        return ExperimentTranslator.translate(experiments, session.getBaseIndexURL(), assignments);
     }
 
     @Override
@@ -1259,7 +1277,11 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
         datasetBO.enrichWithContainedDataSets();
         datasetBO.enrichWithProperties();
         final DataPE dataset = datasetBO.getData();
-        return DataSetTranslator.translate(dataset, session.getBaseIndexURL(), false);
+        Collection<MetaprojectPE> metaprojectPEs =
+                getDAOFactory().getMetaprojectDAO().listMetaprojectsForEntity(
+                        session.tryGetPerson(), dataset);
+        return DataSetTranslator.translate(dataset, session.getBaseIndexURL(), false,
+                MetaprojectTranslator.translate(metaprojectPEs));
     }
 
     @Override
@@ -1296,7 +1318,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
         for (final DataPE hit : resultSet)
         {
             HibernateUtils.initialize(hit.getChildRelationships());
-            list.add(DataSetTranslator.translate(hit, session.getBaseIndexURL(), withDetails));
+            list.add(DataSetTranslator.translate(hit, session.getBaseIndexURL(), withDetails, null));
         }
         return list;
     }
@@ -1919,7 +1941,13 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
             throw UserFailureException.fromTemplate(
                     "No experiment could be found with given identifier '%s'.", identifier);
         }
+
+        Collection<MetaprojectPE> metaprojects =
+                getDAOFactory().getMetaprojectDAO().listMetaprojectsForEntity(
+                        session.tryGetPerson(), experiment);
+
         return ExperimentTranslator.translate(experiment, session.getBaseIndexURL(),
+                MetaprojectTranslator.translate(metaprojects),
                 ExperimentTranslator.LoadableFields.PROPERTIES,
                 ExperimentTranslator.LoadableFields.ATTACHMENTS);
     }
@@ -1936,7 +1964,13 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
         experimentBO.enrichWithProperties();
         experimentBO.enrichWithAttachments();
         final ExperimentPE experiment = experimentBO.getExperiment();
+
+        Collection<MetaprojectPE> metaprojects =
+                getDAOFactory().getMetaprojectDAO().listMetaprojectsForEntity(
+                        session.tryGetPerson(), experiment);
+
         return ExperimentTranslator.translate(experiment, session.getBaseIndexURL(),
+                MetaprojectTranslator.translate(metaprojects),
                 ExperimentTranslator.LoadableFields.PROPERTIES,
                 ExperimentTranslator.LoadableFields.ATTACHMENTS);
     }
@@ -2005,7 +2039,13 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
         IMaterialBO materialBO = getBusinessObjectFactory().createMaterialBO(session);
         materialBO.loadByMaterialIdentifier(identifier);
         materialBO.enrichWithProperties();
-        return MaterialTranslator.translate(materialBO.getMaterial());
+        MaterialPE materialPE = materialBO.getMaterial();
+        Collection<MetaprojectPE> metaprojectPEs =
+                getDAOFactory().getMetaprojectDAO().listMetaprojectsForEntity(
+                        session.tryGetPerson(), materialPE);
+
+        return MaterialTranslator.translate(materialPE,
+                MetaprojectTranslator.translate(metaprojectPEs));
     }
 
     @Override
@@ -2017,7 +2057,11 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
         materialBO.loadDataByTechId(materialId);
         materialBO.enrichWithProperties();
         final MaterialPE material = materialBO.getMaterial();
-        return MaterialTranslator.translate(material, true);
+        Collection<MetaprojectPE> metaprojectPEs =
+                getDAOFactory().getMetaprojectDAO().listMetaprojectsForEntity(
+                        session.tryGetPerson(), material);
+        return MaterialTranslator.translate(material, true,
+                MetaprojectTranslator.translate(metaprojectPEs));
     }
 
     @Override
@@ -3484,19 +3528,19 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
                 if (authorizationUtils.canAccessExperiment(metaprojectAssignment.getExperiment()))
                 {
                     experiments.add(ExperimentTranslator.translate(
-                            metaprojectAssignment.getExperiment(), baseIndexURL,
+                            metaprojectAssignment.getExperiment(), baseIndexURL, null,
                             LoadableFields.PROPERTIES));
                 } else
                 {
-                    experiments.add(ExperimentTranslator
-                            .translateWithoutRevealingData(metaprojectAssignment.getExperiment()));
+                    experiments.add(ExperimentTranslator.translateWithoutRevealingData(
+                            metaprojectAssignment.getExperiment(), null));
                 }
             } else if (metaprojectAssignment.getSample() != null)
             {
                 if (authorizationUtils.canAccessSample(metaprojectAssignment.getSample()))
                 {
                     samples.add(SampleTranslator.translate(metaprojectAssignment.getSample(),
-                            baseIndexURL));
+                            baseIndexURL, null));
                 } else
                 {
                     samples.add(SampleTranslator
@@ -3507,7 +3551,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
                 if (authorizationUtils.canAccessDataSet(metaprojectAssignment.getDataSet()))
                 {
                     dataSets.add(DataSetTranslator.translate(metaprojectAssignment.getDataSet(),
-                            baseIndexURL));
+                            baseIndexURL, null));
                 } else
                 {
                     dataSets.add(DataSetTranslator
@@ -3515,7 +3559,8 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
                 }
             } else if (metaprojectAssignment.getMaterial() != null)
             {
-                materials.add(MaterialTranslator.translate(metaprojectAssignment.getMaterial()));
+                materials.add(MaterialTranslator.translate(metaprojectAssignment.getMaterial(),
+                        null));
             }
         }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
index e96753666fe..b25a4601835 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
@@ -126,6 +126,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListSampleCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewProject;
@@ -165,7 +166,10 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentUpdatesDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataManagementSystemPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ListSamplesByPropertyCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialUpdateDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectAssignmentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.NewContainerDataSet;
 import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.dto.NewProperty;
@@ -199,6 +203,7 @@ import ch.systemsx.cisd.openbis.generic.shared.translator.ExperimentTranslator.L
 import ch.systemsx.cisd.openbis.generic.shared.translator.ExperimentTypeTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.ExternalDataManagementSystemTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.MaterialTranslator;
+import ch.systemsx.cisd.openbis.generic.shared.translator.MetaprojectTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.PersonTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.ProjectTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.SampleTranslator;
@@ -394,7 +399,10 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
             throw new IllegalArgumentException("ExperimentFetchOptions were null");
         }
 
-        if (experimentFetchOptions.isSubsetOf(ExperimentFetchOption.BASIC))
+        checkSession(sessionToken);
+
+        if (experimentFetchOptions.isSubsetOf(ExperimentFetchOption.BASIC,
+                ExperimentFetchOption.METAPROJECTS))
         {
             ExperimentLister lister =
                     new ExperimentLister(getDAOFactory(), getSession(sessionToken)
@@ -438,7 +446,10 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
             throw new IllegalArgumentException("ExperimentFetchOptions were null");
         }
 
-        if (experimentFetchOptions.isSubsetOf(ExperimentFetchOption.BASIC))
+        checkSession(sessionToken);
+
+        if (experimentFetchOptions.isSubsetOf(ExperimentFetchOption.BASIC,
+                ExperimentFetchOption.METAPROJECTS))
         {
             ExperimentLister lister =
                     new ExperimentLister(daoFactory, getSession(sessionToken).getBaseIndexURL());
@@ -485,8 +496,13 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
             return null;
         }
         enrichWithProperties(experiment);
+
+        Collection<MetaprojectPE> metaprojectPEs =
+                getDAOFactory().getMetaprojectDAO().listMetaprojectsForEntity(
+                        session.tryGetPerson(), experiment);
+
         return ExperimentTranslator.translate(experiment, session.getBaseIndexURL(),
-                LoadableFields.PROPERTIES);
+                MetaprojectTranslator.translate(metaprojectPEs), LoadableFields.PROPERTIES);
     }
 
     @Override
@@ -518,7 +534,11 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
             HibernateUtils.initialize(sample.getProperties());
             enrichWithProperties(sample.getExperiment());
         }
-        return SampleTranslator.translate(sample, session.getBaseIndexURL(), true, true);
+        Collection<MetaprojectPE> metaprojects =
+                getDAOFactory().getMetaprojectDAO().listMetaprojectsForEntity(
+                        session.tryGetPerson(), sample);
+        return SampleTranslator.translate(sample, session.getBaseIndexURL(), true, true,
+                MetaprojectTranslator.translate(metaprojects));
     }
 
     @Override
@@ -711,8 +731,13 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
                 businessObjectFactory.createExperimentTable(session);
         experimentTable.load(EntityType.ALL_TYPES_CODE, projectIdentifier);
         final List<ExperimentPE> experiments = experimentTable.getExperiments();
+        final Collection<MetaprojectAssignmentPE> assignmentPEs =
+                getDAOFactory().getMetaprojectDAO().listMetaprojectAssignmentsForEntities(
+                        session.tryGetPerson(), experiments, EntityKind.EXPERIMENT);
+        Map<Long, Set<Metaproject>> assignments =
+                MetaprojectTranslator.translateMetaprojectAssignments(assignmentPEs);
         Collections.sort(experiments);
-        return ExperimentTranslator.translate(experiments, session.getBaseIndexURL());
+        return ExperimentTranslator.translate(experiments, session.getBaseIndexURL(), assignments);
     }
 
     @Override
@@ -989,7 +1014,11 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
         DataPE dataPE = dataBO.tryGetData();
         if (null == dataPE)
             return null;
-        return DataSetTranslator.translate(dataPE, session.getBaseIndexURL());
+        Collection<MetaprojectPE> metaprojects =
+                getDAOFactory().getMetaprojectDAO().listMetaprojectsForEntity(
+                        session.tryGetPerson(), dataPE);
+        return DataSetTranslator.translate(dataPE, session.getBaseIndexURL(),
+                MetaprojectTranslator.translate(metaprojects));
     }
 
     @Override
@@ -1051,7 +1080,15 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
         Session session = getSession(sessionToken);
         ISampleTable sampleTable = businessObjectFactory.createSampleTable(session);
         sampleTable.loadSamplesByCriteria(criteria);
-        return SampleTranslator.translate(sampleTable.getSamples(), "");
+        List<SamplePE> samples = sampleTable.getSamples();
+
+        final Collection<MetaprojectAssignmentPE> assignmentPEs =
+                getDAOFactory().getMetaprojectDAO().listMetaprojectAssignmentsForEntities(
+                        session.tryGetPerson(), samples, EntityKind.SAMPLE);
+        Map<Long, Set<Metaproject>> assignments =
+                MetaprojectTranslator.translateMetaprojectAssignments(assignmentPEs);
+
+        return SampleTranslator.translate(samples, "", assignments);
     }
 
     @Override
@@ -1233,9 +1270,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
 
         // Register the data set
         registerDataSetInternal(sessionToken, externalData, samplePE);
-        Sample result =
-                SampleTranslator.translate(Collections.singletonList(samplePE),
-                        session.getBaseIndexURL()).get(0);
+        Sample result = SampleTranslator.translate(samplePE, session.getBaseIndexURL(), null);
         return result;
     }
 
@@ -1254,9 +1289,13 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
         final SamplePE samplePE = sampleBO.getSample();
         registerDataSetInternal(sessionToken, externalData, samplePE);
 
+        Collection<MetaprojectPE> metaprojectPEs =
+                getDAOFactory().getMetaprojectDAO().listMetaprojectsForEntity(
+                        session.tryGetPerson(), samplePE);
+
         Sample result =
-                SampleTranslator.translate(Collections.singletonList(samplePE),
-                        session.getBaseIndexURL()).get(0);
+                SampleTranslator.translate(samplePE, session.getBaseIndexURL(),
+                        MetaprojectTranslator.translate(metaprojectPEs));
         return result;
     }
 
@@ -1367,7 +1406,12 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
         {
             bo.loadByMaterialIdentifier(materialIdentifier);
             bo.enrichWithProperties();
-            return MaterialTranslator.translate(bo.getMaterial());
+            MaterialPE materialPE = bo.getMaterial();
+            Collection<MetaprojectPE> metaprojectPEs =
+                    getDAOFactory().getMetaprojectDAO().listMetaprojectsForEntity(
+                            session.tryGetPerson(), materialPE);
+            return MaterialTranslator.translate(materialPE,
+                    MetaprojectTranslator.translate(metaprojectPEs));
         } catch (UserFailureException ufe)
         {
             // material does not exist
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/MaterialHelper.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/MaterialHelper.java
index ae169a397f1..9085e39ece6 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/MaterialHelper.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/MaterialHelper.java
@@ -22,6 +22,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.log4j.Logger;
@@ -41,6 +42,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListMaterialCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
@@ -139,7 +141,8 @@ public class MaterialHelper
             };
         BatchOperationExecutor.executeInBatches(strategy);
 
-        return MaterialTranslator.translate(registeredMaterials);
+        return MaterialTranslator.translate(registeredMaterials,
+                new HashMap<Long, Set<Metaproject>>());
     }
 
     public int updateMaterials(String materialTypeCode, final List<NewMaterial> newMaterials,
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java
index 3510f8d3200..92e7a6034e2 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java
@@ -99,6 +99,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AuthorizationGroupPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.RoleAssignmentPE;
@@ -109,6 +110,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifi
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.translator.DataSetTranslator;
+import ch.systemsx.cisd.openbis.generic.shared.translator.MetaprojectTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils;
 
 /**
@@ -319,7 +321,7 @@ public class GeneralInformationService extends AbstractServer<IGeneralInformatio
         Collection<Long> sampleIDs =
                 new SampleSearchManager(getDAOFactory().getHibernateSearchDAO(), sampleLister)
                         .searchForSampleIDs(detailedSearchCriteria);
-        return createSampleLister().getSamples(sampleIDs, sampleFetchOptions);
+        return createSampleLister(session.tryGetPerson()).getSamples(sampleIDs, sampleFetchOptions);
     }
 
     @Override
@@ -369,9 +371,9 @@ public class GeneralInformationService extends AbstractServer<IGeneralInformatio
         return samples;
     }
 
-    protected ISampleLister createSampleLister()
+    protected ISampleLister createSampleLister(PersonPE person)
     {
-        return new SampleLister(getDAOFactory());
+        return new SampleLister(getDAOFactory(), person);
     }
 
     @Override
@@ -585,9 +587,9 @@ public class GeneralInformationService extends AbstractServer<IGeneralInformatio
         { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER })
     public String tryGetDataStoreBaseURL(String sessionToken, String dataSetCode)
     {
-        checkSession(sessionToken);
+        Session session = getSession(sessionToken);
 
-        final IDataSetLister lister = new DataSetLister(getDAOFactory());
+        final IDataSetLister lister = new DataSetLister(getDAOFactory(), session.tryGetPerson());
         final List<DataStoreURLForDataSets> dataStores =
                 lister.getDataStoreDownloadURLs(Collections.singletonList(dataSetCode));
         if (dataStores.isEmpty())
@@ -604,9 +606,9 @@ public class GeneralInformationService extends AbstractServer<IGeneralInformatio
     public List<DataStoreURLForDataSets> getDataStoreBaseURLs(String sessionToken,
             List<String> dataSetCodes)
     {
-        checkSession(sessionToken);
+        Session session = getSession(sessionToken);
 
-        final IDataSetLister lister = new DataSetLister(getDAOFactory());
+        final IDataSetLister lister = new DataSetLister(getDAOFactory(), session.tryGetPerson());
         return lister.getDataStoreDownloadURLs(dataSetCodes);
     }
 
@@ -771,7 +773,12 @@ public class GeneralInformationService extends AbstractServer<IGeneralInformatio
             }
             HibernateUtils.initialize(dataPE.getChildRelationships());
             HibernateUtils.initialize(dataPE.getProperties());
-            ExternalData ds = DataSetTranslator.translate(dataPE, session.getBaseIndexURL());
+            Collection<MetaprojectPE> metaprojects =
+                    getDAOFactory().getMetaprojectDAO().listMetaprojectsForEntity(
+                            session.tryGetPerson(), dataPE);
+            ExternalData ds =
+                    DataSetTranslator.translate(dataPE, session.getBaseIndexURL(),
+                            MetaprojectTranslator.translate(metaprojects));
             result.add(Translator.translate(ds, connections));
         }
         return result;
@@ -806,8 +813,9 @@ public class GeneralInformationService extends AbstractServer<IGeneralInformatio
         if (dataSetFetchOptions.isSubsetOf(DataSetFetchOption.BASIC, DataSetFetchOption.PARENTS,
                 DataSetFetchOption.CHILDREN))
         {
-            checkSession(sessionToken);
-            final IDataSetLister lister = new DataSetLister(getDAOFactory());
+            Session session = getSession(sessionToken);
+            final IDataSetLister lister =
+                    new DataSetLister(getDAOFactory(), session.tryGetPerson());
             return lister.getDataSetMetaData(dataSetCodes, dataSetFetchOptions);
         } else
         {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java
index 8af1c4fb582..fa1509aa989 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java
@@ -60,6 +60,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetArchivingStatus;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetBatchUpdateDetails;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.LinkModel;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModel;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetBatchUpdatesDTO;
@@ -521,7 +522,8 @@ public final class DataSetTable extends AbstractDataSetBusinessObject implements
                 getConversationClient().getDataStoreService(dataStore.getRemoteUrl(),
                         session.getSessionToken());
         String sessionToken = dataStore.getSessionToken();
-        List<ExternalData> cleanDataSets = DataSetTranslator.translate(list, "?", "?");
+        List<ExternalData> cleanDataSets =
+                DataSetTranslator.translate(list, "?", "?", new HashMap<Long, Set<Metaproject>>());
         service.uploadDataSetsToCIFEX(sessionToken, cleanDataSets, context);
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/common/EntityMetaprojectRelationRecord.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/common/EntityMetaprojectRelationRecord.java
new file mode 100644
index 00000000000..6824073ba5f
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/common/EntityMetaprojectRelationRecord.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.server.business.bo.fetchoptions.common;
+
+/**
+ * @author Pawel Glyzewski
+ */
+public class EntityMetaprojectRelationRecord
+{
+    public Long metaproject_id;
+
+    public Long entity_id;
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/common/MetaprojectCreator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/common/MetaprojectCreator.java
new file mode 100644
index 00000000000..03829e60b60
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/common/MetaprojectCreator.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.server.business.bo.fetchoptions.common;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+
+/**
+ * @author Pawel Glyzewski
+ */
+public class MetaprojectCreator
+{
+    public static Metaproject createMetaproject(MetaprojectRecord metaprojectRecord, PersonPE owner)
+    {
+        Metaproject metaproject = new Metaproject();
+
+        metaproject.setId(metaprojectRecord.id);
+        metaproject.setName(metaprojectRecord.name);
+        metaproject.setDescription(metaprojectRecord.description);
+        metaproject.setPrivate(metaprojectRecord.is_private);
+        metaproject.setCreationDate(metaprojectRecord.creation_date);
+
+        metaproject.setOwnerId(owner.getUserId());
+
+        return metaproject;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/common/MetaprojectRecord.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/common/MetaprojectRecord.java
new file mode 100644
index 00000000000..0bfb85f77d4
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/common/MetaprojectRecord.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.server.business.bo.fetchoptions.common;
+
+import java.util.Date;
+
+/**
+ * @author Pawel Glyzewski
+ */
+public class MetaprojectRecord
+{
+    public Long id;
+
+    public String name;
+
+    public String description;
+
+    public Boolean is_private;
+
+    public Date creation_date;
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/datasetlister/DataSetLister.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/datasetlister/DataSetLister.java
index b28ba6d2040..187d21e1916 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/datasetlister/DataSetLister.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/datasetlister/DataSetLister.java
@@ -41,6 +41,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalDataManagementSystem;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.LinkDataSetUrl;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.IdentifierHelper;
@@ -55,19 +56,26 @@ public class DataSetLister implements IDataSetLister
 
     private IDataSetListingQuery query;
 
-    public DataSetLister(IAuthorizationDAOFactory daoFactory)
+    private PersonPE person;
+
+    public DataSetLister(IAuthorizationDAOFactory daoFactory, PersonPE person)
     {
         this(QueryTool.getQuery(DatabaseContextUtils.getConnection(daoFactory),
-                IDataSetListingQuery.class));
+                IDataSetListingQuery.class), person);
     }
 
-    public DataSetLister(IDataSetListingQuery query)
+    public DataSetLister(IDataSetListingQuery query, PersonPE person)
     {
         if (query == null)
         {
             throw new IllegalArgumentException("Query was null");
         }
+        if (person == null)
+        {
+            throw new IllegalArgumentException("Person was null");
+        }
         this.query = query;
+        this.person = person;
     }
 
     @Override
@@ -82,11 +90,13 @@ public class DataSetLister implements IDataSetLister
         {
             throw new IllegalArgumentException("DataSetFetchOptions were null");
         }
-        if (!dataSetFetchOptions.isSubsetOf(DataSetFetchOption.BASIC, DataSetFetchOption.PARENTS,
-                DataSetFetchOption.CHILDREN))
+        if (false == dataSetFetchOptions.isSubsetOf(DataSetFetchOption.BASIC,
+                DataSetFetchOption.PARENTS, DataSetFetchOption.CHILDREN,
+                DataSetFetchOption.METAPROJECTS))
         {
             throw new IllegalArgumentException("Currently only " + DataSetFetchOption.BASIC + ","
-                    + DataSetFetchOption.PARENTS + " and " + DataSetFetchOption.CHILDREN
+                    + DataSetFetchOption.PARENTS + ", and " + DataSetFetchOption.CHILDREN + " and "
+                    + DataSetFetchOption.METAPROJECTS
                     + " fetch options are supported by this method");
         }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/samplelister/ISampleListingQuery.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/samplelister/ISampleListingQuery.java
index 7b0c3eafe23..8ba3dc549f9 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/samplelister/ISampleListingQuery.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/samplelister/ISampleListingQuery.java
@@ -24,6 +24,8 @@ import net.lemnik.eodsql.BaseQuery;
 import net.lemnik.eodsql.Select;
 import net.lemnik.eodsql.TypeMapper;
 
+import ch.systemsx.cisd.openbis.generic.server.business.bo.fetchoptions.common.EntityMetaprojectRelationRecord;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.fetchoptions.common.MetaprojectRecord;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.fetchoptions.common.PropertyRecord;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.LongSetMapper;
 
@@ -95,4 +97,17 @@ public interface ISampleListingQuery extends BaseQuery
         { LongSetMapper.class }, fetchSize = FETCH_SIZE)
     public List<PropertyRecord> getProperties(LongSet entityIDs);
 
+    @Select(sql = "select ma.mepr_id as metaproject_id, ma.samp_id as entity_id "
+            + " from metaproject_assignments as ma "
+            + " join metaprojects as m on ma.mepr_id = m.id "
+            + "where ma.samp_id = any(?{1}) and m.owner = ?{2}", parameterBindings =
+        { LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    public List<EntityMetaprojectRelationRecord> getMetaprojectAssignments(LongSet sampleIDs,
+            Long ownerId);
+
+    @Select(sql = "select id as id, name as name, description as description, "
+            + " private as is_private, creation_date as creation_date " + " from metaprojects"
+            + " where id = any(?{1})", parameterBindings =
+        { LongSetMapper.class }, fetchSize = FETCH_SIZE)
+    public List<MetaprojectRecord> getMetaprojects(LongSet metaprojectIDs);
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/samplelister/SampleLister.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/samplelister/SampleLister.java
index 3e097c74416..a27da73de8d 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/samplelister/SampleLister.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/samplelister/SampleLister.java
@@ -35,6 +35,9 @@ import net.lemnik.eodsql.QueryTool;
 import ch.systemsx.cisd.common.collection.IKeyExtractor;
 import ch.systemsx.cisd.common.collection.TableMap;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.common.DatabaseContextUtils;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.fetchoptions.common.EntityMetaprojectRelationRecord;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.fetchoptions.common.MetaprojectCreator;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.fetchoptions.common.MetaprojectRecord;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.fetchoptions.common.PropertyRecord;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.EntityRegistrationDetails;
@@ -43,6 +46,7 @@ import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SampleFetchOption;
 import ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant;
 import ch.systemsx.cisd.openbis.generic.shared.basic.CodeConverter;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 
 /**
  * @author Franz-Josef Elmer
@@ -90,15 +94,18 @@ public class SampleLister implements ISampleLister
 
     private Long relationID;
 
-    public SampleLister(IDAOFactory daoFactory)
+    private PersonPE person;
+
+    public SampleLister(IDAOFactory daoFactory, PersonPE person)
     {
         this(QueryTool.getQuery(DatabaseContextUtils.getConnection(daoFactory),
-                ISampleListingQuery.class));
+                ISampleListingQuery.class), person);
     }
 
-    SampleLister(ISampleListingQuery query)
+    SampleLister(ISampleListingQuery query, PersonPE person)
     {
         this.query = query;
+        this.person = person;
     }
 
     private Long getRelationShipType()
@@ -165,6 +172,11 @@ public class SampleLister implements ISampleLister
         enrichWithAncestors(ancestors, sampleRecords,
                 fetchOptions.contains(SampleFetchOption.ANCESTORS));
         List<Sample> samples = new ArrayList<Sample>();
+        if (fetchOptions.contains(SampleFetchOption.METAPROJECTS))
+        {
+            enrichWithMetaprojects(sampleRecords, sampleIdSet);
+        }
+
         Map<Long, Sample> repository = new HashMap<Long, Sample>(); // Repository of all unlinked
                                                                     // samples
         for (Long rootSampleID : sampleIDs)
@@ -289,6 +301,48 @@ public class SampleLister implements ISampleLister
         }
     }
 
+    private void enrichWithMetaprojects(TableMap<Long, SampleRecord> sampleRecords,
+            LongSet sampleIdSet)
+    {
+        List<EntityMetaprojectRelationRecord> sampleMetaprojectRelations =
+                query.getMetaprojectAssignments(sampleIdSet, person.getId());
+        LongSet metaprojectIdSet = new LongOpenHashSet();
+        for (EntityMetaprojectRelationRecord record : sampleMetaprojectRelations)
+        {
+            metaprojectIdSet.add(record.metaproject_id);
+        }
+
+        List<MetaprojectRecord> metaprojects = query.getMetaprojects(metaprojectIdSet);
+        TableMap<Long, MetaprojectRecord> metaprojectRecords =
+                new TableMap<Long, MetaprojectRecord>(metaprojects,
+                        new IKeyExtractor<Long, MetaprojectRecord>()
+                            {
+                                @Override
+                                public Long getKey(MetaprojectRecord mr)
+                                {
+                                    return mr.id;
+                                }
+                            });
+
+        for (EntityMetaprojectRelationRecord record : sampleMetaprojectRelations)
+        {
+            SampleRecord sampleRecord = sampleRecords.tryGet(record.entity_id);
+            if (sampleRecord != null)
+            {
+                if (sampleRecord.metaprojects == null)
+                {
+                    sampleRecord.metaprojects = new ArrayList<MetaprojectRecord>();
+                }
+                MetaprojectRecord metaprojectRecord =
+                        metaprojectRecords.tryGet(record.metaproject_id);
+                if (metaprojectRecord != null)
+                {
+                    sampleRecord.metaprojects.add(metaprojectRecord);
+                }
+            }
+        }
+    }
+
     private Sample createSample(SampleRecord sampleRecord, Map<Long, Sample> repository)
     {
         Sample sample = repository.get(sampleRecord.s_id);
@@ -339,6 +393,14 @@ public class SampleLister implements ISampleLister
                 initializer.putProperty(entry.getKey(), entry.getValue());
             }
         }
+        if (sampleRecord.metaprojects != null)
+        {
+            for (MetaprojectRecord metaprojectRecord : sampleRecord.metaprojects)
+            {
+                initializer.addMetaproject(MetaprojectCreator.createMetaproject(metaprojectRecord,
+                        person));
+            }
+        }
         initializer.setRetrievedFetchOptions(sampleRecord.fetchOptions);
         List<SampleRecord> linkedSampleRecords = new ArrayList<SampleRecord>();
         if (sampleRecord.children != null)
@@ -376,9 +438,14 @@ public class SampleLister implements ISampleLister
     private EnumSet<SampleFetchOption> createAppropriateFetchOptions(
             EnumSet<SampleFetchOption> fetchOptions)
     {
-        return EnumSet
-                .of(fetchOptions.contains(SampleFetchOption.PROPERTIES) ? SampleFetchOption.PROPERTIES
+        EnumSet<SampleFetchOption> result =
+                EnumSet.of(fetchOptions.contains(SampleFetchOption.PROPERTIES) ? SampleFetchOption.PROPERTIES
                         : SampleFetchOption.BASIC);
+        if (fetchOptions.contains(SampleFetchOption.METAPROJECTS))
+        {
+            result.add(SampleFetchOption.METAPROJECTS);
+        }
+        return result;
     }
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/samplelister/SampleRecord.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/samplelister/SampleRecord.java
index 8bcb991feec..daf6fdfc28b 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/samplelister/SampleRecord.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/samplelister/SampleRecord.java
@@ -21,6 +21,7 @@ import java.util.EnumSet;
 import java.util.List;
 import java.util.Map;
 
+import ch.systemsx.cisd.openbis.generic.server.business.bo.fetchoptions.common.MetaprojectRecord;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SampleFetchOption;
 
 /**
@@ -75,6 +76,8 @@ public class SampleRecord
 
     public Map<String, String> properties;
 
+    public List<MetaprojectRecord> metaprojects;
+
     public EnumSet<SampleFetchOption> fetchOptions;
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IMetaprojectDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IMetaprojectDAO.java
index 54248625ac8..10194a5a49c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IMetaprojectDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IMetaprojectDAO.java
@@ -20,8 +20,10 @@ import java.util.Collection;
 import java.util.List;
 
 import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityInformationWithPropertiesHolder;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectAssignmentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
 
 /**
  * @author Pawel Glyzewski
@@ -49,4 +51,11 @@ public interface IMetaprojectDAO extends IGenericDAO<MetaprojectPE>
      */
     public Collection<MetaprojectPE> listMetaprojectsForEntity(PersonPE owner,
             IEntityInformationWithPropertiesHolder entity);
+
+    /**
+     * Lists all metaprojects owned by given user, connected with given entities.
+     */
+    public Collection<MetaprojectAssignmentPE> listMetaprojectAssignmentsForEntities(
+            PersonPE owner, Collection<? extends IEntityInformationWithPropertiesHolder> entities,
+            EntityKind entityKind);
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MetaprojectDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MetaprojectDAO.java
index dc1c8e4315f..f6c29ed9252 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MetaprojectDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MetaprojectDAO.java
@@ -38,6 +38,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityInformationWithPropert
 import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectAssignmentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
 
 /**
  * @author Pawel Glyzewski
@@ -132,4 +133,25 @@ public class MetaprojectDAO extends AbstractGenericEntityDAO<MetaprojectPE> impl
 
         return metaprojects;
     }
+
+    @Override
+    public Collection<MetaprojectAssignmentPE> listMetaprojectAssignmentsForEntities(
+            PersonPE owner, Collection<? extends IEntityInformationWithPropertiesHolder> entities,
+            EntityKind entityKind)
+    {
+        final DetachedCriteria criteria = DetachedCriteria.forClass(MetaprojectAssignmentPE.class);
+        criteria.createAlias("metaproject", "m");
+        criteria.add(Restrictions.eq("m.owner", owner));
+        criteria.add(Restrictions.in(entityKind.getLabel(), entities));
+        final List<MetaprojectAssignmentPE> assignments =
+                cast(getHibernateTemplate().findByCriteria(criteria));
+
+        if (operationLog.isDebugEnabled())
+        {
+            operationLog.debug(String.format("%s(%s, %s): %d metaproject(s) have been found.",
+                    MethodUtils.getCurrentMethod().getName(), owner, entities, assignments.size()));
+        }
+
+        return assignments;
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/Experiment.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/Experiment.java
index 12222f952a6..9ebece2b244 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/Experiment.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/Experiment.java
@@ -16,6 +16,7 @@
 
 package ch.systemsx.cisd.openbis.generic.shared.basic.dto;
 
+import java.util.Collection;
 import java.util.List;
 
 import ch.systemsx.cisd.openbis.generic.shared.basic.IAttachmentHolder;
@@ -57,6 +58,8 @@ public class Experiment extends CodeWithRegistrationAndModificationDate<Experime
 
     private final boolean isStub;
 
+    private Collection<Metaproject> metaprojects;
+
     public Experiment()
     {
         this(false);
@@ -221,4 +224,14 @@ public class Experiment extends CodeWithRegistrationAndModificationDate<Experime
     {
         return isStub;
     }
+
+    public Collection<Metaproject> getMetaprojecs()
+    {
+        return metaprojects;
+    }
+
+    public void setMetaprojects(final Collection<Metaproject> metaprojects)
+    {
+        this.metaprojects = metaprojects;
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ExperimentFetchOption.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ExperimentFetchOption.java
index 990f58da5e4..7ba1e6ecb86 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ExperimentFetchOption.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ExperimentFetchOption.java
@@ -22,6 +22,6 @@ package ch.systemsx.cisd.openbis.generic.shared.basic.dto;
 public enum ExperimentFetchOption implements FetchOption
 {
 
-    BASIC, PROPERTIES, PROPERTIES_OF_PROPERTIES, SCRIPTS;
+    BASIC, PROPERTIES, PROPERTIES_OF_PROPERTIES, SCRIPTS, METAPROJECTS;
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ExternalData.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ExternalData.java
index 6685c6ad41a..0f32c3c0dd9 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ExternalData.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/ExternalData.java
@@ -86,6 +86,8 @@ public abstract class ExternalData extends CodeWithRegistrationAndModificationDa
 
     private final boolean isStub;
 
+    private Collection<Metaproject> metaprojects;
+
     public ExternalData(boolean isStub)
     {
         this.isStub = isStub;
@@ -384,6 +386,16 @@ public abstract class ExternalData extends CodeWithRegistrationAndModificationDa
         this.storageConfirmation = storageConfirmation;
     }
 
+    public void setMetaprojects(Collection<Metaproject> metaprojects)
+    {
+        this.metaprojects = metaprojects;
+    }
+
+    public Collection<Metaproject> getMetaprojects()
+    {
+        return metaprojects;
+    }
+
     public DataSetKind getDataSetKind()
     {
         return DataSetKind.PHYSICAL;
@@ -416,5 +428,4 @@ public abstract class ExternalData extends CodeWithRegistrationAndModificationDa
             return order1.compareTo(order2);
         }
     }
-
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/Material.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/Material.java
index 57dc91f324d..afb892ee83f 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/Material.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/Material.java
@@ -16,6 +16,7 @@
 
 package ch.systemsx.cisd.openbis.generic.shared.basic.dto;
 
+import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 
@@ -41,6 +42,8 @@ public class Material extends CodeWithRegistration<Material> implements
 
     private List<IEntityProperty> properties;
 
+    private Collection<Metaproject> metaprojects;
+
     public MaterialType getMaterialType()
     {
         return materialType;
@@ -115,6 +118,16 @@ public class Material extends CodeWithRegistration<Material> implements
         return new MaterialIdentifier(getCode(), getMaterialType().getCode()).print();
     }
 
+    public void setMetaprojects(Collection<Metaproject> metaprojects)
+    {
+        this.metaprojects = metaprojects;
+    }
+
+    public Collection<Metaproject> getMetaprojects()
+    {
+        return metaprojects;
+    }
+
     //
     // Comparable
     //
@@ -155,5 +168,4 @@ public class Material extends CodeWithRegistration<Material> implements
     {
         return getIdentifier();
     }
-
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/Sample.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/Sample.java
index d23119999e6..e97cfce8f12 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/Sample.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/Sample.java
@@ -17,6 +17,7 @@
 package ch.systemsx.cisd.openbis.generic.shared.basic.dto;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 import java.util.TreeSet;
@@ -75,6 +76,8 @@ public final class Sample extends CodeWithRegistrationAndModificationDate<Sample
 
     private final boolean isStub;
 
+    private Collection<Metaproject> metaprojects;
+
     public Sample()
     {
         this(false);
@@ -322,6 +325,16 @@ public final class Sample extends CodeWithRegistrationAndModificationDate<Sample
         return isStub;
     }
 
+    public void setMetaprojects(Collection<Metaproject> metaprojects)
+    {
+        this.metaprojects = metaprojects;
+    }
+
+    public Collection<Metaproject> getMetaprojects()
+    {
+        return metaprojects;
+    }
+
     @Override
     public String toString()
     {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslator.java
index b9c43184dfb..61ac7df294d 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslator.java
@@ -21,6 +21,8 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import ch.systemsx.cisd.common.types.BooleanOrUnknown;
 import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolder;
@@ -35,6 +37,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.LinkDataSet;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PlaceholderDataSet;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
@@ -122,13 +125,14 @@ public class DataSetTranslator
     }
 
     public static List<ExternalData> translate(List<? extends DataPE> list,
-            String defaultDataStoreBaseURL, String baseIndexURL)
+            String defaultDataStoreBaseURL, String baseIndexURL,
+            Map<Long, Set<Metaproject>> metaprojects)
     {
         ArrayList<ExternalData> result = new ArrayList<ExternalData>(list.size());
         for (DataPE dataPE : list)
         {
             ExternalData data =
-                    translate(dataPE, baseIndexURL, true,
+                    translate(dataPE, baseIndexURL, true, metaprojects.get(dataPE.getId()),
                             ExperimentTranslator.LoadableFields.PROPERTIES);
             result.add(data);
         }
@@ -161,13 +165,13 @@ public class DataSetTranslator
     }
 
     public static ExternalData translate(DataPE dataPE, String baseIndexURL,
-            final LoadableFields... withExperimentFields)
+            Collection<Metaproject> metaprojects, final LoadableFields... withExperimentFields)
     {
-        return translate(dataPE, baseIndexURL, true, withExperimentFields);
+        return translate(dataPE, baseIndexURL, true, metaprojects, withExperimentFields);
     }
 
     public static ExternalData translate(DataPE dataPE, String baseIndexURL, boolean withDetails,
-            final LoadableFields... withExperimentFields)
+            Collection<Metaproject> metaprojects, final LoadableFields... withExperimentFields)
     {
         ExternalData externalData = null;
         if (dataPE.isContainer())
@@ -212,8 +216,13 @@ public class DataSetTranslator
         externalData.setPermlink(PermlinkUtilities.createPermlinkURL(baseIndexURL,
                 EntityKind.DATA_SET, externalData.getIdentifier()));
         setProperties(dataPE, externalData);
-        externalData.setExperiment(ExperimentTranslator.translate(experiment, baseIndexURL,
+        externalData.setExperiment(ExperimentTranslator.translate(experiment, baseIndexURL, null,
                 withExperimentFields));
+
+        if (metaprojects != null)
+        {
+            externalData.setMetaprojects(metaprojects);
+        }
         externalData.setDeletion(DeletionTranslator.translate(dataPE.getDeletion()));
         return externalData;
     }
@@ -222,7 +231,7 @@ public class DataSetTranslator
             String baseIndexURL)
     {
         return containerOrNull != null ? (ContainerDataSet) translate(containerOrNull,
-                baseIndexURL, false) : null;
+                baseIndexURL, false, null) : null;
     }
 
     private static ExternalData translateContainerDataSetProperties(DataPE dataPE,
@@ -316,7 +325,7 @@ public class DataSetTranslator
         {
             for (DataPE childPE : dataPE.getContainedDataSets())
             {
-                containedDataSets.add(translate(childPE, baseIndexURL));
+                containedDataSets.add(translate(childPE, baseIndexURL, null));
             }
         }
         containerDataSet.setContainedDataSets(containedDataSets);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/EntityHistoryTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/EntityHistoryTranslator.java
index 78e4314358d..87c0ed0f087 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/EntityHistoryTranslator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/EntityHistoryTranslator.java
@@ -21,8 +21,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityHistory;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AbstractEntityHistoryPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AbstractEntityPropertyHistoryPE;
@@ -36,8 +36,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
  */
 public class EntityHistoryTranslator
 {
-    public static List<EntityHistory> translate(
-            List<AbstractEntityPropertyHistoryPE> history, String baseIndexURL)
+    public static List<EntityHistory> translate(List<AbstractEntityPropertyHistoryPE> history,
+            String baseIndexURL)
     {
         List<EntityHistory> result = new ArrayList<EntityHistory>();
         HashMap<PropertyTypePE, PropertyType> cache = new HashMap<PropertyTypePE, PropertyType>();
@@ -48,8 +48,7 @@ public class EntityHistoryTranslator
         return result;
     }
 
-    private static EntityHistory translate(
-            AbstractEntityPropertyHistoryPE entityPropertyHistory,
+    private static EntityHistory translate(AbstractEntityPropertyHistoryPE entityPropertyHistory,
             Map<PropertyTypePE, PropertyType> cache, String baseIndexURL)
     {
         EntityHistory result = new EntityHistory();
@@ -82,12 +81,12 @@ public class EntityHistoryTranslator
                     case EXPERIMENT:
                         entityType = EntityKind.EXPERIMENT.getDescription();
                         result.setRelatedEntity(ExperimentTranslator.translate(
-                                (ExperimentPE) entityHistory.getRelatedEntity(), baseIndexURL));
+                                (ExperimentPE) entityHistory.getRelatedEntity(), baseIndexURL, null));
                         break;
                     case SAMPLE:
                         entityType = EntityKind.SAMPLE.getDescription();
                         result.setRelatedEntity(SampleTranslator.translate(
-                                (SamplePE) entityHistory.getRelatedEntity(), baseIndexURL));
+                                (SamplePE) entityHistory.getRelatedEntity(), baseIndexURL, null));
                         break;
                     case MATERIAL:
                 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/EntityPropertyTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/EntityPropertyTranslator.java
index 4865f674c0e..277f4383e3d 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/EntityPropertyTranslator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/EntityPropertyTranslator.java
@@ -66,7 +66,7 @@ public final class EntityPropertyTranslator
                 break;
             case MATERIAL:
                 basicProperty.setMaterial(MaterialTranslator.translate(
-                        propertyPE.getMaterialValue(), false));
+                        propertyPE.getMaterialValue(), false, null));
                 break;
             default:
                 basicProperty.setValue(propertyPE.tryGetUntypedValue());
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/ExperimentTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/ExperimentTranslator.java
index a8f062cf0b3..4bd5cd6c0e6 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/ExperimentTranslator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/ExperimentTranslator.java
@@ -17,15 +17,18 @@
 package ch.systemsx.cisd.openbis.generic.shared.translator;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import ch.systemsx.cisd.openbis.generic.shared.basic.PermlinkUtilities;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
@@ -70,25 +73,28 @@ public final class ExperimentTranslator
         }
     }
 
-    public final static Experiment translateWithoutRevealingData(final ExperimentPE experiment)
+    public final static Experiment translateWithoutRevealingData(final ExperimentPE experiment,
+            Collection<Metaproject> metaprojects)
     {
         final Experiment result = new Experiment(true);
 
         result.setId(HibernateUtils.getId(experiment));
         result.setPermId(experiment.getPermId());
         result.setProperties(new ArrayList<IEntityProperty>());
+        result.setMetaprojects(metaprojects);
 
         return result;
     }
 
     public final static Experiment translate(final ExperimentPE experiment, String baseIndexURL,
-            final LoadableFields... withFields)
+            Collection<Metaproject> metaprojects, final LoadableFields... withFields)
     {
-        return translate(experiment, baseIndexURL, false, withFields);
+        return translate(experiment, baseIndexURL, false, metaprojects, withFields);
     }
 
     public final static Experiment translate(final ExperimentPE experiment, String baseIndexURL,
-            final boolean rawManagedProperties, final LoadableFields... withFields)
+            final boolean rawManagedProperties, Collection<Metaproject> metaprojects,
+            final LoadableFields... withFields)
     {
         if (experiment == null)
         {
@@ -125,19 +131,24 @@ public final class ExperimentTranslator
             }
         }
 
+        if (metaprojects != null)
+        {
+            result.setMetaprojects(metaprojects);
+        }
+
         return result;
     }
 
     // NOTE: when translating list of experiments managed properties will contain raw value
     public final static List<Experiment> translate(final List<ExperimentPE> experiments,
-            String baseIndexURL)
+            String baseIndexURL, Map<Long, Set<Metaproject>> metaprojects)
     {
         final List<Experiment> result = new ArrayList<Experiment>(experiments.size());
         for (final ExperimentPE experiment : experiments)
         {
             HibernateUtils.initialize(experiment.getProperties());
             result.add(ExperimentTranslator.translate(experiment, baseIndexURL, true,
-                    LoadableFields.PROPERTIES));
+                    metaprojects.get(experiment.getId()), LoadableFields.PROPERTIES));
         }
         return result;
     }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/MaterialTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/MaterialTranslator.java
index ef007939d8f..bcd66659d77 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/MaterialTranslator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/MaterialTranslator.java
@@ -17,11 +17,15 @@
 package ch.systemsx.cisd.openbis.generic.shared.translator;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
@@ -49,22 +53,25 @@ public final class MaterialTranslator
         return newMaterial;
     }
 
-    public final static List<Material> translate(final List<MaterialPE> materials)
+    public final static List<Material> translate(final List<MaterialPE> materials,
+            Map<Long, Set<Metaproject>> metaprojects)
     {
         final List<Material> result = new ArrayList<Material>();
         for (final MaterialPE material : materials)
         {
-            result.add(MaterialTranslator.translate(material));
+            result.add(MaterialTranslator.translate(material, metaprojects.get(material.getId())));
         }
         return result;
     }
 
-    public final static Material translate(final MaterialPE materialPE)
+    public final static Material translate(final MaterialPE materialPE,
+            Collection<Metaproject> metaprojects)
     {
-        return translate(materialPE, true);
+        return translate(materialPE, true, metaprojects);
     }
 
-    public final static Material translate(final MaterialPE materialPE, final boolean withProperties)
+    public final static Material translate(final MaterialPE materialPE,
+            final boolean withProperties, Collection<Metaproject> metaprojects)
     {
         if (materialPE == null)
         {
@@ -85,6 +92,11 @@ public final class MaterialTranslator
             setProperties(materialPE, result);
         }
 
+        if (metaprojects != null)
+        {
+            result.setMetaprojects(metaprojects);
+        }
+
         return result;
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/MetaprojectTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/MetaprojectTranslator.java
index 488f6b183cc..9304b8f805b 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/MetaprojectTranslator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/MetaprojectTranslator.java
@@ -17,9 +17,15 @@
 package ch.systemsx.cisd.openbis.generic.shared.translator;
 
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectAssignmentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 
 /**
@@ -29,7 +35,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
  */
 public class MetaprojectTranslator
 {
-    public static List<Metaproject> translate(List<MetaprojectPE> metaprojectPEs)
+    public static List<Metaproject> translate(Collection<MetaprojectPE> metaprojectPEs)
     {
         List<Metaproject> metaprojects = new ArrayList<Metaproject>(metaprojectPEs.size());
 
@@ -64,4 +70,51 @@ public class MetaprojectTranslator
         return metaprojectPE;
     }
 
+    public static Map<Long, Set<Metaproject>> translateMetaprojectAssignments(
+            Collection<MetaprojectAssignmentPE> assignments)
+    {
+        Map<Long, Metaproject> metaprojects = new HashMap<Long, Metaproject>();
+        for (MetaprojectAssignmentPE assignment : assignments)
+        {
+            Long metaprojectId = assignment.getMetaproject().getId();
+            if (false == metaprojects.containsKey(metaprojectId))
+            {
+                metaprojects.put(metaprojectId, translate(assignment.getMetaproject()));
+            }
+        }
+
+        Map<Long, Set<Metaproject>> translatedAssignments = new HashMap<Long, Set<Metaproject>>();
+        for (MetaprojectAssignmentPE assignment : assignments)
+        {
+            Long entityId = tryGetEntityId(assignment);
+            Set<Metaproject> metaprojectsSet = translatedAssignments.get(entityId);
+            if (metaprojectsSet == null)
+            {
+                metaprojectsSet = new HashSet<Metaproject>();
+                translatedAssignments.put(entityId, metaprojectsSet);
+            }
+            metaprojectsSet.add(metaprojects.get(assignment.getMetaproject().getId()));
+        }
+
+        return translatedAssignments;
+    }
+
+    private static final Long tryGetEntityId(MetaprojectAssignmentPE assignment)
+    {
+        if (assignment.getExperiment() != null)
+        {
+            return assignment.getExperiment().getId();
+        } else if (assignment.getSample() != null)
+        {
+            return assignment.getSample().getId();
+        } else if (assignment.getDataSet() != null)
+        {
+            return assignment.getDataSet().getId();
+        } else if (assignment.getMaterial() != null)
+        {
+            return assignment.getMaterial().getId();
+        }
+
+        return null;
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/SampleTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/SampleTranslator.java
index be92ba845ee..87b8453a58f 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/SampleTranslator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/SampleTranslator.java
@@ -17,14 +17,18 @@
 package ch.systemsx.cisd.openbis.generic.shared.translator;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import ch.systemsx.cisd.openbis.generic.shared.basic.PermlinkUtilities;
 import ch.systemsx.cisd.openbis.generic.shared.basic.SearchlinkUtilities;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleParentWithDerived;
@@ -47,12 +51,13 @@ public final class SampleTranslator
         // Can not be instantiated.
     }
 
-    public static List<Sample> translate(final List<SamplePE> samples, String baseIndexURL)
+    public static List<Sample> translate(final List<SamplePE> samples, String baseIndexURL,
+            Map<Long, Set<Metaproject>> metaprojects)
     {
         final List<Sample> list = new ArrayList<Sample>(samples.size());
         for (final SamplePE sample : samples)
         {
-            list.add(translate(sample, baseIndexURL));
+            list.add(translate(sample, baseIndexURL, metaprojects.get(sample.getId())));
         }
         return list;
     }
@@ -68,13 +73,15 @@ public final class SampleTranslator
         return result;
     }
 
-    public final static Sample translate(final SamplePE samplePE, String baseIndexURL)
+    public final static Sample translate(final SamplePE samplePE, String baseIndexURL,
+            Collection<Metaproject> metaprojects)
     {
-        return translate(samplePE, baseIndexURL, true, false);
+        return translate(samplePE, baseIndexURL, true, false, metaprojects);
     }
 
     public final static Sample translate(final SamplePE samplePE, String baseIndexURL,
-            final boolean withDetails, boolean withContainedSamples)
+            final boolean withDetails, boolean withContainedSamples,
+            Collection<Metaproject> metaprojects)
     {
         if (samplePE == null)
         {
@@ -86,13 +93,13 @@ public final class SampleTranslator
         final int generatedFromDep =
                 getPositiveIntegerValue(samplePE.getSampleType().getGeneratedFromHierarchyDepth());
         return translate(samplePE, baseIndexURL, containerDep, generatedFromDep, withDetails,
-                withContainedSamples);
+                withContainedSamples, metaprojects);
 
     }
 
     private final static Sample translate(final SamplePE samplePE, String baseIndexURL,
             final int containerDep, final int generatedFromDep, final boolean withDetails,
-            final boolean withContainedSamples)
+            final boolean withContainedSamples, Collection<Metaproject> metaprojects)
     {
         final Sample result = new Sample();
         setCodes(result, samplePE);
@@ -118,7 +125,7 @@ public final class SampleTranslator
             result.setRegistrationDate(samplePE.getRegistrationDate());
             setProperties(result, samplePE);
             result.setExperiment(ExperimentTranslator.translate(samplePE.getExperiment(),
-                    baseIndexURL, LoadableFields.PROPERTIES));
+                    baseIndexURL, null, LoadableFields.PROPERTIES));
             List<Attachment> attachments;
             if (samplePE.attachmentsInitialized() == false)
             {
@@ -135,7 +142,7 @@ public final class SampleTranslator
             if (HibernateUtils.isInitialized(samplePE.getContainer()))
             {
                 result.setContainer(translate(samplePE.getContainer(), baseIndexURL,
-                        containerDep - 1, 0, false, false));
+                        containerDep - 1, 0, false, false, null));
             }
         }
         if (generatedFromDep > 0 && samplePE.getParentRelationships() != null)
@@ -145,7 +152,7 @@ public final class SampleTranslator
                 for (SamplePE parent : samplePE.getParents())
                 {
                     result.addParent(translate(parent, baseIndexURL, 0, generatedFromDep - 1,
-                            false, false));
+                            false, false, null));
                 }
             }
         }
@@ -155,12 +162,17 @@ public final class SampleTranslator
             ArrayList<Sample> containedSamples = new ArrayList<Sample>();
             for (SamplePE containedPE : samplePE.getContained())
             {
-                Sample containedSample = translate(containedPE, baseIndexURL, 0, 0, false, false);
+                Sample containedSample =
+                        translate(containedPE, baseIndexURL, 0, 0, false, false, null);
                 containedSamples.add(containedSample);
 
             }
             result.setContainedSample(containedSamples);
         }
+        if (metaprojects != null)
+        {
+            result.setMetaprojects(metaprojects);
+        }
         result.setDeletion(DeletionTranslator.translate(samplePE.getDeletion()));
         return result;
     }
@@ -190,12 +202,12 @@ public final class SampleTranslator
         final SampleParentWithDerived sampleGeneration = new SampleParentWithDerived();
 
         sampleGeneration.setParent(SampleTranslator.translate(sampleGenerationDTO.getParent(),
-                baseIndexURL));
+                baseIndexURL, null));
 
         final List<Sample> generated = new ArrayList<Sample>();
         for (SamplePE samplePE : sampleGenerationDTO.getDerived())
         {
-            generated.add(SampleTranslator.translate(samplePE, baseIndexURL, false, false));
+            generated.add(SampleTranslator.translate(samplePE, baseIndexURL, false, false, null));
         }
         sampleGeneration.setDerived(generated.toArray(new Sample[generated.size()]));
         return sampleGeneration;
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java
index 8eafe12f7ab..15cd7c215c8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java
@@ -101,6 +101,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentBatchUpdatesDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentUpdatesDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SampleBatchUpdatesDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePE;
@@ -116,6 +117,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.translator.AttachmentTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.ExperimentTranslator;
+import ch.systemsx.cisd.openbis.generic.shared.translator.MetaprojectTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.SampleTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.util.ServerUtils;
 import ch.systemsx.cisd.openbis.plugin.generic.shared.IGenericServer;
@@ -226,12 +228,16 @@ public final class GenericServer extends AbstractServer<IGenericServer> implemen
         experimentBO.enrichWithProperties();
         experimentBO.enrichWithAttachments();
         final ExperimentPE experiment = experimentBO.getExperiment();
+        Collection<MetaprojectPE> metaprojectPEs =
+                getDAOFactory().getMetaprojectDAO().listMetaprojectsForEntity(
+                        session.tryGetPerson(), experiment);
         if (experiment == null)
         {
             throw UserFailureException.fromTemplate(
                     "No experiment could be found with given identifier '%s'.", identifier);
         }
         return ExperimentTranslator.translate(experiment, session.getBaseIndexURL(),
+                MetaprojectTranslator.translate(metaprojectPEs),
                 ExperimentTranslator.LoadableFields.PROPERTIES,
                 ExperimentTranslator.LoadableFields.ATTACHMENTS);
     }
@@ -244,7 +250,11 @@ public final class GenericServer extends AbstractServer<IGenericServer> implemen
         experimentBO.enrichWithProperties();
         experimentBO.enrichWithAttachments();
         final ExperimentPE experiment = experimentBO.getExperiment();
+        Collection<MetaprojectPE> metaprojectPEs =
+                getDAOFactory().getMetaprojectDAO().listMetaprojectsForEntity(
+                        session.tryGetPerson(), experiment);
         return ExperimentTranslator.translate(experiment, session.getBaseIndexURL(),
+                MetaprojectTranslator.translate(metaprojectPEs),
                 ExperimentTranslator.LoadableFields.PROPERTIES,
                 ExperimentTranslator.LoadableFields.ATTACHMENTS);
     }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java
index d1597f2ea89..6d034293708 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java
@@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.generic.server;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -82,6 +83,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.FileFormatTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.LocatorTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE;
@@ -573,7 +575,7 @@ public final class CommonServerTest extends AbstractServerTestCase
         dataStorePE.setCode("DST");
         externalDataPE.setDataStore(dataStorePE);
         final ExternalData externalData =
-                DataSetTranslator.translate(externalDataPE, BASE_INDEX_URL);
+                DataSetTranslator.translate(externalDataPE, BASE_INDEX_URL, null);
         prepareGetSession();
         final boolean showOnlyDirectlyConnected = true;
         context.checking(new Expectations()
@@ -612,7 +614,7 @@ public final class CommonServerTest extends AbstractServerTestCase
         dataStorePE.setCode("DST");
         externalDataPE.setDataStore(dataStorePE);
         final ExternalData externalData =
-                DataSetTranslator.translate(externalDataPE, BASE_INDEX_URL);
+                DataSetTranslator.translate(externalDataPE, BASE_INDEX_URL, null);
         prepareGetSession();
         context.checking(new Expectations()
             {
@@ -638,6 +640,7 @@ public final class CommonServerTest extends AbstractServerTestCase
         return EqualsBuilder.reflectionEquals(data1, data2);
     }
 
+    @SuppressWarnings("unchecked")
     @Test
     public void testListExperiments()
     {
@@ -657,6 +660,12 @@ public final class CommonServerTest extends AbstractServerTestCase
 
                     one(experimentTable).getExperiments();
                     will(returnValue(new ArrayList<ExperimentPE>()));
+
+                    one(metaprojectDAO)
+                            .listMetaprojectAssignmentsForEntities(
+                                    with(any(PersonPE.class)),
+                                    with(any(Collection.class)),
+                                    with(any(ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind.class)));
                 }
             });
         createServer().listExperiments(SESSION_TOKEN, experimentType, projectIdentifier);
@@ -1646,6 +1655,10 @@ public final class CommonServerTest extends AbstractServerTestCase
 
                     one(experimentBO).getExperiment();
                     will(returnValue(experimentPE));
+
+                    one(metaprojectDAO).listMetaprojectsForEntity(session.tryGetPerson(),
+                            experimentPE);
+                    will(returnValue(new HashSet<MetaprojectPE>()));
                 }
             });
         final Experiment experiment =
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceTest.java
index 023755fa857..6bbeabc0f46 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceTest.java
@@ -59,6 +59,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchAssociationCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Person;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
@@ -108,7 +109,7 @@ public class GeneralInformationServiceTest extends AbstractServerTestCase
                         propertiesBatchManager, commonServer)
                     {
                         @Override
-                        protected ISampleLister createSampleLister()
+                        protected ISampleLister createSampleLister(PersonPE person)
                         {
                             return sampleLister2;
                         }
@@ -629,6 +630,9 @@ public class GeneralInformationServiceTest extends AbstractServerTestCase
                                     .property("alpha", DataTypeCode.REAL, "3.14159")
                                     .property("status", DataTypeCode.VARCHAR, "normal");
                     will(returnValue(ds1.getDataSet()));
+                    one(metaprojectDAO).listMetaprojectsForEntity(session.tryGetPerson(),
+                            ds1.getDataSet());
+                    will(returnValue(new HashSet<Metaproject>()));
 
                     one(dataSetDAO).tryToFindDataSetByCode("ds2");
                     ExternalDataPEBuilder ds2 =
@@ -637,6 +641,9 @@ public class GeneralInformationServiceTest extends AbstractServerTestCase
                                     .property("status", DataTypeCode.VARCHAR, "low")
                                     .parent(ds1.getDataSet());
                     will(returnValue(ds2.getDataSet()));
+                    one(metaprojectDAO).listMetaprojectsForEntity(session.tryGetPerson(),
+                            ds2.getDataSet());
+                    will(returnValue(new HashSet<Metaproject>()));
                 }
             });
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/ExperimentValidatorTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/ExperimentValidatorTest.java
index 3ea8a7c21ab..67dfc5803ce 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/ExperimentValidatorTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/ExperimentValidatorTest.java
@@ -19,9 +19,8 @@ package ch.systemsx.cisd.openbis.generic.server.authorization.validator;
 import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.openbis.generic.server.authorization.AuthorizationTestCase;
-import ch.systemsx.cisd.openbis.generic.server.authorization.validator.ExperimentValidator;
-import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
 import ch.systemsx.cisd.openbis.generic.shared.translator.ExperimentTranslator;
 
 /**
@@ -39,7 +38,7 @@ public class ExperimentValidatorTest extends AuthorizationTestCase
         ExperimentValidator validator = new ExperimentValidator();
         PersonPE person = createPersonWithRoleAssignments();
         assertEquals(true, validator.isValid(person, ExperimentTranslator.translate(
-                createExperiment(createAnotherGroup()), BASE_URL)));
+                createExperiment(createAnotherGroup()), BASE_URL, null)));
     }
 
     @Test
@@ -47,8 +46,8 @@ public class ExperimentValidatorTest extends AuthorizationTestCase
     {
         ExperimentValidator validator = new ExperimentValidator();
         PersonPE person = createPersonWithRoleAssignments();
-        assertEquals(true, validator.isValid(person, ExperimentTranslator.translate(
-                createExperiment(createGroup()), BASE_URL)));
+        assertEquals(true, validator.isValid(person,
+                ExperimentTranslator.translate(createExperiment(createGroup()), BASE_URL, null)));
     }
 
     @Test
@@ -57,7 +56,9 @@ public class ExperimentValidatorTest extends AuthorizationTestCase
         ExperimentValidator validator = new ExperimentValidator();
         PersonPE person = createPersonWithRoleAssignments();
         SpacePE group = createGroup("blabla", createAnotherDatabaseInstance());
-        assertEquals(false, validator.isValid(person, ExperimentTranslator.translate(
-                createExperiment(group), BASE_URL)));
+        assertEquals(
+                false,
+                validator.isValid(person,
+                        ExperimentTranslator.translate(createExperiment(group), BASE_URL, null)));
     }
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/ExternalDataValidatorTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/ExternalDataValidatorTest.java
index 8c7c443de16..8d40e16768c 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/ExternalDataValidatorTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/ExternalDataValidatorTest.java
@@ -19,7 +19,6 @@ package ch.systemsx.cisd.openbis.generic.server.authorization.validator;
 import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.openbis.generic.server.authorization.AuthorizationTestCase;
-import ch.systemsx.cisd.openbis.generic.server.authorization.validator.ExternalDataValidator;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSet;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
@@ -33,8 +32,8 @@ public class ExternalDataValidatorTest extends AuthorizationTestCase
     private DataSet createData(SpacePE group)
     {
         DataSet data = new DataSet();
-        data.setExperiment(ExperimentTranslator
-                .translate(createExperiment(group), "http://someURL"));
+        data.setExperiment(ExperimentTranslator.translate(createExperiment(group),
+                "http://someURL", null));
         return data;
     }
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/SampleValidatorTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/SampleValidatorTest.java
index 0236a830d1c..661693337a0 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/SampleValidatorTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/SampleValidatorTest.java
@@ -19,9 +19,8 @@ package ch.systemsx.cisd.openbis.generic.server.authorization.validator;
 import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.openbis.generic.server.authorization.AuthorizationTestCase;
-import ch.systemsx.cisd.openbis.generic.server.authorization.validator.SampleValidator;
-import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
 import ch.systemsx.cisd.openbis.generic.shared.translator.SampleTranslator;
 
 /**
@@ -38,8 +37,8 @@ public class SampleValidatorTest extends AuthorizationTestCase
     {
         SampleValidator validator = new SampleValidator();
         PersonPE person = createPersonWithRoleAssignments();
-        assertEquals(true, validator.isValid(person, SampleTranslator.translate(
-                createSample(createAnotherGroup()), BASE_URL)));
+        assertEquals(true, validator.isValid(person,
+                SampleTranslator.translate(createSample(createAnotherGroup()), BASE_URL, null)));
     }
 
     @Test
@@ -47,8 +46,8 @@ public class SampleValidatorTest extends AuthorizationTestCase
     {
         SampleValidator validator = new SampleValidator();
         PersonPE person = createPersonWithRoleAssignments();
-        assertEquals(true, validator.isValid(person, SampleTranslator.translate(
-                createSample(createDatabaseInstance()), BASE_URL)));
+        assertEquals(true, validator.isValid(person,
+                SampleTranslator.translate(createSample(createDatabaseInstance()), BASE_URL, null)));
     }
 
     @Test
@@ -57,7 +56,7 @@ public class SampleValidatorTest extends AuthorizationTestCase
         SampleValidator validator = new SampleValidator();
         PersonPE person = createPersonWithRoleAssignments();
         assertEquals(false, validator.isValid(person, SampleTranslator.translate(
-                createSample(createDatabaseInstance("blabla")), BASE_URL)));
+                createSample(createDatabaseInstance("blabla")), BASE_URL, null)));
     }
 
     @Test
@@ -65,8 +64,10 @@ public class SampleValidatorTest extends AuthorizationTestCase
     {
         SampleValidator validator = new SampleValidator();
         PersonPE person = createPersonWithRoleAssignments();
-        assertEquals(true, validator.isValid(person, SampleTranslator.translate(
-                createSample(createGroup()), BASE_URL)));
+        assertEquals(
+                true,
+                validator.isValid(person,
+                        SampleTranslator.translate(createSample(createGroup()), BASE_URL, null)));
     }
 
     @Test
@@ -75,7 +76,9 @@ public class SampleValidatorTest extends AuthorizationTestCase
         SampleValidator validator = new SampleValidator();
         PersonPE person = createPersonWithRoleAssignments();
         SpacePE group = createGroup("blabla", createAnotherDatabaseInstance());
-        assertEquals(false, validator.isValid(person, SampleTranslator.translate(
-                createSample(group), BASE_URL)));
+        assertEquals(
+                false,
+                validator.isValid(person,
+                        SampleTranslator.translate(createSample(group), BASE_URL, null)));
     }
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetListerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetListerTest.java
index 81b06885675..40163f97957 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetListerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetListerTest.java
@@ -51,6 +51,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSet;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetArchivingStatus;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IDatasetLocationNode;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TrackingDataSetCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetShareId;
@@ -142,7 +143,8 @@ public class DatasetListerTest extends AbstractDAOTest
         HashSet<String> samplePermIDs =
                 new HashSet<String>(Arrays.asList("200902091250077-1026", "200902091225616-1027"));
         List<SamplePE> samplePEs = daoFactory.getSampleDAO().listByPermID(samplePermIDs);
-        List<Sample> samples = SampleTranslator.translate(samplePEs, "");
+        List<Sample> samples =
+                SampleTranslator.translate(samplePEs, "", new HashMap<Long, Set<Metaproject>>());
 
         Map<Sample, List<ExternalData>> dataSets = lister.listAllDataSetsFor(samples);
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/datasetlister/DataSetListerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/datasetlister/DataSetListerTest.java
index def6af530c3..3d0225c818a 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/datasetlister/DataSetListerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/fetchoptions/datasetlister/DataSetListerTest.java
@@ -81,8 +81,7 @@ public class DataSetListerTest extends AbstractDAOTest
     {
         sessionToken = service.tryToAuthenticateForAllServices("test", "password");
         query = EntityListingTestUtils.createQuery(daoFactory, IDataSetListingQueryDynamic.class);
-        lister =
-                new DataSetLister(query);
+        lister = new DataSetLister(query, getTestPerson());
     }
 
     @Test
@@ -130,15 +129,12 @@ public class DataSetListerTest extends AbstractDAOTest
                     + " where code='STANDARD'");
             final long newDataStoreId =
                     (Long) query
-                            .select(
-                                    "insert into data_stores (id,dbin_id,code,download_url,remote_url,session_token)"
-                                            + " values (nextval('data_store_id_seq'),1,'DSS2','http://download_2','http://remote_2','') returning id")
+                            .select("insert into data_stores (id,dbin_id,code,download_url,remote_url,session_token)"
+                                    + " values (nextval('data_store_id_seq'),1,'DSS2','http://download_2','http://remote_2','') returning id")
                             .get(0).get("id");
-            query.update(
-                    "update data set dast_id = ?{1} where code = ?{2}", newDataStoreId,
+            query.update("update data set dast_id = ?{1} where code = ?{2}", newDataStoreId,
                     "20081105092259000-20");
-            query.update(
-                    "update data set dast_id = ?{1} where code = ?{2}", newDataStoreId,
+            query.update("update data set dast_id = ?{1} where code = ?{2}", newDataStoreId,
                     "20081105092259000-21");
 
             List<String> codes = new ArrayList<String>();
@@ -153,14 +149,12 @@ public class DataSetListerTest extends AbstractDAOTest
             {
                 if (url.getDataStoreURL().equals("http://download_1"))
                 {
-                    assertEquals(
-                            Arrays.asList("20081105092159188-3", "20081105092159111-1",
-                                    "20081105092259000-19"),
-                            url.getDataSetCodes());
+                    assertEquals(Arrays.asList("20081105092159188-3", "20081105092159111-1",
+                            "20081105092259000-19"), url.getDataSetCodes());
                 } else if (url.getDataStoreURL().equals("http://download_2"))
                 {
-                    assertEquals(Arrays.asList("20081105092259000-20", "20081105092259000-21"), url
-                            .getDataSetCodes());
+                    assertEquals(Arrays.asList("20081105092259000-20", "20081105092259000-21"),
+                            url.getDataSetCodes());
                 } else
                 {
                     fail("URL " + url + " not expected.");
@@ -173,14 +167,12 @@ public class DataSetListerTest extends AbstractDAOTest
             {
                 if (url.getDataStoreURL().equals("http://remote_1"))
                 {
-                    assertEquals(
-                            Arrays.asList("20081105092159188-3", "20081105092159111-1",
-                                    "20081105092259000-19"),
-                            url.getDataSetCodes());
+                    assertEquals(Arrays.asList("20081105092159188-3", "20081105092159111-1",
+                            "20081105092259000-19"), url.getDataSetCodes());
                 } else if (url.getDataStoreURL().equals("http://remote_2"))
                 {
-                    assertEquals(Arrays.asList("20081105092259000-20", "20081105092259000-21"), url
-                            .getDataSetCodes());
+                    assertEquals(Arrays.asList("20081105092259000-20", "20081105092259000-21"),
+                            url.getDataSetCodes());
                 } else
                 {
                     fail("URL " + url + " not expected.");
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MetaprojectDAOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MetaprojectDAOTest.java
index 11e6e96ccb3..1da3f963328 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MetaprojectDAOTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MetaprojectDAOTest.java
@@ -21,6 +21,7 @@ import static org.testng.AssertJUnit.assertNotNull;
 import static org.testng.AssertJUnit.assertTrue;
 import static org.testng.AssertJUnit.fail;
 
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 
@@ -28,7 +29,10 @@ import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityInformationWithPropertiesHolder;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectAssignmentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
 
 /**
  * @author Pawel Glyzewski
@@ -181,4 +185,23 @@ public class MetaprojectDAOTest extends AbstractDAOTest
                     || metaproject.getId().longValue() == 3l);
         }
     }
+
+    @Test
+    public void testListMetaprojectsForEntities()
+    {
+        ExperimentPE experiment1 = daoFactory.getExperimentDAO().getByTechId(new TechId(4));
+        ExperimentPE experiment2 = daoFactory.getExperimentDAO().getByTechId(new TechId(23));
+
+        Collection<MetaprojectAssignmentPE> assignments =
+                daoFactory.getMetaprojectDAO().listMetaprojectAssignmentsForEntities(
+                        getTestPerson(), Arrays.asList(new IEntityInformationWithPropertiesHolder[]
+                            { experiment1, experiment2 }), EntityKind.EXPERIMENT);
+
+        assertEquals(3, assignments.size());
+        for (MetaprojectAssignmentPE assignment : assignments)
+        {
+            assertTrue(assignment.getMetaproject().getId().longValue() == 1l
+                    || assignment.getMetaproject().getId().longValue() == 3l);
+        }
+    }
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerTestCase.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerTestCase.java
index 50d3de4f59c..627446d199e 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerTestCase.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerTestCase.java
@@ -65,6 +65,7 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityTypeDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExperimentDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IFileFormatTypeDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IHibernateSearchDAO;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IMetaprojectDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IPersonDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IProjectDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IPropertyTypeDAO;
@@ -200,6 +201,8 @@ public abstract class AbstractServerTestCase extends AssertJUnit
 
     protected IEntityOperationsLogDAO entityOperationsLogDAO;
 
+    protected IMetaprojectDAO metaprojectDAO;
+
     private MaterialConfigurationProvider oldProvider;
 
     @BeforeMethod
@@ -236,6 +239,7 @@ public abstract class AbstractServerTestCase extends AssertJUnit
         deletionDAO = context.mock(IDeletionDAO.class);
         hibernateSearchDAO = context.mock(IHibernateSearchDAO.class);
         entityOperationsLogDAO = context.mock(IEntityOperationsLogDAO.class);
+        metaprojectDAO = context.mock(IMetaprojectDAO.class);
         // BO
         groupBO = context.mock(ISpaceBO.class);
         entityTypeBO = context.mock(IEntityTypeBO.class);
@@ -297,6 +301,8 @@ public abstract class AbstractServerTestCase extends AssertJUnit
                     will(returnValue(hibernateSearchDAO));
                     allowing(daoFactory).getEntityOperationsLogDAO();
                     will(returnValue(entityOperationsLogDAO));
+                    allowing(daoFactory).getMetaprojectDAO();
+                    will(returnValue(metaprojectDAO));
                 }
             });
         oldProvider = MaterialConfigurationProvider.initializeForTesting(false);
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslatorTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslatorTest.java
index 5bb670f747e..d41eb71e9ac 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslatorTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslatorTest.java
@@ -64,7 +64,7 @@ public class DataSetTranslatorTest extends AssertJUnit
     {
         ExternalDataPE externalDataPE = new ExternalDataPE();
         externalDataPE.setDataStore(createStore());
-        ExternalData data = DataSetTranslator.translate(externalDataPE, BASE_INDEX_URL);
+        ExternalData data = DataSetTranslator.translate(externalDataPE, BASE_INDEX_URL, null);
 
         DataSet translated = data.tryGetAsDataSet();
 
@@ -129,7 +129,7 @@ public class DataSetTranslatorTest extends AssertJUnit
         deletionPE.setRegistrator(personPE);
         externalDataPE.setDeletion(deletionPE);
         externalDataPE.setSampleAcquiredFrom(samplePE);
-        ExternalData data = DataSetTranslator.translate(externalDataPE, BASE_INDEX_URL);
+        ExternalData data = DataSetTranslator.translate(externalDataPE, BASE_INDEX_URL, null);
 
         DataSet translated = data.tryGetAsDataSet();
 
@@ -185,7 +185,8 @@ public class DataSetTranslatorTest extends AssertJUnit
         externalDataPE.addParentRelationship(createParentRelationship(externalDataPE, "parent-1"));
         externalDataPE.addParentRelationship(createParentRelationship(externalDataPE, "parent-2"));
 
-        ExternalData externalData = DataSetTranslator.translate(externalDataPE, BASE_INDEX_URL);
+        ExternalData externalData =
+                DataSetTranslator.translate(externalDataPE, BASE_INDEX_URL, null);
 
         assertEquals("my-experiment", externalData.getExperiment().getCode());
         assertEquals(2, externalData.getParents().size());
@@ -227,7 +228,7 @@ public class DataSetTranslatorTest extends AssertJUnit
         linkDataPE.addParentRelationship(createParentRelationship(linkDataPE, "parent-1"));
         linkDataPE.addParentRelationship(createParentRelationship(linkDataPE, "parent-2"));
 
-        ExternalData externalData = DataSetTranslator.translate(linkDataPE, BASE_INDEX_URL);
+        ExternalData externalData = DataSetTranslator.translate(linkDataPE, BASE_INDEX_URL, null);
 
         assertEquals("my-experiment", externalData.getExperiment().getCode());
         assertEquals(2, externalData.getParents().size());
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/api/v1/GeneralInformationServiceTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/api/v1/GeneralInformationServiceTest.java
index c653bff1c07..ed53a3908f7 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/api/v1/GeneralInformationServiceTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/api/v1/GeneralInformationServiceTest.java
@@ -17,6 +17,7 @@
 package ch.systemsx.cisd.openbis.systemtest.api.v1;
 
 import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNotNull;
 import static org.testng.AssertJUnit.assertTrue;
 import static org.testng.AssertJUnit.fail;
 
@@ -199,6 +200,51 @@ public class GeneralInformationServiceTest extends SystemTestCase
         assertEntities("[]", samples);
     }
 
+    @Test
+    public void testSearchForSamplesWithMetaprojects()
+    {
+        SearchCriteria searchCriteria = new SearchCriteria();
+        searchCriteria.addMatchClause(MatchClause.createAttributeMatch(MatchClauseAttribute.TYPE,
+                "DILUTION_PLATE"));
+
+        EnumSet<SampleFetchOption> fetchOptions =
+                EnumSet.of(SampleFetchOption.PROPERTIES, SampleFetchOption.METAPROJECTS);
+        List<Sample> samples =
+                generalInformationService.searchForSamples(sessionToken, searchCriteria,
+                        fetchOptions);
+
+        assertEntities("[/CISD/3V-125, /CISD/3V-126, /CISD/DP1-A, /CISD/DP1-B, /CISD/DP2-A, /DP]",
+                samples);
+        assertEquals(fetchOptions, samples.get(0).getRetrievedFetchOptions());
+        assertEquals("3V-125", samples.get(0).getCode());
+        assertEquals("CISD", samples.get(0).getSpaceCode());
+        assertEquals(979L, samples.get(0).getId().longValue());
+        assertEquals("200811050945092-976", samples.get(0).getPermId());
+        assertEquals("DILUTION_PLATE", samples.get(0).getSampleTypeCode());
+        assertEquals(2L, samples.get(0).getSampleTypeId().longValue());
+        assertEquals("test", samples.get(0).getRegistrationDetails().getUserId());
+        assertEquals("John", samples.get(0).getRegistrationDetails().getUserFirstName());
+        assertEquals("Doe", samples.get(0).getRegistrationDetails().getUserLastName());
+        assertEquals("franz-josef.elmer@systemsx.ch", samples.get(0).getRegistrationDetails()
+                .getUserEmail());
+        assertEquals("{OFFSET=49}", samples.get(0).getProperties().toString());
+        assertEquals(1, samples.get(0).getMetaprojects().size());
+
+        Metaproject metaproject = samples.get(0).getMetaprojects().get(0);
+        assertEquals(3l, metaproject.getId().longValue());
+        assertEquals("ANOTHER_TEST_METAPROJECTS", metaproject.getName());
+        assertEquals("Another example metaproject", metaproject.getDescription());
+        assertTrue(metaproject.isPrivate());
+        assertNotNull(metaproject.getCreationDate());
+
+        loginAsObserver();
+        samples =
+                generalInformationService.searchForSamples(sessionToken, searchCriteria,
+                        fetchOptions);
+
+        assertEntities("[]", samples);
+    }
+
     @Test
     public void testSearchForSamplesWithParents()
     {
diff --git a/openbis/sourceTest/sql/postgresql/124/042=metaproject_assignments_all.tsv b/openbis/sourceTest/sql/postgresql/124/042=metaproject_assignments_all.tsv
index c405d1ac7c8..ca14a3027cc 100644
--- a/openbis/sourceTest/sql/postgresql/124/042=metaproject_assignments_all.tsv
+++ b/openbis/sourceTest/sql/postgresql/124/042=metaproject_assignments_all.tsv
@@ -11,3 +11,4 @@
 11	1	\N	978	\N	\N	3	2012-09-05 10:18:10.581+02
 12	1	\N	\N	2	\N	1	2012-09-05 10:18:10.581+02
 13	3	4	\N	\N	\N	\N	2012-09-05 10:18:10.581+02
+14	3	\N	979	\N	\N	\N	2012-09-05 10:18:10.581+02
diff --git a/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/DataSetFetchOption.java b/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/DataSetFetchOption.java
index ece756283d3..a0f02bab4b1 100644
--- a/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/DataSetFetchOption.java
+++ b/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/DataSetFetchOption.java
@@ -26,6 +26,6 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.FetchOption;
 public enum DataSetFetchOption implements FetchOption
 {
 
-    BASIC, PROPERTIES, PROPERTIES_OF_PROPERTIES, PARENTS, CHILDREN, CONTAINED
+    BASIC, PROPERTIES, PROPERTIES_OF_PROPERTIES, PARENTS, CHILDREN, CONTAINED, METAPROJECTS
 
 }
diff --git a/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/Sample.java b/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/Sample.java
index adb2f442f3a..90fe02f3fc2 100644
--- a/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/Sample.java
+++ b/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/Sample.java
@@ -35,6 +35,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import ch.systemsx.cisd.base.annotation.JsonObject;
 import ch.systemsx.cisd.openbis.generic.shared.basic.IIdHolder;
 import ch.systemsx.cisd.openbis.generic.shared.basic.IIdentifierHolder;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
 
 /**
  * Immutable value object representing a sample.
@@ -94,6 +95,8 @@ public final class Sample implements Serializable, IIdentifierHolder, IIdHolder
 
         private HashMap<String, String> properties = new HashMap<String, String>();
 
+        private List<Metaproject> metaprojects = new ArrayList<Metaproject>();
+
         private EntityRegistrationDetails registrationDetails;
 
         private EnumSet<SampleFetchOption> retrievedFetchOptions = EnumSet
@@ -199,6 +202,16 @@ public final class Sample implements Serializable, IIdentifierHolder, IIdHolder
             properties.put(propCode, value);
         }
 
+        public List<Metaproject> getMetaprojects()
+        {
+            return metaprojects;
+        }
+
+        public void addMetaproject(Metaproject metaproject)
+        {
+            metaprojects.add(metaproject);
+        }
+
         public void setRegistrationDetails(EntityRegistrationDetails registrationDetails)
         {
             this.registrationDetails = registrationDetails;
@@ -297,6 +310,8 @@ public final class Sample implements Serializable, IIdentifierHolder, IIdHolder
 
     private boolean isStub;
 
+    private List<Metaproject> metaprojects;
+
     /**
      * Creates a new instance with the provided initializer
      * 
@@ -338,6 +353,8 @@ public final class Sample implements Serializable, IIdentifierHolder, IIdHolder
 
             this.properties = initializer.getProperties();
 
+            this.metaprojects = initializer.getMetaprojects();
+
             InitializingChecks.checkValidRegistrationDetails(initializer.getRegistrationDetails(),
                     "Unspecified entity registration details.");
             this.registrationDetails = initializer.getRegistrationDetails();
@@ -435,6 +452,19 @@ public final class Sample implements Serializable, IIdentifierHolder, IIdHolder
         }
     }
 
+    @JsonIgnore
+    public List<Metaproject> getMetaprojects() throws IllegalArgumentException
+    {
+        if (getRetrievedFetchOptions().contains(SampleFetchOption.METAPROJECTS))
+        {
+            return Collections.unmodifiableList(metaprojects);
+        } else
+        {
+            throw new IllegalArgumentException("Metaprojects were not retrieved for sample "
+                    + getIdentifier() + ".");
+        }
+    }
+
     /**
      * Return the sample registration details.
      * 
@@ -638,6 +668,18 @@ public final class Sample implements Serializable, IIdentifierHolder, IIdHolder
         this.properties = properties;
     }
 
+    @JsonProperty("metaprojects")
+    public List<Metaproject> getMetaprojectsJson()
+    {
+        return retrievedFetchOptions.contains(SampleFetchOption.METAPROJECTS) ? metaprojects : null;
+    }
+
+    @JsonProperty("metaprojects")
+    private void setMetaprojectsJson(List<Metaproject> metaprojects)
+    {
+        this.metaprojects = metaprojects;
+    }
+
     private void setRegistrationDetails(EntityRegistrationDetails registrationDetails)
     {
         this.registrationDetails = registrationDetails;
diff --git a/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/SampleFetchOption.java b/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/SampleFetchOption.java
index db2483b08f4..0c26e79b41f 100644
--- a/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/SampleFetchOption.java
+++ b/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/SampleFetchOption.java
@@ -17,7 +17,6 @@
 package ch.systemsx.cisd.openbis.generic.shared.api.v1.dto;
 
 import ch.systemsx.cisd.base.annotation.JsonObject;
-
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.FetchOption;
 
@@ -30,7 +29,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.FetchOption;
  * @author Franz-Josef Elmer
  */
 @JsonObject("SampleFetchOption")
-public enum SampleFetchOption implements FetchOption  
+public enum SampleFetchOption implements FetchOption
 {
     /**
      * Samples will have only basic attributes (id, code, type, space code, experiment identifier,
@@ -48,7 +47,7 @@ public enum SampleFetchOption implements FetchOption
     /**
      * Samples contain also their children samples.
      */
-    CHILDREN, 
+    CHILDREN,
     /**
      * Ask for all ancestors.
      */
@@ -60,5 +59,9 @@ public enum SampleFetchOption implements FetchOption
     /**
      * Ask for contained samples. This is not supported in search operations
      */
-    CONTAINED
+    CONTAINED,
+    /**
+     * Ask for metaprojects this sample belongs to.
+     */
+    METAPROJECTS
 }
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/ProteomicsDataServiceInternal.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/ProteomicsDataServiceInternal.java
index a0adeed4e49..1acd4f96b82 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/ProteomicsDataServiceInternal.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/ProteomicsDataServiceInternal.java
@@ -17,6 +17,7 @@
 package ch.systemsx.cisd.openbis.plugin.proteomics.server;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -32,8 +33,8 @@ import ch.systemsx.cisd.openbis.generic.server.AbstractServer;
 import ch.systemsx.cisd.openbis.generic.server.authorization.annotation.AuthorizationGuard;
 import ch.systemsx.cisd.openbis.generic.server.authorization.annotation.ReturnValueFilter;
 import ch.systemsx.cisd.openbis.generic.server.authorization.annotation.RolesAllowed;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.DataSetCodeCollectionPredicate;
 import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.AbstractTechIdPredicate.ExperimentTechIdPredicate;
+import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.DataSetCodeCollectionPredicate;
 import ch.systemsx.cisd.openbis.generic.server.authorization.validator.ExperimentValidator;
 import ch.systemsx.cisd.openbis.generic.server.authorization.validator.IValidator;
 import ch.systemsx.cisd.openbis.generic.server.business.IPropertiesBatchManager;
@@ -48,6 +49,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Code;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataStoreServiceKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
@@ -55,11 +57,13 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataStoreServicePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectAssignmentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.translator.DataSetTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.ExperimentTranslator;
+import ch.systemsx.cisd.openbis.generic.shared.translator.MetaprojectTranslator;
 import ch.systemsx.cisd.openbis.plugin.proteomics.server.authorization.validator.ParentSampleValidator;
 import ch.systemsx.cisd.openbis.plugin.proteomics.server.authorization.validator.RawDataSampleValidator;
 import ch.systemsx.cisd.openbis.plugin.proteomics.server.business.ExperimentLoader;
@@ -177,7 +181,7 @@ public class ProteomicsDataServiceInternal extends AbstractServer<IProteomicsDat
     @ReturnValueFilter(validatorClass = ExperimentValidator.class)
     public List<Experiment> listExperiments(String sessionToken, String experimentTypeCode)
     {
-        checkSession(sessionToken);
+        Session session = getSession(sessionToken);
 
         IDAOFactory daoFactory = getDAOFactory();
         IEntityTypeDAO entityTypeDAO = daoFactory.getEntityTypeDAO(EntityKind.EXPERIMENT);
@@ -185,7 +189,12 @@ public class ProteomicsDataServiceInternal extends AbstractServer<IProteomicsDat
                 (ExperimentTypePE) entityTypeDAO.tryToFindEntityTypeByCode(experimentTypeCode);
         List<ExperimentPE> experiments =
                 daoFactory.getExperimentDAO().listExperimentsWithProperties(type, null, null);
-        return ExperimentTranslator.translate(experiments, "");
+        final Collection<MetaprojectAssignmentPE> assignmentPEs =
+                getDAOFactory().getMetaprojectDAO().listMetaprojectAssignmentsForEntities(
+                        session.tryGetPerson(), experiments, EntityKind.EXPERIMENT);
+        Map<Long, Set<Metaproject>> assignments =
+                MetaprojectTranslator.translateMetaprojectAssignments(assignmentPEs);
+        return ExperimentTranslator.translate(experiments, "", assignments);
     }
 
     @Override
@@ -198,7 +207,12 @@ public class ProteomicsDataServiceInternal extends AbstractServer<IProteomicsDat
 
         IDataSetTable dataSetTable = commonBoFactory.createDataSetTable(session);
         dataSetTable.loadByExperimentTechId(experimentID);
-        return DataSetTranslator.translate(dataSetTable.getDataSets(), "", "");
+        List<DataPE> dataSetPEs = dataSetTable.getDataSets();
+        Collection<MetaprojectAssignmentPE> assignmentPEs =
+                getDAOFactory().getMetaprojectDAO().listMetaprojectAssignmentsForEntities(
+                        session.tryGetPerson(), dataSetPEs, EntityKind.DATA_SET);
+        return DataSetTranslator.translate(dataSetPEs, "", "",
+                MetaprojectTranslator.translateMetaprojectAssignments(assignmentPEs));
     }
 
     @Override
@@ -222,7 +236,7 @@ public class ProteomicsDataServiceInternal extends AbstractServer<IProteomicsDat
                         + " [" + experiment.getIdentifier() + "] is not of type " + experimentType
                         + " but of type " + actualExperimentTypeCode + ".");
             }
-            Experiment translatedExperiment = ExperimentTranslator.translate(experiment, "");
+            Experiment translatedExperiment = ExperimentTranslator.translate(experiment, "", null);
             if (EXPERIMENT_VALIDATOR.isValid(person, translatedExperiment))
             {
                 List<DataPE> dataSets = dataSetDAO.listDataSets(experiment);
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/business/ExperimentLoader.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/business/ExperimentLoader.java
index 5c1e6c49cc3..cba31196ff7 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/business/ExperimentLoader.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/business/ExperimentLoader.java
@@ -30,8 +30,6 @@ import ch.systemsx.cisd.openbis.generic.shared.translator.ExperimentTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.ExperimentTranslator.LoadableFields;
 
 /**
- * 
- *
  * @author Franz-Josef Elmer
  */
 public class ExperimentLoader
@@ -41,9 +39,9 @@ public class ExperimentLoader
     public ExperimentLoader(IDAOFactory daoFactory)
     {
         this.daoFactory = daoFactory;
-        
+
     }
-    
+
     public void enrichWithExperiments(Collection<Sample> samples)
     {
         Map<Long, List<Sample>> samplesByID = new LinkedHashMap<Long, List<Sample>>();
@@ -66,7 +64,8 @@ public class ExperimentLoader
                 daoFactory.getExperimentDAO().listExperimentsWithProperties(samplesByID.keySet());
         for (ExperimentPE experiment : experiments)
         {
-            Experiment e = ExperimentTranslator.translate(experiment, "", LoadableFields.PROPERTIES);
+            Experiment e =
+                    ExperimentTranslator.translate(experiment, "", null, LoadableFields.PROPERTIES);
             List<Sample> list = samplesByID.get(experiment.getId());
             for (Sample sample : list)
             {
diff --git a/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/business/ExperimentLoaderTest.java b/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/business/ExperimentLoaderTest.java
index 4a92d677da4..12cc28d0cfc 100644
--- a/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/business/ExperimentLoaderTest.java
+++ b/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/proteomics/server/business/ExperimentLoaderTest.java
@@ -28,11 +28,8 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.translator.SampleTranslator;
-import ch.systemsx.cisd.openbis.plugin.proteomics.server.business.ExperimentLoader;
 
 /**
- * 
- *
  * @author Franz-Josef Elmer
  */
 @Test(groups = "db")
@@ -43,9 +40,9 @@ public class ExperimentLoaderTest extends AbstractLoaderTestCase
     {
         ExperimentLoader loader = new ExperimentLoader(daoFactory);
         List<Sample> samples = loadSamples(980L, 981L, 986L);
-        
+
         loader.enrichWithExperiments(samples);
-        
+
         StringBuilder builder = new StringBuilder();
         for (Sample sample : samples)
         {
@@ -58,20 +55,19 @@ public class ExperimentLoaderTest extends AbstractLoaderTestCase
             }
             builder.append('\n');
         }
-        assertEquals("980 3V-126\n" 
-                   + "981 DP\n"
-                   + "986 3VCP5: EXP10 [DESCRIPTION: A simple experiment, GENDER: MALE]\n",
+        assertEquals("980 3V-126\n" + "981 DP\n"
+                + "986 3VCP5: EXP10 [DESCRIPTION: A simple experiment, GENDER: MALE]\n",
                 builder.toString());
     }
-    
+
     private List<Sample> loadSamples(Long... ids)
     {
         ISampleDAO sampleDAO = daoFactory.getSampleDAO();
         List<Sample> list = new ArrayList<Sample>();
         for (Long id : ids)
         {
-            list.add(SampleTranslator.translate(sampleDAO.tryGetByTechId(new TechId(id)), ""));
-   
+            list.add(SampleTranslator.translate(sampleDAO.tryGetByTechId(new TechId(id)), "", null));
+
         }
         return list;
     }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/LogicalImageLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/LogicalImageLoader.java
index 97bc5de618e..20e520e655f 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/LogicalImageLoader.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/LogicalImageLoader.java
@@ -223,6 +223,6 @@ public class LogicalImageLoader
 
     private ExternalData translate(DataPE dataSet)
     {
-        return DataSetTranslator.translate(dataSet, session.getBaseIndexURL());
+        return DataSetTranslator.translate(dataSet, session.getBaseIndexURL(), null);
     }
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateContentLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateContentLoader.java
index f1cc4064865..b186c7e7a72 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateContentLoader.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateContentLoader.java
@@ -390,7 +390,7 @@ public class PlateContentLoader
 
     private Sample translate(SamplePE sample)
     {
-        return SampleTranslator.translate(sample, session.getBaseIndexURL());
+        return SampleTranslator.translate(sample, session.getBaseIndexURL(), null);
     }
 
     private List<WellMetadata> loadWells(TechId plateId)
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java
index 9a25d00294a..010d7760d61 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java
@@ -442,7 +442,7 @@ public class ScreeningApiImpl
             SampleIdentifier sampleIdentifier = createSampleIdentifier(plateIdentifier);
             ISampleBO sampleBO = businessObjectFactory.createSampleBO(session);
             sampleBO.loadBySampleIdentifier(sampleIdentifier);
-            sample = SampleTranslator.translate(sampleBO.getSample(), "");
+            sample = SampleTranslator.translate(sampleBO.getSample(), "", null);
         }
         return sample;
     }
@@ -474,7 +474,7 @@ public class ScreeningApiImpl
 
     private Sample translate(SamplePE sample)
     {
-        return SampleTranslator.translate(sample, session.getBaseIndexURL());
+        return SampleTranslator.translate(sample, session.getBaseIndexURL(), null);
     }
 
     private static SampleIdentifier createSampleIdentifier(PlateIdentifier plate)
@@ -954,8 +954,9 @@ public class ScreeningApiImpl
                     if (apiMaterial == null)
                     {
                         apiMaterial = asApiMaterial(material, materialsCache);
-                        // FIXME: Caching disabled because a not fully filled Material could be cached
-//                        materialsCache.put(material.getId(), apiMaterial);
+                        // FIXME: Caching disabled because a not fully filled Material could be
+                        // cached
+                        // materialsCache.put(material.getId(), apiMaterial);
                     }
                     String propCode = property.getPropertyType().getCode();
                     result.put(propCode, apiMaterial);
@@ -966,14 +967,16 @@ public class ScreeningApiImpl
     }
 
     private Material asApiMaterial(
-            ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material materialDto,  Map<Long, Material> materialsCache)
+            ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material materialDto,
+            Map<Long, Material> materialsCache)
     {
         MaterialTypeIdentifier typeIdentifier =
                 new MaterialTypeIdentifier(materialDto.getMaterialType().getCode());
 
         List<IEntityProperty> originalProperties = materialDto.getProperties();
         Map<String, String> properties = EntityHelper.convertToStringMap(originalProperties);
-        Map<String, Material> materialProperties = convertMaterialProperties(originalProperties, materialsCache);
+        Map<String, Material> materialProperties =
+                convertMaterialProperties(originalProperties, materialsCache);
 
         return new Material(typeIdentifier, materialDto.getCode(), properties, materialProperties);
     }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningUtils.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningUtils.java
index 5dcc9255939..9f809a96e20 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningUtils.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningUtils.java
@@ -67,7 +67,7 @@ public class ScreeningUtils
         String dataTypeCode = dataset.getDataSetType().getCode();
         String fileTypeCode = null;
         Experiment experiment =
-                ExperimentTranslator.translate(dataset.getExperiment(), baseIndexURL);
+                ExperimentTranslator.translate(dataset.getExperiment(), baseIndexURL, null);
         String analysisProcedureOrNull =
                 EntityHelper.tryFindPropertyValue(dataset, ScreeningConstants.ANALYSIS_PROCEDURE);
         return createDatasetReference(dataset.getId(), dataset.getCode(), analysisProcedureOrNull,
-- 
GitLab