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 382d0be6da33be0be81e3164809f12953366f8b0..76d219f561a606f83d748202989df0909e4549a7 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
@@ -17,9 +17,11 @@
 package ch.systemsx.cisd.etlserver.registrator;
 
 import java.io.File;
+import java.util.LinkedList;
 import java.util.List;
 
 import org.python.core.Py;
+import org.python.core.PyBaseCode;
 import org.python.core.PyException;
 import org.python.core.PyFunction;
 import org.python.util.PythonInterpreter;
@@ -43,43 +45,58 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation;
 public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends
         AbstractOmniscientTopLevelDataSetRegistrator<T>
 {
-    /**
-     * The name of the function to define to hook into the service rollback mechanism.
-     */
-    private static final String ROLLBACK_SERVICE_FUNCTION_NAME = "rollback_service";
+    private enum JythonHookFunction
+    {
+        /**
+         * The name of the function to define to hook into the service rollback mechanism.
+         */
+        ROLLBACK_SERVICE_FUNCTION_NAME("rollback_service", 2),
 
-    /**
-     * The name of the function to define to hook into the transaction rollback mechanism.
-     */
-    private static final String ROLLBACK_TRANSACTION_FUNCTION_NAME = "rollback_transaction";
+        /**
+         * The name of the function to define to hook into the transaction rollback mechanism.
+         */
+        ROLLBACK_TRANSACTION_FUNCTION_NAME("rollback_transaction", 4),
 
-    /**
-     * The name of the function called after successful transaction commit.
-     */
-    private static final String COMMIT_TRANSACTION_FUNCTION_NAME = "commit_transaction";
+        /**
+         * The name of the function called after successful transaction commit.
+         */
+        COMMIT_TRANSACTION_FUNCTION_NAME("commit_transaction", 2),
 
-    /**
-     * The name of the function called after successful transaction commit.
-     */
-    private static final String POST_STORAGE_FUNCTION_NAME = "post_storage";
+        /**
+         * The name of the function called after successful transaction commit.
+         */
+        POST_STORAGE_FUNCTION_NAME("post_storage", 2),
 
-    /**
-     * The name of the function called just before registration of datasets in application server.
-     */
-    private static final String PRE_REGISTRATION_FUNCTION_NAME = "pre_metadata_registration";
+        /**
+         * The name of the function called just before registration of datasets in application
+         * server.
+         */
+        PRE_REGISTRATION_FUNCTION_NAME("pre_metadata_registration", 2),
 
-    /**
-     * The name of the function called just after successful registration of datasets in application
-     * server.
-     */
-    private static final String POST_REGISTRATION_FUNCTION_NAME = "post_metadata_registration";
+        /**
+         * The name of the function called just after successful registration of datasets in
+         * application server.
+         */
+        POST_REGISTRATION_FUNCTION_NAME("post_metadata_registration", 2),
 
-    /**
-     * The name of the function called when secondary transactions, DynamicTransactionQuery objects,
-     * fail.
-     */
-    private static final String DID_ENCOUNTER_SECONDARY_TRANSACTION_ERRORS_FUNCTION_NAME =
-            "did_encounter_secondary_transaction_errors";
+        /**
+         * The name of the function called when secondary transactions, DynamicTransactionQuery
+         * objects, fail.
+         */
+        DID_ENCOUNTER_SECONDARY_TRANSACTION_ERRORS_FUNCTION_NAME(
+                "did_encounter_secondary_transaction_errors", 3);
+
+        String name;
+
+        int argCount;
+
+        private JythonHookFunction(String name, int argCount)
+        {
+            this.name = name;
+            this.argCount = argCount;
+
+        }
+    }
 
     private static final String FACTORY_VARIABLE_NAME = "factory";
 
@@ -144,6 +161,30 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends
 
         // Invoke the evaluator
         interpreter.exec(scriptString);
+
+        for (JythonHookFunction function : JythonHookFunction.values())
+        {
+            PyFunction py = tryJythonFunction(interpreter, function);
+            if (py != null)
+            {
+                if (py.func_code instanceof PyBaseCode)
+                {
+                    int co_argcount = ((PyBaseCode) py.func_code).co_argcount;
+                    if (co_argcount != function.argCount)
+                    {
+                        throw new IllegalArgumentException(
+                                String.format(
+                                        "The function %s in %s has wrong number of arguments(%s instead of %s).",
+                                        function.name, scriptFile.getName(), co_argcount,
+                                        function.argCount));
+                    }
+                } else
+                {
+                    System.err
+                            .println("Possibly incorrect python code. Can't verify script correctness.");
+                }
+            }
+        }
     }
 
     /**
@@ -182,7 +223,7 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends
     protected void rollback(DataSetRegistrationService<T> service, Throwable throwable)
     {
         PythonInterpreter interpreter = getInterpreterFromService(service);
-        PyFunction function = tryJythonFunction(interpreter, ROLLBACK_SERVICE_FUNCTION_NAME);
+        PyFunction function = tryJythonFunction(interpreter, JythonHookFunction.ROLLBACK_SERVICE_FUNCTION_NAME);
         if (null != function)
         {
             invokeRollbackServiceFunction(function, service, throwable);
@@ -239,7 +280,7 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends
             DataSetStorageAlgorithmRunner<T> algorithmRunner, Throwable ex)
     {
         PythonInterpreter interpreter = getInterpreterFromService(service);
-        PyFunction function = tryJythonFunction(interpreter, ROLLBACK_TRANSACTION_FUNCTION_NAME);
+        PyFunction function = tryJythonFunction(interpreter, JythonHookFunction.ROLLBACK_TRANSACTION_FUNCTION_NAME);
         if (null != function)
         {
             invokeRollbackTransactionFunction(function, service, transaction, algorithmRunner, ex);
@@ -247,7 +288,7 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends
         {
             // No Rollback transaction function was called, see if the rollback service function was
             // defined, and call it.
-            function = tryJythonFunction(interpreter, ROLLBACK_SERVICE_FUNCTION_NAME);
+            function = tryJythonFunction(interpreter, JythonHookFunction.ROLLBACK_SERVICE_FUNCTION_NAME);
             if (null != function)
             {
                 invokeRollbackServiceFunction(function, service, ex);
@@ -260,13 +301,13 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends
     {
         PythonInterpreter interpreter = getInterpreterFromService(service);
 
-        PyFunction function = tryJythonFunction(interpreter, POST_STORAGE_FUNCTION_NAME);
+        PyFunction function = tryJythonFunction(interpreter, JythonHookFunction.POST_STORAGE_FUNCTION_NAME);
         if (null != function)
         {
             invokeTransactionFunctionWithContext(function, service, transaction);
         } else
         {
-            function = tryJythonFunction(interpreter, COMMIT_TRANSACTION_FUNCTION_NAME);
+            function = tryJythonFunction(interpreter, JythonHookFunction.COMMIT_TRANSACTION_FUNCTION_NAME);
             if (null != function)
             {
                 invokeServiceTransactionFunction(function, service, transaction);
@@ -278,7 +319,8 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends
             DataSetRegistrationTransaction<T> transaction)
     {
         PythonInterpreter interpreter = getInterpreterFromService(service);
-        PyFunction function = tryJythonFunction(interpreter, PRE_REGISTRATION_FUNCTION_NAME);
+        PyFunction function = tryJythonFunction(interpreter, JythonHookFunction.PRE_REGISTRATION_FUNCTION_NAME);
+
         if (null != function)
         {
             invokeTransactionFunctionWithContext(function, service, transaction);
@@ -289,7 +331,7 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends
             DataSetRegistrationTransaction<T> transaction)
     {
         PythonInterpreter interpreter = getInterpreterFromService(service);
-        PyFunction function = tryJythonFunction(interpreter, POST_REGISTRATION_FUNCTION_NAME);
+        PyFunction function = tryJythonFunction(interpreter, JythonHookFunction.POST_REGISTRATION_FUNCTION_NAME);
         if (null != function)
         {
             invokeTransactionFunctionWithContext(function, service, transaction);
@@ -303,7 +345,7 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends
         PythonInterpreter interpreter = getInterpreterFromService(service);
         PyFunction function =
                 tryJythonFunction(interpreter,
-                        DID_ENCOUNTER_SECONDARY_TRANSACTION_ERRORS_FUNCTION_NAME);
+                        JythonHookFunction.DID_ENCOUNTER_SECONDARY_TRANSACTION_ERRORS_FUNCTION_NAME);
         if (null != function)
         {
             invokeDidEncounterSecondaryTransactionErrorsFunction(function, service, transaction,
@@ -311,11 +353,12 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends
         }
     }
 
-    private PyFunction tryJythonFunction(PythonInterpreter interpreter, String functionName)
+    private PyFunction tryJythonFunction(PythonInterpreter interpreter,
+            JythonHookFunction functionDefinition)
     {
         try
         {
-            PyFunction function = interpreter.get(functionName, PyFunction.class);
+            PyFunction function = interpreter.get(functionDefinition.name, PyFunction.class);
             return function;
         } catch (Exception e)
         {
@@ -344,17 +387,6 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends
                 Py.java2py(algorithmRunner), Py.java2py(throwable));
     }
 
-    /**
-     * Pulled out as a separate method so tests can hook in.
-     */
-    protected void invokeRollbackDataSetRegistrationFunction(PyFunction function,
-            DataSetRegistrationService<T> service,
-            DataSetRegistrationAlgorithm registrationAlgorithm, Throwable throwable)
-    {
-        function.__call__(Py.java2py(service), Py.java2py(registrationAlgorithm),
-                Py.java2py(throwable));
-    }
-
     /**
      * Pulled out as a separate method so tests can hook in.
      */
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/AbstractJythonDataSetHandlerTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/AbstractJythonDataSetHandlerTest.java
index 27359ccae6f8041ae6788cd4454d3fe355e582fa..0599ab1445313c7638504ffc708d2be8d2d3f714 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/AbstractJythonDataSetHandlerTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/AbstractJythonDataSetHandlerTest.java
@@ -386,8 +386,6 @@ public abstract class AbstractJythonDataSetHandlerTest extends AbstractFileSyste
 
         protected boolean didRollbackServiceFunctionRun = false;
 
