diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c
index bbb412aa0ca415fb4ed84212b687b1274eba387d..6fe209c82f07c0ad0bef642a34efddeb76417307 100644
--- a/src/lib-sieve/cmd-redirect.c
+++ b/src/lib-sieve/cmd-redirect.c
@@ -285,6 +285,7 @@ static bool act_redirect_send
 
 	const struct sieve_message_data *msgdata = aenv->msgdata;
 	const struct sieve_script_env *senv = aenv->scriptenv;
+	const char *sender = sieve_message_get_sender(aenv->msgctx);
 	struct istream *input, *crlf_input;
 	void *smtp_handle;
 	FILE *f;
@@ -302,7 +303,7 @@ static bool act_redirect_send
 		return FALSE;
 		
 	/* Open SMTP transport */
-	smtp_handle = sieve_smtp_open(senv, ctx->to_address, msgdata->return_path, &f);
+	smtp_handle = sieve_smtp_open(senv, ctx->to_address, sender, &f);
 
 	/* Remove unwanted headers */
 	input = i_stream_create_header_filter
diff --git a/src/lib-sieve/ext-envelope.c b/src/lib-sieve/ext-envelope.c
index cdcda8d32e3eca785a8dd4b2083d0033bb2de4e1..7f24e52a314b941febfe3e635faeb7b0d78a4dca 100644
--- a/src/lib-sieve/ext-envelope.c
+++ b/src/lib-sieve/ext-envelope.c
@@ -23,6 +23,7 @@
 #include "sieve-comparators.h"
 #include "sieve-match-types.h"
 #include "sieve-address-parts.h"
+#include "sieve-message.h"
 
 #include "sieve-validator.h"
 #include "sieve-generator.h"
@@ -322,7 +323,7 @@ static const struct sieve_address *const *_from_part_get_addresses
 {
 	ARRAY_DEFINE(envelope_values, const struct sieve_address *);
 	const struct sieve_address *address =
-		sieve_address_parse_envelope_path(renv->msgdata->return_path);
+		sieve_message_get_sender_address(renv->msgctx);
 	
 	if ( address != NULL ) {
 		t_array_init(&envelope_values, 2);
@@ -357,7 +358,7 @@ static const struct sieve_address *const *_to_part_get_addresses
 {
 	ARRAY_DEFINE(envelope_values, const struct sieve_address *);
 	const struct sieve_address *address = 
-		sieve_address_parse_envelope_path(renv->msgdata->to_address);	
+		sieve_message_get_recipient_address(renv->msgctx);	
 
 	if ( address != NULL && address->local_part != NULL ) {
 		t_array_init(&envelope_values, 2);
diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c
index a08ebfcf71ead07b8c5c3ffccaa1739435902a28..2669947511ada324977f1a48db705a9f46384747 100644
--- a/src/lib-sieve/ext-reject.c
+++ b/src/lib-sieve/ext-reject.c
@@ -385,10 +385,11 @@ static void act_reject_print
 }
 
 static bool act_reject_send	
-	(const struct sieve_action_exec_env *aenv, struct act_reject_context *ctx)
+(const struct sieve_action_exec_env *aenv, struct act_reject_context *ctx,
+	const char *sender, const char *recipient)
 {
-	const struct sieve_message_data *msgdata = aenv->msgdata;
 	const struct sieve_script_env *senv = aenv->scriptenv;
+	const struct sieve_message_data *msgdata = aenv->msgdata;
 	struct istream *input;
 	void *smtp_handle;
 	struct message_size hdr_size;
@@ -405,7 +406,7 @@ static bool act_reject_send
 		return TRUE;
 	}
 
-	smtp_handle = sieve_smtp_open(senv, msgdata->return_path, NULL, &f);
+	smtp_handle = sieve_smtp_open(senv, sender, NULL, &f);
 
 	new_msgid = sieve_message_get_new_id(senv);
 	boundary = t_strdup_printf("%s/%s", my_pid, senv->hostname);
@@ -415,7 +416,7 @@ static bool act_reject_send
 	rfc2822_header_field_write(f, "Date", message_date_create(ioloop_time));
 	rfc2822_header_field_printf(f, "From", "Mail Delivery Subsystem <%s>",
 		senv->postmaster_address);
-	rfc2822_header_field_printf(f, "To", "<%s>", msgdata->return_path);
+	rfc2822_header_field_printf(f, "To", "<%s>", sender);
 	rfc2822_header_field_write(f, "Subject", "Automatically rejected mail");
 	rfc2822_header_field_write(f, "Auto-Submitted", "auto-replied (rejected)");
 	rfc2822_header_field_write(f, "Precedence", "bulk");
@@ -435,7 +436,7 @@ static bool act_reject_send
 
 	/* FIXME: var_expand_table expansion not possible */
 	fprintf(f, "Your message to <%s> was automatically rejected:\r\n"	
-		"%s\r\n", msgdata->to_address, ctx->reason);
+		"%s\r\n", recipient, ctx->reason);
 
 	/* MDN status report */
 	fprintf(f, "--%s\r\n"
@@ -444,7 +445,7 @@ static bool act_reject_send
 		senv->hostname);
 	if (mail_get_first_header(msgdata->mail, "Original-Recipient", &header) > 0)
 		fprintf(f, "Original-Recipient: rfc822; %s\r\n", header);
-	fprintf(f, "Final-Recipient: rfc822; %s\r\n",	msgdata->to_address);
+	fprintf(f, "Final-Recipient: rfc822; %s\r\n", recipient);
 
 	if ( msgdata->id != NULL )
 		fprintf(f, "Original-Message-ID: %s\r\n", msgdata->id);
@@ -486,7 +487,7 @@ static bool act_reject_send
 		sieve_result_error(aenv, 
 			"failed to send rejection message to <%s> "
 			"(refer to server log for more information)",
-			str_sanitize(msgdata->return_path, 80));
+			str_sanitize(sender, 80));
 		return FALSE;
 	}
 	
