diff --git a/doc/man/sieve-test.1 b/doc/man/sieve-test.1
index 4955f1d5ce6ed4132d6f17ea992191b5c6361f1c..a2de66c1ddcb49b29db1ab96d981148bfc00113c 100644
--- a/doc/man/sieve-test.1
+++ b/doc/man/sieve-test.1
@@ -2,8 +2,8 @@
 .SH NAME
 sieve-test \- Sieve script tester for the Dovecot secure IMAP server
 .SH SYNOPSIS
-sieve-test [\fB-r\fR \fIrecipient-address\fR] [\fB-s\fR \fIenvelope-sender\fR] [\fB-m\fR \fImailbox\fR] [\fB-d\fR \fIdump-file\fR] [\fB-c\fR] [\fB-t\fR]
-[\fB-x\fR "\fIextension extension ...\fR"] \fIscript-file\fR \fImail-file\fR
+sieve-test [\fB-r\fR \fIrecipient-address\fR] [\fB-f\fR \fIenvelope-sender\fR] [\fB-m\fR \fImailbox\fR] [\fB-d\fR \fIdump-file\fR] [\fB-c\fR] [\fB-t\fR] [\fB-x\fR "\fIextension extension ...\fR"] [\fB-s\fR \fIscript-file\fR]  
+\fIscript-file\fR \fImail-file\fR
 .SH DESCRIPTION
 .PP
 The \fBsieve-test\fP command is part of the Sieve implementation for the Dovecot secure 
@@ -27,7 +27,7 @@ the e-mail message to filter.
 The envelope recipient address. This is what Sieve's envelope test will compare to when the "to"
 envelope part is requested.
 .TP
-\fB-s\fP \fIenvelope-sender\fP
+\fB-f\fP \fIenvelope-sender\fP
 The envelope sender. This is what Sieve's envelope test will compare to when the "from" envelope
 part is requested.
 .TP
@@ -51,6 +51,11 @@ Enable simple trace debugging; prints all encountered byte code instructions on
 \fB-x\fP "\fIextension extension ...\fP"
 Set the available extensions. The parameter is a space-separated list of the active extensions. 
 Unknown extensions are ignored, but a warning is produced.
+.TP
+\fB-s\fP \fIscript-file\fP (not implemented)
+Specify additional scripts to be executed before the main script. Multiple \fB-s\fP arguments are
+allowed and the specified scripts are executed sequentially in the order specified at the command
+line.
 .SH AUTHOR
 .PP
 The Sieve implementation for Dovecot was written by Stephan Bosch <stephan@rename-it.nl>.
diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c
index 0c8398c4dfcb2654333d9be536bd167e5c453002..ca2b21b2c524772344b0d59dcf1cab307764de00 100644
--- a/src/lib-sieve/cmd-redirect.c
+++ b/src/lib-sieve/cmd-redirect.c
@@ -355,7 +355,7 @@ static bool act_redirect_commit
 			str_sanitize(ctx->to_address, 128));	
 
 		/* Indicate that message was successfully forwarded */
-		aenv->estatus->message_forwarded = TRUE;
+		aenv->exec_status->message_forwarded = TRUE;
 
 		/* Cancel implicit keep */
 		*keep = FALSE;
diff --git a/src/lib-sieve/plugins/imapflags/tag-flags.c b/src/lib-sieve/plugins/imapflags/tag-flags.c
index 01da24a36084d20724735418a6367e7bb617d10b..aa80745f8415e539f4e9f61d54efc362d431c26f 100644
--- a/src/lib-sieve/plugins/imapflags/tag-flags.c
+++ b/src/lib-sieve/plugins/imapflags/tag-flags.c
@@ -217,31 +217,31 @@ static struct seff_flags_context *seff_flags_get_implicit_context
 	ctx = p_new(pool, struct seff_flags_context, 1);
 	p_array_init(&ctx->keywords, pool, 2);
 	
-	t_push();
+	T_BEGIN {
 		
-	/* Unpack */
-	ext_imapflags_get_implicit_flags_init(&flit, result);
-	while ( (flag=ext_imapflags_iter_get_flag(&flit)) != NULL ) {		
-		if (flag != NULL && *flag != '\\') {
-			/* keyword */
-			const char *keyword = p_strdup(pool, flag);
-			array_append(&ctx->keywords, &keyword, 1);
-		} else {
-			/* system flag */
-			if (flag == NULL || strcasecmp(flag, "\\flagged") == 0)
-				ctx->flags |= MAIL_FLAGGED;
-			else if (strcasecmp(flag, "\\answered") == 0)
-				ctx->flags |= MAIL_ANSWERED;
-			else if (strcasecmp(flag, "\\deleted") == 0)
-				ctx->flags |= MAIL_DELETED;
-			else if (strcasecmp(flag, "\\seen") == 0)
-				ctx->flags |= MAIL_SEEN;
-			else if (strcasecmp(flag, "\\draft") == 0)
-				ctx->flags |= MAIL_DRAFT;
+		/* Unpack */
+		ext_imapflags_get_implicit_flags_init(&flit, result);
+		while ( (flag=ext_imapflags_iter_get_flag(&flit)) != NULL ) {		
+			if (flag != NULL && *flag != '\\') {
+				/* keyword */
+				const char *keyword = p_strdup(pool, flag);
+				array_append(&ctx->keywords, &keyword, 1);
+			} else {
+				/* system flag */
+				if (flag == NULL || strcasecmp(flag, "\\flagged") == 0)
+					ctx->flags |= MAIL_FLAGGED;
+				else if (strcasecmp(flag, "\\answered") == 0)
+					ctx->flags |= MAIL_ANSWERED;
+				else if (strcasecmp(flag, "\\deleted") == 0)
+					ctx->flags |= MAIL_DELETED;
+				else if (strcasecmp(flag, "\\seen") == 0)
+					ctx->flags |= MAIL_SEEN;
+				else if (strcasecmp(flag, "\\draft") == 0)
+					ctx->flags |= MAIL_DRAFT;
+			}
 		}
-	}
 
-	t_pop();
+	} T_END;
 	
 	return ctx;
 }
diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c
index 25f136dfd7f223f568797f462826cff41710aaf0..d9b65881bff429609e91209af62aa2acd4e130ed 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.c
+++ b/src/lib-sieve/plugins/include/ext-include-common.c
@@ -496,8 +496,7 @@ bool ext_include_execute_include
 		if ( result > 0 ) {
 			/* Create interpreter for top-level included script (first sub-interpreter) 
 			 */
-			subinterp = sieve_interpreter_create
-				(renv->sbin, ehandler, renv->trace_stream);
+			subinterp = sieve_interpreter_create(renv->sbin, ehandler);
 
 			if ( subinterp != NULL ) {			
 				curctx = ext_include_interpreter_context_init_child
@@ -506,7 +505,7 @@ bool ext_include_execute_include
 				/* Activate and start the top-level included script */
 				result = ( sieve_interpreter_start
 					(subinterp, renv->msgdata, renv->scriptenv, renv->msgctx, renv->result, 
-						renv->estatus, &interrupted) == 1 );
+						&interrupted) == 1 );
 			} else
 				result = SIEVE_EXEC_BIN_CORRUPT;
 		}
@@ -555,8 +554,7 @@ bool ext_include_execute_include
 						
 						if ( result > 0 ) {
 							/* Create sub-interpreter */
-							subinterp = sieve_interpreter_create
-								(renv->sbin, ehandler, renv->trace_stream);			
+							subinterp = sieve_interpreter_create(renv->sbin, ehandler);			
 
 							if ( subinterp != NULL ) {
 								curctx = ext_include_interpreter_context_init_child
@@ -567,7 +565,7 @@ bool ext_include_execute_include
 								curctx->returned = FALSE;
 								result = ( sieve_interpreter_start
 									(subinterp, renv->msgdata, renv->scriptenv, renv->msgctx,
-										renv->result, renv->estatus, &interrupted) == 1 );		 	
+										renv->result, &interrupted) == 1 );		 	
 							} else
 								result = SIEVE_EXEC_BIN_CORRUPT;
 						}
diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c
index 110678ebbe86cd06e62c188a34292cd40942ac4f..c544cb79352a97199f44ab8c22a95694b6343e6f 100644
--- a/src/lib-sieve/sieve-actions.c
+++ b/src/lib-sieve/sieve-actions.c
@@ -176,7 +176,7 @@ static void act_store_get_storage_error
 static struct mailbox *act_store_mailbox_open
 (const struct sieve_action_exec_env *aenv, struct mail_namespace *ns, const char *folder)
 {
-	struct mail_storage **storage = &(aenv->estatus->last_storage);
+	struct mail_storage **storage = &(aenv->exec_status->last_storage);
 	enum mailbox_open_flags open_flags = 
 		MAILBOX_OPEN_FAST | MAILBOX_OPEN_KEEP_RECENT | 
 		MAILBOX_OPEN_SAVEONLY | MAILBOX_OPEN_POST_SESSION;
@@ -288,12 +288,12 @@ static bool act_store_execute
 	/* Mark attempt to store in default mailbox */
 	if ( strcmp(trans->context->folder, 
 		SIEVE_SCRIPT_DEFAULT_MAILBOX(aenv->scriptenv)) == 0 ) 
-		aenv->estatus->tried_default_save = TRUE;
+		aenv->exec_status->tried_default_save = TRUE;
 
 	/* Mark attempt to use storage. Can only get here when all previous actions
 	 * succeeded. 
 	 */
-	aenv->estatus->last_storage = trans->namespace->storage;
+	aenv->exec_status->last_storage = trans->namespace->storage;
 	
 	/* Start mail transaction */
 	trans->mail_trans = mailbox_transaction_begin
@@ -388,7 +388,7 @@ static bool act_store_commit
 	/* Mark attempt to use storage. Can only get here when all previous actions
 	 * succeeded. 
 	 */
-	aenv->estatus->last_storage = trans->namespace->storage;
+	aenv->exec_status->last_storage = trans->namespace->storage;
 
 	/* Free mail object for stored message */
 	if ( trans->dest_mail != NULL ) 
@@ -399,7 +399,7 @@ static bool act_store_commit
 
 	/* Note the fact that the message was stored at least once */
 	if ( status )
-		aenv->estatus->message_saved = TRUE;
+		aenv->exec_status->message_saved = TRUE;
 	
 	/* Log our status */
 	act_store_log_status(trans, aenv, FALSE, status);
diff --git a/src/lib-sieve/sieve-actions.h b/src/lib-sieve/sieve-actions.h
index 47aca68e60031b01597ab4c5df89867fc1ab057c..65a3228b5996cdfad8eb75c4049977bcae076b2b 100644
--- a/src/lib-sieve/sieve-actions.h
+++ b/src/lib-sieve/sieve-actions.h
@@ -19,7 +19,7 @@ struct sieve_action_exec_env {
 	struct sieve_result *result;
 	const struct sieve_message_data *msgdata;
 	const struct sieve_script_env *scriptenv;
-	struct sieve_exec_status *estatus;
+	struct sieve_exec_status *exec_status;
 };
 
 const char *sieve_action_get_location(const struct sieve_action_exec_env *aenv);
diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c
index de524d20e0bdbe0c1a161dca5284ba1a50795481..8a580016e71af8fd0bcf1279c51e84cc7b0e871b 100644
--- a/src/lib-sieve/sieve-interpreter.c
+++ b/src/lib-sieve/sieve-interpreter.c
@@ -60,13 +60,12 @@ struct sieve_interpreter {
 	/* Start address of current operation */
 	sieve_size_t current_op_addr;             
 	
-	/* Runtime environment environment */
+	/* Runtime environment */
 	struct sieve_runtime_env runenv; 
 };
 
 struct sieve_interpreter *sieve_interpreter_create
-(struct sieve_binary *sbin, struct sieve_error_handler *ehandler,
-	struct ostream *trace_stream) 
+(struct sieve_binary *sbin, struct sieve_error_handler *ehandler) 
 {
 	unsigned int i, ext_count;
 	bool success = TRUE;
@@ -83,7 +82,6 @@ struct sieve_interpreter *sieve_interpreter_create
 
 	interp->runenv.interp = interp;	
 	interp->runenv.sbin = sbin;
-	interp->runenv.trace_stream = trace_stream;
 	interp->runenv.script = sieve_binary_script(sbin);
 	sieve_binary_ref(sbin);
 	
@@ -478,8 +476,7 @@ int sieve_interpreter_continue
 int sieve_interpreter_start
 (struct sieve_interpreter *interp, const struct sieve_message_data *msgdata,
 	const struct sieve_script_env *senv, struct sieve_message_context *msgctx, 
-	struct sieve_result *result, struct sieve_exec_status *estatus,
-	bool *interrupted) 
+	struct sieve_result *result, bool *interrupted) 
 {
 	const struct sieve_interpreter_extension_reg *extrs;
 	unsigned int ext_count, i;
@@ -487,7 +484,12 @@ int sieve_interpreter_start
 	interp->runenv.msgdata = msgdata;
 	interp->runenv.result = result;		
 	interp->runenv.scriptenv = senv;
-	interp->runenv.estatus = estatus;
+	interp->runenv.trace_stream = senv->trace_stream;
+
+	if ( senv->exec_status == NULL ) 
+		interp->runenv.exec_status = p_new(interp->pool, struct sieve_exec_status, 1);
+	else
+		interp->runenv.exec_status = senv->exec_status;
 	
 	if ( msgctx == NULL )
 		interp->runenv.msgctx = sieve_message_context_create();
@@ -508,36 +510,16 @@ int sieve_interpreter_start
 
 int sieve_interpreter_run
 (struct sieve_interpreter *interp, const struct sieve_message_data *msgdata,
-	const struct sieve_script_env *senv, struct sieve_result **result,
-	struct sieve_exec_status *estatus)
+	const struct sieve_script_env *senv, struct sieve_result *result)
 {
-	bool is_topmost = ( *result == NULL );
 	int ret = 0;
-
-	sieve_interpreter_reset(interp);
-
-	/* Reset execution status */
-    memset(estatus, 0, sizeof(*estatus));
 	
-	if ( is_topmost )
-		*result = sieve_result_create(interp->ehandler);
-	else {
-		sieve_result_ref(*result);
-	}
+	sieve_interpreter_reset(interp);
+	sieve_result_ref(result);
 	
-	ret = sieve_interpreter_start
-		(interp, msgdata, senv, NULL, *result, estatus, NULL);
-
-	if ( ret >= 0 && is_topmost ) {
-		if ( ret > 0 ) 
-			ret = sieve_result_execute(*result, msgdata, senv, estatus);
-		else {
-			if ( !sieve_result_implicit_keep(*result, msgdata, senv, estatus) )
-	            return SIEVE_EXEC_KEEP_FAILED;
-		}
-	}
+	ret = sieve_interpreter_start(interp, msgdata, senv, NULL, result, NULL);
 	
-	sieve_result_unref(result);
+	sieve_result_unref(&result);
 	
 	return ret;
 }
diff --git a/src/lib-sieve/sieve-interpreter.h b/src/lib-sieve/sieve-interpreter.h
index f677d9507d7c5c7d8aa247103fd663fb3437d0ca..c2d53b28ca959cd1c612dd1b59b9a210654342c1 100644
--- a/src/lib-sieve/sieve-interpreter.h
+++ b/src/lib-sieve/sieve-interpreter.h
@@ -32,9 +32,8 @@ struct sieve_runtime_env {
 
 	struct sieve_binary *sbin;
 	struct sieve_result *result;
-
-	struct sieve_exec_status *estatus;
-
+	
+	struct sieve_exec_status *exec_status;
 	struct ostream *trace_stream;
 };
 
@@ -43,8 +42,7 @@ struct sieve_runtime_env {
  */
 
 struct sieve_interpreter *sieve_interpreter_create
-	(struct sieve_binary *sbin, struct sieve_error_handler *ehandler,
-		struct ostream *trace_stream);
+	(struct sieve_binary *sbin, struct sieve_error_handler *ehandler);
 void sieve_interpreter_free(struct sieve_interpreter **interp);
 
 /*
@@ -162,11 +160,9 @@ int sieve_interpreter_continue
 int sieve_interpreter_start
 	(struct sieve_interpreter *interp, const struct sieve_message_data *msgdata,
 		const struct sieve_script_env *senv, struct sieve_message_context *msgctx, 
-		struct sieve_result *result, struct sieve_exec_status *estatus,
-		bool *interrupted);
+		struct sieve_result *result, bool *interrupted);
 int sieve_interpreter_run
 	(struct sieve_interpreter *interp, const struct sieve_message_data *msgdata,
-		const struct sieve_script_env *senv, struct sieve_result **result,
-		struct sieve_exec_status *estatus);
+		const struct sieve_script_env *senv, struct sieve_result *result);
 
 #endif /* __SIEVE_INTERPRETER_H */
diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c
index 7e2467c5815e43bcf989aefa1d25165fad97be5f..4f22c853aa60869ec723687e9e93e3b5eb3b62be 100644
--- a/src/lib-sieve/sieve-result.c
+++ b/src/lib-sieve/sieve-result.c
@@ -71,7 +71,6 @@ struct sieve_result {
 	struct sieve_action_exec_env action_env;
 	
 	const struct sieve_action *keep_action;
-	bool keep;
 
 	unsigned int action_count;
 	struct sieve_result_action *first_action;
@@ -101,7 +100,6 @@ struct sieve_result *sieve_result_create
 	result->action_env.result = result;
 		
 	result->keep_action = &act_store;
-	result->keep = FALSE;
 	
 	result->action_count = 0;
 	result->first_action = NULL;
@@ -179,7 +177,8 @@ void sieve_result_error
 	va_list args;
 	
 	va_start(args, fmt);	
-	sieve_verror(aenv->result->ehandler, sieve_action_get_location(aenv), fmt, args); 
+	sieve_verror(aenv->result->ehandler, sieve_action_get_location(aenv), fmt, 
+		args); 
 	va_end(args);
 }
 
@@ -189,7 +188,8 @@ void sieve_result_warning
 	va_list args;
 	
 	va_start(args, fmt);	
-	sieve_vwarning(aenv->result->ehandler, sieve_action_get_location(aenv), fmt, args); 
+	sieve_vwarning(aenv->result->ehandler, sieve_action_get_location(aenv), fmt, 
+		args); 
 	va_end(args);
 }
 
@@ -199,7 +199,8 @@ void sieve_result_log
 	va_list args;
 	
 	va_start(args, fmt);	
-	sieve_vinfo(aenv->result->ehandler, sieve_action_get_location(aenv), fmt, args); 
+	sieve_vinfo(aenv->result->ehandler, sieve_action_get_location(aenv), fmt, 
+		args); 
 	va_end(args);
 }
 
