diff --git a/src/lib-sieve/ext-envelope.c b/src/lib-sieve/ext-envelope.c
index 92064737e442ab8dd19cf674f559ba1b3cbc9b15..0d2a3d7699dbc0c2f3874439e85a8b84ee4e2922 100644
--- a/src/lib-sieve/ext-envelope.c
+++ b/src/lib-sieve/ext-envelope.c
@@ -219,7 +219,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_message_get_recipient_address(renv->msgctx);	
+		sieve_message_get_orig_recipient_address(renv->msgctx);	
 
 	if ( address != NULL && address->local_part != NULL ) {
 		t_array_init(&envelope_values, 2);
@@ -240,8 +240,8 @@ static const char *const *_to_part_get_values
 
 	t_array_init(&envelope_values, 2);
 
-	if ( renv->msgdata->to_address != NULL ) {
-        array_append(&envelope_values, &renv->msgdata->to_address, 1);
+	if ( renv->msgdata->orig_envelope_to != NULL ) {
+        array_append(&envelope_values, &renv->msgdata->orig_envelope_to, 1);
 	}
 
 	(void)array_append_space(&envelope_values);
@@ -249,7 +249,6 @@ static const char *const *_to_part_get_values
 	return array_idx(&envelope_values, 0);
 }
 
-
 static const char *const *_auth_part_get_values
 (const struct sieve_runtime_env *renv)
 {
diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c
index e942b852340ba15bb1dae3baccc977cbf5c878d6..d2b23ac30d0174143a3e3f738eccb6cf54c720b6 100644
--- a/src/lib-sieve/ext-reject.c
+++ b/src/lib-sieve/ext-reject.c
@@ -503,7 +503,7 @@ static bool act_reject_commit
 	struct act_reject_context *rj_ctx =
 		(struct act_reject_context *) action->context;
 	const char *sender = sieve_message_get_sender(aenv->msgctx);
-	const char *recipient = sieve_message_get_recipient(aenv->msgctx);
+	const char *recipient = sieve_message_get_final_recipient(aenv->msgctx);
 
 	if ( recipient == NULL ) {
 		sieve_result_global_warning(aenv, 
diff --git a/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c b/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c
index 5e4dd4992c297b6a967da05d0e13565bf1296c55..e4470b6ab8bd8da9e90c34bc73136454f8e60dff 100644
--- a/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c
+++ b/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c
@@ -551,7 +551,7 @@ static bool ntfy_mailto_action_execute
 {
 	const char *const *headers;
 	const char *sender = sieve_message_get_sender(nenv->msgctx);
-	const char *recipient = sieve_message_get_recipient(nenv->msgctx);
+	const char *recipient = sieve_message_get_final_recipient(nenv->msgctx);
 
 	/* Is the recipient unset? 
 	 */
@@ -571,8 +571,8 @@ static bool ntfy_mailto_action_execute
 			if ( strcasecmp(*hdsp, "no") != 0 ) {
 				sieve_enotify_global_info(nenv, 
 					"not sending notification for auto-submitted message from <%s>", 
-					str_sanitize(sender, 128));	
-					return TRUE;				 
+					str_sanitize(sender, 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 bbabae3daacc79355aea3c7f776eadf085574e89..61a4ea1a9270ed085313fc11d60d9f5235d49981 100644
--- a/src/lib-sieve/plugins/vacation/cmd-vacation.c
+++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c
@@ -974,7 +974,7 @@ static bool act_vacation_commit
 	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);
+	const char *recipient = sieve_message_get_final_recipient(aenv->msgctx);
 	const char *reply_from = NULL;
 
 	/* Is the recipient unset? 
diff --git a/src/lib-sieve/sieve-message.c b/src/lib-sieve/sieve-message.c
index 1ff42a197713b6f3562ea3155c726719635a9a0f..d2f0f0a8964cf4366d9f7d825db21232443e7f8a 100644
--- a/src/lib-sieve/sieve-message.c
+++ b/src/lib-sieve/sieve-message.c
@@ -50,7 +50,9 @@ struct sieve_message_context {
 	bool envelope_parsed;
 
 	const struct sieve_address *envelope_sender;
-	const struct sieve_address *envelope_recipient;
+	const struct sieve_address *envelope_orig_recipient;
+	const struct sieve_address *envelope_final_recipient;
+
 	
 	/* Context data for extensions */
 	ARRAY_DEFINE(ext_contexts, void *); 
@@ -101,7 +103,8 @@ 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_orig_recipient = NULL;
+	msgctx->envelope_final_recipient = NULL;
 	msgctx->envelope_sender = NULL;
 	msgctx->envelope_parsed = FALSE;
 
@@ -142,43 +145,70 @@ const void *sieve_message_context_extension_get
 
 static void sieve_message_envelope_parse(struct sieve_message_context *msgctx)
 {
+	const struct sieve_message_data *msgdata = msgctx->msgdata;
 	struct sieve_instance *svinst = msgctx->svinst;
 
 	/* FIXME: log parse problems properly; logs only 'failure' now */
 
-	msgctx->envelope_recipient = sieve_address_parse_envelope_path
-		(msgctx->pool, msgctx->msgdata->to_address);	
+	msgctx->envelope_orig_recipient = sieve_address_parse_envelope_path
+		(msgctx->pool, msgdata->orig_envelope_to);	
 
-	if ( msgctx->envelope_recipient == NULL ) {
+	if ( msgctx->envelope_orig_recipient == NULL ) {
 		sieve_sys_error(svinst,
-			"envelope recipient address '%s' is unparsable",
-			msgctx->msgdata->to_address); 
-	} else if ( msgctx->envelope_recipient->local_part == NULL ) {
+			"original envelope recipient address '%s' is unparsable",
+			msgdata->orig_envelope_to); 
+	} else if ( msgctx->envelope_orig_recipient->local_part == NULL ) {
 		sieve_sys_error(svinst,
-			"envelope recipient address '%s' is a null path",
-			msgctx->msgdata->to_address);
+			"original envelope recipient address '%s' is a null path",
+			msgdata->orig_envelope_to);
 	} 
 
+	msgctx->envelope_final_recipient = sieve_address_parse_envelope_path
+		(msgctx->pool, msgdata->final_envelope_to);	
+	
+	if ( msgctx->envelope_final_recipient == NULL ) {
+		if ( msgctx->envelope_orig_recipient != NULL ) {
+			sieve_sys_error(svinst,
+				"final envelope recipient address '%s' is unparsable",
+				msgdata->final_envelope_to);
+		} 
+	} else if ( msgctx->envelope_final_recipient->local_part == NULL ) {
+		if ( strcmp(msgdata->orig_envelope_to, msgdata->final_envelope_to) != 0 ) {
+			sieve_sys_error(svinst,
+				"final envelope recipient address '%s' is a null path",
+				msgdata->final_envelope_to);
+		}
+	}
+
 	msgctx->envelope_sender = sieve_address_parse_envelope_path
-		(msgctx->pool, msgctx->msgdata->return_path);	
+		(msgctx->pool, msgdata->return_path);	
 
 	if ( msgctx->envelope_sender == NULL ) {
 		sieve_sys_error(svinst, 
 			"envelope sender address '%s' is unparsable", 
-			msgctx->msgdata->return_path);
+			msgdata->return_path);
 	}
 
 	msgctx->envelope_parsed = TRUE;
 }
 
-const struct sieve_address *sieve_message_get_recipient_address
+const struct sieve_address *sieve_message_get_orig_recipient_address
 (struct sieve_message_context *msgctx)
 {
 	if ( !msgctx->envelope_parsed ) 
 		sieve_message_envelope_parse(msgctx);
 
-	return msgctx->envelope_recipient;
-} 
+	return msgctx->envelope_orig_recipient;
+}
+
+const struct sieve_address *sieve_message_get_final_recipient_address
+(struct sieve_message_context *msgctx)
+{
+	if ( !msgctx->envelope_parsed ) 
+		sieve_message_envelope_parse(msgctx);
+
+	return msgctx->envelope_final_recipient;
+}
 
 const struct sieve_address *sieve_message_get_sender_address
 (struct sieve_message_context *msgctx)
@@ -189,13 +219,22 @@ const struct sieve_address *sieve_message_get_sender_address
 	return msgctx->envelope_sender;	
 } 
 
-const char *sieve_message_get_recipient
+const char *sieve_message_get_orig_recipient
+(struct sieve_message_context *msgctx)
+{
+	if ( !msgctx->envelope_parsed ) 
+		sieve_message_envelope_parse(msgctx);
+
+	return sieve_address_to_string(msgctx->envelope_orig_recipient);
+}
+
+const char *sieve_message_get_final_recipient
 (struct sieve_message_context *msgctx)
 {
 	if ( !msgctx->envelope_parsed ) 
 		sieve_message_envelope_parse(msgctx);
 
-	return sieve_address_to_string(msgctx->envelope_recipient);
+	return sieve_address_to_string(msgctx->envelope_final_recipient);
 }
 
 const char *sieve_message_get_sender
diff --git a/src/lib-sieve/sieve-message.h b/src/lib-sieve/sieve-message.h
index 47a275623f9df3695f925d5a41c34be9b0168552..471d0db287c001861417e9cfef42ecfec18b5fa9 100644
--- a/src/lib-sieve/sieve-message.h
+++ b/src/lib-sieve/sieve-message.h
@@ -37,13 +37,17 @@ const void *sieve_message_context_extension_get
 
 /* Envelope */
 
-const struct sieve_address *sieve_message_get_recipient_address
+const struct sieve_address *sieve_message_get_final_recipient_address
+	(struct sieve_message_context *msgctx);
+const struct sieve_address *sieve_message_get_orig_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
+const char *sieve_message_get_orig_recipient
+	(struct sieve_message_context *msgctx);
+const char *sieve_message_get_final_recipient
 	(struct sieve_message_context *msgctx);
 
 const char *sieve_message_get_sender
diff --git a/src/lib-sieve/sieve-types.h b/src/lib-sieve/sieve-types.h
index 459b17fc65d0dd27340857db5f6e78b153400624..c75f87524bafb593d70c236c84f2c35c99965172 100644
--- a/src/lib-sieve/sieve-types.h
+++ b/src/lib-sieve/sieve-types.h
@@ -69,7 +69,8 @@ enum sieve_error {
 struct sieve_message_data {
 	struct mail *mail;
 	const char *return_path;
-	const char *to_address;
+	const char *orig_envelope_to;
+	const char *final_envelope_to;
 	const char *auth_user;
 	const char *id;
 };
diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c
index 6183dccdb399d3550d2b1fd3a02e50ff2cd7f507..030033ceeabdbef9e0083513ddfd6b164c0efc46 100644
--- a/src/plugins/lda-sieve/lda-sieve-plugin.c
+++ b/src/plugins/lda-sieve/lda-sieve-plugin.c
@@ -588,7 +588,8 @@ static int lda_sieve_run
 
 	msgdata.mail = mdctx->src_mail;
 	msgdata.return_path = mail_deliver_get_return_address(mdctx);
-	msgdata.to_address = mdctx->dest_addr;
+	msgdata.orig_envelope_to = mdctx->dest_addr;
+	msgdata.final_envelope_to = mdctx->final_dest_addr;
 	msgdata.auth_user = mdctx->dest_user->username;
 	(void)mail_get_first_header(msgdata.mail, "Message-ID", &msgdata.id);
 
diff --git a/src/sieve-tools/sieve-test.c b/src/sieve-tools/sieve-test.c
index b9ca7601bcd32b962b877ca5b990997e7940e149..157b3902a9cfcebb4a54d0f796624f01e7a6bc2d 100644
--- a/src/sieve-tools/sieve-test.c
+++ b/src/sieve-tools/sieve-test.c
@@ -105,8 +105,8 @@ int main(int argc, char **argv)
 {
 	struct sieve_instance *svinst;
 	ARRAY_TYPE (const_string) scriptfiles;
-	const char *scriptfile, *recipient, *sender, *mailbox, *dumpfile, *tracefile,
-		*mailfile, *mailloc; 
+	const char *scriptfile, *recipient, *final_recipient, *sender, *mailbox,
+		*dumpfile, *tracefile, *mailfile, *mailloc;
 	struct sieve_trace_config tr_config;
 	struct mail *mail;
 	struct sieve_binary *main_sbin, *sbin = NULL;
@@ -121,13 +121,13 @@ int main(int argc, char **argv)
 	int ret, c;
 
 	sieve_tool = sieve_tool_init
-		("sieve-test", &argc, &argv, "r:f:m:d:l:s:eCt:T:DP:x:u:", FALSE);
+		("sieve-test", &argc, &argv, "r:a:f:m:d:l:s:eCt:T:DP:x:u:", FALSE);
 
 	t_array_init(&scriptfiles, 16);
-	
+
 	/* Parse arguments */
-	scriptfile = recipient = sender = mailbox = dumpfile = tracefile =
-		mailfile = mailloc = NULL;
+	scriptfile = recipient = final_recipient = sender = mailbox = dumpfile =
+		tracefile = mailfile = mailloc = NULL;
 	memset(&tr_config, 0, sizeof(tr_config));
 	tr_config.level = SIEVE_TRLVL_ACTIONS;
 	while ((c = sieve_tool_getopt(sieve_tool)) > 0) {
@@ -136,6 +136,10 @@ int main(int argc, char **argv)
 			/* destination address */
 			recipient = optarg;
 			break;
+		case 'a':
+			/* final destination address */
+			final_recipient = optarg;
+			break;
 		case 'f':
 			/* envelope sender address */
 			sender = optarg;
@@ -243,7 +247,9 @@ int main(int argc, char **argv)
 		memset(&msgdata, 0, sizeof(msgdata));
 		msgdata.mail = mail;
 		msgdata.return_path = sender;
-		msgdata.to_address = recipient;
+		msgdata.orig_envelope_to = recipient;
+		msgdata.final_envelope_to =
+			( final_recipient == NULL ? recipient : final_recipient );
 		msgdata.auth_user = sieve_tool_get_username(sieve_tool);
 		(void)mail_get_first_header(mail, "Message-ID", &msgdata.id);
 
diff --git a/src/testsuite/testsuite-message.c b/src/testsuite/testsuite-message.c
index a87cbbb94375335c7345c7ee7aeac3f76d3cb0d3..0c60d6dc86465395104bcb1320c009566c4e1157 100644
--- a/src/testsuite/testsuite-message.c
+++ b/src/testsuite/testsuite-message.c
@@ -65,7 +65,8 @@ static void testsuite_message_set_data(struct mail *mail)
 	testsuite_msgdata.mail = mail;
 	testsuite_msgdata.auth_user = sieve_tool_get_username(sieve_tool);
 	testsuite_msgdata.return_path = sender;
-	testsuite_msgdata.to_address = recipient;
+	testsuite_msgdata.orig_envelope_to = recipient;
+	testsuite_msgdata.final_envelope_to = recipient;
 
 	(void)mail_get_first_header(mail, "Message-ID", &testsuite_msgdata.id);
 }
@@ -137,7 +138,8 @@ void testsuite_envelope_set_recipient
 	if ( value != NULL )
 		str_append(envelope_to, value);
 
-	testsuite_msgdata.to_address = str_c(envelope_to);
+	testsuite_msgdata.orig_envelope_to = str_c(envelope_to);
+	testsuite_msgdata.final_envelope_to = str_c(envelope_to);
 
 	sieve_message_context_flush(renv->msgctx);
 }