@@ -497,8 +498,14 @@ static bool act_reject_commit
 (const struct sieve_action *action ATTR_UNUSED, 
 	const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep)
 {
-	const struct sieve_message_data *msgdata = aenv->msgdata;
 	struct act_reject_context *rj_ctx = (struct act_reject_context *) tr_context;
+	const char *sender = sieve_message_get_sender(aenv->msgctx);
+	const char *recipient = sieve_message_get_recipient(aenv->msgctx);
+
+	if ( recipient == NULL ) {
+		sieve_result_warning(aenv, "reject action aborted: envelope recipient is <>");
+		return TRUE;
+	}
 	
 	if ( rj_ctx->reason == NULL ) {
 		sieve_result_log(aenv, "not sending reject message (would cause second response to sender)");
@@ -507,16 +514,15 @@ static bool act_reject_commit
 		return TRUE;
 	}
 
-	if ( msgdata->return_path == NULL || *(msgdata->return_path) == '\0' ) {
+	if ( sender == NULL ) {
 		sieve_result_log(aenv, "not sending reject message to <>");
     
 		*keep = FALSE;
 		return TRUE;
 	}
 		
-	if ( act_reject_send(aenv, rj_ctx) ) {
-		sieve_result_log(aenv, "rejected message from <%s> (%s)",
-			str_sanitize(msgdata->return_path, 80),
+	if ( act_reject_send(aenv, rj_ctx, sender, recipient) ) {
+		sieve_result_log(aenv, "rejected message from <%s> (%s)", str_sanitize(sender, 80),
 			( rj_ctx->ereject ? "ereject" : "reject" ));
 
 		*keep = FALSE;
diff --git a/src/lib-sieve/plugins/enotify/cmd-notify.c b/src/lib-sieve/plugins/enotify/cmd-notify.c
index 0d243b493e2b271f4b6e5b753369ac5ce1708f2f..7149be15b4659da3601dcf2f0c5dbe6287a8edb7 100644
--- a/src/lib-sieve/plugins/enotify/cmd-notify.c
+++ b/src/lib-sieve/plugins/enotify/cmd-notify.c
@@ -583,6 +583,7 @@ static bool act_notify_commit
 
 	nenv.scriptenv = aenv->scriptenv;
 	nenv.msgdata = aenv->msgdata;
+	nenv.msgctx = aenv->msgctx;
 	nenv.notify_log = &nlog;
 
 	if ( act->method->action_execute != NULL )
diff --git a/src/lib-sieve/plugins/enotify/ntfy-mailto.c b/src/lib-sieve/plugins/enotify/ntfy-mailto.c
index 5ebd2ce59ea8be21513de1e0fe542bbf09a07de9..20d3ecd30ceec840eec2570e4a7040593911ab92 100644
--- a/src/lib-sieve/plugins/enotify/ntfy-mailto.c
+++ b/src/lib-sieve/plugins/enotify/ntfy-mailto.c
@@ -894,7 +894,7 @@ static bool _contains_8bit(const char *msg)
 
 static bool ntfy_mailto_send
 (const struct sieve_enotify_exec_env *nenv, 
-	const struct sieve_enotify_action *act)
+	const struct sieve_enotify_action *act, const char *recipient)
 { 
 	const struct sieve_enotify_log *nlog = nenv->notify_log;
 	const struct sieve_message_data *msgdata = nenv->msgdata;
@@ -934,7 +934,7 @@ static bool ntfy_mailto_send
 	}
 
 	/* Determine SMTP from address */
-	if ( msgdata->return_path != NULL && *(msgdata->return_path) != '\0' ) {
+	if ( sieve_message_get_sender(nenv->msgctx) != NULL ) {
 		if ( mtctx->from_normalized == NULL ) {
 			from_smtp = senv->postmaster_address;
 		} else {
@@ -1004,7 +1004,7 @@ static bool ntfy_mailto_send
 			rfc2822_header_field_printf(f, "Cc", "%s", str_c(cc));
 			
 		rfc2822_header_field_printf(f, "Auto-Submitted", 
-			"auto-notified; owner-email=\"%s\"", msgdata->to_address);
+			"auto-notified; owner-email=\"%s\"", recipient);
 		rfc2822_header_field_write(f, "Precedence", "bulk");
 
 		/* Set importance */
@@ -1069,12 +1069,21 @@ static bool ntfy_mailto_action_execute
 (const struct sieve_enotify_exec_env *nenv, 
 	const struct sieve_enotify_action *act)
 {
-	const struct sieve_message_data *msgdata = nenv->msgdata;
 	const char *const *headers;
+	const char *sender = sieve_message_get_sender(nenv->msgctx);
+	const char *recipient = sieve_message_get_recipient(nenv->msgctx);
 
+	/* Is the recipient unset? 
+	 */
+	if ( recipient == NULL ) {
+		sieve_enotify_warning(nenv->notify_log, 
+			"notify mailto action aborted: envelope recipient is <>");
+		return TRUE;
+	}
+	
 	/* Is the message an automatic reply ? */
 	if ( mail_get_headers
-		(msgdata->mail, "auto-submitted", &headers) >= 0 ) {
+		(nenv->msgdata->mail, "auto-submitted", &headers) >= 0 ) {
 		const char *const *hdsp = headers;
 
 		/* Theoretically multiple headers could exist, so lets make sure */
@@ -1082,14 +1091,14 @@ static bool ntfy_mailto_action_execute
 			if ( strcasecmp(*hdsp, "no") != 0 ) {
 				sieve_enotify_log(nenv->notify_log, 
 					"not sending notification for auto-submitted message from <%s>", 
-					str_sanitize(msgdata->return_path, 128));	
+					str_sanitize(sender, 128));	
 					return TRUE;				 
 			}
 			hdsp++;
 		}
 	}
 
-	return ntfy_mailto_send(nenv, act);
+	return ntfy_mailto_send(nenv, act, recipient);
 }
 
 
diff --git a/src/lib-sieve/plugins/enotify/sieve-ext-enotify.h b/src/lib-sieve/plugins/enotify/sieve-ext-enotify.h
index 9a8750e862c8bb3c43a6cbfb8c99dab5503f0494..494480dc835bb54aecfa7919459ae4553279ec11 100644
--- a/src/lib-sieve/plugins/enotify/sieve-ext-enotify.h
+++ b/src/lib-sieve/plugins/enotify/sieve-ext-enotify.h
@@ -105,6 +105,7 @@ struct sieve_enotify_exec_env {
 
 	const struct sieve_script_env *scriptenv;
 	const struct sieve_message_data *msgdata;
+	struct sieve_message_context *msgctx;
 };
 
 /*
diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c
index d6dcbd7ef4165fbbcb6cfdff00c6027128f90754..70d9bf755a00f7f491e2eefe93f610f705a435da 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.c
+++ b/src/lib-sieve/plugins/include/ext-include-common.c
@@ -580,8 +580,8 @@ 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, &interrupted) == 1 );
+					(subinterp, renv->msgdata, renv->scriptenv, renv->result, 
+						&interrupted) == 1 );
 			} else
 				result = SIEVE_EXEC_BIN_CORRUPT;
 		}
@@ -644,8 +644,8 @@ bool ext_include_execute_include
 								curctx->include = NULL;
 								curctx->returned = FALSE;
 								result = ( sieve_interpreter_start
-									(subinterp, renv->msgdata, renv->scriptenv, renv->msgctx,
-										renv->result, &interrupted) == 1 );		 	
+									(subinterp, renv->msgdata, renv->scriptenv, renv->result, 
+										&interrupted) == 1 );		 	
 							} else
 								result = SIEVE_EXEC_BIN_CORRUPT;
 						}
diff --git a/src/lib-sieve/plugins/notify/cmd-notify.c b/src/lib-sieve/plugins/notify/cmd-notify.c
index 6738df28c6fa519d4022d8a6fa9784a61983e492..39f55e57f851ec13df3d8ea4a541e79ba2ce37fe 100644
--- a/src/lib-sieve/plugins/notify/cmd-notify.c
+++ b/src/lib-sieve/plugins/notify/cmd-notify.c
@@ -473,14 +473,14 @@ static void cmd_notify_construct_message
 	string_t *out_msg)
 {
 	const struct sieve_message_data *msgdata = renv->msgdata;
-  const char *p;
+	const char *p;
 
-  if ( msg_format == NULL )
+	if ( msg_format == NULL )
 		msg_format = "$from$: $subject$";
  
  	/* Scan message for substitutions */
 	p = msg_format;
-  while ( *p != '\0' ) {
+	while ( *p != '\0' ) {
 		const char *const *header;
 
 		if ( strncasecmp(p, "$from$", 6) == 0 ) {
@@ -491,10 +491,11 @@ static void cmd_notify_construct_message
 				 str_append(out_msg, header[0]); 
 
 		} else if ( strncasecmp(p, "$env-from$", 10) == 0 ) {
+			const char *from = sieve_message_get_sender(renv->msgctx);
 			p += 10;
 
-			if ( msgdata->return_path != NULL ) 
-				str_append(out_msg, msgdata->return_path);
+			if ( from != NULL ) 
+				str_append(out_msg, from);
 
 		} else if ( strncasecmp(p, "$subject$", 9) == 0 ) {	
 			p += 9;
@@ -509,7 +510,7 @@ static void cmd_notify_construct_message
 			const char *begin = p;
 			bool valid = TRUE;
 
-    	p += 5;
+			p += 5;
 			if ( *p == '[' ) {
 				p += 1;
 
@@ -834,10 +835,8 @@ static bool contains_8bit(const char *msg)
 }
 
 static bool act_notify_send
-(const struct sieve_action_exec_env *aenv, 
-	const struct ext_notify_action *act)
+(const struct sieve_action_exec_env *aenv, const struct ext_notify_action *act)
 { 
-	const struct sieve_message_data *msgdata = aenv->msgdata;
 	const struct sieve_script_env *senv = aenv->scriptenv;
 	const struct ext_notify_recipient *recipients;
 	void *smtp_handle;
@@ -863,7 +862,7 @@ static bool act_notify_send
 	/* Send message to all recipients */
 	for ( i = 0; i < count; i++ ) {
 
-		if ( msgdata->return_path != NULL && *(msgdata->return_path) != '\0' )
+		if ( sieve_message_get_sender(aenv->msgctx) != NULL )
 			smtp_handle = sieve_smtp_open
 				(senv, recipients[i].normalized, senv->postmaster_address, &f);
 		else		
@@ -949,7 +948,7 @@ static bool act_notify_commit
 			if ( strcasecmp(*hdsp, "no") != 0 ) {
 				sieve_result_log(aenv, 
 					"not sending notification for auto-submitted message from <%s>", 
-					str_sanitize(msgdata->return_path, 128));	
+					str_sanitize(sieve_message_get_sender(aenv->msgctx), 128));	
 					return TRUE;				 
 			}
 			hdsp++;
diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c
index 81b5161eb62ab665e591c2ab916dd25130260fbf..62b87fb62d7b642d51ce346e4d3b502d74045ca6 100644
--- a/src/lib-sieve/plugins/vacation/cmd-vacation.c
+++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c
@@ -858,7 +858,8 @@ static inline bool _contains_my_address
 }
 
 static bool act_vacation_send	
-	(const struct sieve_action_exec_env *aenv, struct act_vacation_context *ctx)
+(const struct sieve_action_exec_env *aenv, struct act_vacation_context *ctx,
+	const char *sender, const char *recipient)
 {
 	const struct sieve_message_data *msgdata = aenv->msgdata;
 	const struct sieve_script_env *senv = aenv->scriptenv;
@@ -877,7 +878,7 @@ static bool act_vacation_send
 
 	/* Open smtp session */
 
-	smtp_handle = sieve_smtp_open(senv, msgdata->return_path, NULL, &f);
+	smtp_handle = sieve_smtp_open(senv, sender, NULL, &f);
 	outmsgid = sieve_message_get_new_id(senv);
 
 	/* Produce a proper reply */
@@ -888,13 +889,15 @@ static bool act_vacation_send
 
 	if ( ctx->from != NULL && *(ctx->from) != '\0' )
 		rfc2822_header_field_printf(f, "From", "%s", ctx->from);
+	else if ( recipient != NULL ) 
+		rfc2822_header_field_printf(f, "From", "<%s>", recipient);
 	else
-		rfc2822_header_field_printf(f, "From", "<%s>", msgdata->to_address);
+		rfc2822_header_field_printf(f, "From", "Postmaster <%s>", senv->postmaster_address);
 		
 	/* FIXME: If From header of message has same address, we should use that in 
 	 * stead properly include the phrase part.
 	 */
-	rfc2822_header_field_printf(f, "To", "<%s>", msgdata->return_path);
+	rfc2822_header_field_printf(f, "To", "<%s>", sender);
 
 	rfc2822_header_field_printf(f, "Subject", "%s", 
 		str_sanitize(ctx->subject, 256));
@@ -934,7 +937,7 @@ static bool act_vacation_send
 		sieve_result_error(aenv, 
 			"failed to send vacation response to <%s> "
 			"(refer to server log for more information)", 
-			str_sanitize(msgdata->return_path, 128));	
+			str_sanitize(sender, 128));	
 		return TRUE;
 	}
 	
@@ -942,10 +945,9 @@ static bool act_vacation_send
 }
 
 static void act_vacation_hash
-(const struct sieve_message_data *msgdata, struct act_vacation_context *vctx, 
-	unsigned char hash_r[])
+(struct act_vacation_context *vctx, const char *sender, unsigned char hash_r[])
 {
-	const char *rpath = t_str_lcase(msgdata->return_path);
+	const char *rpath = t_str_lcase(sender);
 	struct md5_context ctx;
 
 	md5_init(&ctx);
@@ -967,11 +969,20 @@ static bool act_vacation_commit
 	struct act_vacation_context *ctx = (struct act_vacation_context *) tr_context;
 	unsigned char dupl_hash[MD5_RESULTLEN];
 	const char *const *headers;
+	const char *sender = sieve_message_get_sender(aenv->msgctx);
+	const char *recipient = sieve_message_get_recipient(aenv->msgctx);
 	pool_t pool;
 
-	/* Is the return_path unset ?
+	/* Is the recipient unset? 
 	 */
-	if ( msgdata->return_path == NULL || *(msgdata->return_path) == '\0' ) {
+	if ( recipient == NULL ) {
+		sieve_result_warning(aenv, "vacation action aborted: envelope recipient is <>");
+		return TRUE;
+	}
+
+	/* Is the return path unset ?
+	 */
+	if ( sender == NULL ) {
 		sieve_result_log(aenv, "discarded vacation reply to <>");
 		return TRUE;
 	}    
@@ -979,7 +990,7 @@ static bool act_vacation_commit
 	/* Are we perhaps trying to respond to ourselves ? 
 	 * (FIXME: verify this to :addresses as well?)
 	 */
-	if ( sieve_address_compare(msgdata->return_path, msgdata->to_address, TRUE) 
+	if ( sieve_address_compare(sender, recipient, TRUE) 
 		== 0 ) {
 		sieve_result_log(aenv, "discarded vacation reply to own address");	
 		return TRUE;
@@ -987,12 +998,12 @@ static bool act_vacation_commit
 	
 	/* Did whe respond to this user before? */
 	if ( sieve_action_duplicate_check_available(senv) ) {
-		act_vacation_hash(msgdata, ctx, dupl_hash);
+		act_vacation_hash(ctx, sender, dupl_hash);
 	
 		if ( sieve_action_duplicate_check(senv, dupl_hash, sizeof(dupl_hash)) ) 
 		{
 			sieve_result_log(aenv, "discarded duplicate vacation response to <%s>",
-				str_sanitize(msgdata->return_path, 128));
+				str_sanitize(sender, 128));
 			return TRUE;
 		}
 	}
@@ -1005,7 +1016,7 @@ static bool act_vacation_commit
 			/* Yes, bail out */
 			sieve_result_log(aenv, 
 				"discarding vacation response to mailinglist recipient <%s>", 
-				str_sanitize(msgdata->return_path, 128));	
+				str_sanitize(sender, 128));	
 			return TRUE;				 
 		}
 		hdsp++;
@@ -1020,7 +1031,7 @@ static bool act_vacation_commit
 			if ( strcasecmp(*hdsp, "no") != 0 ) {
 				sieve_result_log(aenv, 
 					"discardig vacation response to auto-submitted message from <%s>", 
-					str_sanitize(msgdata->return_path, 128));	
+					str_sanitize(sender, 128));	
 					return TRUE;				 
 			}
 			hdsp++;
@@ -1037,7 +1048,7 @@ static bool act_vacation_commit
 				strcasecmp(*hdsp, "list") == 0 ) {
 				sieve_result_log(aenv, 
 					"discarding vacation response to precedence=%s message from <%s>", 
-					*hdsp, str_sanitize(msgdata->return_path, 128));	
+					*hdsp, str_sanitize(sender, 128));	
 					return TRUE;				 
 			}
 			hdsp++;
@@ -1045,10 +1056,10 @@ static bool act_vacation_commit
 	}
 	
 	/* Do not reply to system addresses */
-	if ( _is_system_address(msgdata->return_path) ) {
+	if ( _is_system_address(sender) ) {
 		sieve_result_log(aenv, 
 			"not sending vacation response to system address <%s>", 
-			str_sanitize(msgdata->return_path, 128));	
+			str_sanitize(sender, 128));	
 		return TRUE;				
 	} 
 	
@@ -1060,7 +1071,7 @@ static bool act_vacation_commit
 		if ( mail_get_headers_utf8
 			(msgdata->mail, *hdsp, &headers) >= 0 && headers[0] != NULL ) {	
 			
-			if ( _contains_my_address(headers, msgdata->to_address) ) 
+			if ( _contains_my_address(headers, recipient) ) 
 				break;
 			
 			if ( ctx->addresses != NULL ) {
@@ -1082,7 +1093,7 @@ static bool act_vacation_commit
 		/* No, bail out */
 		sieve_result_log(aenv, 
 			"discarding vacation response for message implicitly delivered to <%s>",
-			( msgdata->to_address == NULL ? "UNKNOWN" : msgdata->to_address ) );	
+			recipient );	
 		return TRUE;				 
 	}	
 		
@@ -1099,9 +1110,9 @@ static bool act_vacation_commit
 	
 	/* Send the message */
 	
-	if ( act_vacation_send(aenv, ctx) ) {
+	if ( act_vacation_send(aenv, ctx, sender, recipient) ) {
 		sieve_result_log(aenv, "sent vacation response to <%s>", 
-			str_sanitize(msgdata->return_path, 128));	
+			str_sanitize(sender, 128));	
 
 		/* Mark as replied */
 		sieve_action_duplicate_mark
diff --git a/src/lib-sieve/sieve-actions.h b/src/lib-sieve/sieve-actions.h
index ef82f090fea936e56056cbcbabd0f5cc6ab59d8f..fe6c9cbc028a68644e77c5e3e61f15f297df74d4 100644
--- a/src/lib-sieve/sieve-actions.h
+++ b/src/lib-sieve/sieve-actions.h
@@ -18,6 +18,7 @@
 struct sieve_action_exec_env { 
 	struct sieve_result *result;
 	const struct sieve_message_data *msgdata;
+	struct sieve_message_context *msgctx;
 	const struct sieve_script_env *scriptenv;
 	struct sieve_exec_status *exec_status;
 };
diff --git a/src/lib-sieve/sieve-address.c b/src/lib-sieve/sieve-address.c
index d43070ce192a5056fa2e6335d309f638bb295e2c..ce8ddf60600a4847e0a9fa2f96ee3e164a07a5ad 100644
--- a/src/lib-sieve/sieve-address.c
+++ b/src/lib-sieve/sieve-address.c
@@ -443,6 +443,8 @@ static unsigned char rfc2821_chars[256] = {
 };
 
 struct sieve_envelope_address_parser {
+	pool_t pool;
+
 	const unsigned char *data;
 	const unsigned char *end;
 
@@ -561,7 +563,7 @@ static int path_parse_domain
 	}
 
 	if ( !skip )
-		parser->address->domain = t_strdup(str_c(parser->str));
+		parser->address->domain = p_strdup(parser->pool, str_c(parser->str));
 
 	return path_skip_white_space(parser);
 }
@@ -680,7 +682,7 @@ static int path_parse_local_part(struct sieve_envelope_address_parser *parser)
 		}
 	}
 