@@ -575,12 +576,16 @@ void sieve_result_seffect_printf
 
 bool sieve_result_print
 (struct sieve_result *result, const struct sieve_script_env *senv, 
-	struct ostream *stream)
+	struct ostream *stream, bool *keep)
 {
 	struct sieve_result_print_env penv;
 	bool implicit_keep = TRUE;
 	struct sieve_result_action *rac;
 	
+	if ( keep != NULL ) *keep = FALSE;
+	
+	/* Prepare environment */
+	
 	penv.result = result;
 	penv.stream = stream;
 	penv.scriptenv = senv;
@@ -588,14 +593,16 @@ bool sieve_result_print
 	sieve_result_printf(&penv, "\nPerformed actions:\n\n");
 	rac = result->first_action;
 	while ( rac != NULL ) {		
-		bool keep = TRUE;
+		bool impl_keep = TRUE;
 		struct sieve_result_side_effect *rsef;
 		const struct sieve_side_effect *sef;
 		const struct sieve_action *act = rac->data.action;
 
+		if ( rac->keep && keep != NULL ) *keep = TRUE;
+
 		if ( act != NULL ) {
 			if ( act->print != NULL )
-				act->print(act, &penv, rac->data.context, &keep);
+				act->print(act, &penv, rac->data.context, &impl_keep);
 			else
 				sieve_result_action_printf(&penv, act->name); 
 		} else {
@@ -612,14 +619,17 @@ bool sieve_result_print
 		while ( rsef != NULL ) {
 			sef = rsef->seffect;
 			if ( sef->print != NULL ) 
-				sef->print(sef, rac->data.action, &penv, rsef->context, &keep);
+				sef->print(sef, rac->data.action, &penv, rsef->context, &impl_keep);
 			rsef = rsef->next;
 		}
 			
-		implicit_keep = implicit_keep && keep;		
+		implicit_keep = implicit_keep && impl_keep;		
+		
 		rac = rac->next;	
 	}
 	
+	if ( implicit_keep && keep != NULL ) *keep = TRUE;
+	
 	sieve_result_printf
 		(&penv, "\nImplicit keep: %s\n", implicit_keep ? "yes" : "no");
 	
@@ -714,37 +724,59 @@ static bool _sieve_result_implicit_keep
 
 bool sieve_result_implicit_keep
 (struct sieve_result *result, const struct sieve_message_data *msgdata,
-	const struct sieve_script_env *senv, struct sieve_exec_status *estatus)
+	const struct sieve_script_env *senv)
 {
+	struct sieve_exec_status dummy_status;
+
 	result->action_env.msgdata = msgdata;
 	result->action_env.scriptenv = senv;
-	result->action_env.estatus = estatus;
+	result->action_env.exec_status = 
+		( senv->exec_status == NULL ? &dummy_status : senv->exec_status );
 
 	return _sieve_result_implicit_keep(result, TRUE);	
 }
 
+void sieve_result_mark_executed(struct sieve_result *result)
+{
+	struct sieve_result_action *first_action, *rac;
+	
+	first_action = ( result->last_attempted_action == NULL ?
+		result->first_action : result->last_attempted_action );
+	result->last_attempted_action = result->last_action;
+
+	rac = first_action;
+	while ( rac != NULL ) {
+ 		rac->data.executed = TRUE;
+ 		
+		rac = rac->next;	
+	}
+}
+
 int sieve_result_execute
 (struct sieve_result *result, const struct sieve_message_data *msgdata,
-	const struct sieve_script_env *senv, struct sieve_exec_status *estatus)
-{ 
+	const struct sieve_script_env *senv, bool *keep)
+{
+	struct sieve_exec_status dummy_status;
 	bool implicit_keep = TRUE;
 	bool success = TRUE, commit_ok;
 	struct sieve_result_action *rac, *first_action;
 	struct sieve_result_action *last_attempted;
 
+	if ( keep != NULL ) *keep = FALSE;
+
 	/* Prepare environment */
 
 	result->action_env.msgdata = msgdata;
 	result->action_env.scriptenv = senv;
-	result->action_env.estatus = estatus;
+	result->action_env.exec_status = 
+		( senv->exec_status == NULL ? &dummy_status : senv->exec_status );
 	
 	/* Make notice of this attempt */
 	
 	first_action = ( result->last_attempted_action == NULL ?
 		result->first_action : result->last_attempted_action );
 	result->last_attempted_action = result->last_action;
-	result->keep = FALSE;
-	
+		
 	/* 
 	 * Transaction start 
 	 */
@@ -822,17 +854,17 @@ int sieve_result_execute
 		const struct sieve_side_effect *sef;
 		
 		if ( success ) {
-			bool keep = TRUE;
+			bool impl_keep = TRUE;
 			
 			rac->data.executed = TRUE;
-			if ( rac->keep ) result->keep = TRUE;
+			if ( rac->keep && keep != NULL ) *keep = TRUE;
 			
 			/* Skip non-action (inactive keep) */
 			if ( act == NULL ) continue;
 		
 			if ( act->commit != NULL ) 
 				commit_ok = act->commit
-					(act, &result->action_env, rac->tr_context, &keep) && commit_ok;
+					(act, &result->action_env, rac->tr_context, &impl_keep) && commit_ok;
 	
 			/* Execute post_commit event of side effects */
 			rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL;
@@ -841,11 +873,11 @@ int sieve_result_execute
 				if ( sef->post_commit != NULL ) 
 					sef->post_commit
 						(sef, act, &result->action_env, rsef->context, rac->tr_context, 
-							&keep);
+							&impl_keep);
 				rsef = rsef->next;
 			}
 			
-			implicit_keep = implicit_keep && keep;
+			implicit_keep = implicit_keep && impl_keep;
 		} else {
 			/* Skip non-action (inactive keep) */
 			if ( act == NULL ) continue;
@@ -868,7 +900,7 @@ int sieve_result_execute
 		rac = rac->next;	
 	}
 	
