diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/AbstractExternalDataGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/AbstractExternalDataGrid.java
index a035f65eec07161a25a45d85b17d130678d34f28..dfa4411338e60c01cc41d9c87648232285998b30 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/AbstractExternalDataGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/AbstractExternalDataGrid.java
@@ -62,6 +62,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ISerializableComparable;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRowWithObject;
 
 /**
@@ -86,31 +87,43 @@ public abstract class AbstractExternalDataGrid extends AbstractEntityGrid<Abstra
 
     private void linkProject()
     {
-        registerListenerAndLinkGenerator(ExternalDataGridColumnIDs.PROJECT,
-                new ICellListenerAndLinkGenerator<AbstractExternalData>()
-                    {
-                        @Override
-                        public void handle(TableModelRowWithObject<AbstractExternalData> rowItem,
-                                boolean specialKeyPressed)
-                        {
-                            Experiment experiment = rowItem.getObjectOrNull().getExperiment();
-                            if (experiment != null)
-                            {
-                                final Project project = experiment.getProject();
-                                final String href = LinkExtractor.tryExtract(project);
-                                OpenEntityDetailsTabHelper.open(viewContext, project,
-                                        specialKeyPressed, href);
-                            }
-                        }
+        ICellListenerAndLinkGenerator<AbstractExternalData> listenerAndLinkGenerator = new ICellListenerAndLinkGenerator<AbstractExternalData>()
+            {
+                @Override
+                public void handle(TableModelRowWithObject<AbstractExternalData> rowItem,
+                        boolean specialKeyPressed)
+                {
+                    Project project = tryGetProject(rowItem.getObjectOrNull());
+                    final String href = LinkExtractor.tryExtract(project);
+                    OpenEntityDetailsTabHelper.open(viewContext, project,
+                            specialKeyPressed, href);
+                }
+                
+                @Override
+                public String tryGetLink(AbstractExternalData entity,
+                        ISerializableComparable comparableValue)
+                {
+                    Project project = tryGetProject(entity);
+                    return project == null ? null : LinkExtractor.tryExtract(project);
+                }
 
-                        @Override
-                        public String tryGetLink(AbstractExternalData entity,
-                                ISerializableComparable comparableValue)
-                        {
-                            final Experiment exp = entity.getExperiment();
-                            return exp == null ? null : LinkExtractor.tryExtract(exp.getProject());
-                        }
-                    });
+                private Project tryGetProject(AbstractExternalData dataSet)
+                {
+                    Experiment experiment = dataSet.getExperiment();
+                    Sample sample = dataSet.getSample();
+                    Project project = null;
+                    if (experiment != null)
+                    {
+                        project = experiment.getProject();
+                    } else if (sample != null)
+                    {
+                        project = sample.getProject();
+                    }
+                    return project;
+                }
+            };
+        registerListenerAndLinkGenerator(ExternalDataGridColumnIDs.PROJECT, listenerAndLinkGenerator);
+        registerListenerAndLinkGenerator(ExternalDataGridColumnIDs.PROJECT_IDENTIFIER, listenerAndLinkGenerator);
     }
 
     @Override
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserGrid.java
index 9ac13c78ab0aa475aface8d179e8f52f3a98dac9..3d2e1d33fafcdd76d4e7985aaccbe63116cdb389 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserGrid.java
@@ -228,26 +228,27 @@ public class ExperimentBrowserGrid extends AbstractEntityGrid<Experiment>
 
     private void linkProject()
     {
-        registerListenerAndLinkGenerator(ExperimentBrowserGridColumnIDs.PROJECT,
-                new ICellListenerAndLinkGenerator<Experiment>()
-                    {
-                        @Override
-                        public void handle(TableModelRowWithObject<Experiment> rowItem,
-                                boolean specialKeyPressed)
-                        {
-                            final Project project = rowItem.getObjectOrNull().getProject();
-                            final String href = LinkExtractor.tryExtract(project);
-                            OpenEntityDetailsTabHelper.open(viewContext, project,
-                                    specialKeyPressed, href);
-                        }
+        ICellListenerAndLinkGenerator<Experiment> listenerAndLinkGenerator = new ICellListenerAndLinkGenerator<Experiment>()
+            {
+                @Override
+                public void handle(TableModelRowWithObject<Experiment> rowItem,
+                        boolean specialKeyPressed)
+                {
+                    final Project project = rowItem.getObjectOrNull().getProject();
+                    final String href = LinkExtractor.tryExtract(project);
+                    OpenEntityDetailsTabHelper.open(viewContext, project,
+                            specialKeyPressed, href);
+                }
 
-                        @Override
-                        public String tryGetLink(Experiment entity,
-                                ISerializableComparable comparableValue)
-                        {
-                            return LinkExtractor.tryExtract(entity.getProject());
-                        }
-                    });
+                @Override
+                public String tryGetLink(Experiment entity,
+                        ISerializableComparable comparableValue)
+                {
+                    return LinkExtractor.tryExtract(entity.getProject());
+                }
+            };
+        registerListenerAndLinkGenerator(ExperimentBrowserGridColumnIDs.PROJECT, listenerAndLinkGenerator);
+        registerListenerAndLinkGenerator(ExperimentBrowserGridColumnIDs.PROJECT_IDENTIFIER, listenerAndLinkGenerator);
     }
 
     private void extendBottomToolbar()
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserGrid.java
index d690607b74742ae56c9472d270219a2b9da5847b..47e5dbd91503d57ef7a6f5c29dfc0edbe16949af 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserGrid.java
@@ -380,39 +380,40 @@ public class SampleBrowserGrid extends AbstractEntityGrid<Sample>
 
     private void linkProject()
     {
-        registerListenerAndLinkGenerator(SampleGridColumnIDs.PROJECT,
-                new ICellListenerAndLinkGenerator<Sample>()
+        ICellListenerAndLinkGenerator<Sample> listenerAndLinkGenerator = new ICellListenerAndLinkGenerator<Sample>()
+            {
+                @Override
+                public void handle(TableModelRowWithObject<Sample> rowItem,
+                        boolean specialKeyPressed)
+                {
+                    Project project =
+                            rowItem.getObjectOrNull().getProject();
+                    if (project == null)
                     {
-                        @Override
-                        public void handle(TableModelRowWithObject<Sample> rowItem,
-                                boolean specialKeyPressed)
-                        {
-                            Project project =
-                                    rowItem.getObjectOrNull().getProject();
-                            if (project == null)
-                            {
-                                project = rowItem.getObjectOrNull().getExperiment().getProject();
-                            }
-                            final String href = LinkExtractor.tryExtract(project);
-                            OpenEntityDetailsTabHelper.open(viewContext, project,
-                                    specialKeyPressed, href);
-                        }
+                        project = rowItem.getObjectOrNull().getExperiment().getProject();
+                    }
+                    final String href = LinkExtractor.tryExtract(project);
+                    OpenEntityDetailsTabHelper.open(viewContext, project,
+                            specialKeyPressed, href);
+                }
 
-                        @Override
-                        public String tryGetLink(Sample entity,
-                                ISerializableComparable comparableValue)
-                        {
-                            final Project proj = entity.getProject();
-                            if (proj == null)
-                            {
-                                final Experiment exp = entity.getExperiment();
-                                return exp == null ? null : LinkExtractor.tryExtract(exp.getProject());
-                            } else
-                            {
-                                return LinkExtractor.tryExtract(proj);
-                            }
-                        }
-                    });
+                @Override
+                public String tryGetLink(Sample entity,
+                        ISerializableComparable comparableValue)
+                {
+                    final Project proj = entity.getProject();
+                    if (proj == null)
+                    {
+                        final Experiment exp = entity.getExperiment();
+                        return exp == null ? null : LinkExtractor.tryExtract(exp.getProject());
+                    } else
+                    {
+                        return LinkExtractor.tryExtract(proj);
+                    }
+                }
+            };
+        registerListenerAndLinkGenerator(SampleGridColumnIDs.PROJECT, listenerAndLinkGenerator);
+        registerListenerAndLinkGenerator(SampleGridColumnIDs.PROJECT_IDENTIFIER, listenerAndLinkGenerator);
     }
 
     @Override
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ExperimentBrowserGridColumnIDs.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ExperimentBrowserGridColumnIDs.java
index 6285a09b47ec81ca2845bef58e50a1f94f6afaad..139ec3a77a76ec641bfaf730bb9253a1bb9a3006 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ExperimentBrowserGridColumnIDs.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ExperimentBrowserGridColumnIDs.java
@@ -33,6 +33,8 @@ public class ExperimentBrowserGridColumnIDs
 
     public static final String PROJECT = "PROJECT";
 
+    public static final String PROJECT_IDENTIFIER = "PROJECT_IDENTIFIER";
+
     public static final String REGISTRATOR = "REGISTRATOR";
 
     public static final String REGISTRATION_DATE = "REGISTRATION_DATE";
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ExternalDataGridColumnIDs.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ExternalDataGridColumnIDs.java
index 1617bc131b8c6fe1f3b0b9d348322fef76944b05..4f86d57390467277d7cc9047009c8fe835f53971 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ExternalDataGridColumnIDs.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ExternalDataGridColumnIDs.java
@@ -51,6 +51,8 @@ public class ExternalDataGridColumnIDs
     public static final String EXPERIMENT_TYPE = "EXPERIMENT_TYPE";
 
     public static final String PROJECT = "PROJECT";
+    
+    public static final String PROJECT_IDENTIFIER = "PROJECT_IDENTIFIER";
 
     public static final String REGISTRATOR = "REGISTRATOR";
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/SampleGridColumnIDs.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/SampleGridColumnIDs.java
index 411516aaf40c08fb16ac7251a904abe9beec4280..4f937cb25d2ae4e857c01543c1b109845bce2b0e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/SampleGridColumnIDs.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/SampleGridColumnIDs.java
@@ -51,6 +51,8 @@ public class SampleGridColumnIDs
 
     public static final String PROJECT = "PROJECT";
 
+    public static final String PROJECT_IDENTIFIER = "PROJECT_IDENTIFIER";
+
     public static final String PERM_ID = "PERM_ID";
 
     public static final String SHOW_DETAILS_LINK_COLUMN_NAME = "SHOW_DETAILS_LINK";
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/AbstractExternalDataProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/AbstractExternalDataProvider.java
index ca8c5b770a51e98a2ee9dd6d5288bb3107066d14..96452a9d8ef2c85f474fc648c6be86afa3422b4c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/AbstractExternalDataProvider.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/AbstractExternalDataProvider.java
@@ -42,6 +42,7 @@ import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExternalDat
 import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExternalDataGridColumnIDs.PRESENT_IN_ARCHIVE;
 import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExternalDataGridColumnIDs.PRODUCTION_DATE;
 import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExternalDataGridColumnIDs.PROJECT;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExternalDataGridColumnIDs.PROJECT_IDENTIFIER;
 import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExternalDataGridColumnIDs.PROPERTIES_PREFIX;
 import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExternalDataGridColumnIDs.REGISTRATION_DATE;
 import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExternalDataGridColumnIDs.REGISTRATOR;
@@ -70,6 +71,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.LinkDataSet;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.LinkDataSetUrl;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.LinkTableCell;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PhysicalDataSet;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TypedTableModel;
@@ -106,6 +108,7 @@ public abstract class AbstractExternalDataProvider extends
                 .hideByDefault();
         builder.addColumn(EXPERIMENT_TYPE).withDefaultWidth(120).hideByDefault();
         builder.addColumn(PROJECT);
+        builder.addColumn(PROJECT_IDENTIFIER);
         builder.addColumn(REGISTRATOR);
         builder.addColumn(MODIFIER);
         builder.addColumn(REGISTRATION_DATE).withDefaultWidth(200);
@@ -177,6 +180,7 @@ public abstract class AbstractExternalDataProvider extends
                             sample.getIdentifier());
                     SampleType sampleType = dataSet.getSampleType();
                     builder.column(SAMPLE_TYPE).addString(sampleType.getCode());
+                    addProject(builder, sample.getProject());
                 }
                 Experiment experiment = dataSet.getExperiment();
                 if (experiment != null)
@@ -185,7 +189,10 @@ public abstract class AbstractExternalDataProvider extends
                     builder.column(EXTERNAL_DATA_EXPERIMENT_IDENTIFIER).addEntityLink(experiment,
                             experiment.getIdentifier());
                     builder.column(EXPERIMENT_TYPE).addString(experiment.getEntityType().getCode());
-                    builder.column(PROJECT).addString(experiment.getProject().getCode());
+                    if (sample == null)
+                    {
+                        addProject(builder, experiment.getProject());
+                    }
                 }
                 builder.column(REGISTRATOR).addPerson(dataSet.getRegistrator());
                 builder.column(MODIFIER).addPerson(dataSet.getModifier());
@@ -232,6 +239,15 @@ public abstract class AbstractExternalDataProvider extends
         return builder.getModel();
     }
 
+    private void addProject(TypedTableModelBuilder<AbstractExternalData> builder, Project project)
+    {
+        if (project != null)
+        {
+            builder.column(PROJECT).addString(project.getCode());
+            builder.column(PROJECT_IDENTIFIER).addString(project.getIdentifier());
+        }
+    }
+
     private TableMap<String, DataSetType> getDataSetTypes()
     {
         List<DataSetType> dataSetTypes = commonServer.listDataSetTypes(sessionToken);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/ExperimentProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/ExperimentProvider.java
index 69dfc5384d3e7551a654e7797c2fa0353a38202c..29283863baf6d74668255f7d8937c03605d5ce96 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/ExperimentProvider.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/ExperimentProvider.java
@@ -25,6 +25,7 @@ import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExperimentB
 import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExperimentBrowserGridColumnIDs.METAPROJECTS;
 import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExperimentBrowserGridColumnIDs.PERM_ID;
 import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExperimentBrowserGridColumnIDs.PROJECT;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExperimentBrowserGridColumnIDs.PROJECT_IDENTIFIER;
 import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExperimentBrowserGridColumnIDs.REGISTRATION_DATE;
 import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExperimentBrowserGridColumnIDs.REGISTRATOR;
 import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExperimentBrowserGridColumnIDs.SHOW_DETAILS_LINK;
@@ -93,6 +94,7 @@ public class ExperimentProvider extends AbstractCommonTableModelProvider<Experim
         builder.addColumn(EXPERIMENT_IDENTIFIER).hideByDefault().withDefaultWidth(150);
         builder.addColumn(SPACE).hideByDefault();
         builder.addColumn(PROJECT).hideByDefault();
+        builder.addColumn(PROJECT_IDENTIFIER).hideByDefault();
         builder.addColumn(REGISTRATOR);
         builder.addColumn(MODIFIER);
         builder.addColumn(REGISTRATION_DATE).withDefaultWidth(200);
@@ -117,6 +119,7 @@ public class ExperimentProvider extends AbstractCommonTableModelProvider<Experim
                         experiment.getIdentifier());
                 builder.column(SPACE).addString(experiment.getProject().getSpace().getCode());
                 builder.column(PROJECT).addString(experiment.getProject().getCode());
+                builder.column(PROJECT_IDENTIFIER).addString(experiment.getProject().getIdentifier());
                 builder.column(REGISTRATOR).addPerson(experiment.getRegistrator());
                 builder.column(MODIFIER).addPerson(experiment.getModifier());
                 builder.column(REGISTRATION_DATE).addDate(experiment.getRegistrationDate());
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/SampleProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/SampleProvider.java
index 3cc81e908177cdf8ffd9a752e0bb99e4ef19c5a2..c73bcf22df4028135c25b956ae3d32dd21c0c8be 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/SampleProvider.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/SampleProvider.java
@@ -28,6 +28,7 @@ import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridC
 import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.PARENTS;
 import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.PERM_ID;
 import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.PROJECT;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.PROJECT_IDENTIFIER;
 import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.PROPERTIES_PREFIX;
 import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.REGISTRATION_DATE;
 import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.REGISTRATOR;
@@ -87,6 +88,7 @@ public class SampleProvider extends AbstractCommonTableModelProvider<Sample>
         builder.addColumn(EXPERIMENT);
         builder.addColumn(EXPERIMENT_IDENTIFIER).withDefaultWidth(200).hideByDefault();
         builder.addColumn(PROJECT);
+        builder.addColumn(PROJECT_IDENTIFIER);
         builder.addColumn(PERM_ID).hideByDefault();
         builder.addColumn(SHOW_DETAILS_LINK_COLUMN_NAME).hideByDefault();
         builder.addColumn(PARENTS);
@@ -130,7 +132,7 @@ public class SampleProvider extends AbstractCommonTableModelProvider<Sample>
                     builder.column(EXPERIMENT_IDENTIFIER).addEntityLink(experiment,
                             experiment.getIdentifier());
                 }
-                builder.column(PROJECT).addString(getProjectCode(sample));
+                addProject(builder, sample);
                 builder.column(PERM_ID).addString(sample.getPermId());
                 builder.column(SHOW_DETAILS_LINK_COLUMN_NAME).addString(sample.getPermlink());
                 builder.column(PARENTS).addEntityLink(sample.getParents());
@@ -170,14 +172,22 @@ public class SampleProvider extends AbstractCommonTableModelProvider<Sample>
         return sampleTypMap;
     }
 
-    private String getProjectCode(Sample sample)
+    private void addProject(TypedTableModelBuilder<Sample> builder, Sample sample)
     {
         Project project = sample.getProject();
-        if (project == null) {
+        if (project == null)
+        {
             Experiment experiment = sample.getExperiment();
-            return experiment == null ? "" : experiment.getProject().getCode();
-        } else {
-            return project.getCode();
+            if (experiment != null)
+            {
+                project = experiment.getProject();
+            }
+        }
+        if (project != null)
+        {
+            builder.column(PROJECT).addString(project.getCode());
+            builder.column(PROJECT_IDENTIFIER).addString(project.getIdentifier());
+            
         }
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractDataSetBusinessObject.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractDataSetBusinessObject.java
index 89e171bc16f52f6042809271298ac6b73f18acd7..781dad63bc80b19b64976060a65971aa7b06c4b7 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractDataSetBusinessObject.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractDataSetBusinessObject.java
@@ -28,15 +28,12 @@ import java.util.Set;
 
 import ch.systemsx.cisd.common.collection.CollectionUtils;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
-import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider;
 import ch.systemsx.cisd.openbis.generic.server.business.IRelationshipService;
 import ch.systemsx.cisd.openbis.generic.server.business.IServiceConversationClientManagerLocal;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.util.DataSetTypeWithoutExperimentChecker;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityPropertiesConverter;
-import ch.systemsx.cisd.openbis.generic.shared.ResourceNames;
-import ch.systemsx.cisd.openbis.generic.shared.WebClientConfigurationProvider;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetRelationshipPE;
@@ -52,7 +49,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.managed_property.IManagedPropertyEvaluatorFactory;
 import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils;
 import ch.systemsx.cisd.openbis.generic.shared.util.RelationshipUtils;
-import ch.systemsx.cisd.openbis.generic.shared.util.WebClientConfigUtils;
 
 /**
  * @author Franz-Josef Elmer
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractSampleIdentifierBusinessObject.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractSampleIdentifierBusinessObject.java
index 9b9b7183fc489944c2b4566147bb380e396d0eb8..5a827f227c9ccbc1abf9274803a649c933f52e78 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractSampleIdentifierBusinessObject.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractSampleIdentifierBusinessObject.java
@@ -107,6 +107,9 @@ abstract class AbstractSampleIdentifierBusinessObject extends AbstractBusinessOb
             {
                 result =
                         sampleDAO.tryFindByCodeAndDatabaseInstance(sampleCode);
+            } else if (sampleOwner.isProjectLevel())
+            {
+                result = sampleDAO.tryfindByCodeAndProject(sampleCode, sampleOwner.tryGetProject());
             } else
             {
                 assert sampleOwner.isSpaceLevel() : "Must be of space level.";
@@ -115,6 +118,7 @@ abstract class AbstractSampleIdentifierBusinessObject extends AbstractBusinessOb
             if (result != null)
             {
                 HibernateUtils.initialize(result.getExperiment());
+                HibernateUtils.initialize(result.getProject());
                 sampleByIdentifierCache.put(sampleIdentifier, result);
             }
             return result;
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ISecondaryEntityListingQuery.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ISecondaryEntityListingQuery.java
index 1e7b0fa6bb773bf0a9284886a0d46eefce9b2b05..b4b24a57ec714b92637e8cfa75e785dce40b48f4 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ISecondaryEntityListingQuery.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ISecondaryEntityListingQuery.java
@@ -79,9 +79,12 @@ public interface ISecondaryEntityListingQuery extends BaseQuery
      * Returns the samples for the given ids.
      */
     @Select(sql = "select s.id as id, s.perm_id as perm_id, s.code as s_code, s.del_id as del_id, "
-            + "           st.code as st_code, g.code as spc_code, c.code as c_code"
+            + "           st.code as st_code, g.code as spc_code, c.code as c_code,"
+            + "           p.id as proj_id, p.code as proj_code, ps.code as proj_space_code"
             + "   from samples s join sample_types st on s.saty_id=st.id"
             + "                  join spaces g on s.space_id=g.id "
+            + "                  left join projects p on s.proj_id=p.id "
+            + "                  left join spaces ps on p.space_id=ps.id "
             + "                  left join samples c on s.samp_id_part_of=c.id "
             + "        where s.id = any(?{1})", parameterBindings =
     { LongSetMapper.class }, fetchSize = FETCH_SIZE)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SampleReferenceRecord.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SampleReferenceRecord.java