-        protected boolean didRollbackDataSetRegistrationFunctionRun = false;
-
         protected boolean didTransactionRollbackHappen = false;
 
         protected boolean didRollbackTransactionFunctionRunHappen = false;
@@ -470,21 +468,6 @@ public abstract class AbstractJythonDataSetHandlerTest extends AbstractFileSyste
                     interpreter.get("didRollbackServiceFunctionRun", Boolean.class);
         }
 
-        @Override
-        protected void invokeRollbackDataSetRegistrationFunction(PyFunction function,
-                DataSetRegistrationService<DataSetInformation> service,
-                DataSetRegistrationAlgorithm registrationAlgorithm, Throwable throwable)
-        {
-            super.invokeRollbackDataSetRegistrationFunction(function, service,
-                    registrationAlgorithm, throwable);
-
-            PythonInterpreter interpreter =
-                    ((JythonDataSetRegistrationService<DataSetInformation>) service)
-                            .getInterpreter();
-            didRollbackDataSetRegistrationFunctionRun =
-                    interpreter.get("didRollbackServiceFunctionRun", Boolean.class);
-        }
-
         @Override
         protected void invokeRollbackTransactionFunction(PyFunction function,
                 DataSetRegistrationService<DataSetInformation> service,
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 fc425f841f6f65dc433a6b2a117a4b719f307abc..176233aaccaba9787e081c5ec37b47b34ac767b4 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
@@ -244,11 +244,21 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractJythonDataSetH
                         "Postregistration hook error should not prevent succesfull registration.");
         testCase.dropboxScriptPath = "testcase-postregistration-hook-failed.py";
         testCases.add(testCase);