-	if ( implicit_keep ) result->keep = TRUE;
+	if ( implicit_keep && keep != NULL ) *keep = TRUE;
 	
 	/* Return value indicates whether the caller should attempt an implicit keep 
 	 * of its own. So, if the above transaction fails, but the implicit keep below
@@ -937,11 +969,6 @@ const struct sieve_action *sieve_result_iterate_next
 	return NULL;
 }
 
-bool sieve_result_keep(struct sieve_result *result)
-{
-	return result->keep;
-}
-
 /*
  * Side effects list
  */
diff --git a/src/lib-sieve/sieve-result.h b/src/lib-sieve/sieve-result.h
index 0e961bd12ba2ee999a42f18489ae77778240149d..41dff38f5bf164ca9a4a9bdb4683577d27e5b5be 100644
--- a/src/lib-sieve/sieve-result.h
+++ b/src/lib-sieve/sieve-result.h
@@ -59,7 +59,7 @@ void sieve_result_seffect_printf
 
 bool sieve_result_print
 	(struct sieve_result *result, const struct sieve_script_env *senv, 
-		struct ostream *stream);
+		struct ostream *stream, bool *keep);
 
 /* 
  * Error handling 
@@ -97,11 +97,13 @@ int sieve_result_add_keep
  
 bool sieve_result_implicit_keep
 	(struct sieve_result *result, const struct sieve_message_data *msgdata,
-		const struct sieve_script_env *senv, struct sieve_exec_status *estatus);
+		const struct sieve_script_env *senv);
+
+void sieve_result_mark_executed(struct sieve_result *result);
 
 int sieve_result_execute
 	(struct sieve_result *result, const struct sieve_message_data *msgdata,
-		const struct sieve_script_env *senv, struct sieve_exec_status *estatus);
+		const struct sieve_script_env *senv, bool *keep);
 
 /*
  * Result evaluation
@@ -114,8 +116,6 @@ struct sieve_result_iterate_context *sieve_result_iterate_init
 const struct sieve_action *sieve_result_iterate_next
 	(struct sieve_result_iterate_context *rictx, bool *keep, void **context);
 	
-bool sieve_result_keep(struct sieve_result *result);
-
 /*
  * Side effects list
  */
diff --git a/src/lib-sieve/sieve-types.h b/src/lib-sieve/sieve-types.h
index b884ef7dd91ba98479931c60c3931d85756cd42d..28c4abe768cbe5dac269cca5ea07f80facf1d234 100644
--- a/src/lib-sieve/sieve-types.h
+++ b/src/lib-sieve/sieve-types.h
@@ -62,6 +62,12 @@ struct sieve_script_env {
 		(const void *id, size_t id_size, const char *user);
 	void (*duplicate_mark)
 		(const void *id, size_t id_size, const char *user, time_t time);
+	
+	/* Execution status record */	
+	struct sieve_exec_status *exec_status;
+		
+	/* Trace stream */
+	struct ostream *trace_stream;
 };
 
 #define SIEVE_SCRIPT_DEFAULT_MAILBOX(senv) \
diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c
index 0cf07733a4a4aace1e21e09b8507ffad2251a4b2..7b8e78762da52d6a2da2bc6cf748ac9dce4d5982 100644
--- a/src/lib-sieve/sieve.c
+++ b/src/lib-sieve/sieve.c
@@ -243,28 +243,37 @@ void sieve_dump(struct sieve_binary *sbin, struct ostream *stream)
 
 int sieve_test
 (struct sieve_binary *sbin, const struct sieve_message_data *msgdata,
-	const struct sieve_script_env *senv, struct sieve_exec_status *estatus, 
-	struct ostream *stream, struct sieve_error_handler *ehandler, 
-	struct ostream *trace_stream) 	
+	const struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
+	struct ostream *stream) 	
 {
-	struct sieve_result *sres = sieve_result_create(ehandler);
-	struct sieve_interpreter *interp = 
-		sieve_interpreter_create(sbin, ehandler, trace_stream);			
+	struct sieve_result *result;
+	struct sieve_interpreter *interp; 
 	int ret = 0;
 		
-	if ( interp == NULL )
+	/* Create interpreter */
+	if ( (interp=sieve_interpreter_create(sbin, ehandler)) == NULL )
 		return SIEVE_EXEC_BIN_CORRUPT;
 
 	/* Reset execution status */
-    memset(estatus, 0, sizeof(*estatus));
-					
-	ret = sieve_interpreter_run(interp, msgdata, senv, &sres, estatus);
+	if ( senv->exec_status != NULL )
+		memset(senv->exec_status, 0, sizeof(*senv->exec_status));
 	
+	/* Create result object */	
+	result = sieve_result_create(ehandler);	
+				
+	/* Run interpreter */				
+	ret = sieve_interpreter_run(interp, msgdata, senv, result);
+
+	/* Free interpreter */
+	sieve_interpreter_free(&interp);
+		
+	/* Print result if successful */
 	if ( ret > 0 ) 
-		ret = sieve_result_print(sres, senv, stream);
+		ret = sieve_result_print(result, senv, stream, NULL);
+	
+	/* Cleanup */
+	sieve_result_unref(&result);
 	
-	sieve_interpreter_free(&interp);
-	sieve_result_unref(&sres);
 	return ret;
 }
 
