diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/RelationshipService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/RelationshipService.java
index 4949b04103e2e458b28fa3bf70c2565d942f6147..3f9a7ff90a46f00d2e0956fad3b6434c86830df4 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/RelationshipService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/RelationshipService.java
@@ -22,6 +22,7 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.DAOFactory;
 import ch.systemsx.cisd.openbis.generic.shared.IRelationshipService;
 import ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetRelationshipPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.IAuthSession;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
@@ -41,6 +42,9 @@ public class RelationshipService implements IRelationshipService
     private static final String ERR_SAMPLE_PARENT_RELATIONSHIP_NOT_FOUND =
             "Sample '%s' did not have parent '%s'";
 
+    private static final String ERR_DATASET_PARENT_RELATIONSHIP_NOT_FOUND =
+            "DataSet '%s' did not have parent '%s'";
+
     private DAOFactory daoFactory;
 
     @Override
@@ -161,6 +165,49 @@ public class RelationshipService implements IRelationshipService
         sample.setContainer(null);
     }
 
+    @Override
+    public void addParentToDataSet(IAuthSession session, DataPE data, DataPE parent)
+    {
+        PersonPE actor = session.tryGetPerson();
+        data.addParentRelationship(new DataSetRelationshipPE(parent, data, actor));
+    }
+
+    @Override
+    public void removeParentFromDataSet(IAuthSession session, DataPE data, DataPE parent)
+    {
+        DataSetRelationshipPE remove = null;
+        for (DataSetRelationshipPE r : data.getParentRelationships())
+        {
+            if (r.getParentDataSet().equals(parent))
+            {
+                remove = r;
+                break;
+            }
+        }
+
+        if (remove != null)
+        {
+            data.removeParentRelationship(remove);
+        } else
+        {
+            throw UserFailureException.fromTemplate(ERR_DATASET_PARENT_RELATIONSHIP_NOT_FOUND, data
+                    .getCode(), parent.getCode());
+        }
+    }
+
+    @Override
+    public void assignDataSetToContainer(IAuthSession session, DataPE data, DataPE container)
+    {
+        PersonPE modifier = session.tryGetPerson();
+        container.addComponent(data, modifier);
+    }
+
+    @Override
+    public void removeDataSetFromContainer(IAuthSession session, DataPE sample)
+    {
+        sample.getContainer().removeComponent(sample);
+    }
+
     public void setDaoFactory(DAOFactory daoFactory)
     {
         this.daoFactory = daoFactory;
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 ebf5d549087bc6f3f71482ece46a8f0a902caf91..55705f790a01bc8624e3af7f46da2a0484644684 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
@@ -52,7 +52,7 @@ import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils;
 public abstract class AbstractDataSetBusinessObject extends AbstractSampleIdentifierBusinessObject
 {
 
-    private IRelationshipService relationshipService;
+    protected IRelationshipService relationshipService;
 
     public AbstractDataSetBusinessObject(IDAOFactory daoFactory, Session session,
             IRelationshipService relationshipService)
@@ -185,8 +185,6 @@ public abstract class AbstractDataSetBusinessObject extends AbstractSampleIdenti
 
     protected void replaceParents(DataPE child, Set<DataPE> newParents, boolean validate)
     {
-        PersonPE actor = findPerson();
-
         // quick check for deletions
         for (DataPE parent : newParents)
         {
@@ -212,13 +210,13 @@ public abstract class AbstractDataSetBusinessObject extends AbstractSampleIdenti
         {
             if (false == newParents.contains(r.getParentDataSet()))
             {
-                child.removeParentRelationship(r);
+                relationshipService.removeParentFromDataSet(session, child, r.getParentDataSet());
             }
         }
 
         for (DataPE newParent : newParents)
         {
-            child.addParentRelationship(new DataSetRelationshipPE(newParent, child, actor));
+            relationshipService.addParentToDataSet(session, child, newParent);
         }
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java
index db531395e2d126cb96b49e2e8066e032713f2993..57eb809783c63bf59b84ca36ef95f4c23cda30d8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java
@@ -653,10 +653,9 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
 
     private void addComponents(Collection<DataPE> componentsToAdd)
     {
-        PersonPE modifier = findPerson();
         for (DataPE component : componentsToAdd)
         {
-            data.addComponent(component, modifier);
+            relationshipService.assignDataSetToContainer(session, component, data);
         }
     }
 
@@ -664,7 +663,7 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
     {
         for (DataPE component : componentsToRemove)
         {
-            data.removeComponent(component);
+            relationshipService.removeDataSetFromContainer(session, component);
         }
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IRelationshipService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IRelationshipService.java
index 7b849ae39b9959bae5c82590386605b292b162d8..a875a0d5a94cae3c2c304739ade8e085002752ab 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IRelationshipService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IRelationshipService.java
@@ -167,4 +167,42 @@ public interface IRelationshipService
             @AuthorizationGuard(guardClass = SamplePEPredicate.class)
             SamplePE sample);
 
+    @Transactional(propagation = Propagation.MANDATORY)
+    @RolesAllowed(value =
+        { RoleWithHierarchy.SPACE_ETL_SERVER, RoleWithHierarchy.SPACE_POWER_USER })
+    @Capability("ADD_PARENT_TO_DATASET")
+    public void addParentToDataSet(IAuthSession session,
+            @AuthorizationGuard(guardClass = DataPEPredicate.class)
+            DataPE data,
+            @AuthorizationGuard(guardClass = DataPEPredicate.class)
+            DataPE parent);
+
+    @Transactional(propagation = Propagation.MANDATORY)
+    @RolesAllowed(value =
+        { RoleWithHierarchy.SPACE_ETL_SERVER, RoleWithHierarchy.SPACE_POWER_USER })
+    @Capability("REMOVE_PARENT_FROM_DATASET")
+    public void removeParentFromDataSet(IAuthSession session,
+            @AuthorizationGuard(guardClass = DataPEPredicate.class)
+            DataPE data,
+            @AuthorizationGuard(guardClass = DataPEPredicate.class)
+            DataPE parent);
+
+    @Transactional(propagation = Propagation.MANDATORY)
+    @RolesAllowed(value =
+        { RoleWithHierarchy.SPACE_ETL_SERVER, RoleWithHierarchy.SPACE_POWER_USER })
+    @Capability("ADD_CONTAINER_TO_DATASET")
+    public void assignDataSetToContainer(IAuthSession session,
+            @AuthorizationGuard(guardClass = DataPEPredicate.class)
+            DataPE data,
+            @AuthorizationGuard(guardClass = DataPEPredicate.class)
+            DataPE container);
+
+    @Transactional(propagation = Propagation.MANDATORY)
+    @RolesAllowed(value =
+        { RoleWithHierarchy.SPACE_ETL_SERVER, RoleWithHierarchy.SPACE_POWER_USER })
+    @Capability("REMOVE_CONTAINER_FROM_DATASET")
+    public void removeDataSetFromContainer(IAuthSession session,
+            @AuthorizationGuard(guardClass = DataPEPredicate.class)
+            DataPE sample);
+
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBOTest.java
index ebdc64cffab906d4b136a4511aa16f11edcb3419..bff5f815a15d8416dcb31d55a4c2959274161ef0 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBOTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBOTest.java
@@ -55,6 +55,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataManagementSystemPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.FileFormatTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.IAuthSession;
 import ch.systemsx.cisd.openbis.generic.shared.dto.LocatorTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.NewContainerDataSet;
 import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData;
@@ -301,6 +302,9 @@ public class DataBOTest extends AbstractBOTest
                 {
                     one(dataDAO).tryToFindDataSetByCode(PARENT_CODE);
                     will(returnValue(data));
+
+                    one(relationshipService).addParentToDataSet(with(any(IAuthSession.class)),
+                            with(any(DataPE.class)), with(any(DataPE.class)));
                 }
             });
 
@@ -312,8 +316,6 @@ public class DataBOTest extends AbstractBOTest
         assertEquals(null, loadedData.tryGetSample());
         assertSame(true, loadedData.isMeasured());
         assertSame(dataStore, loadedData.getDataStore());
-        assertEquals(1, loadedData.getParents().size());
-        assertSame(data, loadedData.getParents().iterator().next());
         context.assertIsSatisfied();
     }
 
@@ -347,6 +349,10 @@ public class DataBOTest extends AbstractBOTest
                     will(returnValue(dataSetTypeUnknown));
 
                     one(dataDAO).createDataSet(parentData, EXAMPLE_PERSON);
+
+                    one(relationshipService).addParentToDataSet(with(any(IAuthSession.class)),
+                            with(any(DataPE.class)), with(any(DataPE.class)));
+
                 }
             });
 
