diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/AbstractDataSetRegistrationDetailsFactory.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/AbstractDataSetRegistrationDetailsFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..0c2118e51e0410b0def75cd6db870914eb1274c1
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/AbstractDataSetRegistrationDetailsFactory.java
@@ -0,0 +1,68 @@
+/*
+ * 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.etlserver.registrator;
+
+import java.io.File;
+
+import ch.systemsx.cisd.etlserver.registrator.AbstractOmniscientTopLevelDataSetRegistrator.OmniscientTopLevelDataSetRegistratorState;
+import ch.systemsx.cisd.etlserver.registrator.api.v1.impl.DataSet;
+import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation;
+
+/**
+ * @author Chandrasekhar Ramakrishnan
+ */
+public abstract class AbstractDataSetRegistrationDetailsFactory<T extends DataSetInformation>
+        implements IDataSetRegistrationDetailsFactory<T>
+{
+    protected final OmniscientTopLevelDataSetRegistratorState registratorState;
+
+    public AbstractDataSetRegistrationDetailsFactory(
+            OmniscientTopLevelDataSetRegistratorState registratorState)
+    {
+        this.registratorState = registratorState;
+    }
+
+    /**
+     * Factory method that creates a new registration details object.
+     */
+    public DataSetRegistrationDetails<T> createDataSetRegistrationDetails()
+    {
+        DataSetRegistrationDetails<T> registrationDetails = new DataSetRegistrationDetails<T>();
+        T dataSetInfo = createDataSetInformation();
+        setDatabaseInstance(dataSetInfo);
+        registrationDetails.setDataSetInformation(dataSetInfo);
+        return registrationDetails;
+    }
+
+    protected final void setDatabaseInstance(T dataSetInfo)
+    {
+        dataSetInfo.setInstanceCode(registratorState.getHomeDatabaseInstance().getCode());
+        dataSetInfo.setInstanceUUID(registratorState.getHomeDatabaseInstance().getUuid());
+    }
+
+    public DataSet<T> createDataSet(DataSetRegistrationDetails<T> registrationDetails,
+            File stagingFile)
+    {
+        return new DataSet<T>(registrationDetails, stagingFile);
+    }
+
+    /**
+     * Factory method that creates a new data set information object.
+     */
+    protected abstract T createDataSetInformation();
+
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/AbstractOmniscientTopLevelDataSetRegistrator.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/AbstractOmniscientTopLevelDataSetRegistrator.java
index e43308aa606b2cfc2d865f81caa77bc7b5399472..9a452c0525fc610463579ca9b95b6068e0930dff 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/AbstractOmniscientTopLevelDataSetRegistrator.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/AbstractOmniscientTopLevelDataSetRegistrator.java
@@ -55,8 +55,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData;
  * 
  * @author Chandrasekhar Ramakrishnan
  */
-public abstract class AbstractOmniscientTopLevelDataSetRegistrator extends
-        AbstractTopLevelDataSetRegistrator
+public abstract class AbstractOmniscientTopLevelDataSetRegistrator<T extends DataSetInformation>
+        extends AbstractTopLevelDataSetRegistrator
 {
     static final Logger notificationLog = LogFactory.getLogger(LogCategory.NOTIFY,
             AbstractOmniscientTopLevelDataSetRegistrator.class);
@@ -234,7 +234,7 @@ public abstract class AbstractOmniscientTopLevelDataSetRegistrator extends
                 };
         }
 
-        DataSetRegistrationService service =
+        DataSetRegistrationService<T> service =
                 createDataSetRegistrationService(cleanAfterwardsAction);
 
         try
@@ -273,7 +273,7 @@ public abstract class AbstractOmniscientTopLevelDataSetRegistrator extends
      * 
      * @param dataSetRegistrationService
      */
