diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
index 6432556f4ad93d7b9ec4cec718c04b45d82bd234..41048b849a40b370cf9b5a2adda2629eed4799f4 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
@@ -164,6 +164,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifierFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifierFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.translator.DataSetTranslator;
@@ -1576,6 +1577,8 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
         List<NewSample> newSamples = operationDetails.getSampleRegistrations();
         List<NewSample> containerSamples = new ArrayList<NewSample>();
         List<NewSample> containedSamples = new ArrayList<NewSample>();
+        List<NewSample> instanceSamples = new ArrayList<NewSample>();
+        List<NewSample> spaceSamples = new ArrayList<NewSample>();
         int index = 0;
         for (NewSample newSample : newSamples)
         {
@@ -1586,9 +1589,19 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
             {
                 containedSamples.add(newSample);
             }
+            SampleIdentifier sampleIdentifier = SampleIdentifierFactory.parse(newSample);
+            if (sampleIdentifier.isDatabaseInstanceLevel())
+            {
+                instanceSamples.add(newSample);
+            } else
+            {
+                spaceSamples.add(newSample);
+            }
             progress.update("createSamples", newSamples.size(), ++index);
         }
 
+        assertInstanceSampleCreationAllowed(session, instanceSamples);
+        assertSpaceSampleCreationAllowed(session, spaceSamples);
         String userIdOrNull = operationDetails.tryUserIdOrNull();
         ArrayList<SamplePE> samplePEsCreated = new ArrayList<SamplePE>();
         // in the first pass register samples without container to avoid dependency inversion
@@ -1600,6 +1613,23 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
         return SampleTranslator.translate(samplePEsCreated, session.getBaseIndexURL());
     }
 
+    private void assertInstanceSampleCreationAllowed(Session session,
+            List<NewSample> instanceSamples)
+    {
+        if (instanceSamples.isEmpty() == false)
+        {
+            entityOperationChecker.assertInstanceSampleCreationAllowed(session, instanceSamples);
+        }
+    }
+
+    private void assertSpaceSampleCreationAllowed(Session session, List<NewSample> spaceSamples)
+    {
+        if (spaceSamples.isEmpty() == false)
+        {
+            entityOperationChecker.assertSpaceSampleCreationAllowed(session, spaceSamples);
+        }
+    }
+
     private List<Sample> updateSamples(Session session,
             AtomicEntityOperationDetails operationDetails, IProgressListener progress)
     {
@@ -1608,12 +1638,44 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
         {
             return Collections.emptyList();
         }
+        List<SampleUpdatesDTO> instanceSamples = new ArrayList<SampleUpdatesDTO>();
+        List<SampleUpdatesDTO> spaceSamples = new ArrayList<SampleUpdatesDTO>();
+        for (SampleUpdatesDTO sampleUpdate : sampleUpdates)
+        {
+            SampleIdentifier sampleIdentifier = sampleUpdate.getSampleIdentifier();
+            if (sampleIdentifier.isDatabaseInstanceLevel())
+            {
+                instanceSamples.add(sampleUpdate);
+            } else
+            {
+                spaceSamples.add(sampleUpdate);
+            }
+        }
+        assertInstanceSampleUpdateAllowed(session, instanceSamples);
+        assertSpaceSampleUpdateAllowed(session, spaceSamples);
         ISampleTable sampleTable = businessObjectFactory.createSampleTable(session);
         BatchOperationExecutor.executeInBatches(new SampleUpdate(sampleTable, sampleUpdates),
                 progress, "updateSamples");
         return SampleTranslator.translate(sampleTable.getSamples(), session.getBaseIndexURL());
     }
 
