diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/AssignSampleToExperimentTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/AssignSampleToExperimentTest.java
index 23138a572a5fc107b17fd8fe17dd70feb6e1247d..ce02933411fd0e9c8347d7a2ab86d39a54c8c356 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/AssignSampleToExperimentTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/AssignSampleToExperimentTest.java
@@ -16,14 +16,15 @@
 
 package ch.systemsx.cisd.openbis.systemtest;
 
-import static org.hamcrest.CoreMatchers.is;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.fail;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
@@ -31,7 +32,6 @@ import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.entitygraph.EntityGraphGenerator;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.entitygraph.ExperimentNode;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.entitygraph.SampleNode;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
@@ -45,6 +45,7 @@ import ch.systemsx.cisd.openbis.systemtest.base.BaseTest;
 import ch.systemsx.cisd.openbis.systemtest.base.auth.AuthorizationRule;
 import ch.systemsx.cisd.openbis.systemtest.base.auth.GuardedDomain;
 import ch.systemsx.cisd.openbis.systemtest.base.auth.InstanceDomain;
+import ch.systemsx.cisd.openbis.systemtest.base.auth.RolePermutator;
 import ch.systemsx.cisd.openbis.systemtest.base.auth.SpaceDomain;
 
 /**
@@ -175,7 +176,22 @@ public class AssignSampleToExperimentTest extends BaseTest
         assertModified(g.s(1));
         assertModified(g.ds(1));
         assertUnmodified(g);
+    }
+
+    @Test
+    public void registerExperimentWithSampleInDifferentSpace()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("/S1/S1\n");
         
+        try
+        {
+            registerExperimentWithSamples(g.e(1), g.s(1));
+            fail("UserFailureException expected");
+        } catch (UserFailureException ex)
+        {
+            assertEquals("Sample '" + entityGraphManager.getSample(g.s(1)).getIdentifier() 
+                    + "' does not belong to the space 'S0'", ex.getMessage());
+        }
     }
     
     @Test
@@ -271,7 +287,7 @@ public class AssignSampleToExperimentTest extends BaseTest
     }
 
     @Test
-    public void addSampleToAnExperimentFailingBecauseSampleHasAlreadyAnExperiment() throws Exception
+    public void addSampleToAnExperimentFailingBecauseSampleHasAlreadyAnExperiment()
     {
         EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1\n"
                 + "E2\n");
@@ -289,7 +305,7 @@ public class AssignSampleToExperimentTest extends BaseTest
     }
 
     @Test
-    public void assignSampleToAnotherExperiment() throws Exception
+    public void assignSampleToAnotherExperiment()
     {
         EntityGraphGenerator g = parseAndCreateGraph("/S1/P1/E1, samples: /S1/S1\n"
                 + "/S2/P2/E2\n");
@@ -303,7 +319,7 @@ public class AssignSampleToExperimentTest extends BaseTest
     }
     
     @Test
-    public void dataSetsOfSampleAreAssociatedWithNewExperiment() throws Exception
+    public void dataSetsOfSampleAreAssociatedWithNewExperiment()
     {
         EntityGraphGenerator g = parseAndCreateGraph("/S1/P1/E1, samples: /S1/S1, data sets: DS1\n"
                 + "/S1/S1, data sets: DS1\n"
@@ -320,7 +336,7 @@ public class AssignSampleToExperimentTest extends BaseTest
     }
 
     @Test
-    public void spaceSampleCanBeAssignedToExperiment() throws Exception
+    public void spaceSampleCanBeAssignedToExperiment()
     {
         EntityGraphGenerator g = parseAndCreateGraph("/S2/P1/E1\n"
                 + "/S1/S1\n");
@@ -334,7 +350,7 @@ public class AssignSampleToExperimentTest extends BaseTest
     }
     
     @Test
-    public void spaceSampleCanNotBeAddedToExperimentFromAnotherSpace() throws Exception
+    public void spaceSampleCanNotBeAddedToExperimentFromAnotherSpace()
     {
         EntityGraphGenerator g = parseAndCreateGraph("/S2/P1/E1\n"
                 + "/S1/S1\n");
@@ -351,7 +367,7 @@ public class AssignSampleToExperimentTest extends BaseTest
     }
     
     @Test
-    public void spaceSamplesCanBeAddedToExperimentInSameSpace() throws Exception
+    public void spaceSamplesCanBeAddedToExperimentInSameSpace()
     {
         EntityGraphGenerator g = parseAndCreateGraph("/S1/P1/E1\n"
                 + "/S1/S1\n"
@@ -366,7 +382,7 @@ public class AssignSampleToExperimentTest extends BaseTest
     }
 
     @Test
-    public void sharedSampleCanBeAssignedToExperiment() throws Exception
+    public void sharedSampleCanBeAssignedToExperiment()
     {
         EntityGraphGenerator g = parseAndCreateGraph("/S2/P1/E1\n"
                 + "/S1\n");
@@ -380,160 +396,106 @@ public class AssignSampleToExperimentTest extends BaseTest
     }
 
     @Test
-    public void childSampleCanBeAssignedToAnotherExperiment() throws Exception
-    {
-        Sample parent = create(aSample().inExperiment(sourceExperiment));
-        Sample child = create(aSample().withParent(parent).inExperiment(sourceExperiment));
-
-        perform(anUpdateOf(child).toExperiment(destinationExperiment));
-
-        assertThat(child, is(inExperiment(destinationExperiment)));
-        assertThat(child, is(inSpace(destinationSpace)));
-    }
-
-    @Test
-    public void experimentAssignmentOfParentSampleIsNotChangedWhenChildSampleIsAssignedToAnotherExperiment()
-            throws Exception
-    {
-        Sample parent = create(aSample().inExperiment(sourceExperiment));
-        Sample child = create(aSample().withParent(parent).inExperiment(sourceExperiment));
-
-        perform(anUpdateOf(child).toExperiment(destinationExperiment));
-
-        assertThat(parent, is(inExperiment(sourceExperiment)));
-        assertThat(parent, is(inSpace(sourceSpace)));
-    }
-
-    @Test
-    public void parentSampleCanBeAssignedToAnotherExperiment() throws Exception
-    {
-        Sample parent = create(aSample().inExperiment(sourceExperiment));
-        create(aSample().withParent(parent).inExperiment(sourceExperiment));
-
-        perform(anUpdateOf(parent).toExperiment(destinationExperiment));
-
-        assertThat(parent, is(inExperiment(destinationExperiment)));
-        assertThat(parent, is(inSpace(destinationSpace)));
-    }
-
-    @Test
-    public void experimentAssignmentOfChildSampleIsNotChangedWhenParentSampleIsAssignmedToAnotherExperiment()
-            throws Exception
-    {
-        Sample parent = create(aSample().inExperiment(sourceExperiment));
-        Sample child = create(aSample().withParent(parent).inExperiment(sourceExperiment));
-
-        perform(anUpdateOf(parent).toExperiment(destinationExperiment));
-
-        assertThat(child, is(inExperiment(sourceExperiment)));
-        assertThat(child, is(inSpace(sourceSpace)));
-    }
-
-    @Test
-    public void componentSampleCanBeAssignedToAnotherExperiment() throws Exception
+    public void childSampleCanBeAssignedToAnotherExperiment()
     {
-        Sample container = create(aSample().inExperiment(sourceExperiment));
-        Sample component = create(aSample().inContainer(container).inExperiment(sourceExperiment));
-
-        perform(anUpdateOf(component).toExperiment(destinationExperiment));
-
-        assertThat(component, is(inExperiment(destinationExperiment)));
-        assertThat(component, is(inSpace(destinationSpace)));
+        EntityGraphGenerator g = parseAndCreateGraph("/S1/P1/E1, samples: /S1/S1 /S1/S2\n"
+                + "/S2/P2/E2\n"
+                + "/S1/S1, children: /S1/S2\n");
+        
+        reassignSampleToExperiment(g.s(2), g.e(2));
+        
+        assertEquals("/S1/P1/E1, samples: /S1/S1\n"
+                + "/S2/P2/E2, samples: /S2/S2\n"
+                + "/S1/S1, children: /S2/S2\n", renderGraph(g));
+        assertModified(g.e(1), g.e(2));
+        assertModified(g.s(2));
+        assertUnmodified(g);
     }
 
     @Test
-    public void experimentAssignmentOfContainerSampleIsNotChangedWhenComponentSampleIsAssignedToAnotherExperiment()
-            throws Exception
+    public void parentSampleCanBeAssignedToAnotherExperiment()
     {
-        Sample container = create(aSample().inExperiment(sourceExperiment));
-        Sample component = create(aSample().inContainer(container).inExperiment(sourceExperiment));
-
-        perform(anUpdateOf(component).toExperiment(destinationExperiment));
-
-        assertThat(container, is(inExperiment(sourceExperiment)));
-        assertThat(container, is(inSpace(sourceSpace)));
+        EntityGraphGenerator g = parseAndCreateGraph("/S1/P1/E1, samples: /S1/S1 /S1/S2\n"
+                + "/S2/P2/E2\n"
+                + "/S1/S1, children: /S1/S2\n");
+        
+        reassignSampleToExperiment(g.s(1), g.e(2));
+        
+        assertEquals("/S1/P1/E1, samples: /S1/S2\n"
+                + "/S2/P2/E2, samples: /S2/S1\n"
+                + "/S2/S1, children: /S1/S2\n", renderGraph(g));
+        assertModified(g.e(1), g.e(2));
+        assertModified(g.s(1));
+        assertUnmodified(g);
     }
 
     @Test
-    public void containerSampleCanBeAssignedToAnotherExperiment() throws Exception
+    public void componentSampleCanBeAssignedToAnotherExperiment()
     {
-        Sample container = create(aSample().inExperiment(sourceExperiment));
-        create(aSample().inContainer(container).inExperiment(sourceExperiment));
-
-        perform(anUpdateOf(container).toExperiment(destinationExperiment));
-
-        assertThat(container, is(inExperiment(destinationExperiment)));
-        assertThat(container, is(inSpace(destinationSpace)));
+        EntityGraphGenerator g = parseAndCreateGraph("/S1/P1/E1, samples: /S1/S1 /S1/S2\n"
+                + "/S2/P2/E2\n"
+                + "/S1/S1, components: /S1/S2\n");
+        
+        reassignSampleToExperiment(g.s(2), g.e(2));
+        
+        assertEquals("/S1/P1/E1, samples: /S1/S1\n"
+                + "/S2/P2/E2, samples: /S2/S2\n"
+                + "/S1/S1, components: /S2/S2\n", renderGraph(g));
+        assertModified(g.e(1), g.e(2));
+        assertModified(g.s(2));
+        assertUnmodified(g);
     }
 
     @Test
-    public void experimentAssignmentOfComponentSampleIsNotChangedWhenContainerSampleIsAssignedToAnotherExperiment()
-            throws Exception
+    public void containerSampleCanBeAssignedToAnotherExperiment()
     {
-        Sample container = create(aSample().inExperiment(sourceExperiment));
-        Sample component = create(aSample().inContainer(container).inExperiment(sourceExperiment));
-
-        perform(anUpdateOf(container).toExperiment(destinationExperiment));
-
-        assertThat(component, is(inExperiment(sourceExperiment)));
-        assertThat(component, is(inSpace(sourceSpace)));
+        EntityGraphGenerator g = parseAndCreateGraph("/S1/P1/E1, samples: /S1/S1 /S1/S2\n"
+                + "/S2/P2/E2\n"
+                + "/S1/S1, components: /S1/S2\n");
+        
+        reassignSampleToExperiment(g.s(1), g.e(2));
+        
+        assertEquals("/S1/P1/E1, samples: /S1/S2\n"
+                + "/S2/P2/E2, samples: /S2/S1\n"
+                + "/S2/S1, components: /S1/S2\n", renderGraph(g));
+        assertModified(g.e(1), g.e(2));
+        assertModified(g.s(1));
+        assertUnmodified(g);
     }
 
     @Test
-    public void sampleWithoutExperimentCanBeAssignedToExperimentInSameSpaceThroughExperimentUpdate()
-            throws Exception
-    {
-        Sample sample = create(aSample().inSpace(destinationSpace));
-
-        perform(anUpdateOf(destinationExperiment).withSamples(sample));
-
-        assertThat(sample, is(inExperiment(destinationExperiment)));
-    }
-
-    @Test(expectedExceptions =
-        { UserFailureException.class })
-    public void sampleWithoutExperimentCanNotBeAssignedToExperimentInAnotherSpaceThroughExperimentUpdate()
-            throws Exception
-    {
-        Sample sample = create(aSample().inSpace(sourceSpace));
-
-        perform(anUpdateOf(destinationExperiment).withSamples(sample));
-
-        assertThat(sample, is(inExperiment(destinationExperiment)));
-    }
-
-    @Test(expectedExceptions =
-        { UserFailureException.class })
     public void sampleWithExperimentCanNotBeAssignedToAnotherExperimentThroughExperimentUpdate()
-            throws Exception
-    {
-        Experiment destinationExperimentInSameSpace =
-                create(anExperiment().inProject(sourceProject));
-        Sample sample = create(aSample().inExperiment(sourceExperiment));
-
-        perform(anUpdateOf(destinationExperimentInSameSpace).withSamples(sample));
-    }
-
-    @Test(expectedExceptions =
-        { UserFailureException.class })
-    public void sharedSampleCanNotBeAssignedToExperimentThroughExperimentUpdate() throws Exception
     {
-        Sample sample = create(aSample());
-
-        perform(anUpdateOf(destinationExperiment).withSamples(sample));
+        EntityGraphGenerator g = parseAndCreateGraph("/S1/P1/E1, samples: /S1/S1\n"
+                + "/S1/P2/E2\n");
 
-        assertThat(sample, is(inExperiment(destinationExperiment)));
+        try
+        {
+            reassignSamplesToExperiment(g.e(2), g.s(1));
+            fail("UserFailureException expected");
+        } catch (UserFailureException ex)
+        {
+            assertEquals("Sample '" + entityGraphManager.getSample(g.s(1)).getIdentifier()
+                    + "' is already assigned to the experiment '"
+                    + entityGraphManager.getExperimentIdentifierOrNull(g.e(1)) + "'.", ex.getMessage());
+        }
     }
 
     @Test
-    public void registeringExperimentWithSampleInSameSpaceThatIsNotAssignedToAnyExperimentAssignsTheSampleToTheExperiment()
-            throws Exception
+    public void sharedSampleCanNotBeAssignedToExperimentThroughExperimentUpdate()
     {
-        Sample sample = create(aSample().inSpace(sourceSpace));
-
-        Experiment experiment = create(anExperiment().inProject(sourceProject).withSamples(sample));
+        EntityGraphGenerator g = parseAndCreateGraph("/S1/P1/E1\n"
+                + "/S1\n");
 
-        assertThat(sample, is(inExperiment(experiment)));
+        try
+        {
+            reassignSamplesToExperiment(g.e(1), g.s(1));
+            fail("UserFailureException expected");
+        } catch (UserFailureException ex)
+        {
+            assertEquals("Samples with following codes do not exist in the space 'S1': '["
+                    + entityGraphManager.getSample(g.s(1)).getCode() + "]'.", ex.getMessage());
+        }
     }
     
     Space unrelatedAdmin;
@@ -547,15 +509,7 @@ public class AssignSampleToExperimentTest extends BaseTest
             RoleWithHierarchy destinationSpaceRole, RoleWithHierarchy instanceRole)
             throws Exception
     {
-        Sample sample = create(aSample().inExperiment(sourceExperiment));
-        String user =
-                create(aSession().withSpaceRole(sourceSpaceRole, sourceSpace)
-                        .withSpaceRole(destinationSpaceRole, destinationSpace)
-                        .withInstanceRole(instanceRole)
-                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
-                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
-
-        perform(anUpdateOf(sample).toExperiment(destinationExperiment).as(user));
+        checkAssigningSampleToExperiment(sourceSpaceRole, destinationSpaceRole, instanceRole);
     }
 
     @Test(dataProvider = "rolesNotAllowedToAssignSampleToExperiment", expectedExceptions =
@@ -564,15 +518,7 @@ public class AssignSampleToExperimentTest extends BaseTest
             RoleWithHierarchy destinationSpaceRole, RoleWithHierarchy instanceRole)
             throws Exception
     {
-        Sample sample = create(aSample().inExperiment(sourceExperiment));
-        String user =
-                create(aSession().withSpaceRole(sourceSpaceRole, sourceSpace)
-                        .withSpaceRole(destinationSpaceRole, destinationSpace)
-                        .withInstanceRole(instanceRole)
-                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
-                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
-
-        perform(anUpdateOf(sample).toExperiment(destinationExperiment).as(user));
+        checkAssigningSampleToExperiment(sourceSpaceRole, destinationSpaceRole, instanceRole);
     }
 
     @Test(dataProvider = "rolesAllowedToAssignSharedSampleToExperiment", groups = "authorization")
@@ -580,14 +526,7 @@ public class AssignSampleToExperimentTest extends BaseTest
             RoleWithHierarchy destinationSpaceRole, RoleWithHierarchy instanceRole)
             throws Exception
     {
-        Sample sample = create(aSample());
-        String user =
-                create(aSession().withSpaceRole(destinationSpaceRole, destinationSpace)
-                        .withInstanceRole(instanceRole)
-                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
-                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
-
-        perform(anUpdateOf(sample).toExperiment(destinationExperiment).as(user));
+        checkAssigningSharedSampleToExperiment(destinationSpaceRole, instanceRole);
     }
 
     @Test(dataProvider = "rolesNotAllowedToAssignSharedSampleToExperiment", expectedExceptions =
@@ -596,14 +535,7 @@ public class AssignSampleToExperimentTest extends BaseTest
             RoleWithHierarchy destinationSpaceRole, RoleWithHierarchy instanceRole)
             throws Exception
     {
-        Sample sample = create(aSample());
-        String user =
-                create(aSession().withSpaceRole(destinationSpaceRole, destinationSpace)
-                        .withInstanceRole(instanceRole)
-                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
-                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
-
-        perform(anUpdateOf(sample).toExperiment(destinationExperiment).as(user));
+        checkAssigningSharedSampleToExperiment(destinationSpaceRole, instanceRole);
     }
 
     @Test(dataProvider = "rolesAllowedToAssignSampleToExperimentThroughExperimentUpdate", groups = "authorization")
@@ -611,14 +543,7 @@ public class AssignSampleToExperimentTest extends BaseTest
             RoleWithHierarchy destinationSpaceRole, RoleWithHierarchy instanceRole)
             throws Exception
     {
-        Sample sample = create(aSample().inSpace(destinationSpace));
-        String user =
-                create(aSession().withSpaceRole(destinationSpaceRole, destinationSpace)
-                        .withInstanceRole(instanceRole)
-                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
-                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
-
-        perform(anUpdateOf(destinationExperiment).withSamples(sample).as(user));
+        checkAssigningSamplesToExperiment(destinationSpaceRole, instanceRole);
     }
 
     @Test(dataProvider = "rolesNotAllowedToAssignSampleToExperimentThroughExperimentUpdate", expectedExceptions =
@@ -627,14 +552,45 @@ public class AssignSampleToExperimentTest extends BaseTest
             RoleWithHierarchy destinationSpaceRole, RoleWithHierarchy instanceRole)
             throws Exception
     {
-        Sample sample = create(aSample().inSpace(destinationSpace));
+        checkAssigningSamplesToExperiment(destinationSpaceRole, instanceRole);
+    }
+
+    private void checkAssigningSampleToExperiment(RoleWithHierarchy sourceSpaceRole, RoleWithHierarchy destinationSpaceRole,
+            RoleWithHierarchy instanceRole)
+    {
+        String user =
+                create(aSession().withSpaceRole(sourceSpaceRole, sourceSpace)
+                        .withSpaceRole(destinationSpaceRole, destinationSpace)
+                        .withInstanceRole(instanceRole)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
+
+        Sample sample = create(aSample().inExperiment(sourceExperiment));
+        reassignSampleToExperiment(sample.getPermId(), destinationExperiment.getIdentifier(), user);
+    }
+    
+    private void checkAssigningSharedSampleToExperiment(RoleWithHierarchy destinationSpaceRole, RoleWithHierarchy instanceRole)
+    {
+        String user =
+                create(aSession().withSpaceRole(destinationSpaceRole, destinationSpace)
+                        .withInstanceRole(instanceRole)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
+        
+        Sample sample = create(aSample());
+        reassignSampleToExperiment(sample.getPermId(), destinationExperiment.getIdentifier(), user);
+    }
+    
+    private void checkAssigningSamplesToExperiment(RoleWithHierarchy destinationSpaceRole, RoleWithHierarchy instanceRole)
+    {
         String user =
                 create(aSession().withSpaceRole(destinationSpaceRole, destinationSpace)
                         .withInstanceRole(instanceRole)
                         .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
                         .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
 
-        perform(anUpdateOf(destinationExperiment).withSamples(sample).as(user));
+        Sample sample = create(aSample().inSpace(destinationSpace));
+        reassignSamplesToExperiment(destinationExperiment.getIdentifier(), Arrays.asList(sample.getPermId()), user);
     }
 
     @BeforeClass(dependsOnMethods = "loginAsSystem")
@@ -694,7 +650,7 @@ public class AssignSampleToExperimentTest extends BaseTest
                 and(rule(destination, RoleWithHierarchy.SPACE_USER),
                         rule(instance, RoleWithHierarchy.INSTANCE_ETL_SERVER));
     }
-/*
+
     @DataProvider
     Object[][] rolesAllowedToAssignSampleToExperiment()
     {
@@ -736,7 +692,7 @@ public class AssignSampleToExperimentTest extends BaseTest
         return RolePermutator.getAcceptedPermutations(not(assignSharedSampleToExperimentRule),
                 destination, instance);
     }
- */    
+     
     
     private void reassignSampleToExperiment(SampleNode sampleNode, ExperimentNode experimentNodeOrNull)
     {
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/entitygraph/EntityGraphManager.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/entitygraph/EntityGraphManager.java
index 4b7f274af5f9e226fd6e17e53d1c54295300e00e..6f33ccd7599e7fc782d1af76055c315a328638d6 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/entitygraph/EntityGraphManager.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/entitygraph/EntityGraphManager.java
@@ -26,7 +26,6 @@ import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -72,7 +71,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
 
 /**
  * Helper class which creates a graph of entities of kind experiment, sample, and data set based on a
- * textual description.
+ * textual description. A simple language defines the entities and its relations.
  *
  * @author Franz-Josef Elmer
  */
@@ -190,6 +189,8 @@ public class EntityGraphManager
         for (SampleNode sampleNode : g.getSamples().values())
         {
             StringBuilder builder2 = new StringBuilder();
+            render(builder2, "components", repository.getComponentSampleNodes(sampleNode));
+            render(builder2, "children", repository.getChildrenSampleNodes(sampleNode));
             render(builder2, "data sets", repository.getDataSetNodes(sampleNode));
             appendNodeTo(builder, getIdentifierAndType(sampleNode), builder2);
         }
@@ -382,21 +383,27 @@ public class EntityGraphManager
         try
         {
             NewSample sample = new NewSample();
-            String prefix = space == null ? "/" : space.getIdentifier() + "/";
-            if (sampleNode.isShared())
-            {
-                prefix = "/";
-            } else if (sampleNode.getSpace() != null)
-            {
-                prefix = createSpace(sampleNode.getSpace()).getIdentifier() + "/";
-            }
-            sample.setIdentifier(prefix + sampleNode.getCode() + generateUniqueId());
+            sample.setIdentifier(createSampleIdentifier(space, sampleNode));
             sample.setSampleType(defaultSampleType);
             ExperimentNode experimentNode = sampleNode.getExperiment();
             if (experimentNode != null)
             {
                 sample.setExperimentIdentifier(repository.tryGetExperiment(experimentNode).getIdentifier());
             }
+            List<String> parentIdentifiers = getParentIdentifiers(sampleNode);
+            sample.setParentsOrNull(parentIdentifiers.toArray(new String[0]));
+            SampleNode container = sampleNode.getContainer();
+            if (container != null)
+            {
+                Sample containerSample = repository.tryGetSample(container);
+                if (containerSample == null)
+                {
+                    throw new IllegalStateException("Sample " + container.getCode() 
+                            + " is specified as container of " + sampleNode.getCode() 
+                            + " but hasn't yet created.");
+                }
+                sample.setContainerIdentifier(containerSample.getIdentifier());
+            }
             sample.setProperties(new IEntityProperty[0]);
             sample.setAttachments(Collections.<NewAttachment>emptyList());
             service.registerSample(sessionToken, sample, null);
@@ -407,6 +414,36 @@ public class EntityGraphManager
                     + ": " + ex.getMessage(), ex);
         }
     }