@@ -274,22 +283,47 @@ int sieve_test
 
 int sieve_execute
 (struct sieve_binary *sbin, const struct sieve_message_data *msgdata,
-	const struct sieve_script_env *senv, struct sieve_exec_status *estatus,
-	struct sieve_error_handler *ehandler, struct ostream *trace_stream) 	
+	const struct sieve_script_env *senv, struct sieve_error_handler *ehandler) 	
 {
-	struct sieve_result *sres = NULL;
-	struct sieve_interpreter *interp = 
-		sieve_interpreter_create(sbin, ehandler, trace_stream);			
+	struct sieve_result *result;
+	struct sieve_interpreter *interp;
 	int ret = 0;
 
-	if ( interp == NULL )
+	/* Create the interpreter */
+	if ( (interp=sieve_interpreter_create(sbin, ehandler)) == NULL )
 		return SIEVE_EXEC_BIN_CORRUPT;
 
 	/* Reset execution status */
-    memset(estatus, 0, sizeof(*estatus));
+	if ( senv->exec_status != NULL )
+		memset(senv->exec_status, 0, sizeof(*senv->exec_status));
+	
+	/* Create result object */	
+	result = sieve_result_create(ehandler);	
 							
-	ret = sieve_interpreter_run(interp, msgdata, senv, &sres, estatus);
-				
+	/* Run the interpreter */
+	ret = sieve_interpreter_run(interp, msgdata, senv, result);
+	
+	/* Free the interpreter */
 	sieve_interpreter_free(&interp);
+	
+	/* Evaluate status and execute the result:
+	 *   Strange situations, e.g. currupt binaries, must be handled by the caller. 
+	 *   In that case no implicit keep is attempted, because the situation may be 
+	 *   resolved.
+	 */
+	if ( ret >= 0 ) {
+		if ( ret > 0 ) 
+			/* Execute result */
+			ret = sieve_result_execute(result, msgdata, senv, NULL);
+		else {
+			/* Perform implicit keep if script failed with a normal runtime error */
+			if ( !sieve_result_implicit_keep(result, msgdata, senv) )
+				ret = SIEVE_EXEC_KEEP_FAILED;
+		}
+	}
+	
+	/* Cleanup */
+	sieve_result_unref(&result);
+
 	return ret;
 }
diff --git a/src/lib-sieve/sieve.h b/src/lib-sieve/sieve.h
index 7acb85ca0bb1477f6ac3583c84c64f8193a14229..cf0cd20a67fcaa4ab6763e21516cb93925593b0e 100644
--- a/src/lib-sieve/sieve.h
+++ b/src/lib-sieve/sieve.h
@@ -98,9 +98,8 @@ void sieve_dump(struct sieve_binary *sbin, struct ostream *stream);
  */ 
 int sieve_test
 	(struct sieve_binary *sbin, const struct sieve_message_data *msgdata, 
-		const struct sieve_script_env *senv, struct sieve_exec_status *estatus,
-		struct ostream *stream, struct sieve_error_handler *ehandler, 
-		struct ostream *trace_stream);
+		const struct sieve_script_env *senv, struct sieve_error_handler *ehandler, 
+		struct ostream *stream);
 
 /*
  * Script execution
@@ -112,7 +111,6 @@ int sieve_test
  */
 int sieve_execute
 	(struct sieve_binary *sbin, const struct sieve_message_data *msgdata,
-		const struct sieve_script_env *senv, struct sieve_exec_status *estatus,
-		struct sieve_error_handler *ehandler, struct ostream *trace_stream);
+		const struct sieve_script_env *senv, struct sieve_error_handler *ehandler);
 
 #endif
diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c
index c9edf3dacdbc2dd49f5a829c6d8f088ce06c9f45..9a88212e915b17ea49b13b5bc44721d93dae2b40 100644
--- a/src/plugins/lda-sieve/lda-sieve-plugin.c
+++ b/src/plugins/lda-sieve/lda-sieve-plugin.c
@@ -174,13 +174,14 @@ static int lda_sieve_run
 	scriptenv.smtp_close = lda_sieve_smtp_close;
 	scriptenv.duplicate_mark = duplicate_mark;
 	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, &estatus, ehandler, NULL);
+	ret = sieve_execute(sbin, &msgdata, &scriptenv, ehandler);
 
 	/* Record status */
 
@@ -218,7 +219,7 @@ static int lda_sieve_run
 
 		/* Execute again */
 	
-		ret = sieve_execute(sbin, &msgdata, &scriptenv, &estatus, ehandler, NULL);
+		ret = sieve_execute(sbin, &msgdata, &scriptenv, ehandler);
 
 		/* Record status */
 
