diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c
index a7fb2425e8e7ff9a6eceb8fa8e02bbe7b0edc0b6..a730ff6fba11439042cdfa08a91ef9de385af456 100644
--- a/src/lib-sieve/sieve-interpreter.c
+++ b/src/lib-sieve/sieve-interpreter.c
@@ -445,7 +445,6 @@ int sieve_interpreter_continue
 
 		if ( ret != SIEVE_EXEC_OK ) {
 			sieve_runtime_trace(&interp->runenv, "[[EXECUTION ABORTED]]");
-			ret = -1;
 		}
 	}
 	
diff --git a/src/testsuite/Makefile.am b/src/testsuite/Makefile.am
index bcb5c5b8daa6766d5abe5282eb86d52f95f81b0b..d320a32844c6334e1d11793ad2fa6da3075d18d4 100644
--- a/src/testsuite/Makefile.am
+++ b/src/testsuite/Makefile.am
@@ -44,6 +44,7 @@ commands = \
 
 tests = \
 	tst-test-compile.c \
+	tst-test-execute.c \
 	tst-test-error.c
 
 testsuite_SOURCES = \
diff --git a/src/testsuite/ext-testsuite.c b/src/testsuite/ext-testsuite.c
index 8978d862008707259ee7166f7909e75beb6df6cb..222b018a8313a377e99a6e3acc9706f51447849c 100644
--- a/src/testsuite/ext-testsuite.c
+++ b/src/testsuite/ext-testsuite.c
@@ -56,6 +56,7 @@ const struct sieve_operation *testsuite_operations[] = {
 	&test_fail_operation, 
 	&test_set_operation,
 	&test_compile_operation,
+	&test_execute_operation,
 	&test_error_operation
 };
 
@@ -110,6 +111,7 @@ static bool ext_testsuite_validator_load(struct sieve_validator *valdtr)
 	sieve_validator_register_command(valdtr, &cmd_test_set);
 
 	sieve_validator_register_command(valdtr, &tst_test_compile);
+	sieve_validator_register_command(valdtr, &tst_test_execute);
 	sieve_validator_register_command(valdtr, &tst_test_error);
 	
 	return testsuite_validator_context_initialize(valdtr);
diff --git a/src/testsuite/testsuite-common.c b/src/testsuite/testsuite-common.c
index 0b670f4dd8fe6e988d4da8a953777a163e348713..d0a3521e4b69ade213ace327f767ab780d30cace 100644
--- a/src/testsuite/testsuite-common.c
+++ b/src/testsuite/testsuite-common.c
@@ -20,6 +20,7 @@
 #include "sieve-validator.h"
 #include "sieve-generator.h"
 #include "sieve-interpreter.h"
+#include "sieve-result.h"
 #include "sieve-dump.h"
 
 #include "testsuite-objects.h"
@@ -301,6 +302,8 @@ unsigned int _testsuite_script_error_index = 0;
 static pool_t _testsuite_scriptmsg_pool = NULL;
 ARRAY_DEFINE(_testsuite_script_errors, struct _testsuite_script_message);
 
+struct sieve_binary *_testsuite_compiled_script;
+
 static void _testsuite_script_verror
 (struct sieve_error_handler *ehandler ATTR_UNUSED, const char *location,
     const char *fmt, va_list args)
@@ -376,6 +379,8 @@ static void testsuite_script_init(void)
     sieve_error_handler_accept_infolog(test_script_ehandler, TRUE);
 
 	testsuite_script_clear_messages();
+
+	_testsuite_compiled_script = NULL;
 }
 
 bool testsuite_script_compile(const char *script_path)
@@ -399,14 +404,62 @@ bool testsuite_script_compile(const char *script_path)
     if ( (sbin = sieve_compile(script_path, test_script_ehandler)) == NULL )
         return FALSE;
 
