diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/TrashBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/TrashBO.java
index fc74d40faea5af8282aceb19c1128b412cb77a53..7a04ddbd043cca7341a0dd4df3a55abfa9f166af 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/TrashBO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/TrashBO.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
+import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
@@ -41,9 +42,11 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDeletionDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISampleDAO;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSetFetchOption;
+import ch.systemsx.cisd.openbis.generic.shared.basic.IIdAndCodeHolder;
 import ch.systemsx.cisd.openbis.generic.shared.basic.IIdHolder;
 import ch.systemsx.cisd.openbis.generic.shared.basic.IIdentifierHolder;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Code;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetArchivingStatus;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
@@ -57,9 +60,11 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.managed_property.IManagedPropertyEvaluatorFactory;
+import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils;
 
 /**
  * @author Piotr Buczek
+ * @author Franz-Josef Elmer
  */
 public class TrashBO extends AbstractBusinessObject implements ITrashBO
 {
@@ -108,7 +113,48 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
     @Override
     public void trashDataSets(List<TechId> dataSetIds)
     {
-        trashDataSets(dataSetIds, true, null);
+        assert deletion != null;
+        
+        IDatasetLister datasetLister = boFactory.createDatasetLister(session);
+        final Set<TechId> experimentIds = new HashSet<TechId>();
+        final Set<TechId> sampleIds = new HashSet<TechId>();
+        for (AbstractExternalData dataSet : datasetLister.listByDatasetIds(TechId.asLongs(dataSetIds), DATA_SET_FETCH_OPTIONS))
+        {
+            Sample sample = dataSet.getSample();
+            if (sample != null)
+            {
+                sampleIds.add(new TechId(sample));
+            } else if (dataSet.getExperiment() != null)
+            {
+                experimentIds.add(new TechId(dataSet.getExperiment()));
+            }
+        }
+        assertDataSetDeletionBusinessRules(experimentIds, sampleIds, dataSetIds);
+        TrashOperationsManager trashManager = new TrashOperationsManager(deletion, getDeletionDAO());
+        trashDataSets(trashManager, dataSetIds, true, new IDataSetFilter()
+            {
+                @Override
+                public List<TechId> filter(List<DataPE> dataSets)
+                {
+                    List<TechId> filtered = new ArrayList<TechId>();
+                    for (DataPE dataSet : dataSets)
+                    {
+                        SamplePE sample = dataSet.tryGetSample();
+                        ExperimentPE experiment = dataSet.getExperiment();
+                        if (contains(sampleIds, sample) || contains(experimentIds, experiment))
+                        {
+                            filtered.add(new TechId(dataSet));
+                        }
+                    }
+                    return filtered;
+                }
+                
+                private boolean contains(Set<TechId> ids, IIdAndCodeHolder entity)
+                {
+                    return entity != null && ids.contains(new TechId(HibernateUtils.getId(entity)));
+                }
+            });
+        trashManager.trash();
     }
 
     @Override
@@ -116,18 +162,13 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
     {
         assert deletion != null;
         
-        TrashBatchOperation batchOperation =
-                new TrashBatchOperation(EntityKind.EXPERIMENT, experimentIds, deletion,
-                        getDeletionDAO(), true);
-        BatchOperationExecutor.executeInBatches(batchOperation);
-        
-        if (batchOperation.counter > 0)
-        {
-            Set<TechId> eIds = new LinkedHashSet<TechId>(experimentIds);
-            Set<TechId> dependentSampleIds = trashExperimentDependentSamples(eIds);
-            assertSampleDeletionBusinessRules(eIds, dependentSampleIds);
-            trashExperimentDependentDataSets(eIds, dependentSampleIds);
-        }
+        TrashOperationsManager trashManager = new TrashOperationsManager(deletion, getDeletionDAO());
+        trashManager.addTrashOperation(EntityKind.EXPERIMENT, experimentIds, true);
+        Set<TechId> eIds = new LinkedHashSet<TechId>(experimentIds);
+        Set<TechId> dependentSampleIds = trashExperimentDependentSamples(trashManager, eIds);
+        assertSampleDeletionBusinessRules(eIds, dependentSampleIds);
+        trashExperimentDependentDataSets(trashManager, eIds, dependentSampleIds);
+        trashManager.trash();
     }
 
     @Override
@@ -135,31 +176,36 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
     {
         assert deletion != null;
 
-        Set<TechId> experimentIds = Collections.<TechId>emptySet();
-        Set<TechId> allSampleIds = trashSamples(experimentIds, sampleIds, 
-                CascadeSampleDependentComponents.TRUE, true);
+        TrashOperationsManager trashManager = new TrashOperationsManager(deletion, getDeletionDAO());
+        Set<TechId> experimentIds = new HashSet<TechId>();
+        ISampleLister sampleLister = boFactory.createSampleLister(session);
+        List<Sample> samples = sampleLister.list(new ListOrSearchSampleCriteria(TechId.asLongs(sampleIds)));
+        for (Sample sample : samples)
+        {
+            Experiment experiment = sample.getExperiment();
+            if (experiment != null)
+            {
+                experimentIds.add(new TechId(experiment));
+            }
+        }
+        Set<TechId> allSampleIds = trashSamples(trashManager, experimentIds, 
+                sampleIds, CascadeSampleDependentComponents.TRUE, true);
         assertSampleDeletionBusinessRules(experimentIds, allSampleIds);
-        trashSampleDependentDataSets(allSampleIds);
-        
+        trashSampleDependentDataSets(trashManager, allSampleIds);
+        trashManager.trash();
     }
 
-    private Set<TechId> trashSamples(Set<TechId> experimentIds, final List<TechId> sampleIds,
-            final CascadeSampleDependentComponents cascadeType, boolean isOriginalDeletion)
+    private Set<TechId> trashSamples(TrashOperationsManager trashManager, Set<TechId> experimentIds,
+            final List<TechId> sampleIds, final CascadeSampleDependentComponents cascadeType, boolean isOriginalDeletion)
     {
         assert deletion != null;
         Set<TechId> allSampleIds = new LinkedHashSet<TechId>(sampleIds);
 
-        TrashBatchOperation batchOperation =
-                new TrashBatchOperation(EntityKind.SAMPLE, sampleIds, deletion, getDeletionDAO(),
-                        isOriginalDeletion);
-        BatchOperationExecutor.executeInBatches(batchOperation);
+        trashManager.addTrashOperation(EntityKind.SAMPLE, sampleIds, isOriginalDeletion);
 
-        if (batchOperation.counter > 0)
+        if (cascadeType == CascadeSampleDependentComponents.TRUE)
         {
-            if (cascadeType == CascadeSampleDependentComponents.TRUE)
-            {
-                allSampleIds.addAll(trashSampleDependentComponents(experimentIds, sampleIds));
-            }
+            allSampleIds.addAll(trashSampleDependentComponents(trashManager, experimentIds, sampleIds));
         }
         return allSampleIds;
     }
@@ -200,7 +246,8 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
         }
     }
 
-    private void trashDataSets(final List<TechId> dataSetIds, boolean isOriginalDeletion, IDataSetFilter filterOrNull)
+    private void trashDataSets(TrashOperationsManager trashManager, final List<TechId> dataSetIds, 
+            boolean isOriginalDeletion, IDataSetFilter filterOrNull)
     {
         assert deletion != null;
 
@@ -223,16 +270,8 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
         if (isOriginalDeletion)
         {
             allDeletables.removeAll(deletableOriginals);
-
-            TrashBatchOperation batchOperation =
-                    new TrashBatchOperation(EntityKind.DATA_SET, deletableOriginals, deletion,
-                            getDeletionDAO(), true);
-            BatchOperationExecutor.executeInBatches(batchOperation);
-
-            batchOperation =
-                    new TrashBatchOperation(EntityKind.DATA_SET, allDeletables, deletion,
-                            getDeletionDAO(), false);
-            BatchOperationExecutor.executeInBatches(batchOperation);
+            trashManager.addTrashOperation(EntityKind.DATA_SET, deletableOriginals, true);
+            trashManager.addTrashOperation(EntityKind.DATA_SET, allDeletables, false);
         } else
         {
             int nonDeletable = dataSetIds.size() - deletableOriginals.size();
@@ -244,10 +283,7 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
                         + Code.extractCodes(datasetLister.listByDatasetIds(TechId.asLongs(dataSetIds), 
                                 EnumSet.of(DataSetFetchOption.BASIC))));
             }
