diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c
index b8c59a86c3e1abb9042abb29df9a29e803a12c43..474b8a2961ba28d50c3af04727e681d0174933f9 100644
--- a/src/lib-sieve/sieve.c
+++ b/src/lib-sieve/sieve.c
@@ -29,6 +29,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <dirent.h>
 
 /* 
  * Main Sieve library interface
@@ -345,11 +346,15 @@ struct sieve_multiscript {
 	const struct sieve_message_data *msgdata;
 	const struct sieve_script_env *scriptenv;
 	struct sieve_error_handler *ehandler;
+
 	int status;
 	bool active;
+	bool ended;
+
+	struct ostream *teststream;
 };
  
-struct sieve_multiscript *sieve_multiscript_start
+struct sieve_multiscript *sieve_multiscript_start_execute
 (const struct sieve_message_data *msgdata, const struct sieve_script_env *senv,
 	struct sieve_error_handler *ehandler)
 {
@@ -373,40 +378,49 @@ struct sieve_multiscript *sieve_multiscript_start
 	return mscript;
 }
 
-bool sieve_multiscript_test
-(struct sieve_multiscript *mscript, struct sieve_binary *sbin, 
-	bool final, struct ostream *stream)
-{		
-	if ( !mscript->active ) return FALSE;
+struct sieve_multiscript *sieve_multiscript_start_test
+(const struct sieve_message_data *msgdata, const struct sieve_script_env *senv,
+	struct sieve_error_handler *ehandler, struct ostream *stream)
+{
+	struct sieve_multiscript *mscript = 
+		sieve_multiscript_start_execute(msgdata, senv, ehandler);
 	
-	if ( final )
-		sieve_result_set_keep_action(mscript->result, &act_store);
+	mscript->teststream = stream;
 
-	/* Run the script */
-	mscript->status = sieve_run(sbin, &mscript->result, mscript->msgdata, 
-		mscript->scriptenv, mscript->ehandler);
-				
-	/* Print result if successful */
-	if ( mscript->status > 0 ) {
-		bool keep = FALSE;
+	return mscript;
+}
+
+static void sieve_multiscript_test
+(struct sieve_multiscript *mscript)
+{						
+	bool keep = FALSE;
+
+	mscript->status = sieve_result_print
+		(mscript->result, mscript->scriptenv, mscript->teststream, &keep);
+		
+	mscript->active = ( mscript->active && keep );
 
-		mscript->status = sieve_result_print
-			(mscript->result, mscript->scriptenv, stream, &keep);
+	sieve_result_mark_executed(mscript->result);
+}
+
+static void sieve_multiscript_execute
+(struct sieve_multiscript *mscript)
+{
+	bool keep = FALSE;
 			
-		mscript->active = ( mscript->active && keep );
+	if ( mscript->status > 0 )
+		mscript->status = sieve_result_execute
+			(mscript->result, mscript->msgdata, mscript->scriptenv, &keep);
+	else {
+		if ( !sieve_result_implicit_keep
+			(mscript->result, mscript->msgdata, mscript->scriptenv) )
+			mscript->status = SIEVE_EXEC_KEEP_FAILED;
 	}
 	
-	if ( mscript->status <= 0 ) {
-		mscript->active = FALSE;
-		return FALSE;
-	}
-	
-	sieve_result_mark_executed(mscript->result);
-	
-	return mscript->active;
+	mscript->active = ( mscript->active && keep );
 }
 
-bool sieve_multiscript_execute
+bool sieve_multiscript_run
 (struct sieve_multiscript *mscript, struct sieve_binary *sbin,
 	bool final)
 {
@@ -414,43 +428,142 @@ bool sieve_multiscript_execute
 	
 	if ( final )
 		sieve_result_set_keep_action(mscript->result, &act_store);
-
+	
 	/* Run the script */
 	mscript->status = sieve_run(sbin, &mscript->result, mscript->msgdata, 
 		mscript->scriptenv, mscript->ehandler);
-		
+
 	if ( mscript->status >= 0 ) {
-		bool keep = FALSE;
-				
-		if ( mscript->status > 0 )
-			mscript->status = sieve_result_execute
-				(mscript->result, mscript->msgdata, mscript->scriptenv, &keep);
-		else {
-			if ( !sieve_result_implicit_keep
-				(mscript->result, mscript->msgdata, mscript->scriptenv) )
-				mscript->status = SIEVE_EXEC_KEEP_FAILED;
-		}
-		
-		mscript->active = ( mscript->active && keep );
-	}
+		if ( mscript->teststream != NULL ) 
+			sieve_multiscript_test(mscript);
+		else
+			sieve_multiscript_execute(mscript);
+
+		if ( final ) mscript->active = FALSE;
+	}	
 