-	parser->address->local_part = t_strdup(str_c(parser->str));
+	parser->address->local_part = p_strdup(parser->pool, str_c(parser->str));
 	return parser->data < parser->end;
 }
 
@@ -753,19 +755,20 @@ static int path_parse(struct sieve_envelope_address_parser *parser)
 }
 
 const struct sieve_address *sieve_address_parse_envelope_path
-(const char *field_value)
+(pool_t pool, const char *field_value)
 {
 	struct sieve_envelope_address_parser parser;
 	int ret;
 
 	if ( field_value == NULL ) {
-		return t_new(struct sieve_address, 1);
+		return p_new(pool, struct sieve_address, 1);
 	}
 
+	parser.pool = pool;
 	parser.data = (const unsigned char *) field_value;
 	parser.end = (const unsigned char *) field_value + strlen(field_value);
-	parser.address = t_new(struct sieve_address, 1);
-	parser.str = t_str_new(256);
+	parser.address = p_new(pool, struct sieve_address, 1);
+	parser.str = t_str_new(256); /* IMPORTAINT: maintain datastack level */
 
 	if ( (ret=path_parse(&parser)) < 0 )
 		return NULL;
diff --git a/src/lib-sieve/sieve-address.h b/src/lib-sieve/sieve-address.h
index 8593ce8becf577fb4c987d3b46423cbf41ed60ab..202e1a5539401067fa14b90590753f6d49654515 100644
--- a/src/lib-sieve/sieve-address.h
+++ b/src/lib-sieve/sieve-address.h
@@ -4,6 +4,9 @@
 #ifndef __SIEVE_ADDRESS_H
 #define __SIEVE_ADDRESS_H
  
+#include "lib.h"
+#include "strfuncs.h"
+
 /*
  * Generic address representation
  */ 
@@ -13,6 +16,14 @@ struct sieve_address {
 	const char *domain;
 };
 
+static inline const char *sieve_address_to_string(const struct sieve_address *address) 
+{
+    if ( address == NULL || address->local_part == NULL || address->domain == NULL )
+        return NULL;
+
+    return t_strconcat(address->local_part, "@", address->domain, NULL);
+}
+
 /* 
  * RFC 2822 addresses
  */ 
@@ -36,6 +47,6 @@ int sieve_address_compare
  */
 
 const struct sieve_address *sieve_address_parse_envelope_path
-	(const char *field_value);
+	(pool_t pool, const char *field_value);
 
 #endif
diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c
index aeecfd03fc5d8ab50dcb5134bf2d8d93de2fa5ba..3edc2f94b94feae9af6857bbd8f098003ff9f37d 100644
--- a/src/lib-sieve/sieve-interpreter.c
+++ b/src/lib-sieve/sieve-interpreter.c
@@ -133,9 +133,6 @@ void sieve_interpreter_free(struct sieve_interpreter **interp)
 
 	sieve_binary_unref(&(*interp)->runenv.sbin);
 
-	if ( (*interp)->runenv.msgctx != NULL )
-		 sieve_message_context_unref(&(*interp)->runenv.msgctx);
-
 	sieve_error_handler_unref(&(*interp)->ehandler);
 
 	/* Signal registered extensions that the interpreter is being destroyed */
@@ -486,14 +483,14 @@ 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, bool *interrupted) 
+	const struct sieve_script_env *senv, struct sieve_result *result, bool *interrupted) 
 {
 	const struct sieve_interpreter_extension_reg *extrs;
 	unsigned int ext_count, i;
 	
 	interp->runenv.msgdata = msgdata;
-	interp->runenv.result = result;		
+	interp->runenv.result = result;
+	interp->runenv.msgctx = sieve_result_get_message_context(result);		
 	interp->runenv.scriptenv = senv;
 	interp->runenv.trace_stream = senv->trace_stream;
 
@@ -502,13 +499,6 @@ int sieve_interpreter_start
 	else
 		interp->runenv.exec_status = senv->exec_status;
 	
-	if ( msgctx == NULL )
-		interp->runenv.msgctx = sieve_message_context_create();
-	else {
-		interp->runenv.msgctx = msgctx;
-		sieve_message_context_ref(msgctx);
-	}
-
 	/* Signal registered extensions that the interpreter is being run */
 	extrs = array_get(&interp->extensions, &ext_count);
 	for ( i = 0; i < ext_count; i++ ) {
@@ -528,7 +518,7 @@ int sieve_interpreter_run
 	sieve_interpreter_reset(interp);
 	sieve_result_ref(result);
 	
-	ret = sieve_interpreter_start(interp, msgdata, senv, NULL, result, NULL);
+	ret = sieve_interpreter_start(interp, msgdata, senv, result, NULL);
 	
 	sieve_result_unref(&result);
 	
diff --git a/src/lib-sieve/sieve-interpreter.h b/src/lib-sieve/sieve-interpreter.h
index 61c5eda7d18f47d45e98497bdf47dd07ce28851d..2da76a9069a8f6fabf130c0f30652b91da43a672 100644
--- a/src/lib-sieve/sieve-interpreter.h
+++ b/src/lib-sieve/sieve-interpreter.h
@@ -165,8 +165,8 @@ int sieve_interpreter_continue
 	(struct sieve_interpreter *interp, bool *interrupted);
 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, bool *interrupted);
+		const struct sieve_script_env *senv, 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);
diff --git a/src/lib-sieve/sieve-message.c b/src/lib-sieve/sieve-message.c
index 9c290747bc54ccf0ac1bbe5d5f712c9409115d50..8327275ee6f04c06f4b77445aa0ddd276e235401 100644
--- a/src/lib-sieve/sieve-message.c
+++ b/src/lib-sieve/sieve-message.c
@@ -7,8 +7,11 @@
 #include "array.h"
 
 #include "sieve-common.h"