-            TrashBatchOperation batchOperation =
-                    new TrashBatchOperation(EntityKind.DATA_SET, allDeletables, deletion,
-                            getDeletionDAO(), false);
-            BatchOperationExecutor.executeInBatches(batchOperation);
+            trashManager.addTrashOperation(EntityKind.DATA_SET, allDeletables, false);
         }
     }
 
@@ -283,7 +319,8 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
                         + builder);
     }
 
-    private Set<TechId> trashSampleDependentComponents(Set<TechId> experimentIds, List<TechId> sampleIds)
+    private Set<TechId> trashSampleDependentComponents(TrashOperationsManager trashManager, 
+            Set<TechId> experimentIds, List<TechId> sampleIds)
     {
         final ISampleDAO sampleDAO = getSampleDAO();
 
@@ -300,10 +337,10 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
         BatchOperationExecutor.executeInBatches(batchOperation);
         // We have a business rule that there is just 1 level of components and using this here
         // improves performance.
-        return trashSamples(experimentIds, batchOperation.getResults(), CascadeSampleDependentComponents.FALSE, false);
+        return trashSamples(trashManager, experimentIds, batchOperation.getResults(), CascadeSampleDependentComponents.FALSE, false);
     }
 
-    private void trashSampleDependentDataSets(Set<TechId> sampleIds)
+    private void trashSampleDependentDataSets(TrashOperationsManager trashManager, Set<TechId> sampleIds)
     {
         AbstractQueryBatchOperation batchOperation =
                 new AbstractQueryBatchOperation(EntityKind.DATA_SET, new ArrayList<TechId>(sampleIds),
@@ -319,18 +356,18 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
         BatchOperationExecutor.executeInBatches(batchOperation);
         List<TechId> dataSetIds = batchOperation.getResults();
         assertDataSetDeletionBusinessRules(Collections.<TechId>emptySet(), sampleIds, dataSetIds);
-        trashDataSets(dataSetIds, false, new DataSetFilter(sampleIds,
-                new IIdHolderProvider()
-                    {
-                        @Override
-                        public IIdHolder getIdHolder(DataPE dataSet)
-                        {
-                            return dataSet.tryGetSample();
-                        }
-                    }));
+        trashDataSets(trashManager, dataSetIds, false, new DataSetFilter(sampleIds,
+                            new IIdHolderProvider()
+                                {
+                                    @Override
+                                    public IIdHolder getIdHolder(DataPE dataSet)
+                                    {
+                                        return dataSet.tryGetSample();
+                                    }
+                                }));
     }
 
-    private Set<TechId> trashExperimentDependentSamples(Set<TechId> experimentIds)
+    private Set<TechId> trashExperimentDependentSamples(TrashOperationsManager trashManager, Set<TechId> experimentIds)
     {
         AbstractQueryBatchOperation batchOperation =
                 new AbstractQueryBatchOperation(EntityKind.SAMPLE, new ArrayList<TechId>(experimentIds),
@@ -344,10 +381,11 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
                     };
         BatchOperationExecutor.executeInBatches(batchOperation);
         List<TechId> sampleIds = batchOperation.getResults();
-        return trashSamples(experimentIds, sampleIds, CascadeSampleDependentComponents.TRUE, false);
+        return trashSamples(trashManager, experimentIds, sampleIds, CascadeSampleDependentComponents.TRUE, false);
     }
 
-    private void trashExperimentDependentDataSets(Set<TechId> experimentIds, Set<TechId> dependentSampleIds)
+    private void trashExperimentDependentDataSets(TrashOperationsManager trashManager, Set<TechId> experimentIds, 
+            Set<TechId> dependentSampleIds)
     {
         AbstractQueryBatchOperation batchOperation =
                 new AbstractQueryBatchOperation(EntityKind.DATA_SET, new ArrayList<TechId>(experimentIds),
@@ -362,15 +400,15 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
         BatchOperationExecutor.executeInBatches(batchOperation);
         List<TechId> dataSetIds = batchOperation.getResults();
         assertDataSetDeletionBusinessRules(experimentIds, dependentSampleIds, dataSetIds);
-        trashDataSets(dataSetIds, false, new DataSetFilter(experimentIds,
-                new IIdHolderProvider()
-                    {
-                        @Override
-                        public IIdHolder getIdHolder(DataPE dataSet)
-                        {
-                            return dataSet.getExperiment();
-                        }
-                    }));
+        trashDataSets(trashManager, dataSetIds, false, new DataSetFilter(experimentIds,
+                            new IIdHolderProvider()
+                                {
+                                    @Override
+                                    public IIdHolder getIdHolder(DataPE dataSet)
+                                    {
+                                        return dataSet.getExperiment();
+                                    }
+                                }));
     }
     
     private void assertSampleDeletionBusinessRules(Set<TechId> experimentIds, Set<TechId> sampleIds)
@@ -420,8 +458,6 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
     private void assertDataSetDeletionBusinessRules(Set<TechId> experimentIds, Set<TechId> sampleIdes, 
             List<TechId> dataSetIds)
     {
-        Set<Long> eIds = new LinkedHashSet<Long>(TechId.asLongs(experimentIds));
-        Set<Long> sIds = new LinkedHashSet<Long>(TechId.asLongs(sampleIdes));
         IDatasetLister datasetLister = boFactory.createDatasetLister(session);
         Map<Long, Set<Long>> containerIds = datasetLister.listContainerIds(TechId.asLongs(dataSetIds));
         if (containerIds.isEmpty())
@@ -430,22 +466,25 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
         }
         Set<Long> allRelatedDataSets = new LinkedHashSet<Long>();
         addIds(allRelatedDataSets, containerIds);
-        IDataSetTable dataSetTable = boFactory.createDataSetTable(session);
-        dataSetTable.loadByIds(TechId.createList(new ArrayList<Long>(allRelatedDataSets)));
+        Set<Long> eIds = new LinkedHashSet<Long>(TechId.asLongs(experimentIds));
+        Set<Long> sIds = new LinkedHashSet<Long>(TechId.asLongs(sampleIdes));
+        List<AbstractExternalData> relatedDataSets 
+                = datasetLister.listByDatasetIds(new ArrayList<Long>(allRelatedDataSets), DATA_SET_FETCH_OPTIONS);
         StringBuilder builder = new StringBuilder();
         int numberOfForeignDataSets = 0;
-        for (DataPE relatedDataSet : dataSetTable.getDataSets())
+        for (AbstractExternalData relatedDataSet : relatedDataSets)
         {
             if (numberOfForeignDataSets >= 10)
             {
                 break;
             }
-            SamplePE sample = relatedDataSet.tryGetSample();
-            ExperimentPE experiment = relatedDataSet.getExperiment();
+            Sample sample = relatedDataSet.getSample();
+            Experiment experiment = relatedDataSet.getExperiment();
             if (sample != null)
             {
                 if (sIds.contains(sample.getId()) == false)
                 {
+                    HibernateUtils.initialize(sample);
                     addTo(builder, "sample " + sample.getIdentifier(), relatedDataSet, containerIds);
                     numberOfForeignDataSets++;
                 }
@@ -453,6 +492,7 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
             {
                 if (eIds.contains(experiment.getId()) == false)
                 {
+                    HibernateUtils.initialize(experiment);
                     addTo(builder, "experiment " + experiment.getIdentifier(), relatedDataSet, containerIds);
                     numberOfForeignDataSets++;
                 }
@@ -464,7 +504,7 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
         }
     }
     
-    private void addTo(StringBuilder builder, String entityDescription, DataPE dataSet, 
+    private void addTo(StringBuilder builder, String entityDescription, AbstractExternalData dataSet, 
             Map<Long, Set<Long>> containerIds)
     {
         String findOriginalDataSet = findOriginalDataSet(containerIds, dataSet);
@@ -472,7 +512,7 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
                 + dataSet.getCode() + " which belongs to " + entityDescription + " outside the deletion set.\n");
     }
     
-    private String findOriginalDataSet(Map<Long, Set<Long>> relations, DataPE dataSet)
+    private String findOriginalDataSet(Map<Long, Set<Long>> relations, AbstractExternalData dataSet)
     {
         Set<Entry<Long, Set<Long>>> entrySet = relations.entrySet();
         for (Entry<Long, Set<Long>> entry : entrySet)
@@ -505,6 +545,35 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
             throwException(ex, "Deletion");
         }
     }
+    
+    private static final class TrashOperationsManager
+    {
+        private final DeletionPE deletion;
+        private final IDeletionDAO deletionDAO;
+        private final List<TrashBatchOperation> operations = new ArrayList<TrashBatchOperation>();
+        
+        TrashOperationsManager(DeletionPE deletion, IDeletionDAO deletionDAO)
+        {
+            this.deletion = deletion;
+            this.deletionDAO = deletionDAO;
+        }
+        
+        void addTrashOperation(EntityKind entityKind, List<TechId> entityIds, boolean isOriginalDeletion)
+        {
+            if (entityIds.isEmpty() == false)
+            {
+                operations.add(new TrashBatchOperation(entityKind, entityIds, deletion, deletionDAO, isOriginalDeletion));
+            }
+        }
+        
+        void trash()
+        {
+            for (TrashBatchOperation operation : operations)
+            {
+                BatchOperationExecutor.executeInBatches(operation);
+            }
+        }
+    }
 
     private static class TrashBatchOperation implements IBatchOperation<TechId>
     {
@@ -518,8 +587,6 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
 
         private final boolean isOriginalDeletion;
 
-        private int counter = 0;
-
         public TrashBatchOperation(EntityKind entityKind, List<TechId> entityIds,
                 DeletionPE deletion, IDeletionDAO deletionDAO, boolean isOriginalDeletion)
         {
@@ -533,7 +600,7 @@ public class TrashBO extends AbstractBusinessObject implements ITrashBO
         @Override
         public void execute(List<TechId> entities)
         {
-            counter += deletionDAO.trash(entityKind, entities, deletion, isOriginalDeletion);
+            deletionDAO.trash(entityKind, entities, deletion, isOriginalDeletion);
         }
 
         @Override
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/TrashBOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/TrashBOTest.java
index 45dee2414180e0c81483a66864dbb56db4f7ebd4..d53831d60094261e18918ff90e04e7dd1a2eb7ff 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/TrashBOTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/TrashBOTest.java
@@ -41,8 +41,6 @@ import ch.systemsx.cisd.common.test.RecordingMatcher;
 import ch.systemsx.cisd.openbis.generic.server.business.ManagerTestTool;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.entitygraph.DataSetNode;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.entitygraph.EntityGraphGenerator;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.entitygraph.EntityNode;
-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.server.business.bo.entitygraph.Utils;
 import ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant;
@@ -194,6 +192,9 @@ public final class TrashBOTest extends AbstractBOTest
     @Test
     public final void testTrashExperimentsAlreadyTrashed()
     {
+        EntityGraphGenerator g = new EntityGraphGenerator();
+        g.parse("E1\nE2\nE3\n");
+        prepareEntityGraph(g);
         final DeletionPE deletion = createDeletion();
         final List<TechId> experimentIds = EXAMPLE_ID_LIST;
         context.checking(new Expectations()
@@ -207,404 +208,6 @@ public final class TrashBOTest extends AbstractBOTest
         context.assertIsSatisfied();
     }
 
-    @Test
-    public final void testTrashExperimentsWithOneLevelOfDependencies()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("E1, samples: S50, data sets: DS60 DS61\n"
-                + "E2, samples: S51\n"
-                + "E3\n"
-                );
-        prepareEntityGraph(g);
-        final DeletionPE deletion = createDeletion();
-        prepareTrashExperiments(deletion, true, g.e(1), g.e(2), g.e(3));
-        prepareTrashSamples(deletion, false, g.s(50), g.s(51));
-        prepareTrashDataSets(deletion, false, g.ds(60), g.ds(61));
-        
-        trashBO.trashExperiments(asIds(g.e(1), g.e(2), g.e(3)));
-
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public final void testTrashExperimentsWithDeepDependencies()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("E1, samples: S50, data sets: DS60 DS61\n"
-                + "E2, samples: S51\n"
-                + "E3\n"
-                + "S50, components: S52, data sets: DS70 DS71\n"
-                + "S51, components: S53\n"
-                );
-        prepareEntityGraph(g);
-        final DeletionPE deletion = createDeletion();
-        prepareTrashExperiments(deletion, true, g.e(1), g.e(2), g.e(3));
-        prepareTrashSamples(deletion, false, g.s(50), g.s(51));
-        prepareTrashSamples(deletion, false, g.s(52), g.s(53));
-        prepareTrashDataSets(deletion, false, g.ds(60), g.ds(61), g.ds(70), g.ds(71));
-
-        trashBO.trashExperiments(asIds(g.e(1), g.e(2), g.e(3)));
-
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public final void testTrashExperimentWithSamplesAndDataSetsAndNoExternalLinks()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("E1, samples: S1, data sets: DS1\n"
-                + "E2, data sets: DS2\n"
-                + "S1, data sets: DS1\n"
-                + "DS1, components: DS2\n");
-        ExperimentNode e1 = g.e(1);
-        SampleNode s1 = g.s(1);
-        ExperimentNode e2 = g.e(2);
-        DataSetNode ds1 = g.ds(1);
-        DataSetNode ds2 = g.ds(2);
-        prepareEntityGraph(g);
-        final DeletionPE deletion = createDeletion();
-        prepareTrashExperiments(deletion, true, e1, e2);
-        prepareTrashSamples(deletion, false, s1);
-        prepareTrashDataSets(deletion, false, ds1, ds2);
-
-        trashBO.trashExperiments(asIds(e1, e2));
-
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public final void testTrashExperimentWithARelatedDataSetComponentWhichBelongsToAnExternalExperiment()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("E1, samples: S1, data sets: DS1\n"
-                + "E2, data sets: DS2\n"
-                + "S1, data sets: DS1\n"
-                + "DS1, components: DS2\n");
-        ExperimentNode e1 = g.e(1);
-        SampleNode s1 = g.s(1);
-        prepareEntityGraph(g);
-        final DeletionPE deletion = createDeletion();
-        prepareTrashExperiments(deletion, true, e1);
-        prepareTrashSamples(deletion, false, s1);
-        prepareTrashDataSets(deletion, false, g.ds(1));
-        
-        trashBO.trashExperiments(asIds(e1));
-        
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public final void testTrashExperimentWithARelatedDataSetInAnExternalContainer()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("E1, samples: S1, data sets: DS1\n"
-                + "E2, data sets: DS2\n"
-                + "S1, data sets: DS1\n"
-                + "DS1, components: DS2\n");
-        ExperimentNode e2 = g.e(2);
-        DataSetNode ds2 = g.ds(2);
-        prepareEntityGraph(g);
-        final DeletionPE deletion = createDeletion();
-        prepareTrashExperiments(deletion, true, e2);
-        
-        failTrashExperiment(e2, ds2, g.ds(1), g.s(1));
-        
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public void testTrashPublishedExperiment()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("E1, data sets: DS1 DS2 DS3 DS4\n"
-                + "DS1, components: DS3\n"
-                + "DS2, children: DS4\n"
-                + "E2, data sets: DS5 DS6\n"
-                + "DS5, components: DS1\n"
-                + "DS6, components: DS2\n");
-        ExperimentNode e2 = g.e(2); // published experiment
-        DataSetNode ds5 = g.ds(5);
-        DataSetNode ds6 = g.ds(6);
-        prepareEntityGraph(g);
-        DeletionPE deletion = createDeletion();
-        prepareTrashExperiments(deletion, true, e2);
-        prepareTrashDataSets(deletion, false, ds5 , ds6);
-        
-        trashBO.trashExperiments(asIds(e2));
-        
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public final void testTrashPublishedExperimentWithOrginalExperimentWithSamples()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("E1, samples: S1\n"
-                + "S1, data sets: DS1 DS2\n"
-                + "DS1, components: DS2\n"
-                + "E2, data sets: DS3\n"
-                + "DS3, components: DS1");
-        prepareEntityGraph(g);
-        final DeletionPE deletion = createDeletion();
-        prepareTrashExperiments(deletion, true, g.e(2));
-        prepareTrashDataSets(deletion, false, g.ds(3));
-        
-        trashBO.trashExperiments(asIds(g.e(2)));
-        
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public final void testTrashOrginalExperimentWithSample()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("E1, samples: S1\n"
-                + "S1, data sets: DS1 DS2\n"
-                + "DS1, components: DS2\n"
-                + "E2, data sets: DS3\n"
-                + "DS3, components: DS1");
-        prepareEntityGraph(g);
-        final DeletionPE deletion = createDeletion();
-        prepareTrashExperiments(deletion, true, g.e(1));
-        prepareTrashSamples(deletion, false, g.s(1));
-        
-        failTrashExperiment(g.e(1), g.ds(1), g.ds(3), g.e(2));
-        
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public final void testTrashExperimentsWithContainerDataSetWithPhysicalDataSetFromAnotherExperiment()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("E1, data sets: DS1\n"
-                + "E2, data sets: DS2\n"
-                + "DS1, components: DS2\n"
-                + "DS2, containers: DS1");
-        prepareEntityGraph(g);
-        DeletionPE deletion = createDeletion();
-        prepareTrashExperiments(deletion, true, g.e(1));
-        prepareTrashDataSets(deletion, false, g.ds(1));
-        
-        trashBO.trashExperiments(asIds(g.e(1)));
-        
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public final void testTrashSamplesAlreadyTrashed()
-    {
-        final EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("S1\nS2\n");
-        prepareEntityGraph(g);
-
-        final DeletionPE deletion = createDeletion();
-        context.checking(new Expectations()
-            {
-                {
-                    one(deletionDAO).trash(EntityKind.SAMPLE, asIds(g.s(1), g.s(2)), deletion, true);
-                    will(returnValue(0));
-                }
-            });
-        trashBO.trashSamples(asIds(g.s(1), g.s(2)));
-        context.assertIsSatisfied();
-    }
-
-    @Test
-    public final void testTrashSamplesWithOneLevelOfDependencies()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("S1, components: S20\n"
-                + "S3, data sets: DS60\n"
-                + "S20, data sets: DS61\n");
-        prepareEntityGraph(g);
-        final DeletionPE deletion = createDeletion();
-        prepareTrashSamples(deletion, true, g.s(1), g.s(3));
-        prepareTrashSamples(deletion, false, g.s(20));
-        prepareTrashDataSets(deletion, false, g.ds(60), g.ds(61));
-        
-        trashBO.trashSamples(asIds(g.s(1), g.s(3)));
-        
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public final void testTrashSampleWithTwoLevelOfDependencies()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("S1, components: S2, data sets: DS1\n"
-                + "S2, components: S3, data sets: DS2\n"
-                + "S3, data sets: DS3\n");
-        prepareEntityGraph(g);
-        final DeletionPE deletion = createDeletion();
-        prepareTrashSamples(deletion, true, g.s(1));
-        prepareTrashSamples(deletion, false, g.s(2));
-        prepareTrashDataSets(deletion, false, g.ds(1), g.ds(2));
-        
-        trashBO.trashSamples(asIds(g.s(1)));
-        
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public final void testTrashSampleWithAComponentWithAContainerDataSetWithAComponentDataSetOfFirstSample()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("S1, components: S2, data sets: DS1\n"
-                + "S2, data sets: DS2\n"
-                + "DS2, components: DS1\n");
-        prepareEntityGraph(g);
-        final DeletionPE deletion = createDeletion();
-        prepareTrashSamples(deletion, true, g.s(1));
-        prepareTrashSamples(deletion, false, g.s(2));
-        prepareTrashDataSets(deletion, false, g.ds(1), g.ds(2));
-        
-        trashBO.trashSamples(asIds(g.s(1)));
-        
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public final void testTrashSampleWithAComponentWithAComponentDataSetOfAContainerDataSetOfFirstSample()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("S1, components: S2, data sets: DS1\n"
-                + "S2, data sets: DS2\n"
-                + "DS1, components: DS2\n");
-        prepareEntityGraph(g);
-        final DeletionPE deletion = createDeletion();
-        prepareTrashSamples(deletion, true, g.s(1));
-        prepareTrashSamples(deletion, false, g.s(2));
-        prepareTrashDataSets(deletion, false, g.ds(1), g.ds(2));
-        
-        trashBO.trashSamples(asIds(g.s(1)));
-        
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public final void testTrashSampleWithAnExperimentSampleWithADataSet()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("E1, samples: S2\n"
-                + "S1, components: S2\n"
-                + "S2, data sets: DS1\n");
-        prepareEntityGraph(g);
-        final DeletionPE deletion = createDeletion();
-        prepareTrashSamples(deletion, true, g.s(1));
-        prepareTrashSamples(deletion, false, g.s(2));
-        
-        failTrashSample(g.s(1), g.s(2), g.e(1));
-        
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public final void testTrashSampleWithComponentWithDataSetWithComponentOfAnotherSample()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("S1, components: S2\n"
-                + "S2, data sets: DS2\n"
-                + "S3, data sets: DS1\n"
-                + "DS1, components: DS2\n");
-        prepareEntityGraph(g);
-        final DeletionPE deletion = createDeletion();
-        prepareTrashSamples(deletion, true, g.s(1));
-        prepareTrashSamples(deletion, false, g.s(2));
-
-        failTrashSample(g.s(1), g.ds(2), g.ds(1), g.s(3));
-        
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public final void testTrashSampleWithComponentWithDataSetWithComponentOfAnotherExperiment()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("E1, data sets: DS1\n"
-                + "S1, components: S2\n"
-                + "S2, data sets: DS2\n"
-                + "DS1, components: DS2\n");
-        prepareEntityGraph(g);
-        final DeletionPE deletion = createDeletion();
-        prepareTrashSamples(deletion, true, g.s(1));
-        prepareTrashSamples(deletion, false, g.s(2));
-        
-        failTrashSample(g.s(1), g.ds(2), g.ds(1), g.e(1));
-        
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public final void testTrashDataSets()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("S1, data sets: DS1 DS2 DS3 DS4 DS5 DS6\n"
-                + "DS1, components: DS5\n"
-                + "DS2, components: DS6\n");
-        prepareEntityGraph(g);
-        DeletionPE deletion = createDeletion();
-        prepareTrashDataSets(deletion, true, g.ds(1), g.ds(2), g.ds(3));
-        prepareTrashDataSets(deletion, false, g.ds(5), g.ds(6));
-        
-        trashBO.trashDataSets(asIds(g.ds(1), g.ds(2), g.ds(3)));
-        
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public void testTrashDataSetsWithDataSetInAContainer()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("S1, data sets: DS1 DS2 DS3\n"
-                + "DS1, components: DS2\n"
-                + "DS2, components: DS3\n");
-        prepareEntityGraph(g);
-        DeletionPE deletion = createDeletion();
-        prepareTrashDataSets(deletion, true, g.ds(2));
-        prepareTrashDataSets(deletion, false, g.ds(3));
-        
-        trashBO.trashDataSets(asIds(g.ds(2)));
-        
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public void testTrashDataSetsWithDataSetComponentIndirectlyDependentOnOutsideContainer()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("S1, data sets: DS1 DS2 DS3 DS4 DS5 DS6\n"
-                + "DS1, components: DS3 DS4 DS5\n"
-                + "DS2, components: DS4\n"
-                + "DS4, components: DS5 DS6\n");
-        prepareEntityGraph(g);
-        DeletionPE deletion = createDeletion();
-        prepareTrashDataSets(deletion, true, g.ds(1));
-        prepareTrashDataSets(deletion, false, g.ds(3));
-
-        trashBO.trashDataSets(asIds(g.ds(1)));
-
-        context.assertIsSatisfied();
-    }
-    
-    @Test
-    public void testTrashSampleWithDataSetWithDataSetComponentIndirectlyDependentOnOutsideContainer()
-    {
-        EntityGraphGenerator g = new EntityGraphGenerator();
-        g.parse("S1, data sets: DS1 DS3 DS4 DS5 DS6\n"
-                + "S2, data sets: DS2\n"
-                + "DS1, components: DS3 DS4 DS5\n"
-                + "DS2, components: DS4\n"
-                + "DS4, components: DS5 DS6\n");
-        prepareEntityGraph(g);
-        DeletionPE deletion = createDeletion();
-        prepareTrashSamples(deletion, true, g.s(1));
-
-        failTrashSample(g.s(1), g.ds(4), g.ds(2), g.s(2));
-        
-        context.assertIsSatisfied();
-    }
-
     @Test
     public final void testTrashUnavailableDataSets()
     {
@@ -628,85 +231,6 @@ public final class TrashBOTest extends AbstractBOTest
         context.assertIsSatisfied();
     }
     
-    private void prepareTrashExperiments(DeletionPE deletion, boolean isOriginalDeletion, 
-            ExperimentNode... experiments)
-    {
-        prepareTrash(deletion, EntityKind.EXPERIMENT, isOriginalDeletion, asIds(experiments));
-    }
-
-    private void prepareTrashSamples(DeletionPE deletion, boolean isOriginalDeletion, 
-            SampleNode... samples)
-    {
-        prepareTrash(deletion, EntityKind.SAMPLE, isOriginalDeletion, asIds(samples));
-    }
-    
-    private void prepareTrashDataSets(DeletionPE deletion, boolean isOriginalDeletion, 
-            DataSetNode... dataSets)
-    {
-        prepareTrash(deletion, EntityKind.DATA_SET, isOriginalDeletion, asIds(dataSets));
-    }
-    
-    private void prepareTrash(final DeletionPE deletion, final EntityKind entityKind, 
-            final boolean isOriginalDeletion, final List<TechId> entityIds)
-    {
-        context.checking(new Expectations()
-            {
-                {
-                    one(deletionDAO).trash(entityKind, entityIds, deletion, isOriginalDeletion);
-                    will(returnValue(entityIds.size()));
-                }
-            });
-    }
-    
-    private void failTrashExperiment(ExperimentNode experimentNode, DataSetNode originalDataSet,
-            DataSetNode relatedDataSet, EntityNode outsiderNode)
-    {
-        try
-        {
-            trashBO.trashExperiments(asIds(experimentNode));
-            fail("UserFailureException expected");
-        } catch (UserFailureException ex)
-        {
-            assertExceptionMessage(originalDataSet, relatedDataSet, outsiderNode, ex);
-        }
-    }
-    
-    private void failTrashSample(SampleNode sampleNode, SampleNode relatedSample, EntityNode outsiderNode)
-    {
-        try
-        {
-            trashBO.trashSamples(asIds(sampleNode));
-            fail("UserFailureException expected");
-        } catch (UserFailureException ex)
-        {
-            String outsiderType = outsiderNode instanceof ExperimentNode ? "experiment" : "sample";
-            assertEquals("The sample " + relatedSample.getIdentifier() + " belongs to " + outsiderType + " " 
-                    + outsiderNode.getCode() + " is outside the deletion set.", ex.getMessage());
-        }
-    }
-
-    private void failTrashSample(SampleNode sampleNode, DataSetNode originalDataSet,
-            DataSetNode relatedDataSet, EntityNode outsiderNode)
-    {
-        try
-        {
-            trashBO.trashSamples(asIds(sampleNode));
-            fail("UserFailureException expected");
-        } catch (UserFailureException ex)
-        {
-            assertExceptionMessage(originalDataSet, relatedDataSet, outsiderNode, ex);
-        }
-    }
-    
-    private void assertExceptionMessage(DataSetNode originalDataSet, DataSetNode relatedDataSet, 
-            EntityNode outsiderNode, UserFailureException ex)
-    {
-        String outsiderType = outsiderNode instanceof ExperimentNode ? "experiment" : "sample";
-        assertEquals("The data set " + originalDataSet.getCode() + " is a component of the data set " 
-                + relatedDataSet.getCode() + " which belongs to " + outsiderType + " " 
-                + outsiderNode.getIdentifier() + " outside the deletion set.", ex.getMessage());
-    }
-
     private void prepareEntityGraph(EntityGraphGenerator g)
     {
         g.assertConsistency();
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/EntityDeletionTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/EntityDeletionTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5e76e16e505afbea767f1ae98ac66ddb7666884e
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/EntityDeletionTest.java
@@ -0,0 +1,553 @@
+/*
+ * Copyright 2015 ETH Zuerich, SIS
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.systemtest;
+
+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.Test;
+
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.entitygraph.DataSetNode;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.entitygraph.EntityGraphGenerator;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.entitygraph.EntityNode;
+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.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DeletionType;
+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.dto.identifier.ExperimentIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory;
+import ch.systemsx.cisd.openbis.systemtest.base.BaseTest;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class EntityDeletionTest extends BaseTest
+{
+    @Test
+    public final void testTrashExperimentsWithOneLevelOfDependencies()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph(
+                "E1, samples: S50, data sets: DS60 DS61\n"
+                + "E2, samples: S51\n"
+                + "E3\n"
+                );
+        
+        deleteExperiments(g.e(1), g.e(2), g.e(3));
+
+        assertEquals("", renderGraph(g));
+        assertDeleted(g.e(1), g.e(2), g.e(3));
+        assertDeleted(g.s(50), g.s(51));
+        assertDeleted(g.ds(60), g.ds(61));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public final void testTrashExperimentsWithDeepDependencies()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S50, data sets: DS60 DS61 DS70 DS71\n"
+                + "E2, samples: S51\n"
+                + "E3\n"
+                + "S50, components: S52, data sets: DS70 DS71\n"
+                + "S51, components: S53\n"
+                );
+
+        deleteExperiments(g.e(1), g.e(2), g.e(3));
+
+        assertEquals("", renderGraph(g));
+        assertDeleted(g.e(1), g.e(2), g.e(3));
+        assertDeleted(g.s(50), g.s(51), g.s(52), g.s(53));
+        assertDeleted(g.ds(60), g.ds(61), g.ds(70), g.ds(71));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public final void testTrashExperimentWithSamplesAndDataSetsAndNoExternalLinks()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS1\n"
+                + "E2, data sets: DS2\n"
+                + "S1, data sets: DS1\n"
+                + "DS1, components: DS2\n");
+        
+        deleteExperiments(g.e(1), g.e(2));
+
+        assertEquals("", renderGraph(g));
+        assertDeleted(g.e(1), g.e(2));
+        assertDeleted(g.s(1));
+        assertDeleted(g.ds(1), g.ds(2));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public final void testTrashExperimentWithARelatedDataSetComponentWhichBelongsToAnExternalExperiment()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS1\n"
+                + "E2, data sets: DS2\n"
+                + "S1, data sets: DS1\n"
+                + "DS1, components: DS2\n");
+        
+        deleteExperiments(g.e(1));
+        
+        assertEquals("E2, data sets: DS2\n", renderGraph(g));
+        assertDeleted(g.e(1));
+        assertDeleted(g.s(1));
+        assertDeleted(g.ds(1));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public final void testTrashExperimentWithARelatedDataSetInAnExternalContainer()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS1\n"
+                + "E2, data sets: DS2\n"
+                + "S1, data sets: DS1\n"
+                + "DS1, components: DS2\n");
+        
+        failTrashExperiment(g.e(2), g.ds(2), g.ds(1), g.s(1));
+        
+        assertEquals("E1, samples: S1, data sets: DS1\n"
+                + "E2, data sets: DS2\n"
+                + "S1, data sets: DS1\n"
+                + "DS1, components: DS2\n", renderGraph(g));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public void testTrashPublishedExperiment()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("E1, data sets: DS3 DS4 DS5 DS6\n"
+                + "E2, data sets: DS1 DS2\n"
+                + "DS1, components: DS3\n"
+                + "DS2, components: DS6\n"
+                + "DS3, components: DS4\n"
+                + "DS5, parents: DS6\n");
+        
+        deleteExperiments(g.e(2));
+        
+        assertEquals("E1, data sets: DS3 DS4 DS5 DS6\n"
+                + "DS3, components: DS4\n"
+                + "DS5, parents: DS6\n", renderGraph(g));
+        assertDeleted(g.e(2));
+        assertDeleted(g.ds(1), g.ds(2));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public final void testTrashPublishedExperimentWithOrginalExperimentWithSamples()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS2 DS3\n"
+                + "E2, data sets: DS1\n"
+                + "S1, data sets: DS2 DS3\n"
+                + "DS1, components: DS2\n"
+                + "DS2, components: DS3\n"
+                );
+        
+        deleteExperiments(g.e(2));
+        
+        assertEquals("E1, samples: S1, data sets: DS2 DS3\n"
+                + "S1, data sets: DS2 DS3\n"
+                + "DS2, components: DS3\n", renderGraph(g));
+        assertDeleted(g.e(2));
+        assertDeleted(g.ds(1));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public final void testTrashOrginalExperimentWithSample()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS2 DS3\n"
+                + "E2, data sets: DS1\n"
+                + "S1, data sets: DS2 DS3\n"
+                + "DS1, components: DS2\n"
+                + "DS2, components: DS3\n"
+                );
+        
+        failTrashExperiment(g.e(1), g.ds(2), g.ds(1), g.e(2));
+        
+        assertEquals("E1, samples: S1, data sets: DS2 DS3\n"
+                + "E2, data sets: DS1\n"
+                + "S1, data sets: DS2 DS3\n"
+                + "DS1, components: DS2\n"
+                + "DS2, components: DS3\n", renderGraph(g));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public final void testTrashExperimentsWithContainerDataSetWithPhysicalDataSetFromAnotherExperiment()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("E1, data sets: DS1\n"
+                + "E2, data sets: DS2\n"
+                + "DS1, components: DS2\n");
+        
+        deleteExperiments(g.e(1));
+        
+        assertEquals("E2, data sets: DS2\n", renderGraph(g));
+        assertDeleted(g.e(1));
+        assertDeleted(g.ds(1));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public final void testTrashSamplesAlreadyTrashed()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("S1\nS2\n");
+        
+        
+        assertEquals("", renderGraph(g));
+        assertUnmodifiedAndUndeleted(g);
+    }
+
+    @Test
+    public final void testTrashSamplesWithOneLevelOfDependencies()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("S1, components: S20\n"
+                + "S3, data sets: DS60[NET]\n"
+                + "S20, data sets: DS61[NET]\n");
+        
+        deleteSamples(g.s(1), g.s(3));
+        
+        assertEquals("", renderGraph(g));
+        assertDeleted(g.s(1), g.s(3), g.s(20));
+        assertDeleted(g.ds(60), g.ds(61));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public final void testTrashSampleWithTwoLevelOfDependencies()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("S1, components: S2 S3, data sets: DS1[NET]\n"
+                + "S2, data sets: DS2[NET]\n"
+                + "S3, data sets: DS3[NET]\n");
+        
+        deleteSamples(g.s(1));
+        
+        assertEquals("", renderGraph(g));
+        assertDeleted(g.s(1), g.s(2), g.s(3));
+        assertDeleted(g.ds(1), g.ds(2), g.ds(3));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public final void testTrashSampleWithAComponentWithAContainerDataSetWithAComponentDataSetOfFirstSample()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("S1, components: S2, data sets: DS2[NET]\n"
+                + "S2, data sets: DS1[NECT]\n"
+                + "DS1[NECT], components: DS2[NET]\n");
+        
+        deleteSamples(g.s(1));
+        
+        assertEquals("", renderGraph(g));
+        assertDeleted(g.s(1), g.s(2));
+        assertDeleted(g.ds(1), g.ds(2));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public final void testTrashSampleWithAComponentWithAComponentDataSetOfAContainerDataSetOfFirstSample()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("S1, components: S2, data sets: DS1[NECT]\n"
+                + "S2, data sets: DS2[NET]\n"
+                + "DS1[NECT], components: DS2[NET]\n");
+        
+        deleteSamples(g.s(1));
+        
+        assertEquals("", renderGraph(g));
+        assertDeleted(g.s(1), g.s(2));
+        assertDeleted(g.ds(1), g.ds(2));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public final void testTrashSampleWithAnExperimentSampleWithADataSet()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S2, data sets: DS1\n"
+                + "S1, components: S2\n"
+                + "S2, data sets: DS1\n");
+        
+        failTrashSample(g.s(1), g.s(2), g.e(1));
+        
+        assertEquals("E1, samples: S2, data sets: DS1\n"
+                + "S1, components: S2\n"
+                + "S2, data sets: DS1\n", renderGraph(g));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public final void testTrashExperimentSampleWithADataSet()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("E1, samples: S1, data sets: DS1\n"
+                + "S1, data sets: DS1\n");
+        
+        deleteSamples(g.s(1));
+        
+        assertEquals("", renderGraph(g));
+        assertModified(g.e(1));
+        assertDeleted(g.s(1));
+        assertDeleted(g.ds(1));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public final void testTrashSampleWithComponentWithDataSetWithComponentOfAnotherSample()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("S1, components: S2\n"
+                + "S2, data sets: DS2[NET]\n"
+                + "S3, data sets: DS1[NECT]\n"
+                + "DS1[NECT], components: DS2[NET]\n");
+        
+        failTrashSample(g.s(1), g.ds(2), g.ds(1), g.s(3));
+        
+        assertEquals("S1, components: S2\n"
+                + "S2, data sets: DS2[NET]\n"
+                + "S3, data sets: DS1[NECT]\n"
+                + "DS1[NECT], components: DS2[NET]\n", renderGraph(g));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public final void testTrashSampleWithComponentWithDataSetWithComponentOfAnotherExperiment()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("E1, data sets: DS1\n"
+                + "S1, components: S2\n"
+                + "S2, data sets: DS2[NET]\n"
+                + "DS1, components: DS2[NET]\n");
+        
+        failTrashSample(g.s(1), g.ds(2), g.ds(1), g.e(1));
+        
+        assertEquals("E1, data sets: DS1\n"
+                + "S1, components: S2\n"
+                + "S2, data sets: DS2[NET]\n"
+                + "DS1, components: DS2[NET]\n", renderGraph(g));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public void testTrashSampleWithDataSetWithDataSetComponentIndirectlyDependentOnOutsideContainer()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("S1, data sets: DS1[NECT] DS3[NET] DS4[NECT] DS5[NET] DS6[NET]\n"
+                + "S2, data sets: DS2[NECT]\n"
+                + "DS1[NECT], components: DS3[NET] DS4[NECT] DS5[NET]\n"
+                + "DS2[NECT], components: DS4[NECT]\n"
+                + "DS4[NECT], components: DS5[NET] DS6[NET]\n");
+        
+        failTrashSample(g.s(1), g.ds(4), g.ds(2), g.s(2));
+        
+        assertEquals("S1, data sets: DS1[NECT] DS3[NET] DS4[NECT] DS5[NET] DS6[NET]\n"
+                + "S2, data sets: DS2[NECT]\n"
+                + "DS1[NECT], components: DS3[NET] DS4[NECT] DS5[NET]\n"
+                + "DS2[NECT], components: DS4[NECT]\n"
+                + "DS4[NECT], components: DS5[NET] DS6[NET]\n", renderGraph(g));
+        assertUnmodifiedAndUndeleted(g);
+    }
+
+    @Test
+    public final void testTrashDataSets()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("S1, data sets: DS1[NECT] DS2[NECT] DS3[NET] DS4[NET] DS5[NET] DS6[NET]\n"
+                + "DS1[NECT], components: DS5[NET]\n"
+                + "DS2[NECT], components: DS6[NET]\n");
+        
+        deleteDataSets(g.ds(1), g.ds(2), g.ds(3));
+        
+        assertEquals("S1, data sets: DS4[NET]\n", renderGraph(g));
+        assertModified(g.s(1));
+        assertDeleted(g.ds(1), g.ds(2), g.ds(3), g.ds(5), g.ds(6));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public final void testTrashDataSetAndComponentsBelongingToSameExperiment()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("E1, data sets: DS1 DS2\n"
+                + "E2, data sets: DS3\n"
+                + "DS1, components: DS2 DS3\n");
+        
+        deleteDataSets(g.ds(1));
+        
+        assertEquals("E2, data sets: DS3\n", renderGraph(g));
+        assertModified(g.e(1));
+        assertDeleted(g.ds(1), g.ds(2));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public void testTrashDataSetsWithDataSetInAContainer()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("S1, data sets: DS1[NECT] DS2[NECT] DS3[NET]\n"
+                + "DS1[NECT], components: DS2[NECT]\n"
+                + "DS2[NECT], components: DS3[NET]\n");
+        
+        deleteDataSets(g.ds(2));
+        
+        assertEquals("S1, data sets: DS1[NECT]\n", renderGraph(g));
+        assertModified(g.s(1));
+        assertModified(g.ds(1));
+        assertDeleted(g.ds(2), g.ds(3));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    @Test
+    public void testTrashDataSetsWithDataSetComponentIndirectlyDependentOnOutsideContainer()
+    {
+        EntityGraphGenerator g = parseAndCreateGraph("S1, data sets: DS1[NECT] DS2[NECT] DS3[NET] DS4[NECT] DS5[NET] DS6[NET]\n"
+                + "DS1[NECT], components: DS3[NET] DS4[NECT] DS5[NET]\n"
+                + "DS2[NECT], components: DS4[NECT]\n"
+                + "DS4[NECT], components: DS5[NET] DS6[NET]\n");
+
+        deleteDataSets(g.ds(1));
+
+        assertEquals("S1, data sets: DS2[NECT] DS4[NECT] DS5[NET] DS6[NET]\n"
+                + "DS2[NECT], components: DS4[NECT]\n"
+                + "DS4[NECT], components: DS5[NET] DS6[NET]\n", renderGraph(g));
+        assertModified(g.s(1));
+        assertDeleted(g.ds(1), g.ds(3));
+        assertUnmodifiedAndUndeleted(g);
+    }
+    
+    private void failTrashExperiment(ExperimentNode experimentNode, DataSetNode originalDataSet,
+            DataSetNode relatedDataSet, EntityNode outsiderNode)
+    {
+        try
+        {
+            deleteExperiments(experimentNode);
+            fail("UserFailureException expected");
+        } catch (UserFailureException ex)
+        {
+            assertExceptionMessage(originalDataSet, relatedDataSet, outsiderNode, ex);
+        }
+    }
+    
+    private void failTrashSample(SampleNode sampleNode, SampleNode relatedSample, EntityNode outsiderNode)
+    {
+        try
+        {
+            deleteSamples(sampleNode);
+            fail("UserFailureException expected");
+        } catch (UserFailureException ex)
+        {
+            assertEquals("The sample " + entityGraphManager.getSample(relatedSample).getIdentifier() 
+                    + " belongs to " + renderOutsider(outsiderNode) + " is outside the deletion set.", 
+                    ex.getMessage());
+        }
+    }
+
+    private void failTrashSample(SampleNode sampleNode, DataSetNode originalDataSet,
+            DataSetNode relatedDataSet, EntityNode outsiderNode)
+    {
+        try
+        {
+            deleteSamples(sampleNode);
+            fail("UserFailureException expected");
+        } catch (UserFailureException ex)
+        {
+            assertExceptionMessage(originalDataSet, relatedDataSet, outsiderNode, ex);
+        }
+    }
+    
+    private void assertExceptionMessage(DataSetNode originalDataSet, DataSetNode relatedDataSet, 
+            EntityNode outsiderNode, UserFailureException ex)
+    {
+        assertEquals("The data set " + entityGraphManager.getDataSetCodeOrNull(originalDataSet) 
+                + " is a component of the data set " + entityGraphManager.getDataSetCodeOrNull(relatedDataSet) 
+                + " which belongs to " + renderOutsider(outsiderNode) + " outside the deletion set.", 
+                ex.getMessage());
+    }
+
+    private String renderOutsider(EntityNode outsiderNode)
+    {
+        String outsiderType;
+        String outsiderIdentifier;
+        if (outsiderNode instanceof ExperimentNode)
+        {
+            outsiderType = "experiment";
+            outsiderIdentifier = entityGraphManager.getExperimentIdentifierOrNull((ExperimentNode) outsiderNode);
+        } else
+        {
+            outsiderType = "sample";
+            outsiderIdentifier = entityGraphManager.getSample((SampleNode) outsiderNode).getIdentifier();
+        }
+        String outsider = outsiderType + " " 
+        + outsiderIdentifier;
+        return outsider;
+    }
+    
+    private void deleteExperiments(ExperimentNode...experimentNodes)
+    {
+        List<String> experimentIdentifiers = new ArrayList<String>();
+        for (ExperimentNode experimentNode : experimentNodes)
+        {
+            experimentIdentifiers.add(entityGraphManager.getExperimentIdentifierOrNull(experimentNode));
+        }
+        deleteExperiments(experimentIdentifiers, createAdminUser());
+    }
+
+    private void deleteSamples(SampleNode...sampleNodes)
+    {
+        List<String> samplePermIds = new ArrayList<String>();
+        for (SampleNode sampleNode : sampleNodes)
+        {
+            samplePermIds.add(entityGraphManager.getSamplePermIdOrNull(sampleNode));
+        }
+        deleteSamples(samplePermIds, createAdminUser());
+    }
+    
+    private void deleteDataSets(DataSetNode...dataSetNodes)
+    {
+        List<String> dataSetCodes = new ArrayList<String>();
+        for (DataSetNode dataSetNode : dataSetNodes)
+        {
+            dataSetCodes.add(entityGraphManager.getDataSetCodeOrNull(dataSetNode));
+        }
+        deleteDataSets(dataSetCodes, createAdminUser());
+    }
+    
+    private String createAdminUser()
+    {
+        return create(aSession().withInstanceRole(RoleCode.ADMIN));
+    }
+    
+    protected void deleteExperiments(List<String> experimentIdentifiers, String userSessionToken)
+    {
+        List<ExperimentIdentifier> identifiers = new ArrayList<ExperimentIdentifier>();
+        for (String identifier : experimentIdentifiers)
+        {
+            identifiers.add(ExperimentIdentifierFactory.parse(identifier));
+        }
+        List<TechId> experimentIds = TechId.createList(commonServer.listExperiments(userSessionToken, identifiers));
+        commonServer.deleteExperiments(userSessionToken, experimentIds, "test", DeletionType.TRASH);
+    }
+    
+    protected void deleteSamples(List<String> samplePermIds, String userSessionToken)
+    {
+        Sample[] samples = loadSamples(samplePermIds);
+        commonServer.deleteSamples(userSessionToken, TechId.createList(Arrays.asList(samples)), "test", DeletionType.TRASH);
+    }
+
+    protected void deleteDataSets(List<String> dataSetCodes, String userSessionToken)
+    {
+        commonServer.deleteDataSets(userSessionToken, dataSetCodes, "test", DeletionType.TRASH, true);
+    }
+    
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/BaseTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/BaseTest.java
index ea4b536bb7ae87acc458366ead650f4b247c4c8d..ad6a27abc0d9771378cc9fc6e257299f533d5d3f 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/BaseTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/BaseTest.java
@@ -493,21 +493,47 @@ public abstract class BaseTest extends AbstractTransactionalTestNGSpringContextT
         entityGraphManager.assertModified(experimentNodes);
     }
 
+    protected void assertDeleted(ExperimentNode... experimentNodes)
+    {
+        entityGraphManager.assertDeleted(experimentNodes);
+    }
+    
     protected void assertModified(SampleNode... sampleNodes)
     {
         entityGraphManager.assertModified(sampleNodes);
     }
 
+    protected void assertDeleted(SampleNode... sampleNodes)
+    {
+        entityGraphManager.assertDeleted(sampleNodes);
+    }
+    
     protected void assertModified(DataSetNode... dataSetNodes)
     {
         entityGraphManager.assertModified(dataSetNodes);
     }
 
+    protected void assertDeleted(DataSetNode... dataSetNodes)
+    {
+        entityGraphManager.assertDeleted(dataSetNodes);
+    }
+    
     protected void assertUnmodified(EntityGraphGenerator g)
     {
         entityGraphManager.assertUnmodified(g);
     }
 
+    protected void assertUndeleted(EntityGraphGenerator g)
+    {
+        entityGraphManager.assertUndeleted(g);
+    }
+    
+    protected void assertUnmodifiedAndUndeleted(EntityGraphGenerator g)
+    {
+        assertUnmodified(g);
+        assertUndeleted(g);
+    }
+    
     protected String getIdentifierOfDefaultProject()
     {
         return defaultProject.getIdentifier();
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 425fee7d6f97fa38795493bdb4befea737f6d635..7e917a592c514004bd528c5129d090e3c05aef45 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
@@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.systemtest.entitygraph;
 
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNotNull;
+import static org.testng.AssertJUnit.fail;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -142,21 +143,41 @@ public class EntityGraphManager
         repository.assertModified(experimentNodes);
     }
 
+    public void assertDeleted(ExperimentNode[] experimentNodes)
+    {
+        repository.assertDeleted(experimentNodes);
+    }
+    
     public void assertModified(SampleNode[] sampleNodes)
     {
         repository.assertModified(sampleNodes);
     }
 
+    public void assertDeleted(SampleNode[] sampleNodes)
+    {
+        repository.assertDeleted(sampleNodes);
+    }
+    
     public void assertModified(DataSetNode[] dataSetNodes)
     {
         repository.assertModified(dataSetNodes);
     }
 
+    public void assertDeleted(DataSetNode[] dataSetNodes)
+    {
+        repository.assertDeleted(dataSetNodes);
+    }
+    
     public void assertUnmodified(EntityGraphGenerator g)
     {
         repository.assertUnmodified(g);
     }
 
+    public void assertUndeleted(EntityGraphGenerator g)
+    {
+        repository.assertUndeleted(g);
+    }
+    
     public String getIdentifierOfDefaultProject()
     {
         return defaultProject.getIdentifier();
@@ -624,16 +645,19 @@ public class EntityGraphManager
         private Map<Long, Experiment> experimentsNodeToDtoMap = new TreeMap<Long, Experiment>();
         private Map<Long, ModificationInfo> experimentModificationInfoByNodeId = new HashMap<Long, ModificationInfo>();
         private Set<ExperimentNode> modifiedExperimentNodes = new HashSet<ExperimentNode>();
+        private Set<ExperimentNode> deletedExperimentNodes = new HashSet<ExperimentNode>();
         
         private Map<Long, Sample> samplesNodeToDtoMap = new TreeMap<Long, Sample>();
         private Map<Long, SampleNode> samplesDtoToNodeMap = new TreeMap<Long, SampleNode>();
         private Map<Long, ModificationInfo> sampleModificationInfoByNodeId = new HashMap<Long, ModificationInfo>();
         private Set<SampleNode> modifiedSampleNodes = new HashSet<SampleNode>();
+        private Set<SampleNode> deletedSampleNodes = new HashSet<SampleNode>();
 
         private Map<Long, AbstractExternalData> dataSetsNodeToDtoMap = new TreeMap<Long, AbstractExternalData>();
         private Map<Long, DataSetNode> dataSetsDtoToNodeMap = new TreeMap<Long, DataSetNode>();
         private Map<Long, ModificationInfo> dataSetModificationInfoByNodeId = new HashMap<Long, ModificationInfo>();
         private Set<DataSetNode> modifiedDataSetNodes = new HashSet<DataSetNode>();
+        private Set<DataSetNode> deletedDataSetNodes = 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>>();
@@ -901,6 +925,12 @@ public class EntityGraphManager
             modifiedExperimentNodes.addAll(Arrays.asList(experimentNodes));
         }
         
+        public void assertDeleted(ExperimentNode...experimentNodes)
+        {
+            assertDeleted(experimentsNodeToDtoMap,  Arrays.<EntityNode>asList(experimentNodes));
+            deletedExperimentNodes.addAll(Arrays.asList(experimentNodes));
+        }
+        
         void put(SampleNode sampleNode, Sample sample)
         {
             samplesNodeToDtoMap.put(sampleNode.getId(), sample);
@@ -914,6 +944,12 @@ public class EntityGraphManager
             modifiedSampleNodes.addAll(Arrays.asList(sampleNodes));
         }
         
+        public void assertDeleted(SampleNode...sampleNodes)
+        {
+            assertDeleted(samplesNodeToDtoMap, Arrays.<EntityNode>asList(sampleNodes));
+            deletedSampleNodes.addAll(Arrays.asList(sampleNodes));
+        }
+        
         void put(DataSetNode dataSetNode, AbstractExternalData dataSet)
         {
             dataSetsNodeToDtoMap.put(dataSetNode.getId(), dataSet);
@@ -927,6 +963,12 @@ public class EntityGraphManager
             modifiedDataSetNodes.addAll(Arrays.asList(dataSetNodes));
         }
         
+        public void assertDeleted(DataSetNode...dataSetNodes)
+        {
+            assertDeleted(dataSetsNodeToDtoMap, Arrays.<EntityNode>asList(dataSetNodes));
+            deletedDataSetNodes.addAll(Arrays.asList(dataSetNodes));
+        }
+        
         public void assertUnmodified(EntityGraphGenerator g)
         {
             Set<EntityNode> unmodifiedExperimentNodes = new HashSet<EntityNode>(g.getExperiments().values());
@@ -978,6 +1020,50 @@ public class EntityGraphManager
                 }
             }
         }
+        
+        private void assertDeleted(Map<Long, ? extends CodeWithRegistrationAndModificationDate<?>> nodeToDtoMap,
+                Collection<EntityNode> entityNodes)
+        {
+            for (EntityNode node : entityNodes)
+            {
+                if (nodeToDtoMap.containsKey(node.getId()))
+                {
+                    fail("Node " + node.getIdentifierAndType() + " hasn't been deleted.");
+                }
+            }
+        }
+         
+        public void assertUndeleted(EntityGraphGenerator g)
+        {
+            Set<EntityNode> undeletedExperimentNodes = new HashSet<EntityNode>(g.getExperiments().values());
+            undeletedExperimentNodes.removeAll(deletedExperimentNodes);
+            assertUndeleted(experimentsNodeToDtoMap, undeletedExperimentNodes);
+            Set<EntityNode> undeletedSampleNodes = new HashSet<EntityNode>(g.getSamples().values());
+            undeletedSampleNodes.removeAll(deletedSampleNodes);
+            assertUndeleted(samplesNodeToDtoMap, undeletedSampleNodes);
+            Set<EntityNode> undeletedDataSetNodes = new HashSet<EntityNode>(g.getDataSets().values());
+            undeletedDataSetNodes.removeAll(deletedDataSetNodes);
+            assertUndeleted(dataSetsNodeToDtoMap, undeletedDataSetNodes);
+        }
+        
+        private void assertUndeleted(Map<Long, ? extends CodeWithRegistrationAndModificationDate<?>> nodeToDtoMap,
+                Collection<EntityNode> entityNodes)
+        {
+            List<String> deletedNodes = new ArrayList<String>();
+            for (EntityNode node : entityNodes)
+            {
+                if (nodeToDtoMap.containsKey(node.getId()) == false)
+                {
+                    deletedNodes.add(node.getIdentifierAndType());
+                }
+            }
+            if (deletedNodes.isEmpty() == false)
+            {
+                Collections.sort(deletedNodes);
+                fail("The following nodes have been deleted: " + deletedNodes);
+            }
+        }
+         
 
         Set<SampleNode> getSampleNodes(ExperimentNode experimentNode)
         {