diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
index 608b2e2189a8e2789a66e6f4c0e56f5df0752a78..f29c570a1116509421e35c53c5a4cb4378e3407a 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
@@ -1277,6 +1277,10 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
         return SampleTranslator.translate(samplePEsUpdated, session.getBaseIndexURL());
     }
 
+    /**
+     * This method topologically sorts the data sets to be created and creates them in the necessary
+     * order
+     */
     private List<ExternalData> createDataSets(Session session,
             AtomicEntityOperationDetails operationDetails)
     {
@@ -1284,22 +1288,10 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
         List<? extends NewExternalData> dataSetRegistrations =
                 operationDetails.getDataSetRegistrations();
 
-        ArrayList<NewContainerDataSet> containerRegistrations =
-                new ArrayList<NewContainerDataSet>();
-        // In the first pass, skip container data sets
-        for (NewExternalData dataSet : dataSetRegistrations)
-        {
-            if (dataSet instanceof NewContainerDataSet)
-            {
-                containerRegistrations.add((NewContainerDataSet) dataSet);
-            } else
-            {
-                registerDatasetInternal(session, dataSetsCreated, dataSet);
-            }
-        }
+        NewExternalDataDAG dag = new NewExternalDataDAG(dataSetRegistrations);
+        List<? extends NewExternalData> orderedRegistrations = dag.getOrderedRegistrations();
 
-        // Now do the containers
-        for (NewContainerDataSet dataSet : containerRegistrations)
+        for (NewExternalData dataSet : orderedRegistrations)
         {
             registerDatasetInternal(session, dataSetsCreated, dataSet);
         }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/NewExternalDataDAG.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/NewExternalDataDAG.java
new file mode 100644
index 0000000000000000000000000000000000000000..c8fb41cb39b6e24323724f6aa31e49e7a24425f2
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/NewExternalDataDAG.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2011 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.server;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import ch.systemsx.cisd.common.collections.DAG;
+import ch.systemsx.cisd.openbis.generic.shared.dto.NewContainerDataSet;
+import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData;
+
+/**
+ * Represents a DAG of registration dependencies between new data sets.
+ * 
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class NewExternalDataDAG
+{
+    private final List<? extends NewExternalData> dataSetRegistrations;
+
+    // For simplicity, we use the data set codes to construct the graph, so we need a map from
+    // codes to data sets
+    HashMap<String, NewExternalData> codeToDataMap = new HashMap<String, NewExternalData>();
+
+    HashMap<String, ArrayList<String>> dependencyGraph = new HashMap<String, ArrayList<String>>();
+
+    /**
+     * Create a DAG from the registrations.
+     * 
+     * @param dataSetRegistrations
+     */
+    public NewExternalDataDAG(List<? extends NewExternalData> dataSetRegistrations)
+    {
+        super();
+        this.dataSetRegistrations = dataSetRegistrations;
+        constructGraph();
+    }
+
+    /**
+     * @return The registrations ordered topologically such that each registrations comes after the
+     *         ones it depends on.
+     */
+    public List<? extends NewExternalData> getOrderedRegistrations()
+    {
+        DAG<String, ArrayList<String>> dag = new DAG<String, ArrayList<String>>(dependencyGraph);
+        List<String> sortedCodes = dag.sortTopologically();
+        ArrayList<NewExternalData> sortedData = new ArrayList<NewExternalData>();
+        for (String code : sortedCodes)
+        {
+            NewExternalData data = codeToDataMap.get(code);
+            // Some of the dependencies may be to *existing* data -- we don't care about those here.
+            if (null != data)
+            {
+                sortedData.add(data);
+            }
+        }
+
+        return sortedData;
+    }
+
+    /**
+     * Sort the registrations topologically.
+     */
+    private void constructGraph()
+    {
+        for (NewExternalData dataSet : dataSetRegistrations)
+        {
+            String dataSetCode = dataSet.getCode();
+            codeToDataMap.put(dataSetCode, dataSet);
+
+            // There may already be dependents for this data set -- get them or initialize the
+            // dependents
+            ArrayList<String> dependents = getDependentsList(dataSetCode);
+
+            // All the parents are dependents
+            dependents.addAll(dataSet.getParentDataSetCodes());
+
+            if (dataSet instanceof NewContainerDataSet)
+            {
+                // This data set is a dependent on each of the contained ones
+                List<String> containedDataSetCodes =
+                        ((NewContainerDataSet) dataSet).getContainedDataSetCodes();
+                for (String containedDataSetCode : containedDataSetCodes)
+                {
+                    ArrayList<String> containedDependents = getDependentsList(containedDataSetCode);
+                    containedDependents.add(dataSetCode);
+                }
+            }
+
+            dependencyGraph.put(dataSet.getCode(), dependents);
+        }
+    }
+
+    private ArrayList<String> getDependentsList(String dataSetCode)
+    {
+        ArrayList<String> dependents = dependencyGraph.get(dataSetCode);
+        if (null == dependents)
+        {
+            dependents = new ArrayList<String>();
+            dependencyGraph.put(dataSetCode, dependents);
+        }
+        return dependents;
+    }
+
+}