diff --git a/src/sieve-tools/sieve-exec.c b/src/sieve-tools/sieve-exec.c
index 584d17298836ddc3547816c9340506fd9743c4c3..912ed5a5759010d95f6d4bc9b60970e1ee803360 100644
--- a/src/sieve-tools/sieve-exec.c
+++ b/src/sieve-tools/sieve-exec.c
@@ -70,7 +70,7 @@ static void duplicate_mark
 static void print_help(void)
 {
 	printf(
-"Usage: sieve-exec [-r <recipient address>][-s <envelope sender>]\n"
+"Usage: sieve-exec [-r <recipient address>][-f <envelope sender>]\n"
 "                  [-m <mailbox>][-d <dump filename>][-l <mail location>]\n"
 "                  <scriptfile> <mailfile>\n"
 	);
@@ -105,11 +105,11 @@ int main(int argc, char **argv)
 			if (i == argc)
 				i_fatal("Missing -r argument");
 			recipient = argv[i];
-		} else if (strcmp(argv[i], "-s") == 0) {
+		} else if (strcmp(argv[i], "-f") == 0) {
 			/* envelope sender */
 			i++;
 			if (i == argc)
-				i_fatal("Missing -s argument");
+				i_fatal("Missing -f argument");
 			sender = argv[i];
 		} else if (strcmp(argv[i], "-m") == 0) {
 			/* default mailbox (keep box) */
@@ -209,12 +209,13 @@ int main(int argc, char **argv)
 	scriptenv.smtp_close = sieve_smtp_close;
 	scriptenv.duplicate_mark = duplicate_mark;
 	scriptenv.duplicate_check = duplicate_check;
+	scriptenv.exec_status = &estatus;
 	
 	ehandler = sieve_stderr_ehandler_create(0);
 	sieve_error_handler_accept_infolog(ehandler, TRUE);
 
 	/* Run */
-	switch ( sieve_execute(sbin, &msgdata, &scriptenv, &estatus, ehandler, NULL) ) {
+	switch ( sieve_execute(sbin, &msgdata, &scriptenv, ehandler) ) {
 	case SIEVE_EXEC_OK:
 		i_info("final result: success");
 		break;
diff --git a/src/sieve-tools/sieve-test.c b/src/sieve-tools/sieve-test.c
index 41faf336444cc9b22a2b068bc42f4d95d26bd17d..6cfd40ad3fef9315e6509b812a8df72de0ece5c7 100644
--- a/src/sieve-tools/sieve-test.c
+++ b/src/sieve-tools/sieve-test.c
@@ -3,6 +3,7 @@
 
 #include "lib.h"
 #include "ostream.h"
+#include "array.h"
 #include "mail-namespace.h"
 #include "mail-storage.h"
 
@@ -37,9 +38,10 @@ static void print_help(void)
 #  define SVTRACE
 #endif
 	printf(
-"Usage: sieve-test [-r <recipient address>] [-s <envelope sender>]\n"
+"Usage: sieve-test [-r <recipient address>] [-f <envelope sender>]\n"
 "                  [-m <mailbox>] [-d <dump filename>] [-x <extensions>]\n"
-"                  [-c]"SVTRACE" <scriptfile> <mailfile>\n"
+"                  [-s <scriptfile>] [-c]"SVTRACE"\n"
+"                  <scriptfile> <mailfile>\n"
 	);
 }
 
@@ -49,25 +51,29 @@ static void print_help(void)
 
 int main(int argc, char **argv) 
 {
-	const char *scriptfile, *recipient, *sender, *mailbox, *dumpfile, *mailfile,
+	ARRAY_DEFINE(scriptfiles, const char *);
+	const char *scriptfile, *recipient, *sender, *mailbox, *dumpfile, *mailfile, 
 		*extensions; 
 	const char *user;
 	int i;
 	struct mail_raw *mailr;
-	struct sieve_binary *sbin;
+	struct sieve_binary *main_sbin;
 	struct sieve_message_data msgdata;
 	struct sieve_script_env scriptenv;
 	struct sieve_exec_status estatus;
 	struct sieve_error_handler *ehandler;
 	struct ostream *teststream;
 	bool force_compile = FALSE;
-	int ret;
 	bool trace = FALSE;
-	struct ostream *trace_stream = FALSE;
+	int ret;
+
+	sieve_tool_init();
+	
+	t_array_init(&scriptfiles, 16);
 
 	/* Parse arguments */
-	scriptfile = recipient = sender = mailbox = dumpfile = mailfile = 
-		extensions = NULL;
+	scriptfile = recipient = sender = mailbox = dumpfile = mailfile = extensions 
+		= NULL;
 	for (i = 1; i < argc; i++) {
 		if (strcmp(argv[i], "-r") == 0) {
 			/* recipient address */
@@ -75,11 +81,11 @@ int main(int argc, char **argv)
 			if (i == argc)
 				i_fatal("Missing -r argument");
 			recipient = argv[i];
-		} else if (strcmp(argv[i], "-s") == 0) {
+		} else if (strcmp(argv[i], "-f") == 0) {
 			/* envelope sender */
 			i++;
 			if (i == argc)
-				i_fatal("Missing -s argument");
+				i_fatal("Missing -f argument");
 			sender = argv[i];
 		} else if (strcmp(argv[i], "-m") == 0) {
 			/* default mailbox (keep box) */
@@ -99,12 +105,22 @@ int main(int argc, char **argv)
 			if (i == argc)
 				i_fatal("Missing -x argument");
 			extensions = argv[i];
+		} else if (strcmp(argv[i], "-s") == 0) {
+			const char *file;
+			
+			/* scriptfile executed before main script */
+			i++;
+			if (i == argc)
+				i_fatal("Missing -s argument");
+				
+			file = t_strdup(argv[i]);
+			array_append(&scriptfiles, &file, 1);
 		} else if (strcmp(argv[i], "-c") == 0) {
-            /* force compile */
+			/* force compile */
 			force_compile = TRUE;
 #ifdef SIEVE_RUNTIME_TRACE
 		} else if (strcmp(argv[i], "-t") == 0) {
-            /* runtime trace */
+			/* runtime trace */
 			trace = TRUE;
 #endif
 		} else if ( scriptfile == NULL ) {
@@ -127,22 +143,20 @@ int main(int argc, char **argv)
 		i_fatal("Missing <mailfile> argument");
 	}
 
-	sieve_tool_init();
-
 	if ( extensions != NULL ) {
 		sieve_set_extensions(extensions);
 	}
 	
-	/* Compile sieve script */
+	/* Compile main sieve script */
 	if ( force_compile ) {
-		sbin = sieve_tool_script_compile(scriptfile);
-		(void) sieve_save(sbin, NULL);
+		main_sbin = sieve_tool_script_compile(scriptfile);
+		(void) sieve_save(main_sbin, NULL);
 	} else {
-		sbin = sieve_tool_script_open(scriptfile);
+		main_sbin = sieve_tool_script_open(scriptfile);
 	}
 
 	/* Dump script */
-	sieve_tool_dump_binary_to(sbin, dumpfile);
+	sieve_tool_dump_binary_to(main_sbin, dumpfile);
 	
 	user = sieve_tool_get_user();
 
@@ -169,31 +183,36 @@ int main(int argc, char **argv)
 	msgdata.auth_user = user;
 	(void)mail_get_first_header(mailr->mail, "Message-ID", &msgdata.id);
 
+	/* Create stream for test and trace output */
+	
+	teststream = o_stream_create_fd(1, 0, FALSE);	
+		
+	/* Compose script environment */
 	memset(&scriptenv, 0, sizeof(scriptenv));
-	scriptenv.default_mailbox = "INBOX";
+	scriptenv.default_mailbox = mailbox;
 	scriptenv.username = user;
+	scriptenv.trace_stream = ( trace ? teststream : NULL );
+	scriptenv.exec_status = &estatus;
 
+	/* Create error handler */
 	ehandler = sieve_stderr_ehandler_create(0);	
 
-	teststream = o_stream_create_fd(1, 0, FALSE);	
-
-	if ( trace )
-		trace_stream = teststream;
-	else
-		trace_stream = NULL;
-
 	/* Run the test */
-	ret = sieve_test
-		(sbin, &msgdata, &scriptenv, &estatus, teststream, ehandler, trace_stream);
+	
+	if ( array_count(&scriptfiles) == 0 ) {
+		ret = sieve_test(main_sbin, &msgdata, &scriptenv, ehandler, teststream);
 
-	if ( ret == SIEVE_EXEC_BIN_CORRUPT ) {
-		i_info("Corrupt binary deleted.");
-		(void) unlink(sieve_binary_path(sbin));		
+		if ( ret == SIEVE_EXEC_BIN_CORRUPT ) {
+			i_info("Corrupt binary deleted.");
+			(void) unlink(sieve_binary_path(main_sbin));		
+		}
+	} else {
+	
 	}
 
 	o_stream_destroy(&teststream);
 
-	sieve_close(&sbin);
+	sieve_close(&main_sbin);
 	sieve_error_handler_unref(&ehandler);
 
 	/* De-initialize raw mail object */
diff --git a/src/testsuite/testsuite-result.c b/src/testsuite/testsuite-result.c
index d9ba34380b0737c0a21954bf0e2e8e4e472e915c..18ecd3862de34e03984bb1b48394f108f1d3ac93 100644
--- a/src/testsuite/testsuite-result.c
+++ b/src/testsuite/testsuite-result.c
@@ -53,7 +53,6 @@ struct sieve_result_iterate_context *testsuite_result_iterate_init(void)
 bool testsuite_result_execute(const struct sieve_runtime_env *renv)
 {
 	struct sieve_script_env scriptenv;
-	struct sieve_exec_status estatus;
 	int ret;
 
 	if ( _testsuite_result == NULL ) {
@@ -78,7 +77,7 @@ bool testsuite_result_execute(const struct sieve_runtime_env *renv)
 	
 	/* Execute the result */	
 	ret=sieve_result_execute
-		(_testsuite_result, renv->msgdata, &scriptenv, &estatus);
+		(_testsuite_result, renv->msgdata, &scriptenv, NULL);
 	
 	return ( ret > 0 );
 }
@@ -91,7 +90,7 @@ void testsuite_result_print
 	out = o_stream_create_fd(1, 0, FALSE);	
 
 	o_stream_send_str(out, "\n--");
-	sieve_result_print(_testsuite_result, renv->scriptenv, out);
+	sieve_result_print(_testsuite_result, renv->scriptenv, out, NULL);
 	o_stream_send_str(out, "--\n\n");
 
 	o_stream_destroy(&out);	
diff --git a/src/testsuite/testsuite-script.c b/src/testsuite/testsuite-script.c
index 8134e17777ca21dc6f616010660459ca4928ebd7..6573c154b494e4ffc66c55e30c0ebb2b2d8041cc 100644
--- a/src/testsuite/testsuite-script.c
+++ b/src/testsuite/testsuite-script.c
@@ -67,7 +67,6 @@ bool testsuite_script_compile(const char *script_path)
 bool testsuite_script_run(const struct sieve_runtime_env *renv)
 {
 	struct sieve_script_env scriptenv;
-	struct sieve_exec_status estatus;
 	struct sieve_result *result;
 	struct sieve_interpreter *interp;
 	int ret;
@@ -96,13 +95,13 @@ bool testsuite_script_run(const struct sieve_runtime_env *renv)
 
 	/* Execute the script */
 	interp=sieve_interpreter_create
-		(_testsuite_compiled_script, testsuite_log_ehandler, NULL);
+		(_testsuite_compiled_script, testsuite_log_ehandler);
 	
 	if ( interp == NULL )
 		return SIEVE_EXEC_BIN_CORRUPT;
 		
 	ret = sieve_interpreter_run
-		(interp, renv->msgdata, &scriptenv, &result, &estatus);
+		(interp, renv->msgdata, &scriptenv, result);
 
 	sieve_interpreter_free(&interp);
 
diff --git a/src/testsuite/testsuite.c b/src/testsuite/testsuite.c
index 66c96bdbfac344fd2214621283bf15363be69add..ea2b80dcf1b971fa3d9891956d164212c2c86d21 100644
--- a/src/testsuite/testsuite.c
+++ b/src/testsuite/testsuite.c
@@ -66,45 +66,6 @@ static void print_help(void)
 	);
 }
 
-static int testsuite_run
-(struct sieve_binary *sbin, const struct sieve_script_env *scriptenv,
-	bool trace)
-{
-	struct sieve_exec_status estatus;
-	struct sieve_error_handler *ehandler = sieve_stderr_ehandler_create(0);
-	struct sieve_result *sres = sieve_result_create(ehandler);	
-	struct sieve_interpreter *interp;
-	int ret = 0;
-
-	if ( trace ) {
-		struct ostream *tstream = o_stream_create_fd(1, 0, FALSE);
-		
-		interp = sieve_interpreter_create(sbin, ehandler, tstream);
-		
-		if ( interp != NULL ) 
-		    ret = sieve_interpreter_run
-				(interp, &testsuite_msgdata, scriptenv, &sres, &estatus);
-	
-		o_stream_destroy(&tstream);
-	} else {
-		interp=sieve_interpreter_create(sbin, ehandler, NULL);
-
-		if ( interp != NULL ) 
-		    ret = sieve_interpreter_run
-				(interp, &testsuite_msgdata, scriptenv, &sres, &estatus);
-	}
-
-	if ( interp != NULL )
-		sieve_interpreter_free(&interp);
-	else
-		ret = SIEVE_EXEC_BIN_CORRUPT;
-
-	sieve_result_unref(&sres);
-	sieve_error_handler_unref(&ehandler);
-
-	return ret;	
-}
-
 int main(int argc, char **argv) 
 {
 	const char *scriptfile, *dumpfile; 
@@ -113,6 +74,7 @@ int main(int argc, char **argv)
 	struct sieve_binary *sbin;
 	const char *sieve_dir;
 	struct sieve_script_env scriptenv;
+	struct sieve_error_handler *ehandler;
 	bool trace = FALSE;
 
 	/* Parse arguments */
@@ -177,9 +139,11 @@ int main(int argc, char **argv)
 	memset(&scriptenv, 0, sizeof(scriptenv));
 	scriptenv.default_mailbox = "INBOX";
 	scriptenv.username = user;
+	scriptenv.trace_stream = ( trace ? o_stream_create_fd(1, 0, FALSE) : NULL );
 
 	/* Run the test */
-	ret = testsuite_run(sbin, &scriptenv, trace);
+	ehandler = sieve_stderr_ehandler_create(0);
+	ret = sieve_execute(sbin, &testsuite_msgdata, &scriptenv, ehandler);
 
 	switch ( ret ) {
 	case SIEVE_EXEC_OK:
@@ -196,6 +160,10 @@ int main(int argc, char **argv)
 	}
 
 	sieve_close(&sbin);
+	sieve_error_handler_unref(&ehandler);
+
+	if ( scriptenv.trace_stream != NULL )
+		o_stream_unref(&scriptenv.trace_stream);
 
 	/* De-initialize message environment */
 	testsuite_message_deinit();