-#include "sieve-message.h"
+#include "sieve-error.h"
 #include "sieve-extensions.h"
+#include "sieve-address.h"
+
+#include "sieve-message.h"
 
 /*
  * Message transmission
@@ -31,17 +34,29 @@ const char *sieve_message_get_new_id
 struct sieve_message_context {
 	pool_t pool;
 	int refcount;
+
+	const struct sieve_message_data *msgdata;
+
+	/* Normalized envelope addresses */
+
+	bool envelope_parsed;
+
+	const struct sieve_address *envelope_sender;
+	const struct sieve_address *envelope_recipient;
 	
 	/* Context data for extensions */
 	ARRAY_DEFINE(ext_contexts, void *); 
 };
 
-struct sieve_message_context *sieve_message_context_create(void)
+struct sieve_message_context *sieve_message_context_create
+(const struct sieve_message_data *msgdata)
 {
 	struct sieve_message_context *msgctx;
 	
 	msgctx = i_new(struct sieve_message_context, 1);
 	msgctx->refcount = 1;
+
+	msgctx->msgdata = msgdata;
 		
 	sieve_message_context_flush(msgctx);
 
@@ -77,6 +92,10 @@ void sieve_message_context_flush(struct sieve_message_context *msgctx)
 	pool = pool_alloconly_create("sieve_message_context", 1024);
 	msgctx->pool = pool;
 
+	msgctx->envelope_recipient = NULL;
+	msgctx->envelope_sender = NULL;
+	msgctx->envelope_parsed = FALSE;
+
 	p_array_init(&msgctx->ext_contexts, pool, sieve_extensions_get_count());
 }
 