index ce2d15260cb3398457087d16a9a5c905f454b56e..b331e19e37c347b81fa7f0a211d3a7163a488d40 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SampleReferenceRecord.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SampleReferenceRecord.java
@@ -42,6 +42,15 @@ public class SampleReferenceRecord
     /** space code */
     public String spc_code;
 
+    /** project tech id */
+    public Long proj_id;
+    
+    /** project code */
+    public String proj_code;
+    
+    /** project space code */
+    public String proj_space_code;
+    
     /** container code */
     public String c_code;
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityDAO.java
index b1429559bd70aa0af84d7092335a9355025625cb..44e27cef917df9e1842b8e1cea2661f9be940c4d 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityDAO.java
@@ -228,7 +228,8 @@ public class SecondaryEntityDAO
         sample.setCode(IdentifierHelper.convertCode(record.s_code, record.c_code));
         sample.setSampleType(createSampleType(record.st_code, databaseInstance));
         sample.setDeletion(createDeletion(record.del_id));
-        sample.setSpace(tryCreateGroup(record.spc_code, databaseInstance));
+        sample.setSpace(tryCreateSpace(record.spc_code, databaseInstance));
+        sample.setProject(tryCreateProject(record.proj_id, record.proj_space_code, record.proj_code));
         sample.setDatabaseInstance(tryGetDatabaseInstance(record.spc_code, databaseInstance));
         sample.setPermId(record.perm_id);
         sample.setIdentifier(createIdentifier(sample).toString());