@@ -358,8 +364,6 @@ public class DataBOTest extends AbstractBOTest
         assertEquals(null, data.tryGetSample());
         assertSame(true, data.isMeasured());
         assertSame(dataStore, data.getDataStore());
-        assertEquals(1, data.getParents().size());
-        assertEquals(parentData, data.getParents().iterator().next());
         context.assertIsSatisfied();
     }
 
@@ -394,6 +398,10 @@ public class DataBOTest extends AbstractBOTest
                     will(returnValue(dataSetTypeUnknown));
 
                     one(dataDAO).createDataSet(parentData, EXAMPLE_PERSON);
+
+                    one(relationshipService).addParentToDataSet(with(any(IAuthSession.class)),
+                            with(any(DataPE.class)), with(any(DataPE.class)));
+
                 }
             });
 
@@ -404,8 +412,6 @@ public class DataBOTest extends AbstractBOTest
         assertSame(null, data.tryGetSample());
         assertSame(true, data.isMeasured());
         assertSame(dataStore, data.getDataStore());
-        assertEquals(1, data.getParents().size());
-        assertEquals(parentData, data.getParents().iterator().next());
         context.assertIsSatisfied();
     }
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/RelationshipServiceAuthorizationTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/RelationshipServiceAuthorizationTest.java
index 4e00a12f19d6abfe59a50f148f12dc60d47403e4..8fbafadf1825342b72af2815ee93b1286781be62 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/RelationshipServiceAuthorizationTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/RelationshipServiceAuthorizationTest.java
@@ -76,11 +76,9 @@ public class RelationshipServiceAuthorizationTest extends BaseTest
 
     Sample sharedSample;
 