-    public void rollback(DataSetRegistrationService dataSetRegistrationService,
+    public void rollback(DataSetRegistrationService<T> dataSetRegistrationService,
             DataSetRegistrationAlgorithm registrationAlgorithm, Throwable throwable)
     {
         updateStopped(throwable instanceof InterruptedExceptionUnchecked);
@@ -289,8 +289,7 @@ public abstract class AbstractOmniscientTopLevelDataSetRegistrator extends
      * Subclasses may override, but should call super.
      */
 
-    public <T extends DataSetInformation> void rollbackTransaction(
-            DataSetRegistrationService dataSetRegistrationService,
+    public void rollbackTransaction(DataSetRegistrationService<T> dataSetRegistrationService,
             DataSetRegistrationTransaction<T> transaction,
             DataSetStorageAlgorithmRunner<T> algorithm, Throwable ex)
     {
@@ -303,7 +302,7 @@ public abstract class AbstractOmniscientTopLevelDataSetRegistrator extends
      * <p>
      * Subclasses may override, but should call super.
      */
-    protected void rollback(DataSetRegistrationService service, Throwable throwable)
+    protected void rollback(DataSetRegistrationService<T> service, Throwable throwable)
     {
         updateStopped(throwable instanceof InterruptedExceptionUnchecked);
 
@@ -313,11 +312,13 @@ public abstract class AbstractOmniscientTopLevelDataSetRegistrator extends
     /**
      * Create the data set registration service.
      */
-    protected DataSetRegistrationService createDataSetRegistrationService(
+    protected DataSetRegistrationService<T> createDataSetRegistrationService(
             final IDelegatedActionWithResult<Boolean> cleanAfterwardsAction)
     {
-        DataSetRegistrationService service =
-                new DataSetRegistrationService(this, cleanAfterwardsAction);
+        @SuppressWarnings("unchecked")
+        DataSetRegistrationService<T> service =
+                new DataSetRegistrationService(this, new DefaultDataSetRegistrationDetailsFactory(
+                        getRegistratorState()), cleanAfterwardsAction);
         return service;
     }
 
@@ -345,6 +346,6 @@ public abstract class AbstractOmniscientTopLevelDataSetRegistrator extends
      * 
      * @throws Throwable
      */
-    protected abstract void handleDataSet(File dataSetFile, DataSetRegistrationService service)
+    protected abstract void handleDataSet(File dataSetFile, DataSetRegistrationService<T> service)
             throws Throwable;
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetRegistrationService.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetRegistrationService.java
index 3e583a04c8f8ea90f3e86de65dbddcb8b1db7a77..a39b9632cf503f4b8cb563c35e30978671dad0c5 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetRegistrationService.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetRegistrationService.java
@@ -24,8 +24,6 @@ import ch.systemsx.cisd.common.utilities.IDelegatedActionWithResult;
 import ch.systemsx.cisd.common.utilities.PropertyUtils;
 import ch.systemsx.cisd.etlserver.DataSetRegistrationAlgorithm;
 import ch.systemsx.cisd.etlserver.DataSetRegistrationAlgorithm.DataSetRegistrationAlgorithmState;
-import ch.systemsx.cisd.etlserver.DataSetRegistrationAlgorithm.IDataSetInApplicationServerRegistrator;
-import ch.systemsx.cisd.etlserver.DataSetRegistrationAlgorithm.IRollbackDelegate;
 import ch.systemsx.cisd.etlserver.DataSetRegistrationAlgorithmRunner;
 import ch.systemsx.cisd.etlserver.IDataStoreStrategy;
 import ch.systemsx.cisd.etlserver.TopLevelDataSetRegistratorGlobalState;
@@ -40,23 +38,28 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData;
  * 
  * @author Chandrasekhar Ramakrishnan
  */
-public class DataSetRegistrationService implements IRollbackDelegate
+public class DataSetRegistrationService<T extends DataSetInformation> implements
+        DataSetRegistrationAlgorithm.IRollbackDelegate
 {
     static final String STAGING_DIR = "staging-dir";
 
-    private final AbstractOmniscientTopLevelDataSetRegistrator registrator;
+    private final AbstractOmniscientTopLevelDataSetRegistrator<T> registrator;
 
-    private final OmniscientTopLevelDataSetRegistratorState registratorState;
+    private final OmniscientTopLevelDataSetRegistratorState registratorContext;
 
     private final IDelegatedActionWithResult<Boolean> globalCleanAfterwardsAction;
 
     private final ArrayList<DataSetRegistrationAlgorithm> dataSetRegistrations =
             new ArrayList<DataSetRegistrationAlgorithm>();
 
+    private final IDataSetRegistrationDetailsFactory<T> dataSetRegistrationDetailsFactory;
+
+    private final File stagingDirectory;
+
     /**
      * The currently live child transaction.
      */
-    private DataSetRegistrationTransaction<DataSetInformation> liveTransactionOrNull;
+    private DataSetRegistrationTransaction<T> liveTransactionOrNull;
 
     /**
      * A data set that will be created but might not yet exist.
@@ -84,24 +87,37 @@ public class DataSetRegistrationService implements IRollbackDelegate
      * @param registrator The top level data set registrator
      * @param globalCleanAfterwardsAction An action to execute when the service has finished
      */
-    public DataSetRegistrationService(AbstractOmniscientTopLevelDataSetRegistrator registrator,
+    public DataSetRegistrationService(AbstractOmniscientTopLevelDataSetRegistrator<T> registrator,
+            IDataSetRegistrationDetailsFactory<T> registrationDetailsFactory,
             IDelegatedActionWithResult<Boolean> globalCleanAfterwardsAction)
     {
         this.registrator = registrator;
-        this.registratorState = registrator.getRegistratorState();
+        this.registratorContext = registrator.getRegistratorState();
         this.globalCleanAfterwardsAction = globalCleanAfterwardsAction;
+        this.dataSetRegistrationDetailsFactory = registrationDetailsFactory;
+
+        Properties properties =
+                registratorContext.getGlobalState().getThreadParameters().getThreadProperties();
+        String stagingDirString = PropertyUtils.getProperty(properties, STAGING_DIR);
+        if (null == stagingDirString)
+        {
+            stagingDirectory = registratorContext.getGlobalState().getStoreRootDir();
+        } else
+        {
+            stagingDirectory = new File(stagingDirString);
+        }
     }
 
-    public OmniscientTopLevelDataSetRegistratorState getRegistratorState()
+    public OmniscientTopLevelDataSetRegistratorState getRegistratorContext()
     {
-        return registratorState;
+        return registratorContext;
     }
 
     /**
      * Queue registration a data set and return a future for the data set that will be created.
      */
     public FutureDataSet queueDataSetRegistration(File dataSetFile,
-            DataSetRegistrationDetails<?> details)
+            final DataSetRegistrationDetails<T> details)
     {
         DataSetRegistrationAlgorithm registration =
                 createRegistrationAlgorithm(dataSetFile, details);
@@ -112,24 +128,33 @@ public class DataSetRegistrationService implements IRollbackDelegate
         return future;
     }
 
+    /**
+     * Create a new transaction that atomically performs file operations and registers entities.
+     */
+    public IDataSetRegistrationTransaction transaction(File dataSetFile)
+    {
+        return transaction(dataSetFile, getDataSetRegistrationDetailsFactory());
+    }
+
+    protected IDataSetRegistrationDetailsFactory<T> getDataSetRegistrationDetailsFactory()
+    {
+        return dataSetRegistrationDetailsFactory;
+    }
+
     /**
      * Create a new transaction that atomically performs file operations and registers entities.
      */
     public IDataSetRegistrationTransaction transaction(File dataSetFile,
-            IDataSetRegistrationDetailsFactory<DataSetInformation> detailsFactory)
+            IDataSetRegistrationDetailsFactory<T> detailsFactory)
     {
         // If a transaction is hanging around, commit it before starting a new one
         commitExtantTransaction();
 
         File workingDirectory = dataSetFile.getParentFile();
-        Properties properties =
-                registratorState.getGlobalState().getThreadParameters().getThreadProperties();
-        File stagingDirectory =
-                new File(PropertyUtils.getMandatoryProperty(properties, STAGING_DIR));
 
         // Clone this service for the transaction to keep them independent
         liveTransactionOrNull =
-                new DataSetRegistrationTransaction<DataSetInformation>(registrator.getGlobalState()
+                new DataSetRegistrationTransaction<T>(registrator.getGlobalState()
                         .getStoreRootDir(), workingDirectory, stagingDirectory, this,
                         detailsFactory);
 
@@ -160,13 +185,7 @@ public class DataSetRegistrationService implements IRollbackDelegate
         dataSetRegistrations.clear();
     }
 
-    public void rollback(DataSetRegistrationAlgorithm algorithm, Throwable ex)
-    {
-        registrator.rollback(this, algorithm, ex);
-    }
-
-    public <T extends DataSetInformation> void rollbackTransaction(
-            DataSetRegistrationTransaction<T> transaction,
+    public void rollbackTransaction(DataSetRegistrationTransaction<T> transaction,
             DataSetStorageAlgorithmRunner<T> algorithm, Throwable ex)
     {
         registrator.rollbackTransaction(this, transaction, algorithm, ex);
@@ -176,31 +195,53 @@ public class DataSetRegistrationService implements IRollbackDelegate
      * Create a storage algorithm for storing an individual data set. This is internally used by
      * transactions. Other clients may find it useful as well.
      */
-    public <T extends DataSetInformation> DataSetStorageAlgorithm<T> createStorageAlgorithm(
-            File dataSetFile, DataSetRegistrationDetails<T> dataSetDetails)
+    public DataSetStorageAlgorithm<T> createStorageAlgorithm(File dataSetFile,
+            DataSetRegistrationDetails<T> dataSetDetails)
     {
         IDataStoreStrategy strategy =
-                registratorState.getDataStrategyStore().getDataStoreStrategy(
+                registratorContext.getDataStrategyStore().getDataStoreStrategy(
                         dataSetDetails.getDataSetInformation(), dataSetFile);
 
-        TopLevelDataSetRegistratorGlobalState globalContext = registratorState.getGlobalState();
+        TopLevelDataSetRegistratorGlobalState globalContext = registratorContext.getGlobalState();
         DataSetStorageAlgorithm<T> algorithm =
                 new DataSetStorageAlgorithm<T>(dataSetFile, dataSetDetails, strategy,
-                        registratorState.getStorageProcessor(),
+                        registratorContext.getStorageProcessor(),
                         globalContext.getDataSetValidator(), globalContext.getDssCode(),
-                        registratorState.getFileOperations(), globalContext.getMailClient());
+                        registratorContext.getFileOperations(), globalContext.getMailClient());
         return algorithm;
     }
 
-    public <T extends DataSetInformation> IEntityRegistrationService<T> getEntityRegistrationService()
+    public IEntityRegistrationService<T> getEntityRegistrationService()
     {
         return new DefaultEntityRegistrationService<T>(registrator);
     }
 
+    /**
+     * If a transaction is hanging around, commit it
+     */
+    private void commitExtantTransaction()
+    {
+        if (null != liveTransactionOrNull
+                && false == liveTransactionOrNull.isCommittedOrRolledback())
+        {
+            // Commit the existing transaction
+            liveTransactionOrNull.commit();
+        }
+    }
+
+    private void rollbackExtantTransaction()
+    {
+        if (null != liveTransactionOrNull)
+        {
+            liveTransactionOrNull.rollback();
+        }
+    }
+
     private DataSetRegistrationAlgorithm createRegistrationAlgorithm(File incomingDataSetFile,
-            DataSetRegistrationDetails<?> details)
+            DataSetRegistrationDetails<T> details)
     {
-        final TopLevelDataSetRegistratorGlobalState globalState = registratorState.getGlobalState();
+        final TopLevelDataSetRegistratorGlobalState globalState =
+                registratorContext.getGlobalState();
         final IDelegatedActionWithResult<Boolean> cleanAfterwardsAction =
                 new IDelegatedActionWithResult<Boolean>()
                     {
@@ -211,55 +252,34 @@ public class DataSetRegistrationService implements IRollbackDelegate
                     };
 
         IDataStoreStrategy dataStoreStrategy =
-                registratorState.getDataStrategyStore().getDataStoreStrategy(
+                registratorContext.getDataStrategyStore().getDataStoreStrategy(
                         details.getDataSetInformation(), incomingDataSetFile);
 
         DataSetRegistrationAlgorithmState state =
                 new DataSetRegistrationAlgorithmState(incomingDataSetFile,
                         globalState.getOpenBisService(), cleanAfterwardsAction,
-                        registratorState.getPreRegistrationAction(),
-                        registratorState.getPostRegistrationAction(),
+                        registratorContext.getPreRegistrationAction(),
+                        registratorContext.getPostRegistrationAction(),
                         details.getDataSetInformation(), dataStoreStrategy, details,
-                        registratorState.getStorageProcessor(),
-                        registratorState.getFileOperations(), globalState.getDataSetValidator(),
+                        registratorContext.getStorageProcessor(),
+                        registratorContext.getFileOperations(), globalState.getDataSetValidator(),
                         globalState.getMailClient(), globalState.isDeleteUnidentified(),
-                        registratorState.getRegistrationLock(), globalState.getDssCode(),
+                        registratorContext.getRegistrationLock(), globalState.getDssCode(),
                         globalState.isNotifySuccessfulRegistration());
         return new DataSetRegistrationAlgorithm(state, this,
                 new DefaultApplicationServerRegistrator(registrator,
                         details.getDataSetInformation()));
     }
 
-    /**
-     * If a transaction is hanging around, commit it
-     */
-    private void commitExtantTransaction()
-    {
-        if (null != liveTransactionOrNull
-                && false == liveTransactionOrNull.isCommittedOrRolledback())
-        {
-            // Commit the existing transaction
-            liveTransactionOrNull.commit();
-        }
-    }
-
-    private void rollbackExtantTransaction()
-    {
-        if (null != liveTransactionOrNull)
-        {
-            liveTransactionOrNull.rollback();
-        }
-    }
-
     private static class DefaultApplicationServerRegistrator implements
-            IDataSetInApplicationServerRegistrator
+            DataSetRegistrationAlgorithm.IDataSetInApplicationServerRegistrator
     {
-        private final AbstractOmniscientTopLevelDataSetRegistrator registrator;
+        private final AbstractOmniscientTopLevelDataSetRegistrator<?> registrator;
 
         private final DataSetInformation dataSetInformation;
 
         DefaultApplicationServerRegistrator(
-                AbstractOmniscientTopLevelDataSetRegistrator registrator,
+                AbstractOmniscientTopLevelDataSetRegistrator<?> registrator,
                 DataSetInformation dataSetInformation)
         {
             this.dataSetInformation = dataSetInformation;
@@ -272,4 +292,8 @@ public class DataSetRegistrationService implements IRollbackDelegate
         }
     }
 
+    public void rollback(DataSetRegistrationAlgorithm algorithm, Throwable ex)
+    {
+        registrator.rollback(this, algorithm, ex);
+    }
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultDataSetRegistrationDetailsFactory.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultDataSetRegistrationDetailsFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..46020bd244960824a55745b9fa8878b717c79ab6
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultDataSetRegistrationDetailsFactory.java
@@ -0,0 +1,44 @@
+/*
+ * 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.etlserver.registrator;
+
+import ch.systemsx.cisd.etlserver.registrator.AbstractOmniscientTopLevelDataSetRegistrator.OmniscientTopLevelDataSetRegistratorState;
+import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation;
+
+/**
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class DefaultDataSetRegistrationDetailsFactory extends
+        AbstractDataSetRegistrationDetailsFactory<DataSetInformation>
+{
+
+    /**
+     * @param registratorState
+     */
+    public DefaultDataSetRegistrationDetailsFactory(
+            OmniscientTopLevelDataSetRegistratorState registratorState)
+    {
+        super(registratorState);
+    }
+
+    @Override
+    protected DataSetInformation createDataSetInformation()
+    {
+        return new DataSetInformation();
+    }
+
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultEntityRegistrationService.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultEntityRegistrationService.java
index 2e8f3f0f75a0a55b88d45e269766680c7d507916..f491ac1d090accfd082b33ae13a4511746de0d28 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultEntityRegistrationService.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultEntityRegistrationService.java
@@ -33,9 +33,10 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifi
 public class DefaultEntityRegistrationService<T extends DataSetInformation> implements
         IEntityRegistrationService<T>
 {
-    private final AbstractOmniscientTopLevelDataSetRegistrator registrator;
+    private final AbstractOmniscientTopLevelDataSetRegistrator<T> registrator;
 
-    public DefaultEntityRegistrationService(AbstractOmniscientTopLevelDataSetRegistrator registrator)
+    public DefaultEntityRegistrationService(
+            AbstractOmniscientTopLevelDataSetRegistrator<T> registrator)
     {
         this.registrator = registrator;
     }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/JythonTopLevelDataSetHandler.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/JythonTopLevelDataSetHandler.java
index 193a465014ef113ce70a376c8fe70b93296369f5..97e16c62df2f00d7cd01ef3bc2526960eef78e74 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/JythonTopLevelDataSetHandler.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/JythonTopLevelDataSetHandler.java
@@ -28,7 +28,7 @@ import ch.systemsx.cisd.common.utilities.IDelegatedActionWithResult;
 import ch.systemsx.cisd.common.utilities.PropertyUtils;
 import ch.systemsx.cisd.etlserver.DataSetRegistrationAlgorithm;
 import ch.systemsx.cisd.etlserver.TopLevelDataSetRegistratorGlobalState;
-import ch.systemsx.cisd.etlserver.registrator.api.v1.impl.DataSet;
+import ch.systemsx.cisd.etlserver.registrator.api.v1.impl.DataSetRegistrationTransaction;
 import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation;
 
 /**
@@ -36,7 +36,8 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation;
  * 
  * @author Chandrasekhar Ramakrishnan
  */
-public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelDataSetRegistrator
+public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends
+        AbstractOmniscientTopLevelDataSetRegistrator<T>
 {
     /**
      * The name of the function to define to hook into the data set registration rollback mechanism.
@@ -49,6 +50,11 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData
      */
     private static final String ROLLBACK_SERVICE_FUNCTION_NAME = "rollback_service";
 
+    /**
+     * The name of the function to define to hook into the transaction rollback mechanism.
+     */
+    private static final String ROLLBACK_TRANSACTION_FUNCTION_NAME = "rollback_transaction";
+
     private static final String FACTORY_VARIABLE_NAME = "factory";
 
     /**
@@ -94,14 +100,14 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData
     }
 
     @Override
-    protected void handleDataSet(File dataSetFile, DataSetRegistrationService genericService)
+    protected void handleDataSet(File dataSetFile, DataSetRegistrationService<T> genericService)
             throws Throwable
     {
         // Load the script
         String scriptString = FileUtilities.loadToString(scriptFile);
 
-        JythonDataSetRegistrationService service =
-                (JythonDataSetRegistrationService) genericService;
+        JythonDataSetRegistrationService<T> service =
+                (JythonDataSetRegistrationService<T>) genericService;
 
         // Configure the evaluator
         PythonInterpreter interpreter = service.interpreter;
@@ -129,21 +135,21 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData
      * the service so we can use it in error handling).
      */
     @Override
-    protected DataSetRegistrationService createDataSetRegistrationService(
+    protected DataSetRegistrationService<T> createDataSetRegistrationService(
             IDelegatedActionWithResult<Boolean> cleanAfterwardsAction)
     {
         PythonInterpreter interpreter = new PythonInterpreter();
         interpreter.set(STATE_VARIABLE_NAME, getGlobalState());
-        JythonDataSetRegistrationService service =
-                new JythonDataSetRegistrationService(this, cleanAfterwardsAction, interpreter);
+        JythonDataSetRegistrationService<T> service =
+                new JythonDataSetRegistrationService<T>(this, cleanAfterwardsAction, interpreter);
         return service;
     }
 
     @Override
-    public void rollback(DataSetRegistrationService service,
+    public void rollback(DataSetRegistrationService<T> service,
             DataSetRegistrationAlgorithm registrationAlgorithm, Throwable throwable)
     {
-        PythonInterpreter interpreter = ((JythonDataSetRegistrationService) service).interpreter;
+        PythonInterpreter interpreter = getInterpreterFromService(service);
         PyFunction function =
                 tryJythonFunction(interpreter, ROLLBACK_DATA_SET_REGISTRATION_FUNCTION_NAME);
         if (null != function)
@@ -156,9 +162,9 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData
     }
 
     @Override
-    protected void rollback(DataSetRegistrationService service, Throwable throwable)
+    protected void rollback(DataSetRegistrationService<T> service, Throwable throwable)
     {
-        PythonInterpreter interpreter = ((JythonDataSetRegistrationService) service).interpreter;
+        PythonInterpreter interpreter = getInterpreterFromService(service);
         PyFunction function = tryJythonFunction(interpreter, ROLLBACK_SERVICE_FUNCTION_NAME);
         if (null != function)
         {
@@ -168,6 +174,21 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData
         super.rollback(service, throwable);
     }
 
+    @Override
+    public void rollbackTransaction(DataSetRegistrationService<T> service,
+            DataSetRegistrationTransaction<T> transaction,
+            DataSetStorageAlgorithmRunner<T> algorithmRunner, Throwable ex)
+    {
+        PythonInterpreter interpreter = getInterpreterFromService(service);
+        PyFunction function = tryJythonFunction(interpreter, ROLLBACK_TRANSACTION_FUNCTION_NAME);
+        if (null != function)
+        {
+            invokeRollbackTransactionFunction(function, service, transaction, algorithmRunner, ex);
+        }
+
+        super.rollbackTransaction(service, transaction, algorithmRunner, ex);
+    }
+
     private PyFunction tryJythonFunction(PythonInterpreter interpreter, String functionName)
     {
         try
@@ -185,17 +206,28 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData
      * Pulled out as a separate method so tests can hook in.
      */
     protected void invokeRollbackServiceFunction(PyFunction function,
-            DataSetRegistrationService service, Throwable throwable)
+            DataSetRegistrationService<T> service, Throwable throwable)
     {
         function.__call__(Py.java2py(service), Py.java2py(throwable));
     }
 
+    /**
+     * Pulled out as a separate method so tests can hook in.
+     */
+    protected void invokeRollbackTransactionFunction(PyFunction function,
+            DataSetRegistrationService<T> service, DataSetRegistrationTransaction<T> transaction,
+            DataSetStorageAlgorithmRunner<T> algorithmRunner, Throwable throwable)
+    {
+        function.__call__(Py.java2py(service), Py.java2py(transaction),
+                Py.java2py(algorithmRunner), Py.java2py(throwable));
+    }
+
     /**
      * Pulled out as a separate method so tests can hook in.
      */
     protected void invokeRollbackDataSetRegistrationFunction(PyFunction function,
-            DataSetRegistrationService service, DataSetRegistrationAlgorithm registrationAlgorithm,
-            Throwable throwable)
+            DataSetRegistrationService<T> service,
+            DataSetRegistrationAlgorithm registrationAlgorithm, Throwable throwable)
     {
         function.__call__(Py.java2py(service), Py.java2py(registrationAlgorithm),
                 Py.java2py(throwable));
@@ -204,10 +236,12 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData
     /**
      * Set the factory available to the python script. Subclasses may want to override.
      */
-    protected IDataSetRegistrationDetailsFactory<? extends DataSetInformation> createObjectFactory(
+    @SuppressWarnings("unchecked")
+    protected IDataSetRegistrationDetailsFactory<T> createObjectFactory(
             PythonInterpreter interpreter)
     {
-        return new JythonObjectFactory<DataSetInformation>(getRegistratorState())
+        return (IDataSetRegistrationDetailsFactory<T>) new JythonObjectFactory<DataSetInformation>(
+                getRegistratorState())
             {
                 @Override
                 protected DataSetInformation createDataSetInformation()
@@ -217,14 +251,12 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData
             };
     }
 
-    public abstract static class JythonObjectFactory<T extends DataSetInformation> implements
-            IDataSetRegistrationDetailsFactory<T>
+    public abstract static class JythonObjectFactory<T extends DataSetInformation> extends
+            AbstractDataSetRegistrationDetailsFactory<T>
     {
-        protected final OmniscientTopLevelDataSetRegistratorState registratorState;
-
         public JythonObjectFactory(OmniscientTopLevelDataSetRegistratorState registratorState)
         {
-            this.registratorState = registratorState;
+            super(registratorState);
         }
 
         /**
@@ -232,40 +264,12 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData
          */
         public DataSetRegistrationDetails<T> createRegistrationDetails()
         {
-            DataSetRegistrationDetails<T> registrationDetails = new DataSetRegistrationDetails<T>();
-            T dataSetInfo = createDataSetInformation();
-            setDatabaseInstance(dataSetInfo);
-            registrationDetails.setDataSetInformation(dataSetInfo);
-            return registrationDetails;
-        }
-
-        protected final void setDatabaseInstance(T dataSetInfo)
-        {
-            dataSetInfo.setInstanceCode(registratorState.getHomeDatabaseInstance().getCode());
-            dataSetInfo.setInstanceUUID(registratorState.getHomeDatabaseInstance().getUuid());
-        }
-
-        /**
-         * Adaptor for the IDataSetRegistrationDetailsFactory interface.
-         */
-        public DataSetRegistrationDetails<T> createDataSetRegistrationDetails()
-        {
-            return createRegistrationDetails();
+            return createDataSetRegistrationDetails();
         }
-
-        public DataSet<T> createDataSet(DataSetRegistrationDetails<T> registrationDetails,
-                File stagingFile)
-        {
-            return new DataSet<T>(registrationDetails, stagingFile);
-        }
-
-        /**
-         * Factory method that creates a new data set information object.
-         */
-        protected abstract T createDataSetInformation();
     }
 
-    protected static class JythonDataSetRegistrationService extends DataSetRegistrationService
+    protected static class JythonDataSetRegistrationService<T extends DataSetInformation> extends
+            DataSetRegistrationService<T>
     {
         private final PythonInterpreter interpreter;
 
@@ -273,12 +277,12 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData
          * @param registrator
          * @param globalCleanAfterwardsAction
          */
-        public JythonDataSetRegistrationService(
-                AbstractOmniscientTopLevelDataSetRegistrator registrator,
+        public JythonDataSetRegistrationService(JythonTopLevelDataSetHandler<T> registrator,
                 IDelegatedActionWithResult<Boolean> globalCleanAfterwardsAction,
                 PythonInterpreter interpreter)
         {
-            super(registrator, globalCleanAfterwardsAction);
+            super(registrator, registrator.createObjectFactory(interpreter),
+                    globalCleanAfterwardsAction);
             this.interpreter = interpreter;
         }
 
@@ -287,4 +291,10 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData
             return interpreter;
         }
     }
+
+    protected PythonInterpreter getInterpreterFromService(DataSetRegistrationService<T> service)
+    {
+        PythonInterpreter interpreter = ((JythonDataSetRegistrationService<T>) service).interpreter;
+        return interpreter;
+    }
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AbstractTransactionState.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AbstractTransactionState.java
index 66947e3bc3d1c3779e39785c2f0bfbceea052db3..0ca5a6f796e1424f7e5551323f1ec851c36cccb8 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AbstractTransactionState.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AbstractTransactionState.java
@@ -75,7 +75,7 @@ abstract class AbstractTransactionState<T extends DataSetInformation>
         private final File stagingDirectory;
 
         // The registration service that owns this transaction
-        private final DataSetRegistrationService registrationService;
+        private final DataSetRegistrationService<T> registrationService;
 
         // The interface to openBIS
         private final IEncapsulatedOpenBISService openBisService;
@@ -88,7 +88,7 @@ abstract class AbstractTransactionState<T extends DataSetInformation>
 
         public LiveTransactionState(DataSetRegistrationTransaction<T> parent,
                 RollbackStack rollbackStack, File workingDirectory, File stagingDirectory,
-                DataSetRegistrationService registrationService,
+                DataSetRegistrationService<T> registrationService,
                 IDataSetRegistrationDetailsFactory<T> registrationDetailsFactory)
         {
             super(parent);
@@ -97,7 +97,7 @@ abstract class AbstractTransactionState<T extends DataSetInformation>
             this.stagingDirectory = stagingDirectory;
             this.registrationService = registrationService;
             this.openBisService =
-                    this.registrationService.getRegistratorState().getGlobalState()
+                    this.registrationService.getRegistratorContext().getGlobalState()
                             .getOpenBisService();
             this.registrationDetailsFactory = registrationDetailsFactory;
         }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransaction.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransaction.java
index 1b1b9259ccb81ece2988b2cde78c8facff5184a4..071404795c49412b904f88fad01a2ea227daba33 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransaction.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransaction.java
@@ -139,13 +139,13 @@ public class DataSetRegistrationTransaction<T extends DataSetInformation> implem
     private AbstractTransactionState<T> state;
 
     // The registration service that owns this transaction
-    private final DataSetRegistrationService registrationService;
+    private final DataSetRegistrationService<T> registrationService;
 
     // The interface to openBIS
     private final IEncapsulatedOpenBISService openBisService;
 
     public DataSetRegistrationTransaction(File rollBackStackParentFolder, File workingDirectory,
-            File stagingDirectory, DataSetRegistrationService registrationService,
+            File stagingDirectory, DataSetRegistrationService<T> registrationService,
             IDataSetRegistrationDetailsFactory<T> registrationDetailsFactory)
     {
         this(createNewRollbackStack(rollBackStackParentFolder), workingDirectory, stagingDirectory,
@@ -153,7 +153,7 @@ public class DataSetRegistrationTransaction<T extends DataSetInformation> implem
     }
 
     DataSetRegistrationTransaction(RollbackStack rollbackStack, File workingDirectory,
-            File stagingDirectory, DataSetRegistrationService registrationService,
+            File stagingDirectory, DataSetRegistrationService<T> registrationService,
             IDataSetRegistrationDetailsFactory<T> registrationDetailsFactory)
     {
         state =
@@ -161,7 +161,8 @@ public class DataSetRegistrationTransaction<T extends DataSetInformation> implem
                         stagingDirectory, registrationService, registrationDetailsFactory);
         this.registrationService = registrationService;
         this.openBisService =
-                this.registrationService.getRegistratorState().getGlobalState().getOpenBisService();
+                this.registrationService.getRegistratorContext().getGlobalState()
+                        .getOpenBisService();
     }
 
     public IDataSet createNewDataSet()
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/JythonTopLevelDataSetRegistratorTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/JythonTopLevelDataSetRegistratorTest.java
index 9a858e328b6426c179ba083eb5cb646c06c1b077..8c6a3779625efb0dfc2ca184c3ca9344d808b518 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/JythonTopLevelDataSetRegistratorTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/JythonTopLevelDataSetRegistratorTest.java
@@ -82,7 +82,7 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest
 
     private static final DataSetType DATA_SET_TYPE = new DataSetType("O1");
 
-    private JythonTopLevelDataSetHandler handler;
+    private JythonTopLevelDataSetHandler<DataSetInformation> handler;
 
     private Mockery context;
 
@@ -735,7 +735,7 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest
         }
     }
 
-    private class TestingDataSetHandler extends JythonTopLevelDataSetHandler
+    private class TestingDataSetHandler extends JythonTopLevelDataSetHandler<DataSetInformation>
     {
         private final boolean shouldRegistrationFail;
 
@@ -767,7 +767,7 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest
         }
 
         @Override
-        public void rollback(DataSetRegistrationService service,
+        public void rollback(DataSetRegistrationService<DataSetInformation> service,
                 DataSetRegistrationAlgorithm registrationAlgorithm, Throwable throwable)
         {
             super.rollback(service, registrationAlgorithm, throwable);
@@ -775,7 +775,8 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest
         }
 
         @Override
-        public void rollback(DataSetRegistrationService service, Throwable throwable)
+        public void rollback(DataSetRegistrationService<DataSetInformation> service,
+                Throwable throwable)
         {
             super.rollback(service, throwable);
             didServiceRollbackHappen = true;
@@ -783,29 +784,32 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest
             {
                 throw CheckedExceptionTunnel.wrapIfNecessary(throwable);
             }
+            throwable.printStackTrace();
         }
 
         @Override
         protected void invokeRollbackServiceFunction(PyFunction function,
-                DataSetRegistrationService service, Throwable throwable)
+                DataSetRegistrationService<DataSetInformation> service, Throwable throwable)
         {
             super.invokeRollbackServiceFunction(function, service, throwable);
             PythonInterpreter interpreter =
-                    ((JythonDataSetRegistrationService) service).getInterpreter();
+                    ((JythonDataSetRegistrationService<DataSetInformation>) service)
+                            .getInterpreter();
             didRollbackServiceFunctionRun =
                     (Boolean) interpreter.get("didRollbackServiceFunctionRun", Boolean.class);
         }
 
         @Override
         protected void invokeRollbackDataSetRegistrationFunction(PyFunction function,
-                DataSetRegistrationService service,
+                DataSetRegistrationService<DataSetInformation> service,
                 DataSetRegistrationAlgorithm registrationAlgorithm, Throwable throwable)
         {
             super.invokeRollbackDataSetRegistrationFunction(function, service,
                     registrationAlgorithm, throwable);
 
             PythonInterpreter interpreter =
-                    ((JythonDataSetRegistrationService) service).getInterpreter();
+                    ((JythonDataSetRegistrationService<DataSetInformation>) service)
+                            .getInterpreter();
             didRollbackDataSetRegistrationFunctionRun =
                     (Boolean) interpreter.get("didRollbackServiceFunctionRun", Boolean.class);
         }
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransactionTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransactionTest.java
index 537fa8423514018ff8bb1cc459d016b872941255..076c1961f30430d5c9ad780d1db4fe81baac3bc7 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransactionTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransactionTest.java
@@ -92,7 +92,7 @@ public class DataSetRegistrationTransactionTest extends AbstractFileSystemTestCa
 
     private File srcFile;
 
-    private DataSetRegistrationService service;
+    private DataSetRegistrationService<DataSetInformation> service;
 
     @BeforeTest
     public void init()
@@ -457,8 +457,9 @@ public class DataSetRegistrationTransactionTest extends AbstractFileSystemTestCa
         }
     }
 
-    private class TestingDataSetHandler extends AbstractOmniscientTopLevelDataSetRegistrator
-            implements IDataSetRegistrationDetailsFactory<DataSetInformation>
+    private class TestingDataSetHandler extends
+            AbstractOmniscientTopLevelDataSetRegistrator<DataSetInformation> implements
+            IDataSetRegistrationDetailsFactory<DataSetInformation>
     {
 
         /**
@@ -470,13 +471,13 @@ public class DataSetRegistrationTransactionTest extends AbstractFileSystemTestCa
         }
 
         @Override
-        protected void handleDataSet(File dataSetFile, DataSetRegistrationService aService)
-                throws Throwable
+        protected void handleDataSet(File dataSetFile,
+                DataSetRegistrationService<DataSetInformation> aService) throws Throwable
         {
 
         }
 
-        public DataSetRegistrationService createNewService()
+        public DataSetRegistrationService<DataSetInformation> createNewService()
         {
             IDelegatedActionWithResult<Boolean> cleanAfterwardsAction =
                     new IDelegatedActionWithResult<Boolean>()