+
+    private List<String> getParentIdentifiers(SampleNode sampleNode)
+    {
+        List<String> parentIdentifiers = new ArrayList<String>();
+        for (SampleNode parent : sampleNode.getParents())
+        {
+            Sample parentSample = repository.tryGetSample(parent);
+            if (parentSample == null)
+            {
+                throw new IllegalStateException("Sample " + parent.getCode() 
+                        + " is specified as parent of " + sampleNode.getCode() 
+                        + " but hasn't yet created.");
+            }
+            parentIdentifiers.add(parentSample.getIdentifier());
+        }
+        return parentIdentifiers;
+    }
+
+    private String createSampleIdentifier(Space space, SampleNode sampleNode)
+    {
+        String prefix = space == null ? "/" : space.getIdentifier() + "/";
+        if (sampleNode.isShared())
+        {
+            prefix = "/";
+        } else if (sampleNode.getSpace() != null)
+        {
+            prefix = createSpace(sampleNode.getSpace()).getIdentifier() + "/";
+        }
+        return prefix + sampleNode.getCode() + generateUniqueId();
+    }
     
     private Sample refresh(Sample sample)
     {
@@ -425,19 +462,7 @@ public class EntityGraphManager
             {
                 dataSetKind = DataSetKind.CONTAINER;
                 NewContainerDataSet cont = new NewContainerDataSet();
-                List<String> componentCodes = new ArrayList<String>();
-                for (DataSetNode component : components)
-                {
-                    AbstractExternalData componentDataSet = repository.tryGetDataSet(component);
-                    if (componentDataSet == null)
-                    {
-                        throw new IllegalStateException("Data set " + component.getCode() 
-                                + " is specified as component of " + dataSetNode.getCode() 
-                                + " but hasn't yet created.");
-                    }
-                    componentCodes.add(componentDataSet.getCode());
-                }
-                cont.setContainedDataSetCodes(componentCodes);
+                cont.setContainedDataSetCodes(getRelatedDataSetIdentifiers(dataSetNode, "component", components));
                 dataSet = cont;
             }
             dataSet.setCode(dataSetNode.getCode() + generateUniqueId());
@@ -452,29 +477,8 @@ public class EntityGraphManager
             dataSet.setLocation(UUID.randomUUID().toString());
             dataSet.setStorageFormat(StorageFormat.PROPRIETARY);
             dataSet.setDataStoreCode("STANDARD");
-            if (dataSetNode.getSample() != null)
-            {
-                Sample sample = repository.tryGetSample(dataSetNode.getSample());
-                dataSet.setSampleIdentifierOrNull(SampleIdentifierFactory.parse(sample));
-            } else if (dataSetNode.getExperiment() != null)
-            {
-                String identifier = repository.tryGetExperiment(dataSetNode.getExperiment()).getIdentifier();
-                dataSet.setExperimentIdentifierOrNull(ExperimentIdentifierFactory.parse(identifier));
-            }
-            List<String> parentCodes = new ArrayList<String>();
-            List<DataSetNode> parents = dataSetNode.getParents();
-            for (DataSetNode parent : parents)
-            {
-                AbstractExternalData parentDataSet = repository.tryGetDataSet(parent);
-                if (parentDataSet == null)
-                {
-                    throw new IllegalStateException("Data set " + parent.getCode() 
-                            + " is specified as parent of " + dataSetNode.getCode() 
-                            + " but hasn't yet created.");
-                }
-                parentCodes.add(parentDataSet.getCode());
-            }
-            dataSet.setParentDataSetCodes(parentCodes);
+            addSampleOrExperimentIdentifier(dataSet, dataSetNode);
+            dataSet.setParentDataSetCodes(getRelatedDataSetIdentifiers(dataSetNode, "parent", dataSetNode.getParents()));
             if (dataSet.getSampleIdentifierOrNull() != null)
             {
                 service.registerDataSet(sessionToken, dataSet.getSampleIdentifierOrNull(), dataSet);
@@ -490,6 +494,36 @@ public class EntityGraphManager
         }
     }
 
