diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/DataSetRelationshipBrowser.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/DataSetRelationshipBrowser.java
index 3b773e32297f7b1618e3cd3272d6b337438927a3..77bf94c729ac7efb4c633d6f17e34f9e9998e215 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/DataSetRelationshipBrowser.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/DataSetRelationshipBrowser.java
@@ -36,7 +36,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
  * 
  * @author Piotr Buczek
  */
-class DataSetRelationshipBrowser extends AbstractExternalDataGrid
+public class DataSetRelationshipBrowser extends AbstractExternalDataGrid
 {
     private static final String PREFIX = "data-set-relationships-section_";
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/SystemTestSuite.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/SystemTestSuite.java
index 050a669eda76396b8dfa26c5f0b8bc7877dc07a4..1f4567cc04ffe181cd6115ab88dd0ad24a83de9e 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/SystemTestSuite.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/SystemTestSuite.java
@@ -38,6 +38,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.SampleBrow
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.SearchTest;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.VocabularyBrowserTest;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.VocabularyRegistrationTest;
+import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.dataset.GenericDataSetEditorTest;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.dataset.GenericDataSetViewerTest;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.experiment.GenericExperimentAttachmentDownloadTest;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.experiment.GenericExperimentEditorTest;
@@ -59,6 +60,7 @@ public class SystemTestSuite extends GWTTestSuite
         testSuite.addTestSuite(FileFormatTypeGridTest.class);
         testSuite.addTestSuite(DataSetSearchTest.class);
         testSuite.addTestSuite(GenericDataSetViewerTest.class);
+        testSuite.addTestSuite(GenericDataSetEditorTest.class);
         testSuite.addTestSuite(AuthorizationManagementConsolTest.class);
         testSuite.addTestSuite(SampleBrowserTest.class);
         testSuite.addTestSuite(GenericSampleViewerTest.class);
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/ShowDataSetEditor.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/ShowDataSetEditor.java
index 0579fe80f0d6c69a20bb84fdef6ecd58ec87677d..05c2c99df2cb1bc8e18654c77c0be2f11b8107f0 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/ShowDataSetEditor.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/ShowDataSetEditor.java
@@ -16,10 +16,14 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.data;
 
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.entity.PropertyTypesCriteriaProvider.ListPropertyTypesCallback;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.AbstractDefaultTestCommand;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.GWTTestUtil;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetRelationshipRole;
+import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.dataset.DataSetRelationshipBrowser;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.dataset.GenericDataSetViewer;
+import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.dataset.GenericDataSetViewer.DataSetInfoCallback;
 
 /**
  * @author Piotr Buczek
@@ -43,7 +47,14 @@ public class ShowDataSetEditor extends AbstractDefaultTestCommand
     private ShowDataSetEditor(final TechId dataSetId)
     {
         this.dataSetId = dataSetId;
-        addCallbackClass(GenericDataSetViewer.DataSetInfoCallback.class);
+        addCallbackClass(DataSetInfoCallback.class);
+        addCallbackClass(ListPropertyTypesCallback.class);
+        final String childrenGridId =
+                DataSetRelationshipBrowser.createGridId(dataSetId, DataSetRelationshipRole.PARENT);
+        final String parentsGridId =
+                DataSetRelationshipBrowser.createGridId(dataSetId, DataSetRelationshipRole.CHILD);
+        addCallbackClass(childrenGridId);
+        addCallbackClass(parentsGridId);
     }
 
     public void execute()
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/RemoteConsole.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/RemoteConsole.java
index 77e7bb93bdac091a922063e35db793712f18f860..37757aab4df5839f10ff8ada03fac6645bfe2f83 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/RemoteConsole.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/RemoteConsole.java
@@ -180,6 +180,12 @@ public class RemoteConsole
                         cmd.tryValidOnSucess(lastCallbackObjects, result);
                 if (unmatchedCallbacks != null)
                 {
+                	// uncomment to debug unmatched callbacks in system tests
+                    // System.err.println("callback: " + entryIndex);
+                    // for (AbstractAsyncCallback<?> c : unmatchedCallbacks)
+                    // {
+                    //     System.err.println("\t" + c);
+                    // }
                     lastCallbackObjects = unmatchedCallbacks;
                     executeCommand();
                 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/FillDataSetEditForm.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/FillDataSetEditForm.java
index 8e15ea5d1fa93ac9f651332842cc778127fdd0f1..cc50b6254558f4b076a3e99d869b9bcf1c412fb1 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/FillDataSetEditForm.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/FillDataSetEditForm.java
@@ -35,18 +35,19 @@ import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.Pro
  * 
  * @author Piotr Buczek
  */
+// TODO 2009-09-21, Piotr Buczek: test modification of Sample and File Format Type
 public final class FillDataSetEditForm extends AbstractDefaultTestCommand
 {
     private final String formId;
 
-    private final List<PropertyField> properties;
+    private String modifiedParentsOrNull;
 
     // private String newSampleOrNull;
 
-    private String modifiedParentsOrNull;
-
     // private String newFileFormatTypeOrNull;
 
+    private final List<PropertyField> properties;
+
     public FillDataSetEditForm()
     {
         this(TechId.createWildcardTechId());
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetEditorTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetEditorTest.java
index 0ad9fb3b80f3345b595196f52fe44588a3545d5d..e485f85a5deab885cca03b6f394d86e19fa45fe6 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetEditorTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetEditorTest.java
@@ -16,17 +16,16 @@
 
 package ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.dataset;
 
-import java.util.List;
-
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.MainTabPanel;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.menu.TopMenu.ActionMenuKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.data.ShowDataSet;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.data.ShowDataSetEditor;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.data.columns.DataSetRow;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.search.FillSearchCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.AbstractDefaultTestCommand;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.AbstractGWTTestCase;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.CheckTableCommand;
+import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.FailureExpectation;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.GWTTestUtil;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.PropertyField;
@@ -45,80 +44,115 @@ public class GenericDataSetEditorTest extends AbstractGWTTestCase
 
     private static final String DS_WITH_ONE_PARENT_NEW_PARENTS_CODE = "20081105092159111-1";
 
+    private static final String DS_WITH_MANY_PARENTS_CODE = "20081105092259000-9";
+
     public final void testEditDataSetComment()
     {
-        prepareShowDataSetEditor(DS_WITH_ONE_PARENT_CODE);
+        final String modifiedDataSetCode = DS_WITH_ONE_PARENT_CODE;
+
+        prepareShowDataSetEditor(modifiedDataSetCode);
 
         final String newCommentColumnValue = "new comment";
         remoteConsole.prepare(new FillDataSetEditForm().addProperty(new PropertyField("comment",
                 newCommentColumnValue)));
-        final AbstractDefaultTestCommand showUpdatedDataSet = new ShowUpdatedDataSet();
-        remoteConsole.prepare(new AbstractDefaultTestCommand()
-            {
-                @Override
-                public List<AbstractAsyncCallback<Object>> tryValidOnSucess(
-                        List<AbstractAsyncCallback<Object>> callbackObjects, Object result)
-                {
-                    return showUpdatedDataSet.tryValidOnSucess(callbackObjects, result);
-                }
-
-                public void execute()
-                {
-                    showUpdatedDataSet.execute();
-
-                    final CheckDataSet checkDataSet = new CheckDataSet();
-                    checkDataSet.property("Comment").asProperty(newCommentColumnValue);
-                    remoteConsole.prepare(checkDataSet);
-                }
-            });
-        launchTest(20 * SECOND);
+        remoteConsole.prepare(new ShowUpdatedDataSet());
+
+        final CheckDataSet checkDataSet = new CheckDataSet();
+        checkDataSet.property("Comment").asProperty(newCommentColumnValue);
+        remoteConsole.prepare(checkDataSet);
+
+        launchTest(40 * SECOND);
     }
 
     public final void testEditDataSetAddParent()
     {
-        prepareShowDataSetEditor(DS_WITH_ONE_PARENT_CODE);
+        final String modifiedDataSetCode = DS_WITH_ONE_PARENT_CODE;
+
+        prepareShowDataSetEditor(modifiedDataSetCode);
 
         remoteConsole.prepare(new FillDataSetEditForm()
                 .modifyParents(DS_WITH_ONE_PARENT_PARENTS_CODE + ","
                         + DS_WITH_ONE_PARENT_NEW_PARENTS_CODE));
+        remoteConsole.prepare(new ShowUpdatedDataSet());
+
+        final CheckTableCommand checkParents = new CheckDataSet().parentsTable().expectedSize(2);
+        checkParents.expectedRow(new DataSetRow(DS_WITH_ONE_PARENT_PARENTS_CODE));
+        checkParents.expectedRow(new DataSetRow(DS_WITH_ONE_PARENT_NEW_PARENTS_CODE));
+        remoteConsole.prepare(checkParents);
 
-        final AbstractDefaultTestCommand showUpdatedDataSet = new ShowUpdatedDataSet();
-        // remoteConsole.prepare(new ShowUpdatedDataSet());
-        remoteConsole.prepare(new AbstractDefaultTestCommand()
-            {
-                @Override
-                public List<AbstractAsyncCallback<Object>> tryValidOnSucess(
-                        List<AbstractAsyncCallback<Object>> callbackObjects, Object result)
-                {
-                    return showUpdatedDataSet.tryValidOnSucess(callbackObjects, result);
-                }
-
-                public void execute()
-                {
-                    showUpdatedDataSet.execute();
-                    final CheckTableCommand checkParents =
-                            new CheckDataSet().parentsTable().expectedSize(2);
-                    // checkParents.expectedRow(new DataSetRow(DS_WITH_ONE_PARENT_PARENTS_CODE));
-                    // checkParents.expectedRow(new
-                    // DataSetRow(DS_WITH_ONE_PARENT_NEW_PARENTS_CODE));
-
-                    remoteConsole.prepare(checkParents);
-                }
-            });
+        launchTest(20 * SECOND);
+    }
+
+    public final void testEditDataSetRemoveAllParents()
+    {
+        final String modifiedDataSetCode = DS_WITH_ONE_PARENT_CODE;
 
+        prepareShowDataSetEditor(modifiedDataSetCode);
+
+        remoteConsole.prepare(new FillDataSetEditForm().modifyParents(""));
+        remoteConsole.prepare(new ShowUpdatedDataSet());
+        final CheckTableCommand checkParents = new CheckDataSet().parentsTable().expectedSize(0);
+        remoteConsole.prepare(checkParents);
         launchTest(20 * SECOND);
     }
 
-    // public final void testEditDataSetRemoveAllParents()
-    // {
-    // prepareShowDataSetEditor(DS_WITH_ONE_PARENT_CODE);
-    //
-    // remoteConsole.prepare(new FillDataSetEditForm().modifyParents(""));
-    // remoteConsole.prepare(new ShowUpdatedDataSet());
-    // final CheckTableCommand checkParents = new CheckDataSet().parentsTable().expectedSize(0);
-    // remoteConsole.prepare(checkParents);
-    // launchTest(20 * SECOND);
-    // }
+    public final void testEditDataSetParents()
+    {
+        final String modifiedDataSetCode = DS_WITH_MANY_PARENTS_CODE;
+        // Remove three parents and add one in one go. Old parent codes:
+        // 20081105092158673-1, 20081105092159111-1, 20081105092159222-2, 20081105092159333-3
+        final String newParentCode = "20081105092159188-3";
+        final String oldParentCode = "20081105092159111-1";
+
+        prepareShowDataSetEditor(modifiedDataSetCode);
+
+        remoteConsole.prepare(new FillDataSetEditForm().modifyParents(newParentCode + ", "
+                + oldParentCode));
+        remoteConsole.prepare(new ShowUpdatedDataSet());
+        final CheckTableCommand checkParents = new CheckDataSet().parentsTable().expectedSize(2);
+        checkParents.expectedRow(new DataSetRow(newParentCode));
+        checkParents.expectedRow(new DataSetRow(oldParentCode));
+        remoteConsole.prepare(checkParents);
+        launchTest(20 * SECOND);
+    }
+
+    public final void testEditDataSetParentsFailWithCycleRelationships()
+    {
+        final String modifiedDataSetCode = DS_WITH_MANY_PARENTS_CODE;
+        final String descendantCode = "20081105092359990-2";
+
+        prepareShowDataSetEditor(modifiedDataSetCode);
+
+        remoteConsole.prepare(new FillDataSetEditForm().modifyParents(descendantCode));
+        FailureExpectation failureExpectation =
+                new FailureExpectation(GenericDataSetEditForm.UpdateDataSetCallback.class)
+                        .with("Data Set '" + modifiedDataSetCode + "' is an ancestor of Data Set '"
+                                + descendantCode
+                                + "' and cannot be at the same time set as its child.");
+        remoteConsole.prepare(failureExpectation);
+
+        launchTest(20 * SECOND);
+    }
+
+    // This test is needed among system tests because a deferred trigger is executed
+    // just before commit and another test in DAO layer uses manual commit that is unnatural.
+    public final void testAddDataSetParentFailWithDeferredTriggerError()
+    {
+        final String modifiedDataSetCode = DS_WITH_ONE_PARENT_PARENTS_CODE;
+        final String addedParentCode = DS_WITH_ONE_PARENT_NEW_PARENTS_CODE;
+
+        prepareShowDataSetEditor(modifiedDataSetCode);
+
+        remoteConsole.prepare(new FillDataSetEditForm().modifyParents(addedParentCode));
+        FailureExpectation failureExpectation =
+                new FailureExpectation(GenericDataSetEditForm.UpdateDataSetCallback.class)
+                        .with("ERROR: Insert/Update of Data Set (Code: '"
+                                + modifiedDataSetCode
+                                + "') failed because it cannot be connected with a Sample and a parent Data Set at the same time.'");
+        remoteConsole.prepare(failureExpectation);
+
+        launchTest(20 * SECOND);
+    }
 
     private class ShowUpdatedDataSet extends AbstractDefaultTestCommand
     {
@@ -136,23 +170,6 @@ public class GenericDataSetEditorTest extends AbstractGWTTestCase
         }
     }
 
-    //
-    // public final void testEditExperimentProject()
-    // {
-    // String oldProject = NEMO;
-    // String newProject = DEFAULT;
-    // String experiment = EXP11;
-    // prepareShowExperimentEditor(CISD, oldProject, SIRNA_HCS, experiment);
-    // remoteConsole.prepare(new FillExperimentEditForm().changeProject(identifier(CISD,
-    // newProject)));
-    // remoteConsole.prepare(new ListExperiments(withGroup(CISD, newProject), SIRNA_HCS,
-    // GenericExperimentEditForm.UpdateExperimentCallback.class));
-    // CheckExperimentTable table = new CheckExperimentTable();
-    // table.expectedRow(new ExperimentRow(experiment));
-    // remoteConsole.prepare(table);
-    // launchTest(20 * SECOND);
-    // }
-
     private void prepareShowDataSetEditor(String dataSetCode)
     {
         // Open data set editor by simulating 3 steps:
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetViewerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetViewerTest.java
index 6ad9a8e880653b83d44b5048d985a4e1cb8496ec..735a5e42bab9b5f3e745c2aeea01ebe141a8fc35 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetViewerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetViewerTest.java
@@ -71,7 +71,7 @@ public class GenericDataSetViewerTest extends AbstractGWTTestCase
 
         remoteConsole.prepare(checkDataSet);
 
-        launchTest(40 * SECOND);
+        launchTest(20 * SECOND);
     }
 
     public final void testShowExperimentDataSetWithParents()
@@ -100,7 +100,7 @@ public class GenericDataSetViewerTest extends AbstractGWTTestCase
 
         remoteConsole.prepare(checkDataSet);
 
-        launchTest(40 * SECOND);
+        launchTest(20 * SECOND);
     }
 
     private void checkDataSetRelationships(CheckTableCommand checkTable, String[] expectedCodes)