+    private void assertInstanceSampleUpdateAllowed(Session session,
+            List<SampleUpdatesDTO> instanceSamples)
+    {
+        if (instanceSamples.isEmpty() == false)
+        {
+            entityOperationChecker.assertInstanceSampleUpdateAllowed(session, instanceSamples);
+        }
+    }
+
+    private void assertSpaceSampleUpdateAllowed(Session session, List<SampleUpdatesDTO> spaceSamples)
+    {
+        if (spaceSamples.isEmpty() == false)
+        {
+            entityOperationChecker.assertSpaceSampleUpdateAllowed(session, spaceSamples);
+        }
+    }
+
     /**
      * This method topologically sorts the data sets to be created and creates them in the necessary
      * order
@@ -1624,7 +1686,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
         ArrayList<DataPE> dataSetsCreated = new ArrayList<DataPE>();
         List<? extends NewExternalData> dataSetRegistrations =
                 operationDetails.getDataSetRegistrations();
-
+        assertDataSetCreationAllowed(session, dataSetRegistrations);
         NewExternalDataDAG dag = new NewExternalDataDAG(dataSetRegistrations);
         List<? extends NewExternalData> orderedRegistrations = dag.getOrderedRegistrations();
 
@@ -1637,6 +1699,15 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
         return DataSetTranslator.translate(dataSetsCreated, "", session.getBaseIndexURL());
     }
 
+    protected void assertDataSetCreationAllowed(Session session,
+            List<? extends NewExternalData> dataSets)
+    {
+        if (dataSets != null && dataSets.isEmpty() == false)
+        {
+            entityOperationChecker.assertDataSetCreationAllowed(session, dataSets);
+        }
+    }
+
     private List<ExternalData> updateDataSets(Session session,
             AtomicEntityOperationDetails operationDetails, IProgressListener progress)
     {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/EntityOperationChecker.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/EntityOperationChecker.java
index 9dfbace7bab91899b67a06854342cb33bf556f28..7a866848daf341d41ac496faaeda7857f355a8f1 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/EntityOperationChecker.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/EntityOperationChecker.java
@@ -22,9 +22,11 @@ import java.util.Map;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewProject;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSpace;
 import ch.systemsx.cisd.openbis.generic.shared.dto.IAuthSession;
-import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SampleUpdatesDTO;
 
 /**
  * Implementation of {@link IEntityOperationChecker} which does nothing because checking is done by
@@ -47,12 +49,42 @@ public class EntityOperationChecker implements IEntityOperationChecker
     }
 
     @Override
-    public void assertProjectCreationAllowed(Session session, List<NewProject> newProjects)
+    public void assertProjectCreationAllowed(IAuthSession session, List<NewProject> newProjects)
     {
     }
 
     @Override
-    public void assertExperimentCreationAllowed(Session session, List<NewExperiment> newExperiments)
+    public void assertExperimentCreationAllowed(IAuthSession session,
+            List<NewExperiment> newExperiments)
+    {
+    }
+
+    @Override
+    public void assertInstanceSampleCreationAllowed(IAuthSession session,
+            List<NewSample> instanceSamples)
+    {
+    }
+
+    @Override
+    public void assertSpaceSampleCreationAllowed(IAuthSession session, List<NewSample> spaceSamples)
+    {
+    }
+
+    @Override
+    public void assertInstanceSampleUpdateAllowed(IAuthSession session,
+            List<SampleUpdatesDTO> instanceSamples)
+    {
+    }
+
+    @Override
+    public void assertSpaceSampleUpdateAllowed(IAuthSession session,
+            List<SampleUpdatesDTO> spaceSamples)
+    {
+    }
+
+    @Override
+    public void assertDataSetCreationAllowed(IAuthSession session,
+            List<? extends NewExternalData> dataSets)
     {
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/IEntityOperationChecker.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/IEntityOperationChecker.java
index 3a0c228b74aecc7ea4f42a7752aaec9fc07f7182..ddf6f929d39bd585c9e89cab8d860fd73a0ae30b 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/IEntityOperationChecker.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/IEntityOperationChecker.java
@@ -23,14 +23,19 @@ import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.Authoriz
 import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.Capability;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RolesAllowed;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NewExperimentPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NewExternalDataPredicate;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NewProjectPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NewSamplePredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.SampleUpdatesPredicate;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewProject;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSpace;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
 import ch.systemsx.cisd.openbis.generic.shared.dto.IAuthSession;
-import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SampleUpdatesDTO;
 
 /**
  * Checking methods to be invoked to check authorization in context of
@@ -51,14 +56,45 @@ public interface IEntityOperationChecker
     @RolesAllowed(
         { RoleWithHierarchy.SPACE_ADMIN, RoleWithHierarchy.SPACE_ETL_SERVER })
     @Capability("CREATE_PROJECTS_VIA_DSS")
-    public void assertProjectCreationAllowed(Session session,
+    public void assertProjectCreationAllowed(IAuthSession session,
             @AuthorizationGuard(guardClass = NewProjectPredicate.class)
             List<NewProject> newProjects);
 
     @RolesAllowed(
         { RoleWithHierarchy.SPACE_ADMIN, RoleWithHierarchy.SPACE_ETL_SERVER })
-    @Capability("CREATE_PROJECTS_VIA_DSS")
-    public void assertExperimentCreationAllowed(Session session,
+    @Capability("CREATE_EXPERIMENTS_VIA_DSS")
+    public void assertExperimentCreationAllowed(IAuthSession session,
             @AuthorizationGuard(guardClass = NewExperimentPredicate.class)
             List<NewExperiment> newExperiments);
+
+    @RolesAllowed(RoleWithHierarchy.INSTANCE_ETL_SERVER)
+    public void assertInstanceSampleCreationAllowed(IAuthSession session,
+            @AuthorizationGuard(guardClass = NewSamplePredicate.class)
+            List<NewSample> instanceSamples);
+
+    @RolesAllowed(
+        { RoleWithHierarchy.SPACE_USER, RoleWithHierarchy.SPACE_ETL_SERVER })
+    @Capability("CREATE_SPACE_SAMPLES_VIA_DSS")
+    public void assertSpaceSampleCreationAllowed(IAuthSession session,
+            @AuthorizationGuard(guardClass = NewSamplePredicate.class)
+            List<NewSample> spaceSamples);
+
+    @RolesAllowed(RoleWithHierarchy.INSTANCE_ETL_SERVER)
+    public void assertInstanceSampleUpdateAllowed(IAuthSession session,
+            @AuthorizationGuard(guardClass = SampleUpdatesPredicate.class)
+            List<SampleUpdatesDTO> instanceSamples);
+
+    @RolesAllowed(
+        { RoleWithHierarchy.SPACE_USER, RoleWithHierarchy.SPACE_ETL_SERVER })
+    @Capability("UPDATE_SPACE_SAMPLES_VIA_DSS")
+    public void assertSpaceSampleUpdateAllowed(IAuthSession session,
+            @AuthorizationGuard(guardClass = SampleUpdatesPredicate.class)
+            List<SampleUpdatesDTO> spaceSamples);
+
+    @RolesAllowed(
+        { RoleWithHierarchy.SPACE_USER, RoleWithHierarchy.SPACE_ETL_SERVER })
+    @Capability("CREATE_DATA_SET_VIA_DSS")
+    public void assertDataSetCreationAllowed(IAuthSession session,
+            @AuthorizationGuard(guardClass = NewExternalDataPredicate.class)
+            List<? extends NewExternalData> dataSets);
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodePredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodePredicate.java
index 51c016ef0036db30cc6492c2dfe76cdb9105949d..b2a2f02bb16f7567113427f7778d2dfaa778b5c2 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodePredicate.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodePredicate.java
@@ -37,8 +37,8 @@ public class DataSetCodePredicate extends AbstractSpacePredicate<String>
     }
 
     @Override
-    protected
-    Status doEvaluation(PersonPE person, List<RoleWithIdentifier> allowedRoles, String dataSetCode)
+    protected Status doEvaluation(PersonPE person, List<RoleWithIdentifier> allowedRoles,
+            String dataSetCode)
     {
         assert initialized : "Predicate has not been initialized";
 
@@ -48,10 +48,8 @@ public class DataSetCodePredicate extends AbstractSpacePredicate<String>
         {
             String dbInstanceUUID = accessData.getDatabaseInstanceUuid();
             String dbInstanceCode = accessData.getDatabaseInstanceCode();
-            String groupCode = accessData.getSpaceCode();
-            Status result =
-                    evaluate(person, allowedRoles, dbInstanceUUID, dbInstanceCode, groupCode);
-            return result;
+            String spaceCode = accessData.getSpaceCode();
+            return evaluate(person, allowedRoles, dbInstanceUUID, dbInstanceCode, spaceCode);
         }
         return Status.OK;
     }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/NewExternalDataPredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/NewExternalDataPredicate.java
new file mode 100644
index 0000000000000000000000000000000000000000..214854a5c21e5c2769ed8321de4ecc2552eb5de5
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/NewExternalDataPredicate.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.authorization.predicate;
+
+import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData;
+
+/**
+ * Predicate for {@link NewExternalData} instances.
+ * 
+ * @author Franz-Josef Elmer
+ */
+public class NewExternalDataPredicate extends DelegatedPredicate<String, NewExternalData>
+{
+    public NewExternalDataPredicate()
+    {
+        super(new DataSetCodePredicate());
+    }
+
+    @Override
+    public String getCandidateDescription()
+    {
+        return "new data set";
+    }
+
+    @Override
+    public String tryConvert(NewExternalData value)
+    {
+        return value.getCode();
+    }
+
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/EntityOperationTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/EntityOperationTest.java
index c662eb4f6716c86de68b7ea0b900f89e9b09794a..005a2cc465aeb59445284e175ad9608e32a4ad12 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/EntityOperationTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/EntityOperationTest.java
@@ -30,6 +30,7 @@ import org.testng.annotations.Test;
 import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
 import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSet;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
@@ -39,14 +40,20 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewProject;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSpace;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.DataSetBuilder;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.DataStoreBuilder;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.ExperimentBuilder;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.MaterialBuilder;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.SampleBuilder;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationResult;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetUpdatesDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SampleUpdatesDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifierFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.translator.MaterialTranslator;
 
@@ -87,7 +94,7 @@ public class EntityOperationTest extends SystemTestCase
 
         private final List<SampleUpdatesDTO> sampleUpdates = new ArrayList<SampleUpdatesDTO>();
 
-        private final List<? extends NewExternalData> dataSets = new ArrayList<NewExternalData>();
+        private final List<NewExternalData> dataSets = new ArrayList<NewExternalData>();
 
         private final List<DataSetUpdatesDTO> dataSetUpdates = new ArrayList<DataSetUpdatesDTO>();
 
@@ -151,6 +158,45 @@ public class EntityOperationTest extends SystemTestCase
             return this;
         }
 
