diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c
index f7e74915192fc38423ad1f873824a8497b655a79..4594fe674d1a9f3de264d0f1cf9f68f63dbb15fe 100644
--- a/src/lib-sieve/cmd-redirect.c
+++ b/src/lib-sieve/cmd-redirect.c
@@ -376,16 +376,18 @@ static bool act_redirect_commit
 		action->mail : sieve_message_get_mail(aenv->msgctx) );
 	const struct sieve_message_data *msgdata = aenv->msgdata;
 	const struct sieve_script_env *senv = aenv->scriptenv;
+	const char *orig_recipient = sieve_message_get_orig_recipient(aenv->msgctx);
 	const char *dupeid;
 
 	/* Prevent mail loops if possible */
-	dupeid = msgdata->id == NULL ?
-		NULL : t_strdup_printf("%s-%s", msgdata->id, ctx->to_address);
+	dupeid = msgdata->id == NULL ? NULL : t_strdup_printf
+		("%s-%s-%s", msgdata->id, orig_recipient, ctx->to_address);
 	if (dupeid != NULL) {
 		/* Check whether we've seen this message before */
 		if (sieve_action_duplicate_check(senv, dupeid, strlen(dupeid))) {
 			sieve_result_global_log(aenv, "discarded duplicate forward to <%s>",
 				str_sanitize(ctx->to_address, 128));
+			*keep = FALSE;
 			return TRUE;
 		}
 	}
diff --git a/src/lib-sieve/edit-mail.c b/src/lib-sieve/edit-mail.c
index ddb7e028b8ce4b41dba39b16c27bf38b15df5975..76d35c5c26365b53970fb047a130147db789370f 100644
--- a/src/lib-sieve/edit-mail.c
+++ b/src/lib-sieve/edit-mail.c
@@ -322,6 +322,7 @@ struct edit_mail *edit_mail_snapshot(struct edit_mail *edmail)
 				(&edmail_new->header_fields_head, &edmail_new->header_fields_tail,
 					field_idx_new);
 
+			field_idx_new->header->count++;
 			if ( field_idx->header->first == field_idx )
 				field_idx_new->header->first = field_idx_new;
 			if ( field_idx->header->last == field_idx )