@@ -108,3 +127,64 @@ const void *sieve_message_context_extension_get
 	return *ctx;
 }
 
+/* Envelope */
+
+static void sieve_message_envelope_parse(struct sieve_message_context *msgctx)
+{
+	/* FIXME: log parse problems properly; logs only 'failure' now */
+
+	msgctx->envelope_recipient = sieve_address_parse_envelope_path
+		(msgctx->pool, msgctx->msgdata->to_address);	
+
+	if ( msgctx->envelope_recipient == NULL )
+		sieve_sys_error("envelope recipient address '%s' is unparseable", msgctx->msgdata->to_address); 
+	else if ( msgctx->envelope_recipient->local_part == NULL )
+		sieve_sys_error("envelope recipient address '%s' is a null path", msgctx->msgdata->to_address); 
+
+	msgctx->envelope_sender = sieve_address_parse_envelope_path
+		(msgctx->pool, msgctx->msgdata->return_path);	
+
+	if ( msgctx->envelope_sender == NULL )
+		sieve_sys_error("envelope sender address '%s' is unparseable", msgctx->msgdata->return_path); 
+
+	msgctx->envelope_parsed = TRUE;
+}
+
+const struct sieve_address *sieve_message_get_recipient_address
+(struct sieve_message_context *msgctx)
+{
+	if ( !msgctx->envelope_parsed ) 
+		sieve_message_envelope_parse(msgctx);
+
+	return msgctx->envelope_recipient;
+} 
+
+const struct sieve_address *sieve_message_get_sender_address
+(struct sieve_message_context *msgctx)
+{
+	if ( !msgctx->envelope_parsed ) 
+		sieve_message_envelope_parse(msgctx);
+
+	return msgctx->envelope_sender;	
+} 
+
+const char *sieve_message_get_recipient
+(struct sieve_message_context *msgctx)
+{
+	if ( !msgctx->envelope_parsed ) 
+		sieve_message_envelope_parse(msgctx);
+
+	return sieve_address_to_string(msgctx->envelope_recipient);
+}
+
+const char *sieve_message_get_sender
+(struct sieve_message_context *msgctx)
+{
+	if ( !msgctx->envelope_parsed ) 
+		sieve_message_envelope_parse(msgctx);
+
+	return sieve_address_to_string(msgctx->envelope_sender);
+} 
+
+
+
diff --git a/src/lib-sieve/sieve-message.h b/src/lib-sieve/sieve-message.h
index 8f7f236e7452002c5e063179e4f273997ac69cc8..e2a87096bded96bcf836a0eacabfdd64305315b8 100644
--- a/src/lib-sieve/sieve-message.h
+++ b/src/lib-sieve/sieve-message.h
@@ -17,7 +17,8 @@ const char *sieve_message_get_new_id
 
 struct sieve_message_context;
 