-	if ( mscript->status <= 0 ) {
-		mscript->active = FALSE;
+	if ( mscript->status <= 0 )
 		return FALSE;
-	}
-	
+
 	return mscript->active;
 }
 
+int sieve_multiscript_status(struct sieve_multiscript *mscript)
+{
+	return mscript->status;
+}
+
 int sieve_multiscript_finish(struct sieve_multiscript **mscript)
 {
 	struct sieve_result *result = (*mscript)->result;
 	int ret = (*mscript)->status;
+
+	if ( (*mscript)->active ) {
+		ret = SIEVE_EXEC_FAILURE;
+
+		if ( (*mscript)->teststream ) {
+		} else {
+			if ( !sieve_result_implicit_keep
+				((*mscript)->result, (*mscript)->msgdata, (*mscript)->scriptenv) )
+				ret = SIEVE_EXEC_KEEP_FAILED;
+		}
+	}
 	
 	/* Cleanup */
 	sieve_result_unref(&result);
 	*mscript = NULL;
 	
 	return ret;
-}	
+}
+
+/*
+ * Script directory
+ */
+
+struct sieve_directory {
+		DIR *dirp;
+
+		const char *path;
+};
+
+struct sieve_directory *sieve_directory_open(const char *path)
+{ 
+	struct sieve_directory *sdir = NULL;
+	DIR *dirp;
+	struct stat st;
+
+	/* Specified path can either be a regular file or a directory */
+	if ( stat(path, &st) != 0 )
+		return NULL;
+
+	if ( S_ISDIR(st.st_mode) ) {
+	 	
+		/* Open the directory */
+		if ( (dirp = opendir(path)) == NULL ) {
+			sieve_sys_error("opendir(%s) failed: %m", path);
+			return NULL;		
+		}
+	
+		/* Create object */
+		sdir = t_new(struct sieve_directory, 1);
+		sdir->path = path;
+		sdir->dirp = dirp;
+	} else {
+		sdir = t_new(struct sieve_directory, 1);
+		sdir->path = path;
+		sdir->dirp = NULL;
+	}
+
+	return sdir;
+}
+
+const char *sieve_directory_get_scriptfile(struct sieve_directory *sdir)
+{
+	const char *script = NULL;
+	struct dirent *dp;
+	
+	if ( sdir->dirp != NULL ) {
+		while ( script == NULL ) {
+			const char *file;
+			struct stat st;
+
+			errno = 0;
+			if ( (dp = readdir(sdir->dirp)) == NULL ) {
+				if ( errno != 0 ) { 
+					sieve_sys_error("readdir(%s) failed: %m", sdir->path);
+					continue;
+				} else 
+					return NULL;
+			}
+
+			if ( !sieve_script_file_has_extension(dp->d_name) )
+				continue;
+
+			if ( sdir->path[strlen(sdir->path)-1] == '/' )
+				file = t_strconcat(sdir->path, dp->d_name, NULL);
+			else
+				file = t_strconcat(sdir->path, "/", dp->d_name, NULL);
+
+			if ( stat(file, &st) != 0 || !S_ISREG(st.st_mode) )
+				continue;
+
+			script = file;
+		}
+	} else {
+		script = sdir->path;
+		sdir->path = NULL;		
+	}
+							
+	return script;
+}
+
+void sieve_directory_close(struct sieve_directory **sdir)
+{
+	/* Close the directory */
+	if ( (*sdir)->dirp != NULL && closedir((*sdir)->dirp) < 0 ) 
+		sieve_sys_error("closedir(%s) failed: %m", (*sdir)->path);
+		
+	*sdir = NULL;
+}
+
 
diff --git a/src/lib-sieve/sieve.h b/src/lib-sieve/sieve.h
index 54fb1a80aeeb5db907797656516c197e7253844b..fa236e6a7e0136972093caf92847d37790519a54 100644
--- a/src/lib-sieve/sieve.h
+++ b/src/lib-sieve/sieve.h
@@ -120,17 +120,28 @@ int sieve_execute
  
 struct sieve_multiscript;
  