-    Sample childSample;
+    ExternalData sourceDataSet;
 
-    Sample parentSample;
-
-    ExternalData dataSet;
+    ExternalData destinationDataSet;
 
     @BeforeClass
     public void createFixture() throws Exception
@@ -89,7 +87,6 @@ public class RelationshipServiceAuthorizationTest extends BaseTest
         sourceProject = create(aProject().inSpace(sourceSpace));
         sourceExperiment = create(anExperiment().inProject(sourceProject));
         sourceSample = create(aSample().inExperiment(sourceExperiment));
-        dataSet = create(aDataSet().inSample(sourceSample));
 
         destinationSpace = create(aSpace());
         destinationProject = create(aProject().inSpace(destinationSpace));
@@ -98,8 +95,8 @@ public class RelationshipServiceAuthorizationTest extends BaseTest
 
         sharedSample = create(aSample());
 
-        parentSample = create(aSample().inSpace(sourceSpace));
-        childSample = create(aSample().inSpace(destinationSpace).withParent(parentSample));
+        sourceDataSet = create(aDataSet().inSample(sourceSample));
+        destinationDataSet = create(aDataSet().inSample(destinationSample));
 
         unrelatedAdmin = create(aSpace());
         unrelatedObserver = create(aSpace());
@@ -289,6 +286,104 @@ public class RelationshipServiceAuthorizationTest extends BaseTest
         removeParentFromSample(sourceSpaceRole, destinationSpaceRole, instanceRole);
     }
 
+    @Test(dataProvider = "rolesAllowedToAddContainerToSample", groups = "authorization")
+    public void addingContainerToSampleIsAuthorizedFor(RoleWithHierarchy sourceSpaceRole,
+            RoleWithHierarchy destinationSpaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        addContainerToSample(sourceSpaceRole, destinationSpaceRole, instanceRole);
+    }
+
+    @Test(dataProvider = "rolesNotAllowedToAddContainerToSample", expectedExceptions =
+        { AuthorizationFailureException.class }, groups = "authorization")
+    public void addingContainerToSampleIsNotAuthorizedFor(RoleWithHierarchy sourceSpaceRole,
+            RoleWithHierarchy destinationSpaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        addContainerToSample(sourceSpaceRole, destinationSpaceRole, instanceRole);
+    }
+
+    @Test(dataProvider = "rolesAllowedToRemoveContainerFromSample", groups = "authorization")
+    public void removingContainerFromSampleIsAuthorizedFor(RoleWithHierarchy spaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        removeContainerFromSample(spaceRole, instanceRole);
+    }
+
+    @Test(dataProvider = "rolesNotAllowedToRemoveContainerFromSample", expectedExceptions =
+        { AuthorizationFailureException.class }, groups = "authorization")
+    public void removingContainerFromSampleIsNotAuthorizedFor(RoleWithHierarchy spaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        removeContainerFromSample(spaceRole, instanceRole);
+    }
+
+    @Test(dataProvider = "rolesAllowedToAddParentToDataSet", groups = "authorization")
+    public void addingParentToDataSetIsAuthorizedFor(RoleWithHierarchy sourceSpaceRole,
+            RoleWithHierarchy destinationSpaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        addParentToDataSet(sourceSpaceRole, destinationSpaceRole, instanceRole);
+    }
+
+    @Test(dataProvider = "rolesNotAllowedToAddParentToDataSet", expectedExceptions =
+        { AuthorizationFailureException.class }, groups = "authorization")
+    public void addingParentToDataSetIsNotAuthorizedFor(RoleWithHierarchy sourceSpaceRole,
+            RoleWithHierarchy destinationSpaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        addParentToDataSet(sourceSpaceRole, destinationSpaceRole, instanceRole);
+    }
+
+    @Test(dataProvider = "rolesAllowedToRemoveParentFromDataSet", groups = "authorization")
+    public void removingParentFromDataSetIsAuthorizedFor(RoleWithHierarchy sourceSpaceRole,
+            RoleWithHierarchy destinationSpaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        removeParentFromDataSet(sourceSpaceRole, destinationSpaceRole, instanceRole);
+    }
+
+    @Test(dataProvider = "rolesNotAllowedToRemoveParentFromDataSet", expectedExceptions =
+        { AuthorizationFailureException.class }, groups = "authorization")
+    public void removingParentFromDataSetIsNotAuthorizedFor(RoleWithHierarchy sourceSpaceRole,
+            RoleWithHierarchy destinationSpaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        removeParentFromDataSet(sourceSpaceRole, destinationSpaceRole, instanceRole);
+    }
+
+    @Test(dataProvider = "rolesAllowedToAddContainerToDataSet", groups = "authorization")
+    public void addingContainerToDataSetIsAuthorizedFor(RoleWithHierarchy sourceSpaceRole,
+            RoleWithHierarchy destinationSpaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        addContainerToDataSet(sourceSpaceRole, destinationSpaceRole, instanceRole);
+    }
+
+    @Test(dataProvider = "rolesNotAllowedToAddContainerToDataSet", expectedExceptions =
+        { AuthorizationFailureException.class }, groups = "authorization")
+    public void addingContainerToDataSetIsNotAuthorizedFor(RoleWithHierarchy sourceSpaceRole,
+            RoleWithHierarchy destinationSpaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        addContainerToDataSet(sourceSpaceRole, destinationSpaceRole, instanceRole);
+    }
+
+    @Test(dataProvider = "rolesAllowedToRemoveContainerFromDataSet", groups = "authorization")
+    public void removingContainerFromDataSetIsAuthorizedFor(RoleWithHierarchy spaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        removeContainerFromDataSet(spaceRole, instanceRole);
+    }
+
+    @Test(dataProvider = "rolesNotAllowedToRemoveContainerFromDataSet", expectedExceptions =
+        { AuthorizationFailureException.class }, groups = "authorization")
+    public void removingContainerFromDataSetIsNotAuthorizedFor(RoleWithHierarchy spaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        removeContainerFromDataSet(spaceRole, instanceRole);
+    }
+
     void assignExperimentToProject(RoleWithHierarchy sourceSpaceRole,
             RoleWithHierarchy destinationSpaceRole,
             RoleWithHierarchy instanceRole) throws Exception