@@ -658,9 +659,11 @@ static int edit_mail_headers_parse
 	/* Insert header field index items in main list */
 	if ( head != NULL && tail != NULL ) {
 		if ( edmail->header_fields_appended != NULL ) {
-			if ( edmail->header_fields_appended->prev != NULL ) {
+			if ( edmail->header_fields_head != edmail->header_fields_appended ) {
 				edmail->header_fields_appended->prev->next = head;
 				head->prev = edmail->header_fields_appended->prev;
+			} else {
+				edmail->header_fields_head = head;
 			}
 
 			tail->next = edmail->header_fields_appended;
diff --git a/src/lib-sieve/plugins/editheader/ext-editheader-common.c b/src/lib-sieve/plugins/editheader/ext-editheader-common.c
index 4c4c8c0693bd88700642eb00e6a536ad238e01c2..3967b4768becd8cc6113d44dab6c307ef9cd56ab 100644
--- a/src/lib-sieve/plugins/editheader/ext-editheader-common.c
+++ b/src/lib-sieve/plugins/editheader/ext-editheader-common.c
@@ -64,7 +64,7 @@ bool ext_editheader_load
 	}
 
 	T_BEGIN {
-		pool = pool_alloconly_create("editheader_config", 512);
+		pool = pool_alloconly_create("editheader_config", 1024);
 		ext_config = p_new(pool, struct ext_editheader_config, 1);
 		ext_config->pool = pool;
 		ext_config->max_header_size = EXT_EDITHEADER_DEFAULT_MAX_HEADER_SIZE;
diff --git a/src/lib-sieve/sieve-ast.c b/src/lib-sieve/sieve-ast.c
index 2f84465df097cd0e7966497d8ad8cad7b8b5abfb..64510d47c25341431cdde75b7d585fb01cd3b1d3 100644
--- a/src/lib-sieve/sieve-ast.c
+++ b/src/lib-sieve/sieve-ast.c
@@ -59,7 +59,7 @@ struct sieve_ast *sieve_ast_create
 	struct sieve_ast *ast;
 	unsigned int ext_count;
 
-	pool = pool_alloconly_create("sieve_ast", 16384);
+	pool = pool_alloconly_create("sieve_ast", 32768);
 	ast = p_new(pool, struct sieve_ast, 1);
 	ast->pool = pool;
 	ast->refcount = 1;
diff --git a/src/lib-sieve/sieve-binary.c b/src/lib-sieve/sieve-binary.c
index 07d1079c1fa2147db143e3acd3b643407bfec17b..45ae9e8d81a5bbb43e529e4cd0f7962164923ab4 100644
--- a/src/lib-sieve/sieve-binary.c
+++ b/src/lib-sieve/sieve-binary.c
@@ -43,7 +43,7 @@ struct sieve_binary *sieve_binary_create
 	const struct sieve_extension *const *ext_preloaded;
 	unsigned int i, ext_count;
 
-	pool = pool_alloconly_create("sieve_binary", 8192);
+	pool = pool_alloconly_create("sieve_binary", 16384);
 	sbin = p_new(pool, struct sieve_binary, 1);
 	sbin->pool = pool;
 	sbin->refcount = 1;
diff --git a/src/lib-sieve/sieve-error.c b/src/lib-sieve/sieve-error.c
index afb7677efa2c7b00e86556bc5f6f79c65f1eadc4..7796746010fe18e160ceb691a571482b12a748ea 100644
--- a/src/lib-sieve/sieve-error.c
+++ b/src/lib-sieve/sieve-error.c
@@ -1221,7 +1221,7 @@ struct sieve_error_handler *sieve_prefix_ehandler_create
 	if ( parent == NULL )
 		return NULL;
 
-	pool = pool_alloconly_create("sieve_prefix_error_handler", 256);
+	pool = pool_alloconly_create("sieve_prefix_error_handler", 512);
 	ehandler = p_new(pool, struct sieve_prefix_ehandler, 1);
 	sieve_error_handler_init_from_parent(&ehandler->handler, pool, parent);
 
@@ -1320,7 +1320,7 @@ struct sieve_error_handler *sieve_varexpand_ehandler_create
 		return parent;
 	}
 
-	pool = pool_alloconly_create("sieve_varexpand_error_handler", 1024);
+	pool = pool_alloconly_create("sieve_varexpand_error_handler", 2048);
 	ehandler = p_new(pool, struct sieve_varexpand_ehandler, 1);
 	sieve_error_handler_init_from_parent(&ehandler->handler, pool, parent);
 
diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c
index a69619a57248b0624104186712abfdf246f0a445..59127c489970810cf81c8b7cd7c280f3bd6a3ce6 100644
--- a/src/lib-sieve/sieve-validator.c
+++ b/src/lib-sieve/sieve-validator.c
@@ -150,7 +150,7 @@ struct sieve_validator *sieve_validator_create
 	const struct sieve_extension *const *ext_preloaded;
 	unsigned int i, ext_count;
 
-	pool = pool_alloconly_create("sieve_validator", 8192);
+	pool = pool_alloconly_create("sieve_validator", 16384);
 	valdtr = p_new(pool, struct sieve_validator, 1);
 	valdtr->pool = pool;
 
diff --git a/src/managesieve-login/client-authenticate.c b/src/managesieve-login/client-authenticate.c
index 4ae7ef822e9bf82294784cea3e8850f4faf086b3..de698f6dc7f60e5cfee2d2c903faf60982468091 100644
--- a/src/managesieve-login/client-authenticate.c
+++ b/src/managesieve-login/client-authenticate.c
@@ -243,7 +243,7 @@ static int managesieve_client_auth_read_response
 	}
 
 	if ( i_stream_next_line(client->input) == NULL )
-		msieve_client->skip_line = TRUE;
+		return 0;
 
 	return 1;
 }
diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c
index 3d5c735b7de527d7edee5c746edba5e02a15e60c..47925b08b89b241acc4e4801257be79ddcde78bd 100644
--- a/src/plugins/lda-sieve/lda-sieve-plugin.c
+++ b/src/plugins/lda-sieve/lda-sieve-plugin.c
@@ -221,7 +221,7 @@ static int lda_sieve_multiscript_get_scripts
 			(svinst, files[i], NULL, ehandler, &error);
 
 		if ( script == NULL ) {
-			switch ( errno ) {
+			switch ( error ) {
 			case SIEVE_ERROR_NOT_FOUND:
 				/* Shouldn't normally happen, but the script could have disappeared */
 				sieve_sys_warning
@@ -277,25 +277,34 @@ static struct sieve_binary *lda_sieve_open
 		ehandler = srctx->master_ehandler;
 
 	if ( debug )
-		sieve_sys_debug(svinst, "opening script %s", sieve_script_location(script));
+		sieve_sys_debug(svinst, "loading script %s", sieve_script_location(script));
 
 	sieve_error_handler_reset(ehandler);
 
-	/* Open the sieve script */
+	/* Load or compile the sieve script */
 	if ( (sbin=sieve_open_script(script, ehandler, cpflags, error_r)) == NULL ) {
-		if ( *error_r == SIEVE_ERROR_NOT_FOUND ) {
+		switch ( *error_r ) {
+		/* Script not found */
+		case SIEVE_ERROR_NOT_FOUND:
 			if ( debug ) {
 				sieve_sys_debug(svinst, "script file %s is missing",
 					sieve_script_location(script));
 			}
-		} else if ( *error_r == SIEVE_ERROR_NOT_VALID &&
-			script == srctx->user_script && srctx->userlog != NULL ) {
-			sieve_sys_error(svinst,	"failed to open script %s "
-				"(view user logfile %s for more information)",
-				sieve_script_location(script), srctx->userlog);
-		} else {
+			break;
+		/* Compile failed */
+		case SIEVE_ERROR_NOT_VALID:
+			if (script == srctx->user_script && srctx->userlog != NULL ) {
+				sieve_sys_info(svinst, "failed to compile script %s "
+					"(view user logfile %s for more information)",
+					sieve_script_location(script), srctx->userlog);
+				break;
+			}
+			/* Fall through */
+		/* Something else */
+		default:
 			sieve_sys_error(svinst,	"failed to open script %s",
 				sieve_script_location(script));
+			break;
 		}
 
 		return NULL;
@@ -330,19 +339,25 @@ static struct sieve_binary *lda_sieve_recompile
 	if ( (sbin=sieve_compile_script(script, ehandler,	cpflags, error_r))
 		== NULL ) {
 
-		if ( *error_r == SIEVE_ERROR_NOT_FOUND ) {
-			if ( debug )
+		switch ( *error_r ) {
+		case SIEVE_ERROR_NOT_FOUND:
+			if ( debug ) {
 				sieve_sys_debug(svinst, "script file %s is missing for re-compile",
 					sieve_script_location(script));
-		} else if ( *error_r == SIEVE_ERROR_NOT_VALID &&
-			script == srctx->user_script && srctx->userlog != NULL ) {
-			sieve_sys_error(svinst,
-				"failed to re-compile script %s "
-				"(view user logfile %s for more information)",
-				sieve_script_location(script), srctx->userlog);
-		} else {
-			sieve_sys_error(svinst,
-				"failed to re-compile script %s", sieve_script_location(script));
+			}
+			break;
+		case SIEVE_ERROR_NOT_VALID:
+			if ( script == srctx->user_script && srctx->userlog != NULL ) {
+				sieve_sys_info(svinst,
+					"failed to re-compile script %s "
+					"(view user logfile %s for more information)",
+					sieve_script_location(script), srctx->userlog);
+				break;
+			}
+			/* Fall through */
+		default:
+			sieve_sys_error(svinst,	"failed to open script %s for re-compile",
+				sieve_script_location(script));
 		}
 
 		return NULL;
diff --git a/tests/extensions/editheader/alternating.svtest b/tests/extensions/editheader/alternating.svtest
index cef84c4860d595b6d2e6b510dd6c5bad186c9239..44d459c7100f8e6fa8c73ba10110d814c0afa21b 100644
--- a/tests/extensions/editheader/alternating.svtest
+++ b/tests/extensions/editheader/alternating.svtest
@@ -120,3 +120,62 @@ test "Alternating - delete; add" {
 		test_fail "wrong content in redirected mail ";
 	}
 }
+
+test_result_reset;
+
+test_set "message" "${message}";
+test "Alternating - add :last; delete any" {
+	addheader :last "X-Some-Header" "Header content";
+
+	if not exists "x-some-header" {
+		test_fail "header not added";
+	}
+
+	if not header :is "x-some-header" "Header content" {
+		test_fail "wrong content added";
+	}
+
+	redirect "frop@example.com";
+
+	deleteheader "X-Some-Other-Header";
+
+	if not exists "x-some-header" {
+		test_fail "header somehow deleted";
+	}
+
+	fileinto :create "folder3";
+
+	if not test_result_execute {
+		test_fail "failed to execute result";
+	}
+
+	/* redirected message */
+
+	if not test_message :smtp 0 {
+		test_fail "message not redirected";
+	}
+
+	if not exists "x-some-header" {
+		test_fail "added header not in redirected mail";
+	}
+
+	if not header :is "x-some-header" "Header content" {
+		test_fail "wrong content in redirected mail ";
+	}
+
+	/* stored message message */
+
+	if not test_message :folder "folder3" 0 {
+		test_fail "message not stored";
+	}
+
+	if not exists "x-some-header" {
+		test_fail "added header lost in stored mail";
+	}
+
+	if not header :is "x-some-header" "Header content" {
+		test_fail "wrong content in stored mail ";
+	}
+
+}
+