-struct sieve_multiscript *sieve_multiscript_start
+struct sieve_multiscript *sieve_multiscript_start_execute
 	(const struct sieve_message_data *msgdata, const struct sieve_script_env *senv,
 		struct sieve_error_handler *ehandler);
-		
-bool sieve_multiscript_test
-	(struct sieve_multiscript *mscript, struct sieve_binary *sbin, 
-		bool final, struct ostream *stream);
-bool sieve_multiscript_execute
-	(struct sieve_multiscript *mscript, struct sieve_binary *sbin,
-		bool final);
-	
+struct sieve_multiscript *sieve_multiscript_start_test
+	(const struct sieve_message_data *msgdata, const struct sieve_script_env *senv,
+		struct sieve_error_handler *ehandler, struct ostream *stream);
+
+bool sieve_multiscript_run
+	(struct sieve_multiscript *mscript, struct sieve_binary *sbin, bool final);
+
+int sieve_multiscript_status(struct sieve_multiscript *mscript);
+
 int sieve_multiscript_finish(struct sieve_multiscript **mscript);
 
+/*
+ * Script directory
+ */
+
+struct sieve_directory;
+
+struct sieve_directory *sieve_directory_open(const char *path);
+const char *sieve_directory_get_scriptfile(struct sieve_directory *sdir);
+void sieve_directory_close(struct sieve_directory **sdir);
+
 #endif
diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c
index 4055c23d80e8048a6f32c9caa40a2ec172f640a9..03cbc3e0d1038afe5c90d22bdd4ae9f55fb28393 100644
--- a/src/plugins/lda-sieve/lda-sieve-plugin.c
+++ b/src/plugins/lda-sieve/lda-sieve-plugin.c
@@ -2,16 +2,19 @@
  */
 
 #include "lib.h"
+#include "array.h"
 #include "home-expand.h"
 #include "deliver.h"
 #include "duplicate.h"
 #include "smtp-client.h"
+
 #include "sieve.h"
 
 #include "lda-sieve-plugin.h"
 
 #include <stdlib.h>
 #include <sys/stat.h>
+#include <dirent.h>
 
 /*
  * Configuration
@@ -27,6 +30,8 @@
 
 static deliver_mail_func_t *next_deliver_mail;
 
+static bool lda_sieve_debug = FALSE;
+
 /*
  * Mail transmission
  */
@@ -60,8 +65,8 @@ static const char *lda_sieve_get_path(void)
 	if (script_path != NULL) {
 		if (*script_path == '\0') {
 			/* disabled */
-			if (getenv("DEBUG") != NULL)
-                sieve_sys_info("empty script path, disabled");
+			if ( lda_sieve_debug )
+				sieve_sys_info("empty script path, disabled");
 			return NULL;
 		}
 
@@ -101,37 +106,22 @@ static const char *lda_sieve_get_path(void)
 	return script_path;
 }
 