-    sieve_close(&sbin);
+	if ( _testsuite_compiled_script != NULL ) {
+	    sieve_close(&_testsuite_compiled_script);
+	}
+
+	_testsuite_compiled_script = sbin;
+
 	return TRUE;
 }
 
+bool testsuite_script_execute(const struct sieve_runtime_env *renv)
+{
+	struct sieve_script_env scriptenv;
+	struct sieve_result *result;
+	struct sieve_interpreter *interp;
+	int ret;
+
+	if ( _testsuite_compiled_script == NULL ) {
+		sieve_runtime_error(renv, sieve_error_script_location(renv->script,0),
+			"testsuite: no script compiled yet");
+		return FALSE;
+	}
+
+	testsuite_script_clear_messages();
+
+	/* Compose script execution environment */
+	memset(&scriptenv, 0, sizeof(scriptenv));
+	scriptenv.inbox = "INBOX";
+	scriptenv.namespaces = NULL;
+	scriptenv.username = "user";
+	scriptenv.hostname = "host.example.com";
+	scriptenv.postmaster_address = "postmaster@example.com";
+	scriptenv.smtp_open = NULL;
+	scriptenv.smtp_close = NULL;
+	scriptenv.duplicate_mark = NULL;
+	scriptenv.duplicate_check = NULL;
+	
+	result = sieve_result_create(test_script_ehandler);
+
+	/* Execute the script */
+	interp=sieve_interpreter_create(_testsuite_compiled_script, test_script_ehandler, NULL);
+	
+	ret = sieve_interpreter_run(interp, renv->msgdata, &scriptenv, &result);
+
+	sieve_interpreter_free(&interp);
+	
+	return ( ret > 0 );
+}
+
 static void testsuite_script_deinit(void)
 {
 	sieve_error_handler_unref(&test_script_ehandler);
 
+	if ( _testsuite_compiled_script != NULL ) {
+        sieve_close(&_testsuite_compiled_script);
+    }
+
 	pool_unref(&_testsuite_scriptmsg_pool);
 	//str_free(test_script_error_buf);
 }
diff --git a/src/testsuite/testsuite-common.h b/src/testsuite/testsuite-common.h
index 16eee76c6c06ec893c77fb327ad90519a9b745aa..4cb1d5a981ae6db558f1b946a057b476532fad75 100644
--- a/src/testsuite/testsuite-common.h
+++ b/src/testsuite/testsuite-common.h
@@ -61,6 +61,7 @@ extern const struct sieve_command cmd_test_set;
  */
 
 extern const struct sieve_command tst_test_compile;
+extern const struct sieve_command tst_test_execute;
 extern const struct sieve_command tst_test_error;
 
 /* 
@@ -73,6 +74,7 @@ enum testsuite_operation_code {
 	TESTSUITE_OPERATION_TEST_FAIL,
 	TESTSUITE_OPERATION_TEST_SET,
 	TESTSUITE_OPERATION_TEST_COMPILE,
+	TESTSUITE_OPERATION_TEST_EXECUTE,
 	TESTSUITE_OPERATION_TEST_ERROR,
 };
 
@@ -81,6 +83,7 @@ extern const struct sieve_operation test_finish_operation;
 extern const struct sieve_operation test_fail_operation;
 extern const struct sieve_operation test_set_operation;
 extern const struct sieve_operation test_compile_operation;
+extern const struct sieve_operation test_execute_operation;
 extern const struct sieve_operation test_error_operation;
 
 /* 
@@ -109,6 +112,7 @@ int testsuite_testcase_result(void);
  */
 
 bool testsuite_script_compile(const char *script_path);
+bool testsuite_script_execute(const struct sieve_runtime_env *renv);
 
 void testsuite_script_get_error_init(void);
 const char *testsuite_script_get_error_next(bool location);
diff --git a/src/testsuite/testsuite.c b/src/testsuite/testsuite.c
index eb12d91a62683a8b69b47e1e18f38580a8e174ff..16cca8dc730a95d6dd6d788b44891b415b9c0c89 100644
--- a/src/testsuite/testsuite.c
+++ b/src/testsuite/testsuite.c
@@ -66,6 +66,7 @@ static void testsuite_bin_init(void)
 	
 	testsuite_init();
 }