@@ -251,8 +252,22 @@ public class SecondaryEntityDAO
             return null;
         }
     }
+    
+    private static Project tryCreateProject(Long proj_id, String spaceCode, String projectCode)
+    {
+        if (projectCode == null)
+        {
+            return null;
+        }
+        Project project = new Project();
+        project.setId(proj_id);
+        project.setSpace(tryCreateSpace(spaceCode, null));
+        project.setCode(projectCode);
+        project.setIdentifier(new ProjectIdentifier(spaceCode, projectCode).toString());
+        return project;
+    }
 
-    private static Space tryCreateGroup(String codeOrNull, DatabaseInstance databaseInstance)
+    private static Space tryCreateSpace(String codeOrNull, DatabaseInstance databaseInstance)
     {
         if (codeOrNull == null)
         {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java
index 7b23ea35f9b9cc7e9d88ef6f04abfd67583bcf43..fa8cfb1f1b9e36878ae0963c33cf3a31ae165f24 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java
@@ -704,7 +704,8 @@ final class SampleListingWorker extends AbstractLister
             }
             if (row.proj_id != null)
             {
-                sample.setProject(getOrCreateProject(row));
+                Project project = getOrCreateProject(row);
+                setProject(sample, project);
             }
         }
         // prepare loading related samples
