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 b559223231dafa3c3e5ad138dd0d11105d33ea6f..34982998a421b2ae9c4a3a3a56a258ef459e4e7c 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
@@ -43,9 +43,12 @@ import ch.systemsx.cisd.openbis.generic.server.authorization.annotation.Authoriz
 import ch.systemsx.cisd.openbis.generic.server.authorization.annotation.Capability;
 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.ExperimentAugmentedCodePredicate;
 import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.ExperimentIdentifierPredicate;
 import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.ExperimentListPredicate;
+import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.ProjectIdentifierPredicate;
 import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.ProjectPredicate;
+import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.SampleIdentifierPredicate;
 import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.SampleListPredicate;
 import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.SamplePredicate;
 import ch.systemsx.cisd.openbis.generic.server.authorization.validator.DataSetByExperimentIdentifierValidator;
@@ -82,6 +85,7 @@ import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Project;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Role;
 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.api.v1.dto.SampleIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchableEntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SpaceWithProjectsAndRoleAssignments;
@@ -392,7 +396,7 @@ public class GeneralInformationService extends AbstractServer<IGeneralInformatio
     @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
     @ReturnValueFilter(validatorClass = SampleByIdentiferValidator.class)
     public List<Sample> listSamplesForExperiment(String sessionToken,
-            @AuthorizationGuard(guardClass = ExperimentIdentifierPredicate.class)
+            @AuthorizationGuard(guardClass = ExperimentAugmentedCodePredicate.class)
             String experimentIdentifierString)
     {
         checkSession(sessionToken);
@@ -414,7 +418,7 @@ public class GeneralInformationService extends AbstractServer<IGeneralInformatio
     @RolesAllowed(RoleWithHierarchy.INSTANCE_OBSERVER)
     @Capability("SEARCH_ON_BEHALF_OF_USER")
     public List<Sample> listSamplesForExperimentOnBehalfOfUser(String sessionToken,
-            @AuthorizationGuard(guardClass = ExperimentIdentifierPredicate.class)
+            @AuthorizationGuard(guardClass = ExperimentAugmentedCodePredicate.class)
             String experimentIdentifierString, String userId)
     {
         checkSession(sessionToken);
@@ -950,7 +954,7 @@ public class GeneralInformationService extends AbstractServer<IGeneralInformatio
     @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
     @ReturnValueFilter(validatorClass = ExperimentByIdentiferValidator.class)
     public List<Experiment> listExperiments(String sessionToken,
-            @AuthorizationGuard(guardClass = ExperimentIdentifierPredicate.class)
+            @AuthorizationGuard(guardClass = ExperimentAugmentedCodePredicate.class)
             List<String> experimentIdentifiers)
     {
         checkSession(sessionToken);
@@ -1086,36 +1090,126 @@ public class GeneralInformationService extends AbstractServer<IGeneralInformatio
     }
 
     @Override
-    public List<Attachment> listAttachmentsForProject(String sessionToken, Project project,
+    @Transactional(readOnly = true)
+    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
+    public List<Attachment> listAttachmentsForProject(String sessionToken,
+            @AuthorizationGuard(guardClass = ProjectIdentifierPredicate.class)
+            ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ProjectIdentifier project,
             boolean allVersions)
     {
-        final ProjectIdentifier identifier =
-                new ProjectIdentifier(project.getSpaceCode(), project.getCode());
-        final ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project info =
-                commonServer.getProjectInfo(sessionToken, identifier);
+        final TechId techId;
+        if (project.getDatabaseId() != null)
+        {
+            techId = new TechId(project.getDatabaseId());
+        } else if (project.getPermId() != null)
+        {
+            final Long id =
+                    boFactory.getEntityResolver().tryResolveProjectIdByPermId(
+                            project.getPermId());
+            if (id == null)
+            {
+                return Collections.emptyList();
+            }
+            techId = new TechId(id);
+        } else if (project.getCode() != null)
+        {
+            final Long id =
+                    boFactory.getEntityResolver().tryResolveProjectIdByCode(
+                            project.getSpaceCode(), project.getCode());
+            if (id == null)
+            {
+                return Collections.emptyList();
+            }
+            techId = new TechId(id);
+        } else
+        {
+            throw new IllegalArgumentException("No identifier given.");
+        }
         final List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> attachments =
-                commonServer.listProjectAttachments(sessionToken, new TechId(info.getId()));
+                commonServer.listProjectAttachments(sessionToken, techId);
         return Translator.translateAttachments(attachments, allVersions);
     }
 
     @Override
+    @Transactional(readOnly = true)
+    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
     public List<Attachment> listAttachmentsForExperiment(String sessionToken,
-            Experiment experiment, boolean allVersions)
+            @AuthorizationGuard(guardClass = ExperimentIdentifierPredicate.class)
+            ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ExperimentIdentifier experiment,
+            boolean allVersions)
     {
+        final TechId techId;
+        if (experiment.getDatabaseId() != null)
+        {
+            techId = new TechId(experiment.getDatabaseId());
+        } else if (experiment.getPermId() != null)
+        {
+            final Long id =
+                    boFactory.getEntityResolver().tryResolveExperimentIdByPermId(
+                            experiment.getPermId());
+            if (id == null)
+            {
+                return Collections.emptyList();
+            }
+            techId = new TechId(id);
+        } else if (experiment.getCode() != null)
+        {
+            final Long id =
+                    boFactory.getEntityResolver().tryResolveExperimentIdByCode(
+                            experiment.getSpaceCode(), experiment.getProjectCode(),
+                            experiment.getCode());
+            if (id == null)
+            {
+                return Collections.emptyList();
+            }
+            techId = new TechId(id);
+        } else
+        {
+            throw new IllegalArgumentException("No identifier given.");
+        }
         final List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> attachments =
-                commonServer
-                        .listExperimentAttachments(sessionToken, new TechId(experiment.getId()));
+                commonServer.listExperimentAttachments(sessionToken, techId);
         return Translator.translateAttachments(attachments, allVersions);
     }
 
     @Override
-    public List<Attachment> listAttachmentsForSample(String sessionToken, Sample sample,
+    @Transactional(readOnly = true)
+    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
+    public List<Attachment> listAttachmentsForSample(String sessionToken,
+            @AuthorizationGuard(guardClass = SampleIdentifierPredicate.class)
+            SampleIdentifier sample,
             boolean allVersions)
     {
+        final TechId techId;
+        if (sample.getDatabaseId() != null)
+        {
+            techId = new TechId(sample.getDatabaseId());
+        } else if (sample.getPermId() != null)
+        {
+            final Long id =
+                    boFactory.getEntityResolver().tryResolveSampleIdByPermId(
+                            sample.getPermId());
+            if (id == null)
+            {
+                return Collections.emptyList();
+            }
+            techId = new TechId(id);
+        } else if (sample.getCode() != null)
+        {
+            final Long id =
+                    boFactory.getEntityResolver().tryResolveSampleIdByCode(
+                            sample.getSpaceCode(), sample.getCode());
+            if (id == null)
+            {
+                return Collections.emptyList();
+            }
+            techId = new TechId(id);
+        } else
+        {
+            throw new IllegalArgumentException("No identifier given.");
+        }
         final List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> attachments =
-                commonServer
-                        .listSampleAttachments(sessionToken, new TechId(sample.getId()));
+                commonServer.listSampleAttachments(sessionToken, techId);
         return Translator.translateAttachments(attachments, allVersions);
     }
-
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceLogger.java
index d5c998d4eb14930fb21031a8e4190803d9cfeb79..c12767c85a5b654d57ffd8689b0f28c5a958f664 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceLogger.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceLogger.java
@@ -34,13 +34,16 @@ import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSetFetchOption;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSetType;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataStoreURLForDataSets;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Experiment;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ExperimentIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Material;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.MaterialIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.MetaprojectAssignments;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Project;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ProjectIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Role;
 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.api.v1.dto.SampleIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SpaceWithProjectsAndRoleAssignments;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.metaproject.IMetaprojectId;
@@ -388,8 +391,8 @@ class GeneralInformationServiceLogger extends AbstractServerLogger implements
     }
 
     @Override
-    public List<Attachment> listAttachmentsForProject(String sessionToken, Project project,
-            boolean allVersions)
+    public List<Attachment> listAttachmentsForProject(String sessionToken,
+            ProjectIdentifier project, boolean allVersions)
     {
         logAccess(sessionToken, "listAttachmentsForProject", "PROJECT(%s)", "ALL_VERSIONS(%s)",
                 project, allVersions);
@@ -398,7 +401,7 @@ class GeneralInformationServiceLogger extends AbstractServerLogger implements
 
     @Override
     public List<Attachment> listAttachmentsForExperiment(String sessionToken,
-            Experiment experiment, boolean allVersions)
+            ExperimentIdentifier experiment, boolean allVersions)
     {
         logAccess(sessionToken, "listAttachmentsForExperiment", "EXPERIMENT(%s)",
                 "ALL_VERSIONS(%s)", experiment, allVersions);
@@ -406,7 +409,7 @@ class GeneralInformationServiceLogger extends AbstractServerLogger implements
     }
 
     @Override
-    public List<Attachment> listAttachmentsForSample(String sessionToken, Sample sample,
+    public List<Attachment> listAttachmentsForSample(String sessionToken, SampleIdentifier sample,
             boolean allVersions)
     {
         logAccess(sessionToken, "listAttachmentsForSample", "SAMPLE(%s)", "ALL_VERSIONS(%s)",
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/remoteapitest/api/v1/GeneralInformationServiceJsonApiTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/remoteapitest/api/v1/GeneralInformationServiceJsonApiTest.java
index 4ecd00e238b93a8c02a7e6a3b9901964ac69434c..40a9fa15054f531f15a0f89b9356d4ce082bcf6b 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/remoteapitest/api/v1/GeneralInformationServiceJsonApiTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/remoteapitest/api/v1/GeneralInformationServiceJsonApiTest.java
@@ -22,10 +22,13 @@ import static org.testng.AssertJUnit.assertTrue;
 import static org.testng.AssertJUnit.fail;
 
 import java.net.MalformedURLException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.Date;
 import java.util.EnumSet;
 import java.util.List;
 import java.util.Map;
@@ -44,11 +47,14 @@ import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet.Connections;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSetType;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Experiment;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ExperimentIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Project;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ProjectIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.PropertyTypeGroup;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Role;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Sample;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SampleIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria.MatchClause;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria.MatchClauseAttribute;
@@ -794,7 +800,7 @@ public class GeneralInformationServiceJsonApiTest extends RemoteApiTestCase
 
         final List<Attachment> attachments =
                 generalInformationService.listAttachmentsForExperiment(sessionToken,
-                        experiments.get(0),
+                        ExperimentIdentifier.createFromEntity(experiments.get(0)),
                         true);
         assertEquals(4, attachments.size());
         int version = 4;
@@ -828,7 +834,7 @@ public class GeneralInformationServiceJsonApiTest extends RemoteApiTestCase
 
         final List<Attachment> attachments =
                 generalInformationService.listAttachmentsForExperiment(sessionToken,
-                        experiments.get(0), false);
+                        ExperimentIdentifier.createFromEntity(experiments.get(0)), false);
         assertEquals(1, attachments.size());
         final Attachment a = attachments.get(0);
         assertEquals("exampleExperiments.txt", a.getFileName());
@@ -843,8 +849,18 @@ public class GeneralInformationServiceJsonApiTest extends RemoteApiTestCase
         assertEquals(
                 "http://localhost/openbis/index.html?viewMode=SIMPLE#action=DOWNLOAD_ATTACHMENT&file=exampleExperiments.txt&version=4&entity=EXPERIMENT&permId=200811050951882-1028",
                 a.getPermLink());
+
+        final List<Attachment> attachments2 =
+                generalInformationService.listAttachmentsForExperiment(sessionToken,
+                        ExperimentIdentifier.createFromAugmentedCode("/CISD/NEMO/EXP1"), false);
+
+        assertEquals(1, attachments2.size());
+
+        final Attachment a2 = attachments2.get(0);
+        assertEquals(a, a2);
     }
 
+    @Test
     public void testListAttachmentsForSample()
     {
         SearchCriteria searchCriteria = new SearchCriteria();
@@ -856,7 +872,8 @@ public class GeneralInformationServiceJsonApiTest extends RemoteApiTestCase
         assertEquals(1, samples.size());
 
         final List<Attachment> attachments =
-                generalInformationService.listAttachmentsForSample(sessionToken, samples.get(0),
+                generalInformationService.listAttachmentsForSample(sessionToken,
+                        SampleIdentifier.createFromEntity(samples.get(0)),
                         true);
         assertEquals(1, attachments.size());
 
@@ -873,6 +890,71 @@ public class GeneralInformationServiceJsonApiTest extends RemoteApiTestCase
         assertEquals(
                 "http://localhost/openbis/index.html?viewMode=SIMPLE#action=DOWNLOAD_ATTACHMENT&file=sampleHistory.txt&version=1&entity=SAMPLE&permId=200811050946559-980",
                 a.getPermLink());
+
+        final List<Attachment> attachments2 =
+                generalInformationService.listAttachmentsForSample(sessionToken,
+                        SampleIdentifier.createFromPermId("200811050946559-980"), true);
+
+        assertEquals(1, attachments2.size());
+
+        final Attachment a2 = attachments2.get(0);
+        assertEquals(a, a2);
+
+        final List<Attachment> attachments3 =
+                generalInformationService.listAttachmentsForSample(sessionToken,
+                        SampleIdentifier.createFromAugmentedCode("/CISD/3VCP6"), true);
+
+        assertEquals(1, attachments3.size());
+
+        final Attachment a3 = attachments3.get(0);
+        assertEquals(a, a3);
+    }
+
+    @Test
+    public void testListAttachmentsForProjectNoAttachment()
+    {
+        final List<Attachment> attachments =
+                generalInformationService.listAttachmentsForProject(sessionToken,
+                        ProjectIdentifier.createFromAugmentedCode("/CISD/DEFAULT"), true);
+
+        assertEquals(0, attachments.size());
+    }
+
+    @Test
+    public void testListAttachmentsForProjectNonExisting()
+    {
+        final List<Attachment> attachments =
+                generalInformationService.listAttachmentsForProject(sessionToken,
+                        ProjectIdentifier.createFromAugmentedCode("/NONE/EXISTENT"), true);
+
+        assertEquals(0, attachments.size());
+    }
+
+    @Test
+    public void testListAttachmentsForProjects() throws ParseException
+    {
+        final List<Attachment> attachments =
+                generalInformationService.listAttachmentsForProject(sessionToken,
+                        ProjectIdentifier.createFromPermId("20120814110011738-103"), true);
+
+        assertEquals(1, attachments.size());
+
+        final Attachment a = attachments.get(0);
+        assertEquals("projectDescription.txt", a.getFileName());
+        assertEquals("The Project", a.getTitle());
+        assertEquals("All about it.", a.getDescription());
+        assertEquals(1, a.getVersion());
+        final Date date =
+                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS Z")
+                        .parse("2012-01-03 08:27:57.123 +0100");
+        assertEquals(date, a.getRegistrationDate());
+        assertEquals("test", a.getUserId());
+        assertEquals("franz-josef.elmer@systemsx.ch", a.getUserEmail());
+        assertNotNull(a.getUserFirstName());
+        assertNotNull(a.getUserLastName());
+        assertEquals(
+                "http://localhost/openbis/index.html?viewMode=SIMPLE#action=DOWNLOAD_ATTACHMENT&file=projectDescription.txt&version=1&entity=PROJECT&code=NEMO&space=CISD",
+                a.getPermLink());
     }
 
 }
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 87c4c90824a88769bb2a509f219ab9a8a54791d0..a4d864fcd8f7dd66936a39f4690effbccef976c1 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
@@ -48,16 +48,19 @@ import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.EntityRegistrationDeta
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.EntityRegistrationDetails.EntityRegistrationDetailsInitializer;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Experiment.ExperimentInitializer;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ExperimentIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Material;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.MaterialIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.MaterialTypeIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.MetaprojectAssignments;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Project;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ProjectIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.PropertyTypeGroup;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Sample.SampleInitializer;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SampleFetchOption;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SampleIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria.CompareMode;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria.MatchClause;
@@ -1663,7 +1666,7 @@ public class GeneralInformationServiceTest extends SystemTestCase
     }
 
     @Test
-    public void testListAttachmentsForExperimentAllVersions()
+    public void testListAttachmentsForExperimentAllVersions() throws ParseException
     {
         final List<Experiment> experiments =
                 generalInformationService.listExperiments(sessionToken,
@@ -1672,17 +1675,25 @@ public class GeneralInformationServiceTest extends SystemTestCase
 
         final List<Attachment> attachments =
                 generalInformationService.listAttachmentsForExperiment(sessionToken,
-                        experiments.get(0),
+                        ExperimentIdentifier.createFromEntity(experiments.get(0)),
                         true);
         assertEquals(4, attachments.size());
         int version = 4;
+        final String[] regDates =
+                new String[]
+                    { "2008-12-10 13:49:27.901 +0100", "2008-12-10 13:49:20.236 +0100",
+                            "2008-12-10 13:49:14.564 +0100", "2008-12-10 13:48:17.996 +0100" };
         for (Attachment a : attachments)
         {
             assertEquals("exampleExperiments.txt", a.getFileName());
             assertEquals(version, a.getVersion());
             assertEquals("", a.getTitle());
             assertEquals("", a.getDescription());
-            assertTrue(a.getRegistrationDate().getTime() > 0);
+            final Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS Z")
+                    .parse(regDates[4 - version]);
+            assertEquals(
+                    date,
+                    a.getRegistrationDate());
             assertEquals("test", a.getUserId());
             assertEquals("franz-josef.elmer@systemsx.ch", a.getUserEmail());
             assertNotNull(a.getUserFirstName());
@@ -1697,7 +1708,7 @@ public class GeneralInformationServiceTest extends SystemTestCase
     }
 
     @Test
-    public void testListAttachmentsForExperimentLatestVersion()
+    public void testListAttachmentsForExperimentLatestVersion() throws ParseException
     {
         final List<Experiment> experiments =
                 generalInformationService.listExperiments(sessionToken,
@@ -1706,14 +1717,17 @@ public class GeneralInformationServiceTest extends SystemTestCase
 
         final List<Attachment> attachments =
                 generalInformationService.listAttachmentsForExperiment(sessionToken,
-                        experiments.get(0), false);
+                        ExperimentIdentifier.createFromEntity(experiments.get(0)), false);
         assertEquals(1, attachments.size());
         final Attachment a = attachments.get(0);
         assertEquals("exampleExperiments.txt", a.getFileName());
         assertEquals(4, a.getVersion());
         assertEquals("", a.getTitle());
         assertEquals("", a.getDescription());
-        assertTrue(a.getRegistrationDate().getTime() > 0);
+        final Date date =
+                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS Z")
+                        .parse("2008-12-10 13:49:27.901 +0100");
+        assertEquals(date, a.getRegistrationDate());
         assertEquals("test", a.getUserId());
         assertEquals("franz-josef.elmer@systemsx.ch", a.getUserEmail());
         assertNotNull(a.getUserFirstName());
@@ -1721,9 +1735,19 @@ public class GeneralInformationServiceTest extends SystemTestCase
         assertEquals(
                 "http://localhost/openbis/index.html?viewMode=SIMPLE#action=DOWNLOAD_ATTACHMENT&file=exampleExperiments.txt&version=4&entity=EXPERIMENT&permId=200811050951882-1028",
                 a.getPermLink());
+
+        final List<Attachment> attachments2 =
+                generalInformationService.listAttachmentsForExperiment(sessionToken,
+                        ExperimentIdentifier.createFromAugmentedCode("/CISD/NEMO/EXP1"), false);
+
+        assertEquals(1, attachments2.size());
+
+        final Attachment a2 = attachments2.get(0);
+        assertEquals(a, a2);
     }
 
-    public void testListAttachmentsForSample()
+    @Test
+    public void testListAttachmentsForSample() throws ParseException
     {
         SearchCriteria searchCriteria = new SearchCriteria();
         searchCriteria.addMatchClause(MatchClause.createAttributeMatch(MatchClauseAttribute.CODE,
@@ -1734,7 +1758,8 @@ public class GeneralInformationServiceTest extends SystemTestCase
         assertEquals(1, samples.size());
 
         final List<Attachment> attachments =
-                generalInformationService.listAttachmentsForSample(sessionToken, samples.get(0),
+                generalInformationService.listAttachmentsForSample(sessionToken,
+                        SampleIdentifier.createFromEntity(samples.get(0)),
                         true);
         assertEquals(1, attachments.size());
 
@@ -1743,7 +1768,10 @@ public class GeneralInformationServiceTest extends SystemTestCase
         assertEquals("", a.getTitle());
         assertEquals("", a.getDescription());
         assertEquals(1, a.getVersion());
-        assertTrue(a.getRegistrationDate().getTime() > 0);
+        final Date date =
+                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS Z")
+                        .parse("2009-06-09 17:00:00.000 +0200");
+        assertEquals(date, a.getRegistrationDate());
         assertEquals("test", a.getUserId());
         assertEquals("franz-josef.elmer@systemsx.ch", a.getUserEmail());
         assertNotNull(a.getUserFirstName());
@@ -1751,6 +1779,81 @@ public class GeneralInformationServiceTest extends SystemTestCase
         assertEquals(
                 "http://localhost/openbis/index.html?viewMode=SIMPLE#action=DOWNLOAD_ATTACHMENT&file=sampleHistory.txt&version=1&entity=SAMPLE&permId=200811050946559-980",
                 a.getPermLink());
+
+        final List<Attachment> attachments2 =
+                generalInformationService.listAttachmentsForSample(sessionToken,
+                        SampleIdentifier.createFromPermId("200811050946559-980"), true);
+
+        assertEquals(1, attachments2.size());
+
+        final Attachment a2 = attachments2.get(0);
+        assertEquals(a, a2);
+
+        final List<Attachment> attachments3 =
+                generalInformationService.listAttachmentsForSample(sessionToken,
+                        SampleIdentifier.createFromAugmentedCode("/CISD/3VCP6"), true);
+
+        assertEquals(1, attachments3.size());
+
+        final Attachment a3 = attachments3.get(0);
+        assertEquals(a, a3);
+    }
+
+    @Test
+    public void testListAttachmentsForProjectNoAttachment()
+    {
+        final List<Attachment> attachments =
+                generalInformationService.listAttachmentsForProject(sessionToken,
+                        ProjectIdentifier.createFromAugmentedCode("/CISD/DEFAULT"), true);
+
+        assertEquals(0, attachments.size());
+    }
+
+    @Test
+    public void testListAttachmentsForProjectNonExisting()
+    {
+        final List<Attachment> attachments =
+                generalInformationService.listAttachmentsForProject(sessionToken,
+                        ProjectIdentifier.createFromAugmentedCode("/NONE/EXISTENT"), true);
+
+        assertEquals(0, attachments.size());
+    }
+
+    @Test
+    public void testListAttachmentsForProject() throws ParseException
+    {
+        final List<Attachment> attachments =
+                generalInformationService.listAttachmentsForProject(sessionToken,
+                        ProjectIdentifier.createFromPermId("20120814110011738-103"), true);
+
+        assertEquals(1, attachments.size());
+
+        final Attachment a = attachments.get(0);
+        assertEquals("projectDescription.txt", a.getFileName());
+        assertEquals("The Project", a.getTitle());
+        assertEquals("All about it.", a.getDescription());
+        assertEquals(1, a.getVersion());
+        final Date date =
+                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS Z")
+                        .parse("2012-01-03 08:27:57.123 +0100");
+        assertEquals(date, a.getRegistrationDate());
+        assertEquals("test", a.getUserId());
+        assertEquals("franz-josef.elmer@systemsx.ch", a.getUserEmail());
+        assertNotNull(a.getUserFirstName());
+        assertNotNull(a.getUserLastName());
+        assertEquals(
+                "http://localhost/openbis/index.html?viewMode=SIMPLE#action=DOWNLOAD_ATTACHMENT&file=projectDescription.txt&version=1&entity=PROJECT&code=NEMO&space=CISD",
+                a.getPermLink());
+
+        final List<Attachment> attachments2 =
+                generalInformationService.listAttachmentsForProject(sessionToken,
+                        ProjectIdentifier.createFromAugmentedCode("/CISD/NEMO"), true);
+
+        assertEquals(1, attachments2.size());
+
+        final Attachment a2 = attachments2.get(0);
+        assertEquals(a, a2);
+
     }
 
     private void sortDataSets(List<DataSet> dataSets)
diff --git a/openbis/sourceTest/sql/postgresql/130/001=attachment_contents.tsv b/openbis/sourceTest/sql/postgresql/130/001=attachment_contents.tsv
index dc7e8c65cd38a3ff17bbdb7e607c0d51847d6eca..39ac98eae0e777432185cd9ba3a94725b98c3f36 100644
--- a/openbis/sourceTest/sql/postgresql/130/001=attachment_contents.tsv
+++ b/openbis/sourceTest/sql/postgresql/130/001=attachment_contents.tsv
@@ -6,3 +6,4 @@
 6	\\x33564350310a33564350320a3356435033
 7	\\x616c610a6d610a6b6f74610a610a6b6f740a6a6573740a6964696f7461
 8	\\x33564350310a33564350320a3356435033
+9	\\x33564350310a33564350320a3356435033
diff --git a/openbis/sourceTest/sql/postgresql/130/002=attachments.tsv b/openbis/sourceTest/sql/postgresql/130/002=attachments.tsv
index 1e6653c179e778b3f20b39838af64ce362a234aa..dd8d357493407b57786265a81573137fe38ed03c 100644
--- a/openbis/sourceTest/sql/postgresql/130/002=attachments.tsv
+++ b/openbis/sourceTest/sql/postgresql/130/002=attachments.tsv
@@ -6,3 +6,4 @@
 6	8	cellPlates.txt	2008-12-10 13:51:10.050748+01	1	2	6	\N	\N	\N	\N
 7	\N	sampleHistory.txt	2009-06-09 17:00:00+02	1	2	7	987	\N	\N	\N
 8	22	cellPlates.txt	2008-12-10 13:51:10.050748+01	1	2	8	\N	\N	\N	\N
+9	\N	projectDescription.txt	2012-01-03 08:27:57.123+01	1	2	9	\N	3	The Project	All about it.
diff --git a/openbis/sourceTest/sql/postgresql/130/059=scripts.tsv b/openbis/sourceTest/sql/postgresql/130/059=scripts.tsv
index 96742056a53aee1a3f225c900d2ee70454c45226..e2b60712cfecc489f9c964435c3b1dde1542dd49 100644
--- a/openbis/sourceTest/sql/postgresql/130/059=scripts.tsv
+++ b/openbis/sourceTest/sql/postgresql/130/059=scripts.tsv
@@ -1,7 +1,7 @@
 1	1	properties	number of properties	str(entity.properties().size()) + ' properties'	2010-10-27 15:16:48.994831+02	2	\N	DYNAMIC_PROPERTY	JYTHON
 2	1	code	\N	entity.code()	2010-10-27 15:16:48.994831+02	2	\N	DYNAMIC_PROPERTY	JYTHON
 3	1	date	\N	str(currentDate().getTime())	2010-10-27 15:16:48.994831+02	2	\N	DYNAMIC_PROPERTY	JYTHON
-4	1	managed list	\N	fake script	2010-10-27 15:16:48.994831+02	2	\N	MANAGED_PROPERTY	JYTHON
+4	1	managed list	\N	pass	2010-10-27 15:16:48.994831+02	2	\N	MANAGED_PROPERTY	JYTHON
 5	1	validateOK	\N	def validate(entity, isNew):\n  pass\n 	2010-10-27 15:16:48.994831+02	2	\N	ENTITY_VALIDATION	JYTHON
 6	1	validateFAIL	\N	def validate(entity, isNew):\n  return "This check always fail"\n 	2010-10-27 15:16:48.994831+02	2	\N	ENTITY_VALIDATION	JYTHON
 7	1	validateUpdateFAIL	\N	def validate(entity, isNew):\n  if (not isNew):\n    return "Cannot update this entity"\n 	2010-10-27 15:16:48.994831+02	2	\N	ENTITY_VALIDATION	JYTHON
diff --git a/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/IGeneralInformationService.java b/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/IGeneralInformationService.java
index 152aefe9ac5da10032c36cfa91442704a4a7d0e7..61e8e1c8c5d03d5f392795d4903dddb9c666a1de 100644
--- a/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/IGeneralInformationService.java
+++ b/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/IGeneralInformationService.java
@@ -32,13 +32,16 @@ import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSetFetchOption;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSetType;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataStoreURLForDataSets;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Experiment;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ExperimentIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Material;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.MaterialIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.MetaprojectAssignments;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Project;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ProjectIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Role;
 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.api.v1.dto.SampleIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SpaceWithProjectsAndRoleAssignments;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.metaproject.IMetaprojectId;
@@ -494,7 +497,7 @@ public interface IGeneralInformationService extends IRpcService
      * @since 1.22
      */
     public List<Attachment> listAttachmentsForProject(String sessionToken,
-            Project project, boolean allVersions);
+            ProjectIdentifier project, boolean allVersions);
 
     /**
      * @param experiment The experiment to list the attachments for.
@@ -503,7 +506,7 @@ public interface IGeneralInformationService extends IRpcService
      * @since 1.22
      */
     public List<Attachment> listAttachmentsForExperiment(String sessionToken,
-            Experiment experiment, boolean allVersions);
+            ExperimentIdentifier experiment, boolean allVersions);
 
     /**
      * @param sample The sample to list the attachments for.
@@ -512,5 +515,5 @@ public interface IGeneralInformationService extends IRpcService
      * @since 1.22
      */
     public List<Attachment> listAttachmentsForSample(String sessionToken,
-            Sample sample, boolean allVersions);
+            SampleIdentifier sample, boolean allVersions);
 }