diff --git a/.hgignore b/.hgignore
index bdfb8af23c419e3069bb90782ce0e35eaa3ae7a0..ead9aba20440a0422f29b69bd7ad693185f9144f 100644
--- a/.hgignore
+++ b/.hgignore
@@ -1,7 +1,6 @@
 syntax: glob
 aclocal.m4
 autom4te.cache
-compile
 config.cache
 config.guess
 dsieve-config.h
diff --git a/src/lib-sieve/sieve-script.c b/src/lib-sieve/sieve-script.c
index 77716302478197a679621ed51a24c51296478308..6c676193634dcd94f115f043fb308239660f456e 100644
--- a/src/lib-sieve/sieve-script.c
+++ b/src/lib-sieve/sieve-script.c
@@ -244,6 +244,11 @@ const char *sieve_script_path(struct sieve_script *script)
 	return script->path;
 }
 
+const char *sieve_script_dirpath(struct sieve_script *script)
+{
+	return script->dirpath;
+}
+
 const char *sieve_script_binpath(struct sieve_script *script)
 {
 	return t_strconcat(script->dirpath, "/", script->basename, ".svbin", NULL);
diff --git a/src/lib-sieve/sieve-script.h b/src/lib-sieve/sieve-script.h
index 548e9bc6100c362edd8a254242cd914ee53d0c8b..8747f9bcb2485e8780ec30d21c25f23f0355cada 100644
--- a/src/lib-sieve/sieve-script.h
+++ b/src/lib-sieve/sieve-script.h
@@ -34,5 +34,6 @@ const char *sieve_script_name(struct sieve_script *script);
 const char *sieve_script_filename(struct sieve_script *script);
 const char *sieve_script_path(struct sieve_script *script);
 const char *sieve_script_binpath(struct sieve_script *script);
+const char *sieve_script_dirpath(struct sieve_script *script);
 
 #endif /* __SIEVE_SCRIPT_H */
diff --git a/src/testsuite/Makefile.am b/src/testsuite/Makefile.am
index 945b9b7b575b899904ed6632a365567c2c24763d..a25a30c02e3b65748bf6e1ef4a1e30ccb9b7334c 100644
--- a/src/testsuite/Makefile.am
+++ b/src/testsuite/Makefile.am
@@ -37,17 +37,21 @@ ldadd = \
 testsuite_LDADD = $(ldadd)
 testsuite_DEPENDENCIES = $(libs)
 
-cmds = \
+commands = \
 	cmd-test.c \
 	cmd-test-fail.c \
 	cmd-test-set.c
 
+tests = \
+	tst-test-compile.c
+
 testsuite_SOURCES = \
 	namespaces.c \
 	mail-raw.c \
 	testsuite-common.c \
 	testsuite-objects.c \
-	$(cmds) \
+	$(commands) \
+	$(tests) \
 	ext-testsuite.c \
 	testsuite.c
 
@@ -70,7 +74,9 @@ test_cases = \
 	tests/match-types/contains.svtest \
 	tests/match-types/matches.svtest \
 	tests/address-parts/subaddress.svtest \
-	tests/extensions/variables/basic.svtest
+	tests/extensions/variables/basic.svtest \
+	tests/compile/compile.svtest \
+	tests/compile/compile-examples.svtest
 
 $(test_cases): 
 	@$(TESTSUITE_BIN) $@
diff --git a/src/testsuite/cmd-test-fail.c b/src/testsuite/cmd-test-fail.c
index f3a9994cb1e4d24b6c3476887306dbbe86a0e5a2..9106a56985e96c150d98bbbba7a03e487cd3e67a 100644
--- a/src/testsuite/cmd-test-fail.c
+++ b/src/testsuite/cmd-test-fail.c
@@ -9,25 +9,18 @@
 
 #include "testsuite-common.h"
 
-/* Predeclarations */
-
-static bool cmd_test_fail_operation_dump
-	(const struct sieve_operation *op,
-		const struct sieve_dumptime_env *denv, sieve_size_t *address);
-static bool cmd_test_fail_operation_execute
-	(const struct sieve_operation *op, 
-		const struct sieve_runtime_env *renv, sieve_size_t *address);
+/* 
+ * Test_fail command
+ *
+ * Syntax:   
+ *   test <reason: string>
+ */
 
 static bool cmd_test_fail_validate
 	(struct sieve_validator *validator, struct sieve_command_context *cmd);
 static bool cmd_test_fail_generate
 	(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
 
-/* Test_fail command
- *
- * Syntax:   
- *   test <reason: string>
- */
 const struct sieve_command cmd_test_fail = { 
 	"test_fail", 
 	SCT_COMMAND, 
@@ -38,7 +31,16 @@ const struct sieve_command cmd_test_fail = {
 	NULL 
 };
 
-/* Test operation */
+/* 
+ * Test operation 
+ */
+
+static bool cmd_test_fail_operation_dump
+	(const struct sieve_operation *op,
+		const struct sieve_dumptime_env *denv, sieve_size_t *address);
+static bool cmd_test_fail_operation_execute
+	(const struct sieve_operation *op, 
+		const struct sieve_runtime_env *renv, sieve_size_t *address);
 
 const struct sieve_operation test_fail_operation = { 
 	"TEST_FAIL",
@@ -48,7 +50,9 @@ const struct sieve_operation test_fail_operation = {
 	cmd_test_fail_operation_execute 
 };
 
-/* Validation */
+/* 
+ * Validation 
+ */
 
 static bool cmd_test_fail_validate
 (struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *cmd) 
@@ -63,7 +67,9 @@ static bool cmd_test_fail_validate
 	return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE);
 }
 
-/* Code generation */
+/* 
+ * Code generation 
+ */
 
 static inline struct testsuite_generator_context *
 	_get_generator_context(struct sieve_generator *gentr)
@@ -99,7 +105,7 @@ static bool cmd_test_fail_operation_dump
 	const struct sieve_dumptime_env *denv, sieve_size_t *address)
 {
 	unsigned int pc;
-  int offset;
+	int offset;
     
 	sieve_code_dumpf(denv, "TEST_FAIL:");
 	sieve_code_descend(denv);
@@ -127,18 +133,12 @@ static bool cmd_test_fail_operation_execute
 {
 	string_t *reason;
 
-	t_push();
-
-	if ( !sieve_opr_string_read(renv, address, &reason) ) {
-		t_pop();
+	if ( !sieve_opr_string_read(renv, address, &reason) ) 
 		return FALSE;
-	}
 
 	sieve_runtime_trace(renv, "TEST FAIL");
 	testsuite_test_fail(reason);
 	
-	t_pop();
-	
 	return sieve_interpreter_program_jump(renv->interp, TRUE);
 }
 
diff --git a/src/testsuite/cmd-test-set.c b/src/testsuite/cmd-test-set.c
index d6ffcd22c0688c3b0b865c2bab1faa8f48899b73..2381680fd7f01003c49d30ddd16b427e9910ceba 100644
--- a/src/testsuite/cmd-test-set.c
+++ b/src/testsuite/cmd-test-set.c
@@ -19,26 +19,18 @@
 
 #include <stdio.h>
 
-/* Forward declarations */
-
-static bool cmd_test_set_operation_dump
-	(const struct sieve_operation *op,
-		const struct sieve_dumptime_env *denv, sieve_size_t *address);
-static bool cmd_test_set_operation_execute
-	(const struct sieve_operation *op, 
-		const struct sieve_runtime_env *renv, sieve_size_t *address);
+/* 
+ * Test_set command 
+ * 
+ * Syntax
+ *   redirect <address: string>
+ */
 
 static bool cmd_test_set_validate
 	(struct sieve_validator *validator, struct sieve_command_context *cmd);
 static bool cmd_test_set_generate
 	(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
 
-/* Test_set command 
- * 
- * Syntax
- *   redirect <address: string>
- */
-
 const struct sieve_command cmd_test_set = { 
 	"test_set", 
 	SCT_COMMAND,
@@ -49,7 +41,16 @@ const struct sieve_command cmd_test_set = {
 	NULL 
 };
 
-/* Test_set operation */
+/* 
+ * Test_set operation 
+ */
+
+static bool cmd_test_set_operation_dump
+	(const struct sieve_operation *op,
+		const struct sieve_dumptime_env *denv, sieve_size_t *address);
+static bool cmd_test_set_operation_execute
+	(const struct sieve_operation *op, 
+		const struct sieve_runtime_env *renv, sieve_size_t *address);
 
 const struct sieve_operation test_set_operation = { 
 	"TEST_SET",
@@ -93,15 +94,12 @@ static bool cmd_test_set_validate
  */
  
 static bool cmd_test_set_generate
-	(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) 
 {
 	sieve_operation_emit_code(cgenv->sbin, &test_set_operation);
 
 	/* Generate arguments */
-	if ( !sieve_generate_arguments(cgenv, ctx, NULL) )
-		return FALSE;
-	
-	return TRUE;
+	return sieve_generate_arguments(cgenv, ctx, NULL);
 }
 
 /* 
@@ -132,31 +130,20 @@ static bool cmd_test_set_operation_execute
 	string_t *value;
 	int member_id;
 
-	t_push();
-	
 	if ( (object=testsuite_object_read_member(renv->sbin, address, &member_id)) 
-		== NULL ) {
-		t_pop();
+		== NULL )
 		return FALSE;
-	}
 
-	if ( !sieve_opr_string_read(renv, address, &value) ) {
-		t_pop();
+	if ( !sieve_opr_string_read(renv, address, &value) )
 		return FALSE;
-	}
 
 	sieve_runtime_trace(renv, "TEST SET command (%s = \"%s\")", 
 		testsuite_object_member_name(object, member_id), str_c(value));
 	
-	if ( object->set_member == NULL ) {
-		t_pop();
+	if ( object->set_member == NULL )
 		return FALSE;
-	}
 		
-	object->set_member(member_id, value);
-	
-	t_pop();
-	
+	object->set_member(member_id, value);	
 	return TRUE;
 }
 
diff --git a/src/testsuite/cmd-test.c b/src/testsuite/cmd-test.c
index 078c1535468f8ca5a8b840d8e3ca4518c173bc2f..b505f502abce0ce38da757b2a6772b547d1c98ae 100644
--- a/src/testsuite/cmd-test.c
+++ b/src/testsuite/cmd-test.c
@@ -9,28 +9,18 @@
 
 #include "testsuite-common.h"
 
-/* Predeclarations */
-
-static bool cmd_test_operation_dump
-	(const struct sieve_operation *op,
-		const struct sieve_dumptime_env *denv, sieve_size_t *address);
-static bool cmd_test_operation_execute
-	(const struct sieve_operation *op, 
-		const struct sieve_runtime_env *renv, sieve_size_t *address);
-static bool cmd_test_finish_operation_execute
-	(const struct sieve_operation *op, 
-		const struct sieve_runtime_env *renv, sieve_size_t *address);
+/*
+ * Test command
+ *
+ * Syntax:   
+ *   test <test-name: string> <block>
+ */
 
 static bool cmd_test_validate
 	(struct sieve_validator *validator, struct sieve_command_context *cmd);
 static bool cmd_test_generate
 	(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
 
-/* Test command
- *
- * Syntax:   
- *   test <test-name: string> <block>
- */
 const struct sieve_command cmd_test = { 
 	"test", 
 	SCT_COMMAND, 
@@ -41,8 +31,19 @@ const struct sieve_command cmd_test = {
 	NULL 
 };
 
+/* 
+ * Test operations 
+ */
+
 /* Test operation */
 
+static bool cmd_test_operation_dump
+	(const struct sieve_operation *op,
+		const struct sieve_dumptime_env *denv, sieve_size_t *address);
+static bool cmd_test_operation_execute
+	(const struct sieve_operation *op, 
+		const struct sieve_runtime_env *renv, sieve_size_t *address);
+
 const struct sieve_operation test_operation = { 
 	"TEST",
 	&testsuite_extension, 
@@ -51,6 +52,12 @@ const struct sieve_operation test_operation = {
 	cmd_test_operation_execute 
 };
 
+/* Test_finish operation */
+
+static bool cmd_test_finish_operation_execute
+	(const struct sieve_operation *op, 
+		const struct sieve_runtime_env *renv, sieve_size_t *address);
+
 const struct sieve_operation test_finish_operation = { 
 	"TEST-FINISH",
 	&testsuite_extension, 
@@ -59,7 +66,9 @@ const struct sieve_operation test_finish_operation = {
 	cmd_test_finish_operation_execute 
 };
 
-/* Validation */
+/* 
+ * Validation 
+ */
 
 static bool cmd_test_validate
 (struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *cmd) 
@@ -82,7 +91,9 @@ static bool cmd_test_validate
 	return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE);
 }
 
-/* Code generation */
+/* 
+ * Code generation 
+ */
 
 static inline struct testsuite_generator_context *
 	_get_generator_context(struct sieve_generator *gentr)
@@ -142,19 +153,12 @@ static bool cmd_test_operation_execute
 {
 	string_t *test_name;
 
-	t_push();
-
-	if ( !sieve_opr_string_read(renv, address, &test_name) ) {
-		t_pop();
+	if ( !sieve_opr_string_read(renv, address, &test_name) )
 		return FALSE;
-	}
 	
-	testsuite_test_start(test_name);
-
 	sieve_runtime_trace(renv, "TEST \"%s\"", str_c(test_name));
-	
-	t_pop();
-	
+
+	testsuite_test_start(test_name);
 	return TRUE;
 }
 
@@ -166,7 +170,6 @@ static bool cmd_test_finish_operation_execute
 	sieve_runtime_trace(renv, "TEST FINISHED");
 	
 	testsuite_test_succeed(NULL);
-	
 	return TRUE;
 }
 
diff --git a/src/testsuite/ext-testsuite.c b/src/testsuite/ext-testsuite.c
index 2d493b3debc53d894587adad71d71e59b6ea08c5..7b4389e52c74c1fc18f1db592c85cfd939d85765 100644
--- a/src/testsuite/ext-testsuite.c
+++ b/src/testsuite/ext-testsuite.c
@@ -39,13 +39,18 @@ extern const struct sieve_command cmd_test;
 extern const struct sieve_command cmd_test_fail;
 extern const struct sieve_command cmd_test_set;
 
+/* Tests */
+
+extern const struct sieve_command tst_test_compile;
+
 /* Operations */
 
 const struct sieve_operation *testsuite_operations[] = { 
 	&test_operation, 
 	&test_finish_operation,
 	&test_fail_operation, 
-	&test_set_operation 
+	&test_set_operation,
+	&test_compile_operation
 };
 
 /* Operands */
@@ -84,6 +89,8 @@ static bool ext_testsuite_validator_load(struct sieve_validator *valdtr)
 	sieve_validator_register_command(valdtr, &cmd_test);
 	sieve_validator_register_command(valdtr, &cmd_test_fail);
 	sieve_validator_register_command(valdtr, &cmd_test_set);
+
+	sieve_validator_register_command(valdtr, &tst_test_compile);
 	
 	return testsuite_validator_context_initialize(valdtr);
 }
diff --git a/src/testsuite/tests/compile/compile-examples.svtest b/src/testsuite/tests/compile/compile-examples.svtest
new file mode 100644
index 0000000000000000000000000000000000000000..b1161e47498d91f4ad16dfbde5a4f58d45751a6e
--- /dev/null
+++ b/src/testsuite/tests/compile/compile-examples.svtest
@@ -0,0 +1,51 @@
+require "vnd.dovecot.testsuite";
+
+# Compile all example scripts
+
+test "Elvey example" {
+	if not test_compile "../../../../sieve/examples/elvey.sieve" {
+		test_fail "could not compile";
+	}
+}
+
+test "M. Johnson example" {
+	if not test_compile "../../../../sieve/examples/mjohnson.sieve" {
+		test_fail "could not compile";
+	}
+}
+
+test "RFC 3028 example" {
+	if not test_compile "../../../../sieve/examples/rfc3028.sieve" {
+		test_fail "could not compile";
+	}
+}
+
+test "Sieve examples" {
+	if not test_compile "../../../../sieve/examples/sieve_examples.sieve" {
+		test_fail "could not compile";
+	}
+}
+
+test "Vivil example" {
+	if not test_compile "../../../../sieve/examples/vivil.sieve" {
+		test_fail "could not compile";
+	}
+}
+
+test "Jerry example" {
+	if not test_compile "../../../../sieve/examples/jerry.sieve" {
+		test_fail "could not compile";
+	}
+}
+
+test "M. Klose example" {
+	if not test_compile "../../../../sieve/examples/mklose.sieve" {
+		test_fail "could not compile";
+	}
+}
+
+test "Sanjay example" {
+	if not test_compile "../../../../sieve/examples/sanjay.sieve" {
+		test_fail "could not compile";
+	}
+}
diff --git a/src/testsuite/tests/compile/compile.svtest b/src/testsuite/tests/compile/compile.svtest
new file mode 100644
index 0000000000000000000000000000000000000000..5a54d6b558b985dd25a89f211cdfdb42479e5aeb
--- /dev/null
+++ b/src/testsuite/tests/compile/compile.svtest
@@ -0,0 +1,16 @@
+require "vnd.dovecot.testsuite";
+
+# Just test whether valid scripts will compile without problems
+
+test "Trivial" {
+	if not test_compile "trivial.sieve" {
+		test_fail "could not compile";
+	}
+}
+
+test "Redirect" {
+	if not test_compile "redirect.sieve" {
+		test_fail "could not compile";
+	}
+}
+
diff --git a/src/testsuite/tests/compile/redirect.sieve b/src/testsuite/tests/compile/redirect.sieve
new file mode 100644
index 0000000000000000000000000000000000000000..890855202e8c4730f005a1d04103bf49fff3a8e6
--- /dev/null
+++ b/src/testsuite/tests/compile/redirect.sieve
@@ -0,0 +1,23 @@
+# Test various white space occurences
+redirect "stephan@rename-it.nl";
+redirect " stephan@rename-it.nl";
+redirect "stephan @rename-it.nl";
+redirect "stephan@ rename-it.nl";
+redirect "stephan@rename-it.nl ";
+redirect " stephan @ rename-it.nl ";
+redirect "Stephan Bosch<stephan@rename-it.nl>";
+redirect " Stephan Bosch<stephan@rename-it.nl>";
+redirect "Stephan Bosch <stephan@rename-it.nl>";
+redirect "Stephan Bosch< stephan@rename-it.nl>";
+redirect "Stephan Bosch<stephan @rename-it.nl>";
+redirect "Stephan Bosch<stephan@ rename-it.nl>";
+redirect "Stephan Bosch<stephan@rename-it.nl >";
+redirect "Stephan Bosch<stephan@rename-it.nl> ";
+redirect "  Stephan Bosch  <  stephan  @  rename-it.nl  > ";
+
+# Test address syntax
+redirect "\"Stephan Bosch\"@rename-it.nl";
+redirect "Stephan.Bosch@rename-it.nl";
+redirect "Stephan.Bosch@ReNaMe-It.Nl";
+redirect "Stephan Bosch <stephan@rename-it.nl>";
+
diff --git a/src/testsuite/tests/compile/trivial.sieve b/src/testsuite/tests/compile/trivial.sieve
new file mode 100644
index 0000000000000000000000000000000000000000..1bb76a9cc364969c8067e5eee528f616edd49109
--- /dev/null
+++ b/src/testsuite/tests/compile/trivial.sieve
@@ -0,0 +1,3 @@
+keep;
+discard;
+stop;
diff --git a/src/testsuite/testsuite-common.h b/src/testsuite/testsuite-common.h
index 761b4e5566c0cafe3c451417504ddc2932fffc77..54aea4f94fa41a9aa5d306d113b4947b46b0fd9d 100644
--- a/src/testsuite/testsuite-common.h
+++ b/src/testsuite/testsuite-common.h
@@ -42,13 +42,15 @@ enum testsuite_operation_code {
 	TESTSUITE_OPERATION_TEST,
 	TESTSUITE_OPERATION_TEST_FINISH,
 	TESTSUITE_OPERATION_TEST_FAIL,
-	TESTSUITE_OPERATION_TEST_SET
+	TESTSUITE_OPERATION_TEST_SET,
+	TESTSUITE_OPERATION_TEST_COMPILE
 };
 
 extern const struct sieve_operation test_operation;
 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;
 
 /* Testsuite operands */
 
diff --git a/src/testsuite/tst-test-compile.c b/src/testsuite/tst-test-compile.c
new file mode 100644
index 0000000000000000000000000000000000000000..90f0a87e4c33684870452bb36b89c79f2015b83b
--- /dev/null
+++ b/src/testsuite/tst-test-compile.c
@@ -0,0 +1,152 @@
+#include "sieve-common.h"
+#include "sieve-script.h"
+#include "sieve-commands.h"
+#include "sieve-commands-private.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_compile command
+ *
+ * Syntax:   
+ *   test <reason: string>
+ */
+
+static bool tst_test_compile_validate
+	(struct sieve_validator *validator, struct sieve_command_context *cmd);
+static bool tst_test_compile_generate
+	(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx);
+
+const struct sieve_command tst_test_compile = { 
+	"test_compile", 
+	SCT_TEST, 
+	1, 0, FALSE, FALSE,
+	NULL, NULL,
+	tst_test_compile_validate, 
+	tst_test_compile_generate, 
+	NULL 
+};
+
+/* Test_compile operation */
+
+static bool tst_test_compile_operation_dump
+	(const struct sieve_operation *op,
+		const struct sieve_dumptime_env *denv, sieve_size_t *address);
+static bool tst_test_compile_operation_execute
+	(const struct sieve_operation *op, 
+		const struct sieve_runtime_env *renv, sieve_size_t *address);
+
+const struct sieve_operation test_compile_operation = { 
+	"TEST_COMPILE",
+	&testsuite_extension, 
+	TESTSUITE_OPERATION_TEST_COMPILE,
+	tst_test_compile_operation_dump, 
+	tst_test_compile_operation_execute 
+};
+
+/* Validation */
+
+static bool tst_test_compile_validate
+(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *tst) 
+{
+	struct sieve_ast_argument *arg = tst->first_positional;
+	
+	if ( !sieve_validate_positional_argument
+		(valdtr, tst, arg, "script", 1, SAAT_STRING) ) {
+		return FALSE;
+	}
+	
+	return sieve_validator_argument_activate(valdtr, tst, arg, FALSE);
+}
+
+/* Code generation */
+
+static inline struct testsuite_generator_context *
+	_get_generator_context(struct sieve_generator *gentr)
+{
+	return (struct testsuite_generator_context *) 
+		sieve_generator_extension_get_context(gentr, &testsuite_extension);
+}
+
+static bool tst_test_compile_generate
+(const struct sieve_codegen_env *cgenv, struct sieve_command_context *tst)
+{
+	sieve_operation_emit_code(cgenv->sbin, &test_compile_operation);
+
+	/* Generate arguments */
+	return sieve_generate_arguments(cgenv, tst, NULL);
+}
+
+/* 
+ * Code dump
+ */
+ 
+static bool tst_test_compile_operation_dump
+(const struct sieve_operation *op ATTR_UNUSED,
+	const struct sieve_dumptime_env *denv, sieve_size_t *address)
+{
+	sieve_code_dumpf(denv, "TEST_COMPILE:");
+	sieve_code_descend(denv);
+
+	if ( !sieve_opr_string_dump(denv, address) ) 
+		return FALSE;
+
+	return TRUE;
+}
+
+/*
+ * Intepretation
+ */
+
+static bool tst_test_compile_operation_execute
+(const struct sieve_operation *op ATTR_UNUSED,
+	const struct sieve_runtime_env *renv, sieve_size_t *address)
+{
+	struct sieve_error_handler *ehandler;
+    struct sieve_binary *sbin;
+
+	string_t *script_name;
+	const char *script_path;
+	bool result = TRUE;
+
+	if ( !sieve_opr_string_read(renv, address, &script_name) )
+		return FALSE;
+
+	sieve_runtime_trace(renv, "TEST COMPILE: %s", str_c(script_name));
+
+	script_path = sieve_script_dirpath(renv->script);
+	if ( script_path == NULL ) 
+		return FALSE;
+
+	script_path = t_strconcat(script_path, "/", str_c(script_name), NULL);
+
+	/* Attempt script compile */
+
+	ehandler = sieve_stderr_ehandler_create(0);
+    sieve_error_handler_accept_infolog(ehandler, TRUE);
+
+    if ( (sbin = sieve_compile(script_path, ehandler)) == NULL ) {
+        sieve_error_handler_unref(&ehandler);
+		result = FALSE;
+    } else {
+		sieve_close(&sbin);
+	}
+
+    sieve_error_handler_unref(&ehandler);
+
+	/* Set result */
+	sieve_interpreter_set_test_result(renv->interp, result);
+
+	return TRUE;
+}
+
+
+
+