@@ -740,6 +741,12 @@ final class SampleListingWorker extends AbstractLister
         }
     }
 
+    private void setProject(final Sample sample, Project project)
+    {
+        sample.setProject(project);
+        sample.setIdentifier(IdentifierHelper.createSampleIdentifier(sample).toString());
+    }
+
     private void setSpace(final Sample sample, final Space space)
     {
         sample.setSpace(space);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/util/SampleOwner.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/util/SampleOwner.java
index 9bfd4009bda6d68e11b83fbfebbec017108a975f..cc2972af3026b56cb560bbad8bdc5dab85608413 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/util/SampleOwner.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/util/SampleOwner.java
@@ -1,24 +1,36 @@
 package ch.systemsx.cisd.openbis.generic.server.business.bo.util;
 
+import org.apache.commons.lang.builder.EqualsBuilder;
 import org.apache.commons.lang.builder.HashCodeBuilder;
 
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
 
 /**
- * Determines who is the <i>owner</i> of the sample: the space or to the database instance.
+ * Determines who is the <i>owner</i> of the sample: project, space or non
  * <p>
  * Stores the owner <i>PEs</i>.
  * </p>
  */
 public final class SampleOwner
 {
-    // if filled, databaseInstanceOrNull must be null
+    private ProjectPE projectOrNull;
     private SpacePE spaceOrNull;
+    
+    public SampleOwner(ProjectPE projectOrNull)
+    {
+        this.projectOrNull = projectOrNull;
+    }
 
     public SampleOwner(final SpacePE spaceOrNull)
     {
         this.spaceOrNull = spaceOrNull;
     }
+    
+    public static SampleOwner createProject(ProjectPE project)
+    {
+        return new SampleOwner(project);
+    }
 
     public static SampleOwner createSpace(final SpacePE group)
     {
@@ -27,17 +39,27 @@ public final class SampleOwner
 
     public static SampleOwner createDatabaseInstance()
     {
-        return new SampleOwner(null);
+        return new SampleOwner((SpacePE) null);
+    }
+    
+    public boolean isProjectLevel()
+    {
+        return projectOrNull != null;
     }
 
     public boolean isSpaceLevel()
     {
-        return spaceOrNull != null;
+        return projectOrNull == null && spaceOrNull != null;
     }
 
     public boolean isDatabaseInstanceLevel()
     {
-        return spaceOrNull == null;
+        return projectOrNull == null &&  spaceOrNull == null;
+    }
+    
+    public ProjectPE tryGetProject()
+    {
+        return projectOrNull;
     }
 
     public SpacePE tryGetSpace()
@@ -52,6 +74,10 @@ public final class SampleOwner
     @Override
     public String toString()
     {
+        if (isProjectLevel())
+        {
+            return "project: " + projectOrNull;
+        }
         if (isSpaceLevel())
         {
             return "space: " + spaceOrNull;
@@ -73,19 +99,17 @@ public final class SampleOwner
             return false;
         }
         final SampleOwner that = (SampleOwner) obj;
-        if (isSpaceLevel())
-        {
-            return this.spaceOrNull.equals(that.spaceOrNull);
-        } else
-        {
-            return that.isDatabaseInstanceLevel();
-        }
+        EqualsBuilder builder = new EqualsBuilder();
+        builder.append(projectOrNull, that.tryGetProject());
+        builder.append(spaceOrNull, that.tryGetSpace());
+        return builder.isEquals();
     }
 
     @Override
     public final int hashCode()
     {
         final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(projectOrNull);
         builder.append(spaceOrNull);
         return builder.toHashCode();
     }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/util/SampleOwnerFinder.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/util/SampleOwnerFinder.java
index c4316cc787eacf4c78435800aa4a719f54d9f228..e9a2a949617be269efae8da47066751edaf61955 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/util/SampleOwnerFinder.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/util/SampleOwnerFinder.java
@@ -21,13 +21,14 @@ import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.util.SpaceIdentifierHelper;
 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.SpacePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.exception.UndefinedSpaceException;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleOwnerIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
 
 /**
- * Finds a group or database instance for a given owner identifier.
+ * Finds a project or a space instance for a given owner identifier.
  * 
  * @author Tomasz Pylak
  */
@@ -65,9 +66,18 @@ public class SampleOwnerFinder
         } else if (owner.isSpaceLevel())
         {
             return tryFigureSampleGroupOwner(owner);
+        } else if (owner.isProjectLevel())
+        {
+            return tryFigureSampleProjectOwner(owner);
         } else
             throw InternalErr.error();
     }
+    
+    private SampleOwner tryFigureSampleProjectOwner(SampleOwnerIdentifier owner)
+    {
+        ProjectPE project = SpaceIdentifierHelper.tryGetProject(owner.getProjectLevel(), personPE, daoFactory);
+        return project == null ? null : SampleOwner.createProject(project);
+    }
 
     private SampleOwner tryFigureSampleGroupOwner(final SampleOwnerIdentifier owner)
     {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/ISampleDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/ISampleDAO.java
index 6059bd40128157739f42b7db73869479eba74e5c..3412824a0802d6d2874e2778dc9d11c2ef29a53e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/ISampleDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/ISampleDAO.java
@@ -26,6 +26,7 @@ import org.springframework.dao.DataAccessException;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DeletionPE;
 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.SamplePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
 
@@ -61,6 +62,8 @@ public interface ISampleDAO extends IGenericDAO<SamplePE>
     List<SamplePE> listByCodesAndDatabaseInstance(final List<String> sampleCodes,
             String containerCodeOrNull);
 
+    SamplePE tryfindByCodeAndProject(String sampleCode, ProjectPE project);
+
     /**
      * Returns the sample specified by given <var>sampleCode</var> and given <var>space</var>.
      */
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SampleDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SampleDAO.java
index a032102fa40641a1c4f4c0f952be8b426c8b4785..5988005a90bf8271758957eac39370c2d35e2d82 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SampleDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SampleDAO.java
@@ -54,6 +54,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DeletionPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EventPE.EntityType;
 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.SamplePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePropertyPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
@@ -247,6 +248,29 @@ public class SampleDAO extends AbstractGenericEntityWithPropertiesDAO<SamplePE>
         return result;
     }
 
+    @Override
+    public SamplePE tryfindByCodeAndProject(String sampleCode, ProjectPE project)
+    {
+        assert sampleCode != null : "Unspecified sample code.";
+        assert project != null : "Unspecified project.";
+        
+        Criteria criteria = createProjectCriteria(project);
+        addSampleCodeCriterion(criteria, sampleCode);
+        SamplePE sample = (SamplePE) criteria.uniqueResult();
+        if (sample == null && isFullCode(sampleCode) == false)
+        {
+            criteria = createProjectCriteria(project);
+            sample = tryFindContainedSampleWithUniqueSubcode(criteria, sampleCode);
+        }
+        if (operationLog.isDebugEnabled())
+        {
+            operationLog.debug(String.format(
+                    "Following sample '%s' has been found for code '%s' and project '%s'.", sample,
+                    sampleCode, project));
+        }
+        return sample;
+    }
+
     @Override
     public final SamplePE tryFindByCodeAndSpace(final String sampleCode, final SpacePE space)
     {
@@ -313,6 +337,11 @@ public class SampleDAO extends AbstractGenericEntityWithPropertiesDAO<SamplePE>
         return createFindCriteria(Restrictions.eq("space", space));
     }
 
+    private Criteria createProjectCriteria(final ProjectPE project)
+    {
+        return createFindCriteria(Restrictions.eq("project", project));
+    }
+    
     private void addSampleCodesCriterion(Criteria criteria, List<String> sampleCodes,
             String containerCodeOrNull)
     {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/util/SpaceIdentifierHelper.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/util/SpaceIdentifierHelper.java
index 7c6cc6f10e4a5ebfc057d8a3ffd0b6941be979e0..f30db5b7979ecead93323ee87703477085c0326e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/util/SpaceIdentifierHelper.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/util/SpaceIdentifierHelper.java
@@ -18,9 +18,12 @@ package ch.systemsx.cisd.openbis.generic.server.util;
 
 import ch.systemsx.cisd.common.exceptions.InternalErr;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationDAOFactory;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IProjectDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISpaceDAO;
 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.SpacePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.util.SpaceCodeHelper;
@@ -109,4 +112,12 @@ public final class SpaceIdentifierHelper
         final ISpaceDAO groupDAO = daoFactory.getSpaceDAO();
         return groupDAO.tryFindSpaceByCode(spaceCode);
     }
+    
+    public static ProjectPE tryGetProject(ProjectIdentifier projectIdentifier,
+            final PersonPE person, final IAuthorizationDAOFactory daoFactory)
+    {
+        String spaceCode = SpaceCodeHelper.getSpaceCode(person, projectIdentifier);
+        IProjectDAO projectDAO = daoFactory.getProjectDAO();
+        return projectDAO.tryFindProject(spaceCode, projectIdentifier.getProjectCode());
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/IdentifierHelper.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/IdentifierHelper.java
index f21539a269e8aa782de264d8312483967549ad4b..a22ff56a0f7ffcc4aa881acfd0ca452997a53c48 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/IdentifierHelper.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/IdentifierHelper.java
@@ -25,6 +25,7 @@ import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSamplesWithTypes;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Space;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DeletedSamplePE;
@@ -62,9 +63,10 @@ public final class IdentifierHelper
     public final static SampleIdentifier createSampleIdentifier(final SamplePE samplePE)
     {
         assert samplePE != null : "Unspecified sample";
-        final SpacePE group = samplePE.getSpace();
+        ProjectPE project = samplePE.getProject();
+        final SpacePE space = samplePE.getSpace();
         final String sampleCode = extractCode(samplePE);
-        return createSampleIdentifier(group, sampleCode);
+        return createSampleIdentifier(project, space, sampleCode);
     }
 
     public static final SampleIdentifier sample(final SamplePE sample)
@@ -101,9 +103,9 @@ public final class IdentifierHelper
             final DeletedSamplePE deletedSamplePE)
     {
         assert deletedSamplePE != null : "Unspecified sample";
-        final SpacePE group = deletedSamplePE.getSpace();
+        final SpacePE space = deletedSamplePE.getSpace();
         final String sampleCode = deletedSamplePE.getCode();
-        return createSampleIdentifier(group, sampleCode);
+        return createSampleIdentifier(null, space, sampleCode);
     }
 
     public final static SampleIdentifier createSampleIdentifier(SpaceIdentifier spaceIdentifier, String sampleCode, String sampleContainerCode)
@@ -119,14 +121,20 @@ public final class IdentifierHelper
         }
     }
 