+
 static void testsuite_bin_deinit(void)
 {
 	testsuite_deinit();
diff --git a/src/testsuite/tst-test-execute.c b/src/testsuite/tst-test-execute.c
new file mode 100644
index 0000000000000000000000000000000000000000..8c45a308abcd88caf29c3f775717ded63dcfbb66
--- /dev/null
+++ b/src/testsuite/tst-test-execute.c
@@ -0,0 +1,90 @@
+/* Copyright (c) 2002-2008 Dovecot Sieve authors, see the included COPYING file
+ */
+
+#include "sieve-common.h"
+#include "sieve-script.h"
+#include "sieve-commands.h"
+#include "sieve-validator.h"
+#include "sieve-generator.h"
+#include "sieve-interpreter.h"
+#include "sieve-code.h"
+#include "sieve-binary.h"
+#include "sieve-dump.h"
+#include "sieve.h"
+
+#include "testsuite-common.h"
+
+/*
+ * Test_execute command
+ *
+ * Syntax:   
+ *   test_execute
+ */
+
+static bool tst_test_execute_generate
+	(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
+
+const struct sieve_command tst_test_execute = { 
+	"test_execute", 
+	SCT_TEST, 
+	0, 0, FALSE, FALSE,
+	NULL, NULL, NULL,
+	tst_test_execute_generate, 
+	NULL 
+};
+
+/* 
+ * Operation 
+ */
+
+static int tst_test_execute_operation_execute
+	(const struct sieve_operation *op, 
+		const struct sieve_runtime_env *renv, sieve_size_t *address);
+
+const struct sieve_operation test_execute_operation = { 
+	"TEST_EXECUTE",
+	&testsuite_extension, 
+	TESTSUITE_OPERATION_TEST_EXECUTE,
+	NULL, 
+	tst_test_execute_operation_execute 
+};
+
+/* 
+ * Code generation 
+ */
+
+static bool tst_test_execute_generate
+(const struct sieve_codegen_env *cgenv, 
+	struct sieve_command_context *tst ATTR_UNUSED)
+{
+	sieve_operation_emit_code(cgenv->sbin, &test_execute_operation);
+
+	return TRUE;
+}
+
+/*
+ * Intepretation
+ */
+
+static int tst_test_execute_operation_execute
+(const struct sieve_operation *op ATTR_UNUSED,
+	const struct sieve_runtime_env *renv, 
+	sieve_size_t *address ATTR_UNUSED)
+{
+	bool result = TRUE;
+
+	/*
+	 * Perform operation
+	 */
+
+	result = testsuite_script_execute(renv);
+
+	/* Set result */
+	sieve_interpreter_set_test_result(renv->interp, result);
+
+	return SIEVE_EXEC_OK;
+}
+
+
+
+
diff --git a/sieve/errors/action-conflicts.sieve b/tests/execute/errors/action-conflicts.sieve
similarity index 61%
rename from sieve/errors/action-conflicts.sieve
rename to tests/execute/errors/action-conflicts.sieve
index 03949471d5016f02e4270d07864f76fe7486e230..082bdf780f6fad9641ac1d1c5d79059a730832a9 100644
--- a/sieve/errors/action-conflicts.sieve
+++ b/tests/execute/errors/action-conflicts.sieve
@@ -1,8 +1,5 @@
-require "fileinto";
 require "reject";
 require "vacation";
 
-#fileinto "frop";
 reject "No nonsense in my mailbox.";
 vacation "I am gone for a while.";
-redirect "stephan@example.com";
diff --git a/sieve/errors/action-duplicates.sieve b/tests/execute/errors/action-duplicates.sieve
similarity index 100%
rename from sieve/errors/action-duplicates.sieve
rename to tests/execute/errors/action-duplicates.sieve