-struct sieve_message_context *sieve_message_context_create(void);
+struct sieve_message_context *sieve_message_context_create
+	(const struct sieve_message_data *msgdata);
 void sieve_message_context_ref(struct sieve_message_context *msgctx);
 void sieve_message_context_unref(struct sieve_message_context **msgctx);
 
@@ -33,5 +34,19 @@ void sieve_message_context_extension_set
 		void *context);
 const void *sieve_message_context_extension_get
 	(struct sieve_message_context *msgctx, const struct sieve_extension *ext);
+
+/* Envelope */
+
+const struct sieve_address *sieve_message_get_recipient_address
+	(struct sieve_message_context *msgctx);
+
+const struct sieve_address *sieve_message_get_sender_address
+	(struct sieve_message_context *msgctx);
+
+const char *sieve_message_get_recipient
+	(struct sieve_message_context *msgctx);
+
+const char *sieve_message_get_sender
+	(struct sieve_message_context *msgctx);
 	
 #endif /* __SIEVE_MESSAGE_H */
diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c
index b1a3ee964ce8b2b1ae450077f279d61bb7b847d9..653e0d2b948b699db8b6c6e38ecee4d0cf3606ec 100644
--- a/src/lib-sieve/sieve-result.c
+++ b/src/lib-sieve/sieve-result.c
@@ -15,6 +15,8 @@
 #include "sieve-error.h"
 #include "sieve-interpreter.h"
 #include "sieve-actions.h"
+#include "sieve-message.h"
+
 #include "sieve-result.h"
 
 #include <stdio.h>
@@ -83,7 +85,8 @@ struct sieve_result {
 };
 
 struct sieve_result *sieve_result_create
-(struct sieve_error_handler *ehandler) 
+(const struct sieve_message_data *msgdata, const struct sieve_script_env *senv,
+	struct sieve_error_handler *ehandler)
 {
 	pool_t pool;
 	struct sieve_result *result;
@@ -100,6 +103,9 @@ struct sieve_result *sieve_result_create
 	result->ehandler = ehandler;
 
 	result->action_env.result = result;
+	result->action_env.scriptenv = senv;
+	result->action_env.msgdata = msgdata;
+	result->action_env.msgctx = sieve_message_context_create(msgdata); 
 		
 	result->keep_action = &act_store;
 	result->failure_action = &act_store;
@@ -124,6 +130,8 @@ void sieve_result_unref(struct sieve_result **result)
 	if (--(*result)->refcount != 0)
 		return;
 
+	sieve_message_context_unref(&(*result)->action_env.msgctx);
+
 	if ( (*result)->action_contexts != NULL )
         hash_table_destroy(&(*result)->action_contexts);
 
@@ -146,6 +154,12 @@ struct sieve_error_handler *sieve_result_get_error_handler
 	return result->ehandler;
 }
 
+struct sieve_message_context *sieve_result_get_message_context
+(struct sieve_result *result)
+{
+	return result->action_env.msgctx;
+}
+
 void sieve_result_set_error_handler
 (struct sieve_result *result, struct sieve_error_handler *ehandler)
 {
@@ -868,13 +882,11 @@ 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_result *result)
 {
+	const struct sieve_script_env *senv = result->action_env.scriptenv;
 	struct sieve_exec_status dummy_status;
 
-	result->action_env.msgdata = msgdata;
-	result->action_env.scriptenv = senv;
 	result->action_env.exec_status = 
 		( senv->exec_status == NULL ? &dummy_status : senv->exec_status );
 
@@ -899,9 +911,9 @@ 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, bool *keep)
+(struct sieve_result *result, bool *keep)
 {
+	const struct sieve_script_env *senv = result->action_env.scriptenv;
 	struct sieve_exec_status dummy_status;
 	bool implicit_keep = TRUE;
 	bool success = TRUE, commit_ok;
@@ -912,8 +924,6 @@ int sieve_result_execute
 
 	/* Prepare environment */
 
-	result->action_env.msgdata = msgdata;
-	result->action_env.scriptenv = senv;
 	result->action_env.exec_status = 
 		( senv->exec_status == NULL ? &dummy_status : senv->exec_status );
 	
diff --git a/src/lib-sieve/sieve-result.h b/src/lib-sieve/sieve-result.h
index 48fc5836c5d95f0f38524673d9bf185410ce0e3c..314f8c50c8cbf9a074582388191fc9fa6e95a399 100644
--- a/src/lib-sieve/sieve-result.h
+++ b/src/lib-sieve/sieve-result.h
@@ -19,7 +19,8 @@ struct sieve_side_effects_list;
 struct sieve_result;
 
 struct sieve_result *sieve_result_create
-	(struct sieve_error_handler *ehandler);
+	(const struct sieve_message_data *msgdata, const struct sieve_script_env *senv,
+		struct sieve_error_handler *ehandler);
 
 void sieve_result_ref(struct sieve_result *result); 
 
@@ -32,6 +33,9 @@ struct sieve_error_handler *sieve_result_get_error_handler
 void sieve_result_set_error_handler
 	(struct sieve_result *result, struct sieve_error_handler *ehandler);
 
+struct sieve_message_context *sieve_result_get_message_context
+	(struct sieve_result *result);
+
 /*
  * Extension support
  */
@@ -107,15 +111,11 @@ void sieve_result_set_failure_action
  * Result execution
  */
  
-bool sieve_result_implicit_keep
-	(struct sieve_result *result, const struct sieve_message_data *msgdata,
-		const struct sieve_script_env *senv);
+bool sieve_result_implicit_keep(struct sieve_result *result);
 
 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, bool *keep);