-    private static SampleIdentifier createSampleIdentifier(final SpacePE group, final String sampleCode)
+    private static SampleIdentifier createSampleIdentifier(ProjectPE project, final SpacePE space, final String sampleCode)
     {
-        if (group == null)
+        if (project != null)
+        {
+            SpaceIdentifier spaceIdentifier = createGroupIdentifier(project.getSpace());
+            ProjectIdentifier projectIdentifier = new ProjectIdentifier(spaceIdentifier, project.getCode());
+            return new SampleIdentifier(projectIdentifier, sampleCode);
+        }
+        if (space == null)
         {
             return new SampleIdentifier(sampleCode);
         } else
         {
-            return new SampleIdentifier(createGroupIdentifier(group), sampleCode);
+            return new SampleIdentifier(createGroupIdentifier(space), sampleCode);
         }
     }
 
@@ -138,15 +146,24 @@ public final class IdentifierHelper
     public static SampleIdentifier createSampleIdentifier(Sample sample)
     {
         assert sample != null : "Unspecified sample";
+        Project project = sample.getProject();
+        String sampleCode = sample.getCode();
+        if (project != null)
+        {
+            Space space = project.getSpace();
+            if (space == null)
+            {
+                throw new IllegalArgumentException("Missing space code of project sample " + sample);
+            }
+            return new SampleIdentifier(new ProjectIdentifier(space.getCode(), project.getCode()), sampleCode);
+        }
         final Space space = sample.getSpace();
         if (space != null)
         {
-            SpaceIdentifier groupIdentifier =
-                    new SpaceIdentifier(space.getCode());
-            return new SampleIdentifier(groupIdentifier, sample.getCode());
+            return new SampleIdentifier(new SpaceIdentifier(space.getCode()), sampleCode);
         } else
         {
-            return new SampleIdentifier(sample.getCode());
+            return new SampleIdentifier(sampleCode);
         }
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifier.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifier.java
index e08f1fd1e4537321912568d5d99a6eb0fbd6b205..36770f27a612ca453037a2eded61e7e1373940b8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifier.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifier.java
@@ -38,22 +38,29 @@ public class SampleIdentifier extends SampleOwnerIdentifier
 
     private String containerCodeOrNull;
 
+    public SampleIdentifier(final ProjectIdentifier projectIdentifier, final String sampleCode)
+    {
+        super(projectIdentifier);
+        setSampleCode(sampleCode);
+    }
+
     public SampleIdentifier(final SpaceIdentifier spaceIdentOrNull, final String sampleCode)
     {
         super(spaceIdentOrNull);
         setSampleCode(sampleCode);
     }
-
+    
     public static SampleIdentifier createOwnedBy(final SampleOwnerIdentifier owner,
             final String sampleCode)
     {
         if (owner.isDatabaseInstanceLevel())
         {
             return new SampleIdentifier(sampleCode);
-        } else
+        } else if (owner.isSpaceLevel())
         {
             return new SampleIdentifier(owner.getSpaceLevel(), sampleCode);
         }
+        return new SampleIdentifier(owner.getProjectLevel(), sampleCode);
     }
 
     /** Database-instance level {@link SampleIdentifier}. */
