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 42be78c44e3a72ed3bce2caff09baddf1c77e1f1..5fa077addc93b7b78493cc73da3ba2f1cb673af6 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
@@ -103,9 +103,16 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractJythonDataSetH
         params.dontCallOldApiJythonHooks = true;
         params.title += " - V2";
         params.shouldUseAutoRecovery = true;
+        params.dropboxScriptPath = scriptPathV2(other.dropboxScriptPath);
         return params;
     }
 
+    private static String scriptPathV2(String scriptPath)
+    {
+        File script = new File(scriptPath);
+        return new File(script.getParentFile(), "v2-" + script.getName()).getPath();
+    }
+
     @DataProvider(name = "simpleTransactionTestCaseProvider")
     public Object[][] simpleTransactionCases()
     {
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/file-not-found.py b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/file-not-found.py
index 3bca7f4e4f5983d82aefb0abb179c469bd70d660..d3ee2dbd6b04cb0d845f568be004924f29cf89c2 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/file-not-found.py
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/file-not-found.py
@@ -1,8 +1,5 @@
 execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/all-hooks.py")
 
-# this check is to make the script compatible with V1 and V2
-if transaction is None:
-  transaction = service.transaction(incoming, factory)
 dataSet = transaction.createNewDataSet()
 transaction.moveFile('/non/existent/path', dataSet)
 dataSet.setDataSetType('O1')
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-dying-script.py b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-dying-script.py
new file mode 100644
index 0000000000000000000000000000000000000000..6c2caea58119b9081e45f4bad6bb90b3d6fc1d6b
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-dying-script.py
@@ -0,0 +1,16 @@
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier as identifier
+import java.io as io
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto as dto
+
+execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/all-hooks.py")
+
+def process():
+  # Create the Experiment Identifier
+  identifier = identifier.ExperimentIdentifierFactory("/SPACE/PROJECT/EXP-CODE").createIdentifier()
+  
+  # Register data set 1
+  registrationDetails = factory.createRegistrationDetails()
+  dataSetInformation = registrationDetails.getDataSetInformation()
+  dataSetInformation.setExperimentIdentifier(identifier)
+      registrationDetails.setDataSetType(dto.DataSetType("O1"));
+  None.non_existant_function()
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-file-not-found.py b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-file-not-found.py
new file mode 100644
index 0000000000000000000000000000000000000000..1f453f077546e86d452386756db5b230a76715d7
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-file-not-found.py
@@ -0,0 +1,6 @@
+execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/all-hooks.py")
+process():
+  dataSet = transaction.createNewDataSet()
+  transaction.moveFile('/non/existent/path', dataSet)
+  dataSet.setDataSetType('O1')
+  dataSet.setExperiment(transaction.getExperiment('/SPACE/PROJECT/EXP'))
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-rollback-dying-script.py b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-rollback-dying-script.py
new file mode 100644
index 0000000000000000000000000000000000000000..6eb94ca1d059f7fa0bf508ccdf1555997a40f3b0
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-rollback-dying-script.py
@@ -0,0 +1,16 @@
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier as identifier
+import java.io as io
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto as dto
+
+execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/all-hooks.py")
+def process():
+    # Create the Experiment Identifier
+    identifier = identifier.ExperimentIdentifierFactory("/SPACE/PROJECT/EXP-CODE").createIdentifier()
+    
+    # Register data set 1
+    registrationDetails = factory.createRegistrationDetails()
+    dataSetInformation = registrationDetails.getDataSetInformation()
+    dataSetInformation.setExperimentIdentifier(identifier)
+    registrationDetails.setDataSetType(dto.DataSetType("O1"));
+    
+    None.non_existant_function()
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-simple-testcase.py b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-simple-testcase.py
new file mode 100644
index 0000000000000000000000000000000000000000..38ab1efcddceeacf5a44ddaa5902e4315dc45c1b
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-simple-testcase.py
@@ -0,0 +1,3 @@
+execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/all-hooks.py")
+def process():
+    execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/simple-transaction.py")
\ No newline at end of file
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-double-transaction.py b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-double-transaction.py
new file mode 100644
index 0000000000000000000000000000000000000000..35e8b648cae5d806ddd68811ba5c2ef143b88a1a
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-double-transaction.py
@@ -0,0 +1,17 @@
+execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/all-hooks.py")
+def process():
+  transaction = service.transaction(incoming, factory)
+  transaction1 = service.transaction(incoming, factory)
+  
+  dataSet = transaction.createNewDataSet()
+  dataSet1 = transaction1.createNewDataSet()
+  
+  transaction.moveFile(incoming.getPath() + '/sub_data_set_1', dataSet)
+  transaction1.moveFile(incoming.getPath() + '/sub_data_set_2', dataSet1)
+  
+  dataSet.setDataSetType('O1')
+  dataSet1.setDataSetType('O1')
+  
+  dataSet.setExperiment(transaction.getExperiment('/SPACE/PROJECT/EXP'))
+  dataSet1.setExperiment(transaction1.getExperiment('/SPACE/PROJECT/EXP'))
+
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-postregistration-hook-failed.py b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-postregistration-hook-failed.py
new file mode 100644
index 0000000000000000000000000000000000000000..740e4142a03d4c49fed8c1e00ff7608338027840
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-postregistration-hook-failed.py
@@ -0,0 +1,12 @@
+from java.lang import IllegalArgumentException
+
+execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/all-hooks.py")
+
+def post_metadata_registration(context):
+    global didPostRegistrationFunctionRunHappen
+    didPostRegistrationFunctionRunHappen = True
+    raise IllegalArgumentException("Fail at post_metadata_registration to cancel registration")
+
+process():
+  execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/simple-transaction.py")
+
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-postregistration-hook-wrong-signature.py b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-postregistration-hook-wrong-signature.py
new file mode 100644
index 0000000000000000000000000000000000000000..a53ea97cb8bf0e4aa59e0b33d8dbfeef1e2c8d2d
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-postregistration-hook-wrong-signature.py
@@ -0,0 +1,8 @@
+execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/all-hooks.py")
+
+def post_metadata_registration(context, unnecessary_argument):
+    global didPostRegistrationFunctionRunHappen
+    didPostRegistrationFunctionRunHappen = True
+def process():
+  execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/simple-transaction.py")
+
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-preregistration-hook-failed.py b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-preregistration-hook-failed.py
new file mode 100644
index 0000000000000000000000000000000000000000..5f9981046cf331299b3254da4ba6487f21f3dc4e
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-preregistration-hook-failed.py
@@ -0,0 +1,12 @@
+from java.lang import IllegalArgumentException
+
+execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/all-hooks.py")
+
+def pre_metadata_registration(context):
+    global didPreRegistrationFunctionRunHappen
+    didPreRegistrationFunctionRunHappen = True
+    raise IllegalArgumentException("Fail at pre_metadata_registration to cancel registration")
+
+process():
+    execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/simple-transaction.py"):
+
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-registration-context.py b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-registration-context.py
new file mode 100644
index 0000000000000000000000000000000000000000..eaf764eccc8295c90aca1a7e2a8347f618bd9f59
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-registration-context.py
@@ -0,0 +1,49 @@
+def process():
+  execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/simple-transaction.py")
+  transaction.getTransactionPersistentMap().put("body","1")
+
+global contextTestFailed
+contextTestFailed = None
+
+def rollback_transaction(service, transaction, algorithmRunner, throwable):
+    global didTransactionRollbackHappen
+    didTransactionRollbackHappen = True
+
+def pre_metadata_registration(context):
+    
+    assert_context_content(context, "pre_metadata_registration", "body", "1");
+    assert_context_content(context, "pre_metadata_registration", "pre_metadata_registration", None);
+    assert_context_content(context, "pre_metadata_registration", "post_storage", None);
+
+    context.put("pre_metadata_registration", "2")
+    global didPreRegistrationFunctionRunHappen
+    didPreRegistrationFunctionRunHappen = True
+
+def post_metadata_registration(context):
+
+    assert_context_content(context, "post_metadata_registration", "body", "1");
+    assert_context_content(context, "post_metadata_registration", "pre_metadata_registration", "2");
+    assert_context_content(context, "post_metadata_registration", "post_storage", None);
+
+    context.put("post_metadata_registration", "3")
+    global didPostRegistrationFunctionRunHappen
+    didPostRegistrationFunctionRunHappen = True
+
+def post_storage(context):
+
+    assert_context_content(context, "post_storage", "body", "1");
+    assert_context_content(context, "post_storage", "pre_metadata_registration", "2");
+    assert_context_content(context, "post_storage", "post_metadata_registration", "3");
+
+    context.put("post_storage", "4")
+    global didPostStorageFunctionRunHappen
+    didPostStorageFunctionRunHappen = True
+    
+def assert_context_content(context, caller, name, expected):
+    value = context.get(name)
+    if (value != expected):
+        global contextTestFailed
+        if (value != None and expected != None and type(value) != type(expected)):
+            value = "%s:%s" % (type(value), value)
+            expected = "%s:%s" % (type(expected), expected)
+        contextTestFailed = "in %s the value of %s should have been '%s', but was '%s'" % (caller, name, expected, value) 
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-rollback.py b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-rollback.py
new file mode 100644
index 0000000000000000000000000000000000000000..fb7a8a58f8943048716b37a9a9bea3e5c81c937e
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-rollback.py
@@ -0,0 +1,4 @@
+execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/all-hooks.py")
+def process():
+  execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/simple-transaction.py"):
+  transaction.rollback()
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-without-post-storage.py b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-without-post-storage.py
new file mode 100644
index 0000000000000000000000000000000000000000..749866a8fe4f18354204e16381d177fca054d2a2
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/v2-testcase-without-post-storage.py
@@ -0,0 +1,4 @@
+execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/all-hooks-without-post-storage.py")
+process():
+  execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/simple-transaction.py")
+