+    private void addSampleOrExperimentIdentifier(NewExternalData dataSet, DataSetNode dataSetNode)
+    {
+        if (dataSetNode.getSample() != null)
+        {
+            Sample sample = repository.tryGetSample(dataSetNode.getSample());
+            dataSet.setSampleIdentifierOrNull(SampleIdentifierFactory.parse(sample));
+        } else if (dataSetNode.getExperiment() != null)
+        {
+            String identifier = repository.tryGetExperiment(dataSetNode.getExperiment()).getIdentifier();
+            dataSet.setExperimentIdentifierOrNull(ExperimentIdentifierFactory.parse(identifier));
+        }
+    }
+
+    private List<String> getRelatedDataSetIdentifiers(DataSetNode dataSetNode, String relationType, List<DataSetNode> dataSetNodes)
+    {
+        List<String> parentCodes = new ArrayList<String>();
+        for (DataSetNode parent : dataSetNodes)
+        {
+            AbstractExternalData parentDataSet = repository.tryGetDataSet(parent);
+            if (parentDataSet == null)
+            {
+                throw new IllegalStateException("Data set " + parent.getCode() 
+                        + " is specified as " + relationType + " of " + dataSetNode.getCode() 
+                        + " but hasn't yet created.");
+            }
+            parentCodes.add(parentDataSet.getCode());
+        }
+        return parentCodes;
+    }
+
     private AbstractExternalData refresh(AbstractExternalData data)
     {
         return service.tryGetDataSet(sessionToken, data.getCode());
@@ -524,7 +558,9 @@ public class EntityGraphManager
 
     private void createSamples(Space space, EntityGraphGenerator g)
     {
-        for (SampleNode sampleNode : g.getSamples().values())
+        ArrayList<SampleNode> sampleNodes = new ArrayList<SampleNode>(g.getSamples().values());
+//        Collections.reverse(sampleNodes);
+        for (SampleNode sampleNode : sampleNodes)
         {
             repository.put(sampleNode, createSample(sampleNode, space));
         }
@@ -556,10 +592,12 @@ public class EntityGraphManager
         private Set<DataSetNode> modifiedDataSetNodes = new HashSet<DataSetNode>();
 
         private Map<Long, Set<Long>> experimentSamplesMap = new HashMap<Long, Set<Long>>();
+        private Map<Long, Set<Long>> childrenSamplesMap = new HashMap<Long, Set<Long>>();
+        private Map<Long, Set<Long>> componentSamplesMap = new HashMap<Long, Set<Long>>();
         private Map<Long, Set<Long>> experimentDataSetsMap = new HashMap<Long, Set<Long>>();
         private Map<Long, Set<Long>> sampleDataSetsMap = new HashMap<Long, Set<Long>>();
         private Map<Long, Set<Long>> componentDataSetsMap = new HashMap<Long, Set<Long>>();
-        private Map<Long, Set<Long>> parentsDataSetsMap = new HashMap<Long, Set<Long>>();
+        private Map<Long, Set<Long>> parentDataSetsMap = new HashMap<Long, Set<Long>>();
         
         public String renderNodeToDtoMapping()
         {
@@ -648,6 +686,18 @@ public class EntityGraphManager
         }
         
         void refreshGraph(boolean showWhereIAm)
+        {
+            refreshEntityDtos();
+            refreshSamplesMap();
+            refreshDataSetsMap();
+            if (showWhereIAm)
+            {
+                printWhereIAm();
+            }
+            System.out.println("Entities mapping:\n" + renderNodeToDtoMapping());
+        }
+
+        private void refreshEntityDtos()
         {
             for (Long id : experimentsNodeToDtoMap.keySet())
             {
@@ -661,48 +711,48 @@ public class EntityGraphManager
             {
                 dataSetsNodeToDtoMap.put(id, refresh(dataSetsNodeToDtoMap.get(id)));
             }
+        }
+
+        private void refreshSamplesMap()
+        {
             experimentSamplesMap.clear();
+            childrenSamplesMap.clear();
+            componentSamplesMap.clear();
             for (Sample sample : samplesNodeToDtoMap.values())
             {
                 Experiment experiment = sample.getExperiment();
-                if (experiment != null)
+                addToEntitiesMap(experimentSamplesMap, experiment, sample);
+                for (Sample parentSample : sample.getParents())
                 {
-                    Long id = experiment.getId();
-                    Set<Long> sampleIds = experimentSamplesMap.get(id);
-                    if (sampleIds == null)
-                    {
-                        sampleIds = new TreeSet<Long>();
-                        experimentSamplesMap.put(id, sampleIds);
-                    }
-                    sampleIds.add(sample.getId());
+                    addToEntitiesMap(childrenSamplesMap, parentSample, sample);
+                }
+                Sample container = sample.getContainer();
+                if (container != null)
+                {
+                    addToEntitiesMap(componentSamplesMap, container, sample);
                 }
             }
+        }
+
+        private void refreshDataSetsMap()
+        {
             experimentDataSetsMap.clear();
-            for (AbstractExternalData dataSet : dataSetsNodeToDtoMap.values())
-            {
-                addToDataSetsMap(experimentDataSetsMap, dataSet, dataSet.getExperiment());
-            }
             sampleDataSetsMap.clear();
             componentDataSetsMap.clear();
+            parentDataSetsMap.clear();
             for (AbstractExternalData dataSet : dataSetsNodeToDtoMap.values())
             {
-                addToDataSetsMap(sampleDataSetsMap, dataSet, dataSet.getSample());
-                List<ContainerDataSet> containerDataSets = dataSet.getContainerDataSets();
-                for (ContainerDataSet containerDataSet : containerDataSets)
+                addToEntitiesMap(experimentDataSetsMap, dataSet.getExperiment(), dataSet);
+                addToEntitiesMap(sampleDataSetsMap, dataSet.getSample(), dataSet);
+                for (ContainerDataSet containerDataSet : dataSet.getContainerDataSets())
                 {
-                    addToDataSetsMap(componentDataSetsMap, dataSet, containerDataSet);
+                    addToEntitiesMap(componentDataSetsMap, containerDataSet, dataSet);
                 }
-                Collection<AbstractExternalData> parents = dataSet.getParents();
-                for (AbstractExternalData parentDataSet : parents)
+                for (AbstractExternalData parentDataSet : dataSet.getParents())
                 {
-                    addToDataSetsMap(parentsDataSetsMap, parentDataSet, dataSet);
+                    addToEntitiesMap(parentDataSetsMap, dataSet, parentDataSet);
                 }
             }
-            if (showWhereIAm)
-            {
-                printWhereIAm();
-            }
-            System.out.println("Entities mapping:\n" + renderNodeToDtoMapping());
         }
 
         private void printWhereIAm()
@@ -716,19 +766,18 @@ public class EntityGraphManager
             System.out.println("...");
         }
         
-        private void addToDataSetsMap(Map<Long, Set<Long>> holderDataSetsMap, 
-                AbstractExternalData dataSet, IIdHolder idHolder)
+        private void addToEntitiesMap(Map<Long, Set<Long>> entityToEntitiesMap, IIdHolder keyEntity, IIdHolder valueEntity)
         {
-            if (idHolder != null)
+            if (keyEntity != null)
             {
-                Long id = idHolder.getId();
-                Set<Long> dataSetIds = holderDataSetsMap.get(id);
-                if (dataSetIds == null)
+                Long id = keyEntity.getId();
+                Set<Long> entityIds = entityToEntitiesMap.get(id);
+                if (entityIds == null)
                 {
-                    dataSetIds = new TreeSet<Long>();
-                    holderDataSetsMap.put(id, dataSetIds);
+                    entityIds = new TreeSet<Long>();
+                    entityToEntitiesMap.put(id, entityIds);
                 }
-                dataSetIds.add(dataSet.getId());
+                entityIds.add(valueEntity.getId());
             }
         }
         
@@ -839,20 +888,20 @@ public class EntityGraphManager
 
         Set<SampleNode> getSampleNodes(ExperimentNode experimentNode)
         {
-            Set<SampleNode> result = new LinkedHashSet<SampleNode>();
-            Experiment experiment = experimentsNodeToDtoMap.get(experimentNode.getId());
-            if (experiment != null)
-            {
-                Set<Long> sampleDtoIds = experimentSamplesMap.get(experiment.getId());
-                if (sampleDtoIds != null)
-                {
-                    for (Long dtoId : sampleDtoIds)
-                    {
-                        result.add(samplesDtoToNodeMap.get(dtoId));
-                    }
-                }
-            }
-            return result;
+            return getEntityNodes(experimentSamplesMap, experimentsNodeToDtoMap.get(experimentNode.getId()), 
+                    samplesDtoToNodeMap);
+        }
+        
+        Set<SampleNode> getChildrenSampleNodes(SampleNode sampleNode)
+        {
+            return getEntityNodes(childrenSamplesMap, samplesNodeToDtoMap.get(sampleNode.getId()), 
+                    samplesDtoToNodeMap);
+        }
+        
+        Set<SampleNode> getComponentSampleNodes(SampleNode sampleNode)
+        {
+            return getEntityNodes(componentSamplesMap, samplesNodeToDtoMap.get(sampleNode.getId()), 
+                    samplesDtoToNodeMap);
         }
         
         Set<DataSetNode> getDataSetNodes(ExperimentNode experimentNode)
@@ -872,20 +921,26 @@ public class EntityGraphManager
         
         Set<DataSetNode> getParentDataSetNodes(DataSetNode childDataSetNode)
         {
-            return getDataSetNodes(parentsDataSetsMap, dataSetsNodeToDtoMap.get(childDataSetNode.getId()));
+            return getDataSetNodes(parentDataSetsMap, dataSetsNodeToDtoMap.get(childDataSetNode.getId()));
         }
         
-        private Set<DataSetNode> getDataSetNodes(Map<Long, Set<Long>> idHolderDataSetsMap, IIdHolder experiment)
+        private Set<DataSetNode> getDataSetNodes(Map<Long, Set<Long>> idHolderDataSetsMap, IIdHolder idHolder)
         {
-            Set<DataSetNode> result = new TreeSet<DataSetNode>();
-            if (experiment != null)
+            return getEntityNodes(idHolderDataSetsMap, idHolder, dataSetsDtoToNodeMap);
+        }
+
+        private <T extends EntityNode> Set<T> getEntityNodes(Map<Long, Set<Long>> idHolderEntitiesMap, IIdHolder idHolder, 
+                Map<Long, T> dtoToNodeMap)
+        {
+            Set<T> result = new TreeSet<T>();
+            if (idHolder != null)
             {
-                Set<Long> dataSetDtoIds = idHolderDataSetsMap.get(experiment.getId());
-                if (dataSetDtoIds != null)
+                Set<Long> entityDtoIds = idHolderEntitiesMap.get(idHolder.getId());
+                if (entityDtoIds != null)
                 {
-                    for (Long dtoId : dataSetDtoIds)
+                    for (Long dtoId : entityDtoIds)
                     {
-                        result.add(dataSetsDtoToNodeMap.get(dtoId));
+                        result.add(dtoToNodeMap.get(dtoId));
                     }
                 }
             }