@@ -96,7 +103,10 @@ public class SampleIdentifier extends SampleOwnerIdentifier
      */
     public SampleOwnerIdentifier createSampleOwnerIdentifier()
     {
-        if (getSpaceLevel() != null)
+        if (getProjectLevel() != null)
+        {
+            return new SampleOwnerIdentifier(getProjectLevel());
+        } else if (getSpaceLevel() != null)
         {
             return new SampleOwnerIdentifier(getSpaceLevel());
         } else
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifierFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifierFactory.java
index ac163313d5a278dca96d9b000de30e721ae1e438..04b0f3264cb89233e2fa6b55fa10ec02e2604ec1 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifierFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifierFactory.java
@@ -30,7 +30,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier.Co
  * Parses the given text in the constructor to extract the database instance, the group and the sample code.
  * 
  * <pre>
- * [[&lt;database instance code&gt;:][/&lt;group code&gt;]/]&lt;sample code&gt;
+ * /[&lt;space code&gt;/][&lt;project code&gt;/]&lt;sample code&gt;
  * </pre>
  * 
  * @author Tomasz Pylak
@@ -220,13 +220,14 @@ public final class SampleIdentifierFactory extends AbstractIdentifierFactory
             String spaceCode = tokens[1];
             return new SampleOwnerIdentifier(new SpaceIdentifier(
                     assertValidCode(spaceCode)));
+        } else if (tokens.length == 3)
+        {
+            // case: originalText is e.g. "/space/project/CP1"
+            String spaceCode = tokens[1];
+            String projectCode = tokens[2];
+            return new SampleOwnerIdentifier(new ProjectIdentifier(
+                    assertValidCode(spaceCode), assertValidCode(projectCode)));
         } else
             throw createTooManyTokensExcp(originalText);
     }
-
-    public static String getOwnerSchema()
-    {
-        return "[" + Constants.IDENTIFIER_SEPARATOR
-                + "<space-code>]" + Constants.IDENTIFIER_SEPARATOR + "]";
-    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleOwnerIdentifier.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleOwnerIdentifier.java
index ca82712aeec96eacd79583546acb25832bf967b1..9cd6dabef7b5a20e211c8338fefffc56b585df02 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleOwnerIdentifier.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleOwnerIdentifier.java
@@ -23,7 +23,11 @@ import ch.systemsx.cisd.openbis.generic.shared.IServer;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier.Constants;
 
 /**
- * Identifies an owner of a sample: space or database instance.
+ * Identifies an owner of a sample: project, space or non.
+ * <ol><li>Project if <code>projectIdentifier != null</code>
+ * <li>Space if <code>projectIdentifier == null</code> and <code>spaceIdentOrNull != null</code>
+ * <li>Non if <code>projectIdentifier == null</code> and <code>spaceIdentOrNull == null</code>
+ * </ol>
  * 
  * @author Tomasz Pylak
  */
@@ -34,6 +38,8 @@ public class SampleOwnerIdentifier extends AbstractHashable implements Serializa
 
     // if not null, sample is defined on the space level
     private SpaceIdentifier spaceIdentOrNull;
+    
+    private ProjectIdentifier projectIdentifier;
 
     /** Database-instance level {@link SampleOwnerIdentifier}. */
     public SampleOwnerIdentifier()
@@ -41,30 +47,36 @@ public class SampleOwnerIdentifier extends AbstractHashable implements Serializa
     }
 
     /** Space level {@link SampleOwnerIdentifier}. */
-    public SampleOwnerIdentifier(final SpaceIdentifier groupIdentifier)
+    public SampleOwnerIdentifier(final SpaceIdentifier identifier)
     {
-        checkNotNull(groupIdentifier);
-        this.spaceIdentOrNull = groupIdentifier;
+        assert identifier != null : "space identifier cannot be null";
+        this.spaceIdentOrNull = identifier;
     }
 
-    private static SpaceIdentifier checkNotNull(final SpaceIdentifier identifier)
+    /** Project level {@link SampleOwnerIdentifier}. */
+    public SampleOwnerIdentifier(final ProjectIdentifier identifier)
     {
-        assert identifier != null : "space identifier cannot be null";
-        return identifier;
+        assert identifier != null : "project identifier cannot be null";
+        this.projectIdentifier = identifier;
     }
-
+    
     /** @return if sample is connected to its home space */
     public boolean isInsideHomeSpace()
     {
         return isSpaceLevel() && spaceIdentOrNull.isHomeSpace();
     }