-        
-        // TODO: Add more scenarios:
-        // - Test move to error
-        // - Test moving of the original file in case of validation error
-        // - Test other error scenarios
+
+        testCase = new TestCaseParameters("Postregistration hook has wrong signature.");
+        testCase.dropboxScriptPath = "testcase-postregistration-hook-wrong-signature.py";
+        testCase.shouldThrowExceptionDuringRegistration = true;
+        testCase.exceptionAcceptor = new IPredicate<Exception>()
+            {
+                public boolean execute(Exception arg)
+                {
+                    System.out.println(arg);
+                    System.out.println(arg.getMessage());
+                    return arg.getMessage().contains("wrong number of arguments");
+                }
+            };
+        testCase.failurePoint = TestCaseParameters.FailurePoint.AFTER_GET_EXPERIMENT;
+        testCases.add(testCase);
 
         // here is crappy code for
         // return parameters.map( (x) => new Object[]{x} )
@@ -306,6 +316,9 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractJythonDataSetH
          */
         protected boolean shouldValidationFail = false;
 
+        /**
+         * Specifies how far we expect the registration process to go.
+         */
         protected FailurePoint failurePoint = null;
 
         /**
@@ -335,10 +348,10 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractJythonDataSetH
             return title;
         }
 
-        //add more when necessary
+        // add more when necessary
         public enum FailurePoint
         {
-            AFTER_CREATE_DATA_SET_CODE, BEFORE_OPENBIS_REGISTRATION
+            AT_THE_BEGINNING, AFTER_CREATE_DATA_SET_CODE, BEFORE_OPENBIS_REGISTRATION, AFTER_GET_EXPERIMENT
         }
     }
 
@@ -358,6 +371,7 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractJythonDataSetH
         {
             createHandler(properties, false, true);
         }
+
         if (testCase.createDataSetDelegate != null)
         {
             testCase.createDataSetDelegate.execute();
@@ -376,8 +390,19 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractJythonDataSetH
                 {
                     boolean broken = false;
 
-                    one(openBisService).createDataSetCode();
-                    will(returnValue(DATA_SET_CODE));
+                    // this is to initialize openBis
+                    //allowing(openBisService).getClass();
+
+                    if (testCase.failurePoint == TestCaseParameters.FailurePoint.AT_THE_BEGINNING)
+                    {
+                        broken = true;
+                    }
+
+                    if (false == broken)
+                    {
+                        one(openBisService).createDataSetCode();
+                        will(returnValue(DATA_SET_CODE));
+                    }
 
                     if (testCase.failurePoint == TestCaseParameters.FailurePoint.AFTER_CREATE_DATA_SET_CODE)
                     {
@@ -392,6 +417,11 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractJythonDataSetH
                         will(returnValue(experiment));
                     }
 
+                    if (testCase.failurePoint == TestCaseParameters.FailurePoint.AFTER_GET_EXPERIMENT)
+                    {
+                        broken = true;
+                    }
+                    
                     if (false == broken)
                     {
                         one(dataSetValidator).assertValidDataSet(
@@ -524,7 +554,6 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractJythonDataSetH
         {
         } else if (testCase.shouldRegistrationFail)
         {
-            assertFalse(theHandler.didRollbackDataSetRegistrationFunctionRun);
             assertFalse(theHandler.didRollbackServiceFunctionRun);
             assertTrue(theHandler.didTransactionRollbackHappen);
             assertTrue(theHandler.didRollbackTransactionFunctionRunHappen);
@@ -596,7 +625,6 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractJythonDataSetH
                         new File(workingDirectory, "data_set/sub_data_set_2/read2.me")).trim());
 
         TestingDataSetHandler theHandler = (TestingDataSetHandler) handler;
-        assertFalse(theHandler.didRollbackDataSetRegistrationFunctionRun);
         assertFalse(theHandler.didRollbackServiceFunctionRun);
 
         // These do not get called when the caller herself invokes a rollback
@@ -1047,7 +1075,6 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractJythonDataSetH
         assertTrue(logAppender.getLogContent(), logAppender.getLogContent().length() > 0);
 
         TestingDataSetHandler theHandler = (TestingDataSetHandler) handler;
-        assertFalse(theHandler.didRollbackDataSetRegistrationFunctionRun);
         assertTrue(theHandler.didRollbackServiceFunctionRun);
         context.assertIsSatisfied();
     }
@@ -1112,7 +1139,6 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractJythonDataSetH
         TestingDataSetHandler theHandler = (TestingDataSetHandler) handler;
         assertFalse(didServiceRollbackHappen);
         assertFalse(theHandler.didTransactionRollbackHappen);
-        assertFalse(theHandler.didRollbackDataSetRegistrationFunctionRun);
         assertFalse(theHandler.didRollbackServiceFunctionRun);
 
         context.assertIsSatisfied();
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/testcase-postregistration-hook-wrong-signature.py b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/testcase-postregistration-hook-wrong-signature.py
new file mode 100644
index 0000000000000000000000000000000000000000..4669c577aaac0a779e3ad20ef416e8d184585137
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/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(transaction, context, unnecessary_argument):
+    global didPostRegistrationFunctionRunHappen
+    didPostRegistrationFunctionRunHappen = True
+
+execfile("sourceTest/java/ch/systemsx/cisd/etlserver/registrator/simple-transaction.py")
+