+        EntityOperationBuilder sample(Sample sample)
+        {
+            NewSample newSample = new NewSample();
+            newSample.setIdentifier(sample.getIdentifier());
+            newSample.setSampleType(sample.getSampleType());
+            Experiment experiment = sample.getExperiment();
+            if (experiment != null)
+            {
+                newSample.setExperimentIdentifier(experiment.getIdentifier());
+            }
+            newSample.setProperties(sample.getProperties().toArray(new IEntityProperty[0]));
+            samples.add(newSample);
+            return this;
+        }
+
+        EntityOperationBuilder sampleUpdate(Sample sample)
+        {
+            sampleUpdates.add(new SampleUpdatesDTO(new TechId(sample), sample.getProperties(),
+                    null, null, sample.getModificationDate(), SampleIdentifierFactory.parse(sample
+                            .getIdentifier()), null, null));
+            return this;
+        }
+
+        EntityOperationBuilder dataSet(DataSet dataSet)
+        {
+            NewExternalData newExternalData = new NewExternalData();
+            newExternalData.setCode(dataSet.getCode());
+            newExternalData.setDataSetType(dataSet.getDataSetType());
+            newExternalData.setDataStoreCode(dataSet.getDataStore().getCode());
+            Experiment experiment = dataSet.getExperiment();
+            if (experiment != null)
+            {
+                newExternalData.setExperimentIdentifierOrNull(ExperimentIdentifierFactory
+                        .parse(experiment.getIdentifier()));
+            }
+            dataSets.add(newExternalData);
+            return this;
+        }
+
         AtomicEntityOperationDetails create()
         {
             return new AtomicEntityOperationDetails(registrationID, userID, spaces, projects,
@@ -307,6 +353,163 @@ public class EntityOperationTest extends SystemTestCase
                 + SPACE_ETL_SERVER_FOR_B + "' does not have enough privileges.\".");
     }
 