+    
+    public boolean isProjectLevel()
+    {
+        return projectIdentifier != null;
+    }
 
     /**
      * true if sample belongs to a space. {@link #isDatabaseInstanceLevel()} will return false in such a case.
      */
     public boolean isSpaceLevel()
     {
-        return spaceIdentOrNull != null;
+        return projectIdentifier == null && spaceIdentOrNull != null;
     }
 
     /**
@@ -72,7 +84,7 @@ public class SampleOwnerIdentifier extends AbstractHashable implements Serializa
      */
     public boolean isDatabaseInstanceLevel()
     {
-        return this.spaceIdentOrNull == null;
+        return projectIdentifier == null && spaceIdentOrNull == null;
     }
 
     /**
@@ -81,7 +93,10 @@ public class SampleOwnerIdentifier extends AbstractHashable implements Serializa
     @Override
     public String toString()
     {
-        if (isSpaceLevel())
+        if (isProjectLevel())
+        {
+            return projectIdentifier.toString() + Constants.IDENTIFIER_SEPARATOR;
+        } else if (isSpaceLevel())
         {
             if (isInsideHomeSpace())
             {
@@ -98,6 +113,11 @@ public class SampleOwnerIdentifier extends AbstractHashable implements Serializa
             throw new IllegalStateException("sample owner is unknown");
         }
     }
+    
+    public ProjectIdentifier getProjectLevel()
+    {
+        return projectIdentifier;
+    }
 
     /**
      * It is a good pattern to use {@link #isSpaceLevel()} before calling this method.
@@ -116,8 +136,21 @@ public class SampleOwnerIdentifier extends AbstractHashable implements Serializa
     @Override
     public int compareTo(final SampleOwnerIdentifier other)
     {
-        if (isSpaceLevel())
+        if (isProjectLevel())
+        {
+            if (other.isProjectLevel())
+            {
+                return getProjectLevel().toString().compareTo(other.getProjectLevel().toString());
+            } else
+            {
+                return 1;
+            }
+        } else if (isSpaceLevel())
         {
+            if (other.isProjectLevel())
+            {
+                return -1;
+            }
             if (other.isSpaceLevel())
             {
                 return getSpaceLevel().compareTo(other.getSpaceLevel());
@@ -127,7 +160,7 @@ public class SampleOwnerIdentifier extends AbstractHashable implements Serializa
             }
         } else if (isDatabaseInstanceLevel())
         {
-            if (other.isSpaceLevel())
+            if (other.isProjectLevel() || other.isSpaceLevel())
             {
                 return -1;
             } else
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 c4633844b4200122093b215112bb6ef769c57ccd..154b2df859e39637f7151a723462ea74ea3b50eb 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
@@ -365,6 +365,7 @@ public class DataSetTranslator
         sample.setRegistrator(PersonTranslator.translate(samplePE.getRegistrator()));
         sample.setModifier(PersonTranslator.translate(samplePE.getModifier()));
         sample.setSpace(SpaceTranslator.translate(samplePE.getSpace()));
+        sample.setProject(ProjectTranslator.translate(samplePE.getProject()));
         sample.setExperiment(experiment);
         if (loadSampleProperties)
         {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetViewer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetViewer.java
index 28f2552ef692e60cdc1725bc81c7c34490add9b9..ee33d684341bc293a98ff59909ef79c22c2a0440 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetViewer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetViewer.java
@@ -67,6 +67,8 @@ 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.ISerializableComparable;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PhysicalDataSet;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRowWithObject;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.WebAppContext;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.IGenericClientServiceAsync;
@@ -143,9 +145,15 @@ abstract public class GenericDataSetViewer extends AbstractViewerWithVerticalSpl
             widgets.add(experimentBreadcrumb);
         }
 
-        if (originalData.getSample() != null)
+        Sample sample = originalData.getSample();
+        if (sample != null)
         {
-            Widget sampleBreadcrumb = createEntityLink(originalData.getSample());
+            Project project = sample.getProject();
+            if (project != null && experiment == null)
+            {
+                widgets.add(createProjectLink(project));
+            }
+            Widget sampleBreadcrumb = createEntityLink(sample);
             widgets.add(sampleBreadcrumb);
         }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleViewer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleViewer.java
index 39ed45625de941b1472b966248f242fe6a5de3cf..6da0442ff606bbdf4724e9ea9077cc62b1d3ebbb 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleViewer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleViewer.java
@@ -153,6 +153,10 @@ abstract public class GenericSampleViewer extends AbstractViewerWithVerticalSpli
             Widget spaceBreadcrumb = createSpaceLink(originalData.getSpace());
             widgets.add(spaceBreadcrumb);
         }
+        if (originalData.getProject() != null && originalData.getExperiment() == null)
+        {
+            widgets.add(createProjectLink(originalData.getProject()));
+        }
         if (originalData.getExperiment() != null)
         {
             Widget projectBreadcrumb = createProjectLink(originalData.getExperiment().getProject());
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js
index 83e697e7215be5dfe3b5ec7e73a856131e025843..df7fba8de11c7e8b6b6b5687ca5d569bbb941ce7 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js
@@ -312,6 +312,7 @@ var common = {
   space: "Space",
   groups: "Spaces",
   project: "Project",
+  project_identifier: "Project Identifier",
   experiment: entityTypes.experiment,
   experiments: entityTypes.experiments,
   experiment_identifier: entityTypes.experiment + " Identifier",
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifierTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifierTest.java
index 09541fab3048af55246e5e9b346f9adae0d310a7..34cea5fe89a1733a242e8229fd5254cddb65d668 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifierTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifierTest.java
@@ -40,7 +40,7 @@ public final class SampleIdentifierTest
     }
 
     @Test
-    public final void testToStringGroupLevelHomeBd()
+    public final void testToStringSpaceLevelHomeBd()
     {
         final SampleIdentifier sampleIdentifier =
                 new SampleIdentifier(new SpaceIdentifier("GR"),
@@ -49,7 +49,7 @@ public final class SampleIdentifierTest
     }
 
     @Test
-    public final void testToStringGroupLevel()
+    public final void testToStringSpaceLevel()
     {
         final SampleIdentifier sampleIdentifier =
                 new SampleIdentifier(new SpaceIdentifier("GR"), "SAMP");
@@ -57,26 +57,37 @@ public final class SampleIdentifierTest
     }
 
     @Test
-    public final void testToStringHomeGroupLevel()
+    public final void testToStringHomeSpaceLevel()
     {
         final SampleIdentifier sampleIdentifier = SampleIdentifier.createHomeGroup("SAMP");
         assertEquals(sampleIdentifier.toString(), "SAMP");
     }
+    
+    @Test
+    public final void testToStringProjectLevel()
+    {
+        final SampleIdentifier sampleIdentifier =
+                new SampleIdentifier(new ProjectIdentifier("A", "P1"), "SAMP");
+        assertEquals(sampleIdentifier.toString(), "/A/P1/SAMP");
+    }
 
     @Test
     public final void testCompareIdentifiers()
     {
-        String g1 = "AG";
-        String g2 = "BG";
+        String s1 = "AG";
+        String s2 = "BG";
         String c1 = "A";
         String c2 = "B";
         SampleIdentifier[] expectedOrder =
                 new SampleIdentifier[]
                 { SampleIdentifier.createHomeGroup(c1), SampleIdentifier.createHomeGroup(c2),
-                        new SampleIdentifier(new SpaceIdentifier(g1), c1),
-                        new SampleIdentifier(new SpaceIdentifier(g1), c2),
-                        new SampleIdentifier(new SpaceIdentifier(g2), c1),
-                        new SampleIdentifier(new SpaceIdentifier(g2), c2)
+                        new SampleIdentifier(new SpaceIdentifier(s1), c1),
+                        new SampleIdentifier(new SpaceIdentifier(s1), c2),
+                        new SampleIdentifier(new SpaceIdentifier(s2), c1),
+                        new SampleIdentifier(new SpaceIdentifier(s2), c2),
+                        new SampleIdentifier(new ProjectIdentifier(s2, "P1"), c1),
+                        new SampleIdentifier(new ProjectIdentifier(s2, "P1"), c2),
+                        new SampleIdentifier(new ProjectIdentifier(s2, "P2"), c2),
                 };
 
         SampleIdentifier[] idents = revert(expectedOrder);
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleOwnerIdentifierTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleOwnerIdentifierTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..37fe619ef8900d22cbff8da0ee4ff1b36edd8c0e
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleOwnerIdentifierTest.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2016 ETH Zuerich, SIS
+ *
+ * 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.shared.dto.identifier;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.fail;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class SampleOwnerIdentifierTest
+{
+    private SampleOwnerIdentifier noOwner;
+    private SpaceIdentifier spaceA;
+    private SpaceIdentifier spaceB;
+    private SpaceIdentifier homeSpace;
+    private SampleOwnerIdentifier ownerSpaceA;
+    private SampleOwnerIdentifier ownerSpaceB;
+    private SampleOwnerIdentifier ownerHomeSpace;
+    private ProjectIdentifier projectP1;
+    private ProjectIdentifier projectP2;
+    private ProjectIdentifier projectP3;
+    private SampleOwnerIdentifier ownerProjectP1;
+    private SampleOwnerIdentifier ownerProjectP2;
+    private SampleOwnerIdentifier ownerProjectP3;
+
+    @BeforeMethod
+    public void setUpIdentifiers()
+    {
+        noOwner = new SampleOwnerIdentifier();
+        spaceA = new SpaceIdentifier("A");
+        spaceB = new SpaceIdentifier("B");
+        homeSpace = SpaceIdentifier.createHome();
+        ownerHomeSpace = new SampleOwnerIdentifier(homeSpace);
+        ownerSpaceA = new SampleOwnerIdentifier(spaceA);
+        ownerSpaceB = new SampleOwnerIdentifier(spaceB);
+        projectP1 = new ProjectIdentifier(spaceA, "P1");
+        ownerProjectP1 = new SampleOwnerIdentifier(projectP1);
+        projectP2 = new ProjectIdentifier(spaceA, "P2");
+        ownerProjectP2 = new SampleOwnerIdentifier(projectP2);
+        projectP3 = new ProjectIdentifier(spaceB, "P3");
+        ownerProjectP3 = new SampleOwnerIdentifier(projectP3);
+    }
+    
+    @Test
+    public void testIsAndGetProjectLevel()
+    {
+        assertIsAndGetProjectLevel(ownerProjectP1, true, projectP1);
+        assertIsAndGetProjectLevel(ownerSpaceA, false, null);
+        assertIsAndGetProjectLevel(noOwner, false, null);
+    }
+    
+    private void assertIsAndGetProjectLevel(SampleOwnerIdentifier identifier, boolean expected, ProjectIdentifier project)
+    {
+        assertEquals(identifier.isProjectLevel(), expected);
+        assertSame(identifier.getProjectLevel(), project);
+    }
+    
+    @Test
+    public void testIsAndGetSpaceLevel()
+    {
+        assertIsAndGetSpaceLevel(ownerProjectP1, false, null);
+        assertIsAndGetSpaceLevel(ownerSpaceA, true, spaceA);
+        assertIsAndGetSpaceLevel(noOwner, false, null);
+    }
+    
+    private void assertIsAndGetSpaceLevel(SampleOwnerIdentifier identifier, boolean expected, SpaceIdentifier space)
+    {
+        assertEquals(identifier.isSpaceLevel(), expected);
+        assertSame(identifier.getSpaceLevel(), space);
+    }
+    
+    @Test
+    public void testToStringForNoOwner()
+    {
+        assertEquals(noOwner.toString(), "/");
+    }
+
+    @Test
+    public void testToStringForSpaceOwner()
+    {
+        assertEquals(ownerSpaceA.toString(), "/A/");
+    }
+    
+    @Test
+    public void testToStringForProjectOwner()
+    {
+        assertEquals(ownerProjectP1.toString(), "/A/P1/");
+    }
+    
+    @Test
+    public void testCompareTo()
+    {
+        assertCompareToContract(ownerProjectP1, ownerProjectP2);
+        assertCompareToContract(ownerProjectP1, ownerProjectP3);
+        assertCompareToContract(ownerProjectP2, ownerProjectP3);
+        assertCompareToContract(ownerSpaceA, ownerProjectP1);
+        assertCompareToContract(ownerSpaceA, ownerProjectP2);
+        assertCompareToContract(ownerSpaceA, ownerProjectP3);
+        assertCompareToContract(ownerSpaceB, ownerProjectP3);
+        assertCompareToContract(ownerSpaceA, ownerSpaceB);
+        assertCompareToContract(ownerHomeSpace, ownerSpaceB);
+        assertCompareToContract(noOwner, ownerProjectP1);
+        assertCompareToContract(noOwner, ownerSpaceA);
+    }
+    
+    private void assertCompareToContract(SampleOwnerIdentifier id1, SampleOwnerIdentifier id2)
+    {
+        assertSameSign(id1.compareTo(id1), 0);
+        assertSameSign(id1.compareTo(id2), -1);
+        assertSameSign(id2.compareTo(id2), 0);
+        assertSameSign(id2.compareTo(id1), 1);
+    }
+    
+    private void assertSameSign(int actual, int expected)
+    {
+        if (actual < 0)
+        {
+            if (expected < 0)
+            {
+                return;
+            }
+        } else if (actual == 0)
+        {
+            if (expected == 0)
+            {
+                return;
+            }
+        } else if (expected > 0)
+        {
+            return;
+        }
+        fail("Different signs: expected [" + expected + "] actual [" + actual + "]");
+    }
+
+}
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateDatasetLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateDatasetLoader.java
index aef684240c56bfc1a748d179b2e7ce9116edfd54..ef6fa53ea40e9be5fc97c0bef4073c0475ac8ea8 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateDatasetLoader.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateDatasetLoader.java
@@ -25,6 +25,7 @@ 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.Space;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleOwnerIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
@@ -343,43 +344,22 @@ class PlateDatasetLoader
         return datastoreUrl;
     }
 
-    protected static SampleIdentifier createSampleIdentifier(PlateIdentifier plate,
-            String homeSpaceCodeOrNull)
+    protected static SampleIdentifier createSampleIdentifier(Sample sample)
     {
         SampleOwnerIdentifier owner;
-        String spaceCode = plate.tryGetSpaceCode();
-        if (StringUtils.isNotBlank(spaceCode))
-        {
-            final SpaceIdentifier space =
-                    new SpaceIdentifier(spaceCode);
-            owner = new SampleOwnerIdentifier(space);
-        } else
+        Space spaceOrNull = sample.getSpace();
+        Project project = sample.getProject();
+        if (project != null)
         {
-            if (spaceCode == null)
-            {
-                owner = new SampleOwnerIdentifier();
-            } else
+            Space projectSpace = project.getSpace();
+            if (projectSpace == null)
             {
-                if (homeSpaceCodeOrNull == null)
-                {
-                    throw new UserFailureException("No space given and user has no home space.");
-                }
-                final SpaceIdentifier space =
-                        new SpaceIdentifier(homeSpaceCodeOrNull);
-                owner = new SampleOwnerIdentifier(space);
+                throw new IllegalArgumentException("Missing project space of sample " + sample.getIdentifier());
             }
-        }
-        return SampleIdentifier.createOwnedBy(owner, plate.getPlateCode());
-    }
-
-    protected static SampleIdentifier createSampleIdentifier(Sample sample)
-    {
-        SampleOwnerIdentifier owner;
-        Space spaceOrNull = sample.getSpace();
-        String spaceCode = (null == spaceOrNull) ? null : spaceOrNull.getCode();
-        if (spaceCode != null)
+            owner = new SampleOwnerIdentifier(new ProjectIdentifier(projectSpace.getCode(), project.getCode()));
+        } else if (spaceOrNull != null)
         {
-            SpaceIdentifier space = new SpaceIdentifier(spaceCode);
+            SpaceIdentifier space = new SpaceIdentifier(spaceOrNull.getCode());
             owner = new SampleOwnerIdentifier(space);
         } else
         {