-static int lda_sieve_run
-(struct mail_namespace *namespaces, struct mail *mail, const char *script_path,
-	const char *destaddr, const char *username, const char *mailbox,
-	struct mail_storage **storage_r)
+static int lda_sieve_open
+(const char *script_path, struct sieve_error_handler *ehandler, 
+	const char *scriptlog, struct sieve_binary **sbin)
 {
-	bool debug = ( getenv("DEBUG") != NULL );
-	struct sieve_message_data msgdata;
-	struct sieve_script_env scriptenv;
-	struct sieve_exec_status estatus;
-	struct sieve_error_handler *ehandler;
-	struct sieve_binary *sbin;
-	const char *scriptlog;
 	bool exists = TRUE;
 	int ret = 0;
 
-	*storage_r = NULL;
-
-	/* Create error handler */
-	scriptlog = t_strconcat(script_path, ".log", NULL);
-	ehandler = sieve_logfile_ehandler_create(scriptlog, LDA_SIEVE_MAX_ERRORS);
-
-	/* Open the script */
-
-	if ( debug )
+	if ( lda_sieve_debug )
 		sieve_sys_info("opening script %s", script_path);
 
-	if ( (sbin=sieve_open(script_path, "main script", ehandler, &exists)) == NULL ) {
+	if ( (*sbin=sieve_open(script_path, "main script", ehandler, &exists)) 
+		== NULL ) {
 
 		ret = sieve_get_errors(ehandler) > 0 ? -1 : 0;
 
-		if ( debug ) {
+		if ( lda_sieve_debug ) {
 			if ( !exists && ret == 0 ) 
 				sieve_sys_info
 					("script file %s is missing; reverting to default delivery", 
@@ -148,6 +138,261 @@ static int lda_sieve_run
 		return ret;
 	}
 
+	return 1;
+}
+
+static struct sieve_binary *lda_sieve_recompile
+(const char *script_path, struct sieve_error_handler *ehandler, 
+	const char *scriptlog)
+{
+	struct sieve_binary *sbin;
+
+	/* Warn */
+	sieve_sys_warning("encountered corrupt binary: recompiling script %s", 
+		script_path);
+
+	/* Recompile */	
+
+	sieve_error_handler_copy_masterlog(ehandler, FALSE);
+
+	if ( (sbin=sieve_compile(script_path, NULL, ehandler)) == NULL ) {
+		sieve_sys_error
+				("failed to compile script %s "
+					"(view logfile %s for more information); "
+					"reverting to default delivery", 
+					script_path, scriptlog);
+		sieve_error_handler_unref(&ehandler);
+		return NULL;
+	}
+
+	sieve_error_handler_copy_masterlog(ehandler, TRUE);
+
+	return sbin;
+}
+
+static int lda_sieve_handle_exec_status(const char *script_path, int status)
+{
+	int ret; 
+
+	switch ( status ) {
+	case SIEVE_EXEC_FAILURE:
+		sieve_sys_error
+			("execution of script %s failed, but implicit keep was successful", 
+				script_path);
+		ret = 1;
+		break;
+	case SIEVE_EXEC_BIN_CORRUPT:		
+		sieve_sys_error
+			("!!BUG!!: binary compiled from %s is still corrupt; "
+				"bailing out and reverting to default delivery", 
+				script_path);
+		ret = -1;
+		break;
+	case SIEVE_EXEC_KEEP_FAILED:
+		sieve_sys_error
+			("script %s failed with unsuccessful implicit keep", script_path);
+		ret = -1;
+		break;
+	default:
+		ret = status > 0 ? 1 : -1;
+		break;
+	}
+
+	return ret;
+}
+
+static int lda_sieve_singlescript_execute
+(const char *script_path, struct sieve_binary **sbin, 
+	const struct sieve_message_data *msgdata, const struct sieve_script_env *senv,
+	struct sieve_error_handler *ehandler, const char *scriptlog)
+{
+	int ret;
+
+	if ( lda_sieve_debug )
+		sieve_sys_info("executing compiled script %s", script_path);
+
+	/* Execute */
+
+	ret = sieve_execute(*sbin, msgdata, senv, ehandler);
+
+	/* Recompile corrupt binary */
+
+	if ( ret == SIEVE_EXEC_BIN_CORRUPT ) {
+		/* Close corrupt script */
+		sieve_close(sbin);
+
+		/* Recompile */
+		if ( (*sbin=lda_sieve_recompile(script_path, ehandler, scriptlog)) == NULL )
+			return -1;
+
+		/* Execute again */
+	
+		ret = sieve_execute(*sbin, msgdata, senv, ehandler);
+
+		/* Save new version */
+		
+		if ( ret != SIEVE_EXEC_BIN_CORRUPT )
+			sieve_save(*sbin, NULL);
+	}
+
+	/* Report status */
+
+	return lda_sieve_handle_exec_status(script_path, ret);
+}
+
+static int lda_sieve_multiscript_execute_script
+(struct sieve_multiscript *mscript, const char *script, bool final, 
+	struct sieve_error_handler *ehandler, const char *scriptlog)
+{
+	struct sieve_binary *sbin = NULL;
+	bool more = FALSE;
+
+	if ( lda_sieve_open(script, ehandler, scriptlog, &sbin) <= 0 )
+		return -1;
+
+	if ( !(more=sieve_multiscript_run(mscript, sbin, final)) ) {
+		if ( sieve_multiscript_status(mscript) == SIEVE_EXEC_BIN_CORRUPT ) {
+			/* Close corrupt script */
+			sieve_close(&sbin);
+
+			/* Recompile */
+
+			if ( (sbin=lda_sieve_recompile(script, ehandler, scriptlog)) == NULL )
+				return -1;
+
+			/* Execute again */
+
+			more = sieve_multiscript_run(mscript, sbin, final);
+
+			/* Save new version */
+	
+			if ( more && 
+				sieve_multiscript_status(mscript) != SIEVE_EXEC_BIN_CORRUPT )
+				sieve_save(sbin, NULL);
+		}
+	}
+
+	return (int) more;
+}
+
+static void lda_sieve_multiscript_get_scriptfiles
+(const char *script_path, ARRAY_TYPE(const_string) *scriptfiles)
+{
+	struct sieve_directory *sdir = sieve_directory_open(script_path);
+
+	if ( sdir != NULL ) {
+		const char *file;
+
+		while ( (file=sieve_directory_get_scriptfile(sdir)) != NULL ) {
+			array_append(scriptfiles, &file, 1);
+		}
+
+		sieve_directory_close(&sdir);
+	} 
+}
+
+static int lda_sieve_multiscript_execute_scripts
+(struct sieve_multiscript *mscript, ARRAY_TYPE(const_string) *scripts, 
+	bool final, struct sieve_error_handler *ehandler, const char *scriptlog)
+{
+	const char *const *scriptfiles;
+	unsigned int count, i;
+	int ret = 0;
+		 
+	scriptfiles = array_get(scripts, &count);
+	for ( i = 0; i < count; i++ ) {
+		if ( (ret=lda_sieve_multiscript_execute_script
+			(mscript, scriptfiles[i], ( final && i == count - 1 ), ehandler, 
+				scriptlog)) <= 0 )
+			return ret;
+	}
+
+	return 1;
+}
+
+static int lda_sieve_multiscript_execute
+(const char *script_path, struct sieve_binary **main_sbin,
+	ARRAY_TYPE (const_string) *scripts_before, 
+	ARRAY_TYPE (const_string) *scripts_after, 
+	const struct sieve_message_data *msgdata, const struct sieve_script_env *senv, 
+	struct sieve_error_handler *ehandler,const char *scriptlog)
+{
+	/* Multiple scripts */
+	struct sieve_multiscript *mscript = sieve_multiscript_start_execute
+		(msgdata, senv, ehandler);
+	int ret = 1; 
+
+	/* Execute scripts before main script */
+	ret = lda_sieve_multiscript_execute_scripts
+		(mscript, scripts_before, FALSE, ehandler, scriptlog);
+
+	/* Execute main script */
+	if ( ret > 0 ) {
+		bool final = ( array_count(scripts_after) == 0 );
+
+		if ( !(ret=sieve_multiscript_run(mscript, *main_sbin, final)) ) {
+
+			if ( sieve_multiscript_status(mscript) == SIEVE_EXEC_BIN_CORRUPT ) {
+				/* Close corrupt script */
+				sieve_close(main_sbin);
+
+				/* Recompile */
+				if ( (*main_sbin=lda_sieve_recompile(script_path, ehandler, scriptlog))
+					== NULL ) {
+					ret = -1;
+				} else {
+
+					/* Execute again */
+	
+					ret = sieve_multiscript_run(mscript, *main_sbin, final);
+
+					/* Save new version */
+		
+					if ( sieve_multiscript_status(mscript) != SIEVE_EXEC_BIN_CORRUPT )
+						sieve_save(*main_sbin, NULL);
+				}
+			}
+		}
+	}
+
+	/* Execute scripts after main script */
+	if ( ret > 0 )
+		ret = lda_sieve_multiscript_execute_scripts
+			(mscript, scripts_after, TRUE, ehandler, scriptlog); 
+
+	/* Finish execution */
+	ret = sieve_multiscript_finish(&mscript);
+
+	return lda_sieve_handle_exec_status(script_path, ret);
+}
+
+static int lda_sieve_run
+(struct mail_namespace *namespaces, struct mail *mail, const char *script_path,
+	const char *destaddr, const char *username, const char *mailbox,
+	struct mail_storage **storage_r)
+{
+	struct sieve_message_data msgdata;
+	struct sieve_script_env scriptenv;
+	struct sieve_exec_status estatus;
+	struct sieve_error_handler *ehandler;
+	struct sieve_binary *sbin = NULL;
+	const char *scriptlog, *sieve_before, *sieve_after;
+	ARRAY_TYPE (const_string) scripts_before;
+	ARRAY_TYPE (const_string) scripts_after;
+	int ret = 0;
+
+	*storage_r = NULL;
+
+	/* Create error handler */
+
+	scriptlog = t_strconcat(script_path, ".log", NULL);
+	ehandler = sieve_logfile_ehandler_create(scriptlog, LDA_SIEVE_MAX_ERRORS);
+
+	/* Open the script */
+
+	if ( (ret=lda_sieve_open(script_path, ehandler, scriptlog, &sbin)) <= 0 )
+		return ret;
+	
 	/* Log the messages to the system error handlers as well from this moment
 	 * on.
 	 */
@@ -176,85 +421,36 @@ static int lda_sieve_run
 	scriptenv.duplicate_check = duplicate_check;
 	scriptenv.exec_status = &estatus;
 
-	/* Execute the script */	
-	
-	if ( debug )
-		sieve_sys_info("executing compiled script %s", script_path);
-
-	ret = sieve_execute(sbin, &msgdata, &scriptenv, ehandler);
+	/* Check for multiscript */
 
-	/* Record status */
+	t_array_init(&scripts_after, 16);
+	t_array_init(&scripts_before, 16);
 
-	tried_default_save = estatus.tried_default_save;
-	*storage_r = estatus.last_storage;
+	sieve_before = getenv("SIEVE_BEFORE");
+	sieve_after = getenv("SIEVE_AFTER");
 
-	/* Evaluate result */
+	if ( sieve_before != NULL || *sieve_before != '\0' )
+		lda_sieve_multiscript_get_scriptfiles(sieve_before, &scripts_before);
 
-	if ( ret == SIEVE_EXEC_BIN_CORRUPT ) {
-		sieve_sys_warning("encountered corrupt binary: recompiling script %s", 
-			script_path);
+	if ( sieve_after != NULL || *sieve_after != '\0' )
+		lda_sieve_multiscript_get_scriptfiles(sieve_after, &scripts_after);
 
-		/* 
-		 * Try again; possibly author forgot to increase binary version number 
-		 */
+	if ( array_count(&scripts_before) == 0 && array_count(&scripts_after) == 0 )
+		ret = lda_sieve_singlescript_execute
+			(script_path, &sbin, &msgdata, &scriptenv, ehandler, scriptlog);
+	else
+		ret = lda_sieve_multiscript_execute
+			(script_path, &sbin, &scripts_before, &scripts_after, &msgdata, 
+				&scriptenv, ehandler, scriptlog);	
 
-		/* Close corrupt script */
-		sieve_close(&sbin);
-
-		/* Recompile */	
-	
-		sieve_error_handler_copy_masterlog(ehandler, FALSE);
-	
-		if ( (sbin=sieve_compile(script_path, NULL, ehandler)) == NULL ) {
-			sieve_sys_error
-					("failed to compile script %s "
-						"(view logfile %s for more information); "
-						"reverting to default delivery", 
-						script_path, scriptlog);
-			sieve_error_handler_unref(&ehandler);
-			return -1;
-		}
-
-		sieve_error_handler_copy_masterlog(ehandler, TRUE);
-
-		/* Execute again */
-	
-		ret = sieve_execute(sbin, &msgdata, &scriptenv, ehandler);
-
-		/* Record status */
-
-		tried_default_save = estatus.tried_default_save;
-		*storage_r = estatus.last_storage;
-
-		/* Save new version */
-		
-		if ( ret != SIEVE_EXEC_BIN_CORRUPT )
-			sieve_save(sbin, NULL);
-	}
+	/* Record status */
 
-	switch ( ret ) {
-	case SIEVE_EXEC_FAILURE:
-		sieve_sys_error
-			("execution of script %s failed, but implicit keep was successful", 
-				script_path);
-		ret = SIEVE_EXEC_OK;
-		break;
-	case SIEVE_EXEC_BIN_CORRUPT:		
-		sieve_sys_error
-			("!!BUG!!: binary compiled from %s is still corrupt; "
-				"bailing out and reverting to default delivery", 
-				script_path);
-		break;
-	case SIEVE_EXEC_KEEP_FAILED:
-		sieve_sys_error
-			("script %s failed with unsuccessful implicit keep", script_path);
-		break;
-	default:
-		break;
-	}
+	tried_default_save = estatus.tried_default_save;
+	*storage_r = estatus.last_storage;
 
 	/* Clean up */
-	sieve_close(&sbin);
+	if ( sbin != NULL )
+		sieve_close(&sbin);
 	sieve_error_handler_unref(&ehandler);
 
 	return ret;
@@ -271,14 +467,14 @@ static int lda_sieve_deliver_mail
 	
 	script_path = lda_sieve_get_path();
 	if (script_path == NULL) {
-		if (getenv("DEBUG") != NULL)
+		if ( lda_sieve_debug )
 			sieve_sys_info("no valid sieve script path specified: "
 				"reverting to default delivery.");
 
 		return 0;
 	}
 
-	if (getenv("DEBUG") != NULL)
+	if ( lda_sieve_debug )
 		sieve_sys_info("using sieve path: %s", script_path);
 
 	/* Run the script */
@@ -308,6 +504,9 @@ void sieve_plugin_init(void)
 		sieve_set_extensions(extensions);
 	}
 
+	/* Debug mode */
+	lda_sieve_debug = getenv("DEBUG");
+
 	/* Hook into the delivery process */
 	next_deliver_mail = deliver_mail;
 	deliver_mail = lda_sieve_deliver_mail;
diff --git a/src/sieve-tools/sieve-test.c b/src/sieve-tools/sieve-test.c
index e3fefff7ee8ca5d66f0578f3def4dc874d7b257d..b5a56c667cbe419a8fcc1c79d6d2d042354d5227 100644
--- a/src/sieve-tools/sieve-test.c
+++ b/src/sieve-tools/sieve-test.c
@@ -277,7 +277,7 @@ int main(int argc, char **argv)
 		sieve_error_handler_accept_infolog(ehandler, TRUE);
 
 		/* Run the test */
-	
+		ret = 1;
 		if ( array_count(&scriptfiles) == 0 ) {
 			/* Single script */
 			sbin = main_sbin;
@@ -292,13 +292,20 @@ int main(int argc, char **argv)
 			/* Multiple scripts */
 			const char *const *sfiles;
 			unsigned int i, count;
-			struct sieve_multiscript *mscript = sieve_multiscript_start
-				(&msgdata, &scriptenv, ehandler);
-			int result = 1; 
+			struct sieve_multiscript *mscript;
+			bool more = TRUE;
+			int result;
+
+			if ( execute )
+				mscript = sieve_multiscript_start_execute
+					(&msgdata, &scriptenv, ehandler);
+			else
+				mscript = sieve_multiscript_start_test
+					(&msgdata, &scriptenv, ehandler, teststream);
 		
 			/* Execute scripts sequentially */
 			sfiles = array_get(&scriptfiles, &count); 
-			for ( i = 0; i < count && result > 0; i++ ) {
+			for ( i = 0; i < count && more; i++ ) {
 				if ( teststream != NULL ) 
 					o_stream_send_str(teststream, 
 						t_strdup_printf("\n## Executing script: %s\n", sfiles[i]));
@@ -316,20 +323,16 @@ int main(int argc, char **argv)
 				}
 			
 				if ( sbin == NULL ) {
-					result = -1;
+					ret = SIEVE_EXEC_FAILURE;
 					break;
 				}
 			
 				/* Execute/Test script */
-				if ( execute )
-					result = sieve_multiscript_execute(mscript, sbin, FALSE);
-				else
-					result = sieve_multiscript_test(mscript, sbin, FALSE, teststream);
+				more = sieve_multiscript_run(mscript, sbin, FALSE);
 			}
 		
 			/* Execute/Test main script */
-			switch ( result )	{
-			case TRUE:
+			if ( more && ret > 0 ) {
 				if ( teststream != NULL ) 
 					o_stream_send_str(teststream, 
 						t_strdup_printf("## Executing script: %s\n", scriptfile));
@@ -341,18 +344,12 @@ int main(int argc, char **argv)
 				sbin = main_sbin;
 				main_sbin = NULL;
 			
-				if ( execute )
-					(void)sieve_multiscript_execute(mscript, sbin, TRUE);
-				else 
-					(void)sieve_multiscript_test(mscript, sbin, TRUE, teststream);
-				
-			case FALSE:	
-				ret = sieve_multiscript_finish(&mscript);
-				break;
-		
-			default:
-				ret = SIEVE_EXEC_FAILURE;
+				sieve_multiscript_run(mscript, sbin, TRUE);
 			}
+			
+			result = sieve_multiscript_finish(&mscript);
+			
+			ret = ret > 0 ? result : ret;
 		}
 	
 		/* Run */