+int sieve_result_execute(struct sieve_result *result, bool *keep);
 
 /*
  * Result evaluation
diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c
index d54371d0853688de14e5bbc43b391d4edb28d504..63089a5ffdf0a78c6debfeb09f6998c459d87219 100644
--- a/src/lib-sieve/sieve.c
+++ b/src/lib-sieve/sieve.c
@@ -185,7 +185,7 @@ static int sieve_run
 	
 	/* Create result object */
 	if ( *result == NULL )
-		*result = sieve_result_create(ehandler);
+		*result = sieve_result_create(msgdata, senv, ehandler);
 	else {
 		sieve_result_ref(*result);
 		sieve_result_set_error_handler(*result, ehandler);
@@ -325,10 +325,10 @@ int sieve_execute
 	if ( ret >= 0 ) {
 		if ( ret > 0 ) 
 			/* Execute result */
-			ret = sieve_result_execute(result, msgdata, senv, NULL);
+			ret = sieve_result_execute(result, NULL);
 		else {
 			/* Perform implicit keep if script failed with a normal runtime error */
-			if ( !sieve_result_implicit_keep(result, msgdata, senv) )
+			if ( !sieve_result_implicit_keep(result) )
 				ret = SIEVE_EXEC_KEEP_FAILED;
 		}
 	}
@@ -362,7 +362,7 @@ struct sieve_multiscript *sieve_multiscript_start_execute
 	struct sieve_result *result;
 	struct sieve_multiscript *mscript;
 	
-	result = sieve_result_create(NULL);
+	result = sieve_result_create(msgdata, senv, NULL);
 	pool = sieve_result_pool(result);
 	
 	sieve_result_set_keep_action(result, NULL);
@@ -412,11 +412,9 @@ static void sieve_multiscript_execute
 	sieve_result_set_error_handler(mscript->result, ehandler);
 
 	if ( mscript->status > 0 )
-		mscript->status = sieve_result_execute
-			(mscript->result, mscript->msgdata, mscript->scriptenv, &keep);
+		mscript->status = sieve_result_execute(mscript->result, &keep);
 	else {
-		if ( !sieve_result_implicit_keep
-			(mscript->result, mscript->msgdata, mscript->scriptenv) )
+		if ( !sieve_result_implicit_keep(mscript->result) )
 			mscript->status = SIEVE_EXEC_KEEP_FAILED;
 	}
 	
@@ -470,8 +468,7 @@ int sieve_multiscript_finish(struct sieve_multiscript **mscript,
 
 		if ( (*mscript)->teststream ) {
 		} else {
-			if ( !sieve_result_implicit_keep
-				((*mscript)->result, (*mscript)->msgdata, (*mscript)->scriptenv) )
+			if ( !sieve_result_implicit_keep((*mscript)->result) )
 				ret = SIEVE_EXEC_KEEP_FAILED;
 		}
 	}
diff --git a/src/testsuite/testsuite-common.c b/src/testsuite/testsuite-common.c
index b48894025f4732025031ebf1124e094b6f2e4037..87c48a91d37bb730e87ce3bf7f28d6c59c6a9893 100644
--- a/src/testsuite/testsuite-common.c
+++ b/src/testsuite/testsuite-common.c
@@ -232,14 +232,12 @@ void testsuite_init(void)
 	testsuite_tmp_dir_init();
 	
 	testsuite_script_init();
-	testsuite_result_init();
 	testsuite_smtp_init();
 }
 
 void testsuite_deinit(void)
 {
 	testsuite_smtp_deinit();
-	testsuite_result_deinit();
 	testsuite_script_deinit();
 	
 	testsuite_tmp_dir_deinit();
diff --git a/src/testsuite/testsuite-common.h b/src/testsuite/testsuite-common.h
index 50b18523ae660ede75844698379f3f6cb9001109..f9caed1744ae7b6c0dfc2052ac01b0f97afa041e 100644
--- a/src/testsuite/testsuite-common.h
+++ b/src/testsuite/testsuite-common.h
@@ -12,6 +12,8 @@
 
 extern const struct sieve_extension testsuite_extension;
 
+extern const struct sieve_script_env *testsuite_scriptenv;
+
 /* 
  * Validator context 
  */
diff --git a/src/testsuite/testsuite-log.c b/src/testsuite/testsuite-log.c
index a4326dcaa3775196d030e1a7036030ebdf23b6fb..5436ee041ccbd1d6c082633151f1a6461089e1ee 100644
--- a/src/testsuite/testsuite-log.c
+++ b/src/testsuite/testsuite-log.c
@@ -106,11 +106,15 @@ void testsuite_log_init(void)
 	testsuite_log_ehandler = _testsuite_log_ehandler_create(); 	
 	sieve_error_handler_accept_infolog(testsuite_log_ehandler, TRUE);
 
+	sieve_system_ehandler_set(testsuite_log_ehandler);
+
 	testsuite_log_clear_messages();
 }
 
 void testsuite_log_deinit(void)
 {
+	sieve_system_ehandler_reset();
+
 	sieve_error_handler_unref(&testsuite_log_ehandler);
 
 	pool_unref(&_testsuite_logmsg_pool);
diff --git a/src/testsuite/testsuite-message.c b/src/testsuite/testsuite-message.c
index 9488222dd9d7ad33db4579089f5b8137e3c54ae3..4fd4b0bcea63db0258a130a49ec74ee7a5c3a86c 100644
--- a/src/testsuite/testsuite-message.c
+++ b/src/testsuite/testsuite-message.c
@@ -120,7 +120,8 @@ void testsuite_message_deinit(void)
 	pool_unref(&message_pool);
 }
 
-void testsuite_envelope_set_sender(const char *value)
+void testsuite_envelope_set_sender
+(const struct sieve_runtime_env *renv, const char *value)
 {
 	str_truncate(envelope_from, 0);
 
@@ -128,9 +129,12 @@ void testsuite_envelope_set_sender(const char *value)
 		str_append(envelope_from, value);
 
 	testsuite_msgdata.return_path = str_c(envelope_from);
+
+	sieve_message_context_flush(renv->msgctx);
 }
 
-void testsuite_envelope_set_recipient(const char *value)
+void testsuite_envelope_set_recipient
+(const struct sieve_runtime_env *renv, const char *value)
 {
 	str_truncate(envelope_to, 0);
 
@@ -138,9 +142,12 @@ void testsuite_envelope_set_recipient(const char *value)
 		str_append(envelope_to, value);
 
 	testsuite_msgdata.to_address = str_c(envelope_to);
+
+	sieve_message_context_flush(renv->msgctx);
 }
 
-void testsuite_envelope_set_auth_user(const char *value)
+void testsuite_envelope_set_auth_user
+(const struct sieve_runtime_env *renv, const char *value)
 {
 	str_truncate(envelope_auth, 0);
 
@@ -148,5 +155,7 @@ void testsuite_envelope_set_auth_user(const char *value)
 		str_append(envelope_auth, value);
 
 	testsuite_msgdata.auth_user = str_c(envelope_auth);
+
+	sieve_message_context_flush(renv->msgctx);
 } 
  