+    @Test
+    public void testCreateInstanceSampleAsInstanceETLServerSuccessfully()
+    {
+        String sessionToken = authenticateAs(INSTANCE_ETL_SERVER);
+        AtomicEntityOperationDetails eo =
+                new EntityOperationBuilder().sample(
+                        new SampleBuilder().identifier("/S1").type("MASTER_PLATE")
+                                .property("$PLATE_GEOMETRY", "96_WELLS_8X12").getSample()).create();
+
+        AtomicEntityOperationResult result = etlService.performEntityOperations(sessionToken, eo);
+
+        assertEquals("/S1", result.getSamplesCreated().get(0).getIdentifier());
+        assertEquals("MASTER_PLATE", result.getSamplesCreated().get(0).getSampleType().getCode());
+        assertEquals("[$PLATE_GEOMETRY: 96_WELLS_8X12]", result.getSamplesCreated().get(0)
+                .getProperties().toString());
+        assertEquals(1, result.getSamplesCreated().size());
+    }
+
+    @Test
+    public void testCreateInstanceSampleAsSpaceETLServerThrowsAuthorizationFailure()
+    {
+        String sessionToken = authenticateAs(SPACE_ETL_SERVER_FOR_A);
+        AtomicEntityOperationDetails eo =
+                new EntityOperationBuilder().sample(
+                        new SampleBuilder().identifier("/S1").type("MASTER_PLATE")
+                                .property("$PLATE_GEOMETRY", "96_WELLS_8X12").getSample()).create();
+
+        performFailungEntityOperations(sessionToken, eo, "Authorization failure: ERROR: \"User '"
+                + SPACE_ETL_SERVER_FOR_A + "' does not have enough privileges "
+                + "to modify database instance 'CISD'.\".");
+    }
+
+    @Test
+    public void testCreateSpaceSampleAsSpaceETLServerSuccessfully()
+    {
+        String sessionToken = authenticateAs(SPACE_ETL_SERVER_FOR_A);
+        AtomicEntityOperationDetails eo =
+                new EntityOperationBuilder().sample(
+                        new SampleBuilder()
+                                .identifier("/CISD/S1")
+                                .type("CELL_PLATE")
+                                .property("COMMENT", "hello")
+                                .experiment(
+                                        new ExperimentBuilder().identifier("/CISD/NEMO/EXP1")
+                                                .getExperiment()).getSample()).create();
+
+        AtomicEntityOperationResult result = etlService.performEntityOperations(sessionToken, eo);
+
+        assertEquals("/CISD/S1", result.getSamplesCreated().get(0).getIdentifier());
+        assertEquals("CELL_PLATE", result.getSamplesCreated().get(0).getSampleType().getCode());
+        assertEquals("[COMMENT: hello]", result.getSamplesCreated().get(0).getProperties()
+                .toString());
+        assertEquals("/CISD/NEMO/EXP1", result.getSamplesCreated().get(0).getExperiment()
+                .getIdentifier());
+        assertEquals(1, result.getSamplesCreated().size());
+    }
+
+    @Test
+    public void testCreateSpaceSampleAsSpaceETLServerThrowsAuthorizationFailure()
+    {
+        String sessionToken = authenticateAs(SPACE_ETL_SERVER_FOR_B);
+        AtomicEntityOperationDetails eo =
+                new EntityOperationBuilder().sample(
+                        new SampleBuilder().identifier("/CISD/S1").type("CELL_PLATE").getSample())
+                        .create();
+
+        performFailungEntityOperations(sessionToken, eo, "Authorization failure: ERROR: \"User '"
+                + SPACE_ETL_SERVER_FOR_B + "' does not have enough privileges.\".");
+    }
+
+    @Test
+    public void testUpdateInstanceSampleAsInstanceETLServerSuccessfully()
+    {
+        String sessionToken = authenticateAs(INSTANCE_ETL_SERVER);
+        Sample sample = commonServer.getSampleInfo(systemSessionToken, new TechId(646)).getParent();
+        List<IEntityProperty> properties = sample.getProperties();
+        assertEquals("[$PLATE_GEOMETRY: 384_WELLS_16X24]", properties.toString());
+        sample.setProperties(new SampleBuilder().property("$PLATE_GEOMETRY", "96_WELLS_8X12")
+                .getSample().getProperties());
+        AtomicEntityOperationDetails eo =
+                new EntityOperationBuilder().sampleUpdate(sample).create();
+
+        AtomicEntityOperationResult result = etlService.performEntityOperations(sessionToken, eo);
+
+        assertEquals(new Long(646), result.getSamplesUpdated().get(0).getId());
+        assertEquals("/MP", result.getSamplesUpdated().get(0).getIdentifier());
+        assertEquals("MASTER_PLATE", result.getSamplesUpdated().get(0).getSampleType().getCode());
+        assertEquals("[$PLATE_GEOMETRY: 96_WELLS_8X12]", result.getSamplesUpdated().get(0)
+                .getProperties().toString());
+        assertEquals(1, result.getSamplesUpdated().size());
+    }
+
+    @Test
+    public void testUpdateInstanceSampleAsSpaceETLServerThrowsAuthorizationFailure()
+    {
+        String sessionToken = authenticateAs(SPACE_ETL_SERVER_FOR_A);
+        Sample sample = commonServer.getSampleInfo(systemSessionToken, new TechId(646)).getParent();
+        AtomicEntityOperationDetails eo =
+                new EntityOperationBuilder().sampleUpdate(sample).create();
+
+        performFailungEntityOperations(sessionToken, eo, "Authorization failure: ERROR: "
+                + "\"None of method roles '[INSTANCE_ETL_SERVER, INSTANCE_ADMIN]' "
+                + "could be found in roles of user '" + SPACE_ETL_SERVER_FOR_A + "'.\".");
+    }
+
+    @Test
+    public void testUpdateSpaceSampleAsSpaceETLServerSuccessfully()
+    {
+        String sessionToken = authenticateAs(SPACE_ETL_SERVER_FOR_A);
+        Sample sample = commonServer.getSampleInfo(systemSessionToken, new TechId(986)).getParent();
+        List<IEntityProperty> properties = sample.getProperties();
+        assertEquals("[]", properties.toString());
+        sample.setProperties(new SampleBuilder().property("COMMENT", "hello").getSample()
+                .getProperties());
+        AtomicEntityOperationDetails eo =
+                new EntityOperationBuilder().sampleUpdate(sample).create();
+
+        AtomicEntityOperationResult result = etlService.performEntityOperations(sessionToken, eo);
+
+        assertEquals(new Long(986), result.getSamplesUpdated().get(0).getId());
+        assertEquals("/CISD/3VCP5", result.getSamplesUpdated().get(0).getIdentifier());
+        assertEquals("CELL_PLATE", result.getSamplesUpdated().get(0).getSampleType().getCode());
+        assertEquals("[COMMENT: hello]", result.getSamplesUpdated().get(0).getProperties()
+                .toString());
+        assertEquals(1, result.getSamplesUpdated().size());
+    }
+
+    @Test
+    public void testUpdateSpaceSampleAsSpaceETLServerThrowsAuthorizationFailure()
+    {
+        String sessionToken = authenticateAs(SPACE_ETL_SERVER_FOR_B);
+        Sample sample = commonServer.getSampleInfo(systemSessionToken, new TechId(986)).getParent();
+        AtomicEntityOperationDetails eo =
+                new EntityOperationBuilder().sampleUpdate(sample).create();
+
+        performFailungEntityOperations(sessionToken, eo, "Authorization failure: ERROR: \"User '"
+                + SPACE_ETL_SERVER_FOR_B + "' does not have enough privileges.\".");
+    }
+
+    @Test
+    public void testCreateDataSetAsSpaceETLServerThrowsAuthorizationFailure()
+    {
+        String sessionToken = authenticateAs(SPACE_ETL_SERVER_FOR_B);
+        AtomicEntityOperationDetails eo =
+                new EntityOperationBuilder().dataSet(
+                        new DataSetBuilder()
+                                .code("DS-1")
+                                .type("UNKNOWN")
+                                .store(new DataStoreBuilder("STANDARD").getStore())
+                                .experiment(
+                                        new ExperimentBuilder().identifier("/CISD/NEMO/EXP1")
+                                                .getExperiment()).getDataSet()).create();
+
+        performFailungEntityOperations(sessionToken, eo, "Authorization failure: ERROR: \"User '"
+                + SPACE_ETL_SERVER_FOR_B + "' does not have enough privileges.\".");
+    }
+
     private void performFailungEntityOperations(String sessionToken,
             AtomicEntityOperationDetails eo, String expectedMessage)
     {