@@ -408,7 +503,7 @@ public class RelationshipServiceAuthorizationTest extends BaseTest
                         .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
 
         relationshipService.assignDataSetToExperiment(sessionManager.getSession(session),
-                pe(dataSet), pe(destinationExperiment));
+                pe(sourceDataSet), pe(destinationExperiment));
     }
 
     void assignDataSetToSample(RoleWithHierarchy sourceSpaceRole,
@@ -425,7 +520,7 @@ public class RelationshipServiceAuthorizationTest extends BaseTest
                         .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
 
         relationshipService.assignDataSetToSample(sessionManager.getSession(session),
-                pe(dataSet), pe(destinationSample));
+                pe(sourceDataSet), pe(destinationSample));
     }
 
     void addParentToSample(RoleWithHierarchy sourceSpaceRole,
@@ -458,7 +553,105 @@ public class RelationshipServiceAuthorizationTest extends BaseTest
                         .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
 
         relationshipService.removeParentFromSample(sessionManager.getSession(session),
-                pe(childSample), pe(parentSample));
+                pe(sourceSample), pe(destinationSample));
+    }
+
+    void addContainerToSample(RoleWithHierarchy sourceSpaceRole,
+            RoleWithHierarchy destinationSpaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        String session =
+                create(aSession()
+                        .withSpaceRole(sourceSpaceRole, sourceSpace)
+                        .withSpaceRole(destinationSpaceRole, destinationSpace)
+                        .withInstanceRole(instanceRole)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
+
+        relationshipService.assignSampleToContainer(sessionManager.getSession(session),
+                pe(sourceSample),
+                pe(destinationSample));
+
+    }
+
+    void removeContainerFromSample(RoleWithHierarchy sourceSpaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        String session =
+                create(aSession()
+                        .withSpaceRole(sourceSpaceRole, sourceSpace)
+                        .withInstanceRole(instanceRole)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
+
+        relationshipService.removeSampleFromContainer(sessionManager.getSession(session),
+                pe(this.sourceSample));
+    }
+
+    void addParentToDataSet(RoleWithHierarchy sourceSpaceRole,
+            RoleWithHierarchy destinationSpaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        String session =
+                create(aSession()
+                        .withSpaceRole(sourceSpaceRole, sourceSpace)
+                        .withSpaceRole(destinationSpaceRole, destinationSpace)
+                        .withInstanceRole(instanceRole)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
+
+        relationshipService.addParentToDataSet(sessionManager.getSession(session),
+                pe(sourceDataSet),
+                pe(destinationDataSet));
+
+    }
+
+    void removeParentFromDataSet(RoleWithHierarchy sourceSpaceRole,
+            RoleWithHierarchy destinationSpaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        String session =
+                create(aSession()
+                        .withSpaceRole(sourceSpaceRole, sourceSpace)
+                        .withSpaceRole(destinationSpaceRole, destinationSpace)
+                        .withInstanceRole(instanceRole)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
+
+        relationshipService.removeParentFromDataSet(sessionManager.getSession(session),
+                pe(sourceDataSet), pe(destinationDataSet));
+    }
+
+    void addContainerToDataSet(RoleWithHierarchy sourceSpaceRole,
+            RoleWithHierarchy destinationSpaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        String session =
+                create(aSession()
+                        .withSpaceRole(sourceSpaceRole, sourceSpace)
+                        .withSpaceRole(destinationSpaceRole, destinationSpace)
+                        .withInstanceRole(instanceRole)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
+
+        relationshipService.assignDataSetToContainer(sessionManager.getSession(session),
+                pe(sourceDataSet),
+                pe(destinationDataSet));
+
+    }
+
+    void removeContainerFromDataSet(RoleWithHierarchy sourceSpaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        String session =
+                create(aSession()
+                        .withSpaceRole(sourceSpaceRole, sourceSpace)
+                        .withInstanceRole(instanceRole)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
+
+        relationshipService.removeDataSetFromContainer(sessionManager.getSession(session),
+                pe(this.sourceDataSet));
     }
 
     GuardedDomain instance = new InstanceDomain("instance");
@@ -625,7 +818,7 @@ public class RelationshipServiceAuthorizationTest extends BaseTest
                 source, destination, instance);
     }
 
-    @DataProvider(name = "rolesAllowedRemoveAddParentFromSample")
+    @DataProvider(name = "rolesAllowedRemoveParentFromSample")
     RoleWithHierarchy[][] rolesAllowedToRemoveParentFromSample()
     {
         return RolePermutator.getAcceptedPermutations(spaceAdminOrSpaceEtlServer,
@@ -639,6 +832,90 @@ public class RelationshipServiceAuthorizationTest extends BaseTest
                 source, destination, instance);
     }
 
+    @DataProvider(name = "rolesAllowedToAddContainerToSample")
+    RoleWithHierarchy[][] rolesAllowedToAddContainerToSample()
+    {
+        return RolePermutator.getAcceptedPermutations(spaceAdminOrSpaceEtlServer,
+                source, destination, instance);
+    }
+
+    @DataProvider(name = "rolesNotAllowedToAddContainerToSample")
+    RoleWithHierarchy[][] rolesNotAllowedToAddContainerToSample()
+    {
+        return RolePermutator.getAcceptedPermutations(not(spaceAdminOrSpaceEtlServer),
+                source, destination, instance);
+    }
+
+    @DataProvider(name = "rolesAllowedRemoveContainerFromSample")
+    RoleWithHierarchy[][] rolesAllowedToRemoveContainerFromSample()
+    {
+        return RolePermutator.getAcceptedPermutations(spaceAdminOrSpaceEtlServerSingle,
+                source, instance);
+    }
+
+    @DataProvider(name = "rolesNotAllowedToRemoveContainerFromSample")
+    RoleWithHierarchy[][] rolesNotAllowedToRemoveContainerFromSample()
+    {
+        return RolePermutator.getAcceptedPermutations(not(spaceAdminOrSpaceEtlServerSingle),
+                source, instance);
+    }
+
+    @DataProvider(name = "rolesAllowedToAddParentToDataSet")
+    RoleWithHierarchy[][] rolesAllowedToAddParentToDataSet()
+    {
+        return RolePermutator.getAcceptedPermutations(spaceAdminOrSpaceEtlServer,
+                source, destination, instance);
+    }
+
+    @DataProvider(name = "rolesNotAllowedToAddParentToDataSet")
+    RoleWithHierarchy[][] rolesNotAllowedToAddParentToDataSet()
+    {
+        return RolePermutator.getAcceptedPermutations(not(spaceAdminOrSpaceEtlServer),
+                source, destination, instance);
+    }
+
+    @DataProvider(name = "rolesAllowedRemoveParentFromDataSet")
+    RoleWithHierarchy[][] rolesAllowedToRemoveParentFromDataSet()
+    {
+        return RolePermutator.getAcceptedPermutations(spaceAdminOrSpaceEtlServer,
+                source, destination, instance);
+    }
+
+    @DataProvider(name = "rolesNotAllowedToRemoveParentFromDataSet")
+    RoleWithHierarchy[][] rolesNotAllowedToRemoveParentFromDataSet()
+    {
+        return RolePermutator.getAcceptedPermutations(not(spaceAdminOrSpaceEtlServer),
+                source, destination, instance);
+    }
+
+    @DataProvider(name = "rolesAllowedToAddContainerToDataSet")
+    RoleWithHierarchy[][] rolesAllowedToAddContainerToDataSet()
+    {
+        return RolePermutator.getAcceptedPermutations(spaceAdminOrSpaceEtlServer,
+                source, destination, instance);
+    }
+
+    @DataProvider(name = "rolesNotAllowedToAddContainerToDataSet")
+    RoleWithHierarchy[][] rolesNotAllowedToAddContainerToDataSet()
+    {
+        return RolePermutator.getAcceptedPermutations(not(spaceAdminOrSpaceEtlServer),
+                source, destination, instance);
+    }
+
+    @DataProvider(name = "rolesAllowedRemoveContainerFromDataSet")
+    RoleWithHierarchy[][] rolesAllowedToRemoveContainerFromDataSet()
+    {
+        return RolePermutator.getAcceptedPermutations(spaceAdminOrSpaceEtlServerSingle,
+                source, instance);
+    }
+
+    @DataProvider(name = "rolesNotAllowedToRemoveContainerFromDataSet")
+    RoleWithHierarchy[][] rolesNotAllowedToRemoveContainerFromDataSet()
+    {
+        return RolePermutator.getAcceptedPermutations(not(spaceAdminOrSpaceEtlServerSingle),
+                source, instance);
+    }
+
     ExperimentPE pe(Experiment experiment)
     {
         return daoFactory.getExperimentDAO().tryGetByPermID(experiment.getPermId());
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateDataSetContainmentTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateDataSetContainmentTest.java
index 2466c171dec56e1c109b12ace8a164255cab1bc1..873aee7e16df437e0219fa0c7cfb19c6729d0070 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateDataSetContainmentTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateDataSetContainmentTest.java
@@ -16,20 +16,30 @@
 
 package ch.systemsx.cisd.openbis.systemtest;
 
+import static ch.systemsx.cisd.openbis.systemtest.base.auth.RuleBuilder.not;
+import static ch.systemsx.cisd.openbis.systemtest.base.auth.RuleBuilder.rule;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
+import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Space;
 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;
 
 /**
  * @author anttil
@@ -128,6 +138,85 @@ public class UpdateDataSetContainmentTest extends BaseTest
 
     }
 
+    Space unrelatedAdmin;
+
+    Space unrelatedObserver;
+
+    Space unrelatedNone;
+
+    @Test(dataProvider = "rolesAllowedToAddContainerToDataSet", groups = "authorization")
+    public void addingContainerToDataSetIsAllowedFor(
+            RoleWithHierarchy spaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        ExternalData container = create(aDataSet().inSample(sample));
+        ExternalData component = create(aDataSet().inSample(sample));
+        String user =
+                create(aSession()
+                        .withSpaceRole(spaceRole, sample.getSpace())
+                        .withInstanceRole(instanceRole)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
+
+        perform(anUpdateOf(container).withComponent(component).as(user));
+    }
+
+    @Test(dataProvider = "rolesNotAllowedToAddContainerToDataSet", expectedExceptions =
+        { AuthorizationFailureException.class }, groups = "authorization")
+    public void addingContainerToDataSetNotIsAllowedFor(
+            RoleWithHierarchy spaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        ExternalData container = create(aDataSet().inSample(sample));
+        ExternalData component = create(aDataSet().inSample(sample));
+        String user =
+                create(aSession()
+                        .withSpaceRole(spaceRole, sample.getSpace())
+                        .withInstanceRole(instanceRole)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
+
+        perform(anUpdateOf(container).withComponent(component).as(user));
+    }
+
+    @Test(dataProvider = "rolesAllowedToAddContainerToDataSet", groups = "authorization")
+    public void removingContainerFromDataSetIsAllowedFor(
+            RoleWithHierarchy spaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        ExternalData component = create(aDataSet().inSample(sample));
+        ExternalData container =
+                create(aDataSet().inSample(sample).asContainer().withComponent(component));
+
+        String user =
+                create(aSession()
+                        .withSpaceRole(spaceRole, sample.getSpace())
+                        .withInstanceRole(instanceRole)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
+
+        perform(anUpdateOf(container).withComponents().as(user));
+    }
+
+    @Test(dataProvider = "rolesNotAllowedToAddContainerToDataSet", expectedExceptions =
+        { AuthorizationFailureException.class }, groups = "authorization")
+    public void removingContainerFromDataSetNotIsAllowedFor(
+            RoleWithHierarchy spaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        ExternalData component = create(aDataSet().inSample(sample));
+        ExternalData container =
+                create(aDataSet().inSample(sample).asContainer().withComponent(component));
+        String user =
+                create(aSession()
+                        .withSpaceRole(spaceRole, sample.getSpace())
+                        .withInstanceRole(instanceRole)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
+
+        perform(anUpdateOf(container).withComponents().as(user));
+    }
+
     @BeforeClass
     void createFixture() throws Exception
     {
@@ -135,5 +224,37 @@ public class UpdateDataSetContainmentTest extends BaseTest
         Project project = create(aProject().inSpace(space));
         Experiment experiment = create(anExperiment().inProject(project));
         sample = create(aSample().inExperiment(experiment));
+
+        unrelatedAdmin = create(aSpace());
+        unrelatedObserver = create(aSpace());
+        unrelatedNone = create(aSpace());
+    }
+
+    GuardedDomain spaceDomain;
+
+    GuardedDomain instance;
+
+    AuthorizationRule addParentToSampleRule;
+
+    @BeforeClass
+    void createAuthorizationRules()
+    {
+        instance = new InstanceDomain("instance");
+        spaceDomain = new SpaceDomain("space", instance);
+
+        addParentToSampleRule = rule(spaceDomain, RoleWithHierarchy.SPACE_POWER_USER);
+    }
+
+    @DataProvider
+    Object[][] rolesAllowedToAddContainerToDataSet()
+    {
+        return RolePermutator.getAcceptedPermutations(addParentToSampleRule, spaceDomain, instance);
+    }
+
+    @DataProvider
+    Object[][] rolesNotAllowedToAddContainerToDataSet()
+    {
+        return RolePermutator.getAcceptedPermutations(not(addParentToSampleRule), spaceDomain,
+                instance);
     }
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateDataSetParentsTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateDataSetParentsTest.java
index 8bab6547df57099101e2d4b5f337598ddb0e4de1..93d6a3ecebe7e189bdc46d05614a2a8aaa5605df 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateDataSetParentsTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateDataSetParentsTest.java
@@ -16,19 +16,31 @@
 
 package ch.systemsx.cisd.openbis.systemtest;
 
+import static ch.systemsx.cisd.openbis.systemtest.base.auth.RuleBuilder.and;
+import static ch.systemsx.cisd.openbis.systemtest.base.auth.RuleBuilder.not;
+import static ch.systemsx.cisd.openbis.systemtest.base.auth.RuleBuilder.or;
+import static ch.systemsx.cisd.openbis.systemtest.base.auth.RuleBuilder.rule;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
+import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Space;
 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;
 
 /**
  * @author anttil
@@ -126,18 +138,110 @@ public class UpdateDataSetParentsTest extends BaseTest
     @Test
     public void parentCanBeInDifferentSpaceThanChild() throws Exception
     {
-        Space parentSpace = create(aSpace());
-        Project parentProject = create(aProject().inSpace(parentSpace));
-        Experiment parentExperiment = create(anExperiment().inProject(parentProject));
-        Sample parentSample = create(aSample().inExperiment(parentExperiment));
         ExternalData parent = create(aDataSet().inSample(parentSample));
-        ExternalData child = create(aDataSet().inSample(sample));
+        ExternalData child = create(aDataSet().inSample(childSample));
 
         perform(anUpdateOf(child).withParent(parent));
 
         assertThat(serverSays(child).getParents(), containsExactly(parent));
     }
 
+    Sample childSample;
+
+    Sample parentSample;
+
+    Space childSpace;
+
+    Space parentSpace;
+
+    Space unrelatedAdmin;
+
+    Space unrelatedObserver;
+
+    Space unrelatedNone;
+
+    @Test(dataProvider = "rolesAllowedToAddParentToDataSet", groups = "authorization")
+    public void addingParentToDataSetIsAllowedFor(
+            RoleWithHierarchy childSpaceRole,
+            RoleWithHierarchy parentSpaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        ExternalData parentToBe = create(aDataSet().inSample(parentSample));
+        ExternalData childToBe = create(aDataSet().inSample(childSample));
+        String user =
+                create(aSession()
+                        .withSpaceRole(childSpaceRole, childSpace)
+                        .withSpaceRole(parentSpaceRole, parentSpace)
+                        .withInstanceRole(instanceRole)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
+
+        perform(anUpdateOf(childToBe).withParent(parentToBe).as(user));
+    }
+
+    @Test(dataProvider = "rolesNotAllowedToAddParentToDataSet", expectedExceptions =
+        { AuthorizationFailureException.class }, groups = "authorization")
+    public void addingParentToDataSetNotIsAllowedFor(
+            RoleWithHierarchy childSpaceRole,
+            RoleWithHierarchy parentSpaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        ExternalData parentToBe = create(aDataSet().inSample(parentSample));
+        ExternalData childToBe = create(aDataSet().inSample(childSample));
+        String user =
+                create(aSession()
+                        .withSpaceRole(childSpaceRole, childSpace)
+                        .withSpaceRole(parentSpaceRole, parentSpace)
+                        .withInstanceRole(instanceRole)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
+
+        perform(anUpdateOf(childToBe).withParent(parentToBe).as(user));
+    }
+
+    @Test(dataProvider = "rolesAllowedToRemoveParentFromDataSet", groups = "authorization")
+    public void removingParentFromDataSetIsAllowedFor(
+            RoleWithHierarchy childSpaceRole,
+            RoleWithHierarchy parentSpaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        ExternalData parent1 = create(aDataSet().inSample(parentSample));
+        ExternalData parent2 = create(aDataSet().inSample(parentSample));
+        ExternalData child = create(aDataSet().inSample(childSample).withParents(parent1, parent2));
+
+        String user =
+                create(aSession()
+                        .withSpaceRole(childSpaceRole, childSpace)
+                        .withSpaceRole(parentSpaceRole, parentSpace)
+                        .withInstanceRole(instanceRole)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
+
+        perform(anUpdateOf(child).withParent(parent1).as(user));
+    }
+
+    @Test(dataProvider = "rolesNotAllowedToRemoveParentFromDataSet", expectedExceptions =
+        { AuthorizationFailureException.class }, groups = "authorization")
+    public void removingParentFromDataSetNotIsAllowedFor(
+            RoleWithHierarchy childSpaceRole,
+            RoleWithHierarchy parentSpaceRole,
+            RoleWithHierarchy instanceRole) throws Exception
+    {
+        ExternalData parent1 = create(aDataSet().inSample(parentSample));
+        ExternalData parent2 = create(aDataSet().inSample(parentSample));
+        ExternalData child = create(aDataSet().inSample(childSample).withParents(parent1, parent2));
+
+        String user =
+                create(aSession()
+                        .withSpaceRole(childSpaceRole, childSpace)
+                        .withSpaceRole(parentSpaceRole, parentSpace)
+                        .withInstanceRole(instanceRole)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin)
+                        .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver));
+
+        perform(anUpdateOf(child).withParent(parent1).as(user));
+    }
+
     @BeforeClass
     void createFixture() throws Exception
     {
@@ -146,5 +250,73 @@ public class UpdateDataSetParentsTest extends BaseTest
         Experiment experiment = create(anExperiment().inProject(project));
         sample = create(aSample().inExperiment(experiment));
 
+        unrelatedAdmin = create(aSpace());
+        unrelatedObserver = create(aSpace());
+        unrelatedNone = create(aSpace());
+
+        childSpace = create(aSpace());
+        parentSpace = create(aSpace());
+        Project childProject = create(aProject().inSpace(childSpace));
+        Project parentProject = create(aProject().inSpace(parentSpace));
+        Experiment childExperiment = create(anExperiment().inProject(childProject));
+        Experiment parentExperiment = create(anExperiment().inProject(parentProject));
+        childSample = create(aSample().inExperiment(childExperiment));
+        parentSample = create(aSample().inExperiment(parentExperiment));
+
+    }
+
+    GuardedDomain childSpaceDomain;
+
+    GuardedDomain parentSpaceDomain;
+
+    GuardedDomain instance;
+
+    AuthorizationRule updateParentsOfDataSetRule;
+
+    AuthorizationRule removeParentFromDataSetRule;
+
+    @BeforeClass
+    void createAuthorizationRules()
+    {
+        instance = new InstanceDomain("instance");
+        childSpaceDomain = new SpaceDomain("child", instance);
+        parentSpaceDomain = new SpaceDomain("parent", instance);
+
+        updateParentsOfDataSetRule =
+                and(
+                        rule(childSpaceDomain, RoleWithHierarchy.SPACE_POWER_USER),
+                        or(
+                                rule(parentSpaceDomain, RoleWithHierarchy.SPACE_POWER_USER),
+                                rule(parentSpaceDomain, RoleWithHierarchy.SPACE_ETL_SERVER)
+                        )
+                );
+    }
+
+    @DataProvider
+    Object[][] rolesAllowedToAddParentToDataSet()
+    {
+        return RolePermutator.getAcceptedPermutations(updateParentsOfDataSetRule, childSpaceDomain,
+                parentSpaceDomain, instance);
+    }
+
+    @DataProvider
+    Object[][] rolesNotAllowedToAddParentToDataSet()
+    {
+        return RolePermutator.getAcceptedPermutations(not(updateParentsOfDataSetRule),
+                childSpaceDomain, parentSpaceDomain, instance);
+    }
+
+    @DataProvider
+    Object[][] rolesAllowedToRemoveParentFromDataSet()
+    {
+        return RolePermutator.getAcceptedPermutations(updateParentsOfDataSetRule, childSpaceDomain,
+                parentSpaceDomain, instance);
+    }
+
+    @DataProvider
+    Object[][] rolesNotAllowedToRemoveParentFromDataSet()
+    {
+        return RolePermutator.getAcceptedPermutations(not(updateParentsOfDataSetRule),
+                childSpaceDomain, parentSpaceDomain, instance);
     }
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateSampleParentsTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateSampleParentsTest.java
index 88f5b81d058ff9ec3365a31dcea6768925376c3d..602bd0332ab5a92808c487646b1023c8bad63bd9 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateSampleParentsTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateSampleParentsTest.java
@@ -140,6 +140,16 @@ public class UpdateSampleParentsTest extends BaseTest
         perform(anUpdateOf(child).toHaveParent(parent));
     }
 
+    @Test(expectedExceptions =
+        { UserFailureException.class })
+    public void childCannotBeShared() throws Exception
+    {
+        Sample parent = create(aSample().inSpace(space));
+        Sample child = create(aSample());
+
+        perform(anUpdateOf(child).toHaveParent(parent));
+    }
+
     Space unrelatedAdmin;
 
     Space unrelatedObserver;
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/RelationshipServiceStub.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/RelationshipServiceStub.java
index 28bff546d9b52dd471fc94967749efb5ef2c4650..ef6714871a26b531fece48d9b3da5bc9a0eac8c0 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/RelationshipServiceStub.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/RelationshipServiceStub.java
@@ -100,4 +100,24 @@ public class RelationshipServiceStub implements IRelationshipService
     public void removeSampleFromContainer(IAuthSession session, SamplePE sample)
     {
     }
+
+    @Override
+    public void addParentToDataSet(IAuthSession session, DataPE data, DataPE parent)
+    {
+    }
+
+    @Override
+    public void removeParentFromDataSet(IAuthSession session, DataPE data, DataPE parent)
+    {
+    }
+
+    @Override
+    public void assignDataSetToContainer(IAuthSession session, DataPE data, DataPE container)
+    {
+    }
+
+    @Override
+    public void removeDataSetFromContainer(IAuthSession session, DataPE sample)
+    {
+    }
 }