diff --git a/src/testsuite/testsuite-message.h b/src/testsuite/testsuite-message.h
index ca869c75e896a0b326510c72e26cd4038cca895b..bb89a93b95f79c82336ffcd889ef1ebd7e64cfc7 100644
--- a/src/testsuite/testsuite-message.h
+++ b/src/testsuite/testsuite-message.h
@@ -20,8 +20,11 @@ void testsuite_message_set_string
 void testsuite_message_set_file
 	(const struct sieve_runtime_env *renv, const char *file_path);
 
-void testsuite_envelope_set_sender(const char *value);
-void testsuite_envelope_set_recipient(const char *value);
-void testsuite_envelope_set_auth_user(const char *value);
+void testsuite_envelope_set_sender
+	(const struct sieve_runtime_env *renv, const char *value);
+void testsuite_envelope_set_recipient
+	(const struct sieve_runtime_env *renv, const char *value);
+void testsuite_envelope_set_auth_user
+	(const struct sieve_runtime_env *renv, const char *value);
 
 #endif /* __TESTSUITE_MESSAGE_H */
diff --git a/src/testsuite/testsuite-objects.c b/src/testsuite/testsuite-objects.c
index bfbf74d9c1de064864a87081ccad7e9ef8efe220..5cc734f7afde50dba88f70016cf98ec6fea921db 100644
--- a/src/testsuite/testsuite-objects.c
+++ b/src/testsuite/testsuite-objects.c
@@ -317,17 +317,17 @@ static const char *tsto_envelope_get_member_name(int id)
 }
 
 static bool tsto_envelope_set_member
-(const struct sieve_runtime_env *renv ATTR_UNUSED, int id, string_t *value)
+(const struct sieve_runtime_env *renv, int id, string_t *value)
 {
 	switch ( id ) {
 	case TESTSUITE_OBJECT_ENVELOPE_FROM: 
-		testsuite_envelope_set_sender(str_c(value));
+		testsuite_envelope_set_sender(renv, str_c(value));
 		return TRUE;
 	case TESTSUITE_OBJECT_ENVELOPE_TO:
-		testsuite_envelope_set_recipient(str_c(value));
+		testsuite_envelope_set_recipient(renv, str_c(value));
 		return TRUE;
 	case TESTSUITE_OBJECT_ENVELOPE_AUTH_USER: 
-		testsuite_envelope_set_auth_user(str_c(value));
+		testsuite_envelope_set_auth_user(renv, str_c(value));
 		return TRUE;
 	}
 	
diff --git a/src/testsuite/testsuite-result.c b/src/testsuite/testsuite-result.c
index 9cbaf54786778d8cb3081793f7cb54d4a956a431..d1175db42310e7bcdc5fceb4ba22d1d2506dbd1c 100644
--- a/src/testsuite/testsuite-result.c
+++ b/src/testsuite/testsuite-result.c
@@ -12,13 +12,16 @@
 
 #include "testsuite-common.h"
 #include "testsuite-log.h"
+#include "testsuite-message.h"
+
 #include "testsuite-result.h"
 
 static struct sieve_result *_testsuite_result;
 
 void testsuite_result_init(void)
 {
-	_testsuite_result = sieve_result_create(testsuite_log_ehandler);
+	_testsuite_result = sieve_result_create
+		(&testsuite_msgdata, testsuite_scriptenv, testsuite_log_ehandler);
 }
 
 void testsuite_result_deinit(void)
@@ -35,7 +38,8 @@ void testsuite_result_reset
 		sieve_result_unref(&_testsuite_result);
 	}
 
-	_testsuite_result = sieve_result_create(testsuite_log_ehandler);
+	_testsuite_result = sieve_result_create
+		(&testsuite_msgdata, testsuite_scriptenv, testsuite_log_ehandler);
 	sieve_interpreter_set_result(renv->interp, _testsuite_result);
 }
 
@@ -65,8 +69,7 @@ bool testsuite_result_execute(const struct sieve_runtime_env *renv)
 	testsuite_log_clear_messages();
 
 	/* Execute the result */	
-	ret=sieve_result_execute
-		(_testsuite_result, renv->msgdata, renv->scriptenv, NULL);
+	ret=sieve_result_execute(_testsuite_result, NULL);
 	
 	return ( ret > 0 );
 }
diff --git a/src/testsuite/testsuite-smtp.c b/src/testsuite/testsuite-smtp.c
index 5308d3af28436e71483730c9ef728b03dca71b7e..8bd9010ef5aced473237fabd38229825ad984221 100644
--- a/src/testsuite/testsuite-smtp.c
+++ b/src/testsuite/testsuite-smtp.c
@@ -124,8 +124,8 @@ bool testsuite_smtp_get
 	smtp_msg = array_idx(&testsuite_smtp_messages, index);
 
 	testsuite_message_set_file(renv, smtp_msg->file);
-	testsuite_envelope_set_sender(smtp_msg->envelope_from);
-	testsuite_envelope_set_recipient(smtp_msg->envelope_to);
+	testsuite_envelope_set_sender(renv, smtp_msg->envelope_from);
+	testsuite_envelope_set_recipient(renv, smtp_msg->envelope_to);
 
 	return TRUE;
 }
diff --git a/src/testsuite/testsuite.c b/src/testsuite/testsuite.c
index 99b113ff6d9d85eb2fd47d0ca85f12fd1f910ee8..7c1ea07ae963c7d1e7a5e9423087e5f3db7dc7de 100644
--- a/src/testsuite/testsuite.c
+++ b/src/testsuite/testsuite.c
@@ -35,6 +35,8 @@
 #include <pwd.h>
 #include <sysexits.h>
 
+const struct sieve_script_env *testsuite_scriptenv;
+
 /*
  * Configuration
  */
@@ -191,9 +193,9 @@ int main(int argc, char **argv)
 	
 	/* Compile sieve script */
 	if ( (sbin = sieve_tool_script_compile(scriptfile, NULL)) != NULL ) {
+		struct sieve_error_handler *ehandler;
 	    struct mail_storage_service_input input;
 		struct sieve_script_env scriptenv;
-		struct sieve_error_handler *ehandler;
 		struct mail_user *mail_user;
 
 		/* Dump script */
@@ -223,6 +225,10 @@ int main(int argc, char **argv)
 		scriptenv.smtp_close = testsuite_smtp_close;
 		scriptenv.trace_stream = ( trace ? o_stream_create_fd(1, 0, FALSE) : NULL );
 
+		testsuite_scriptenv = &scriptenv;
+
+		testsuite_result_init();
+
 		/* Run the test */
 		ehandler = sieve_stderr_ehandler_create(0);
 		ret = testsuite_run(sbin, &testsuite_msgdata, &scriptenv, ehandler);
@@ -249,6 +255,7 @@ int main(int argc, char **argv)
 
 		/* De-initialize message environment */
 		testsuite_message_deinit();
+		testsuite_result_deinit();
 
 		/* De-initialize mail user */
 		if ( mail_user != NULL )