diff --git a/TODO b/TODO
index 15dd0f8c07c66195a51aa572a30a9d8b1d1188ee..40eea335f831be597108bab289fc65dae383e1f6 100644
--- a/TODO
+++ b/TODO
@@ -7,6 +7,13 @@ Next (in order of descending priority/precedence):
 	  MUST win.
 	- 'If an address is not syntactically valid, then it will not be matched
 	  by tests specifying ":localpart" or ":domain"'.
+	- Vacation: If the Sieve variables extension is used, the arguments 
+	  MUST NOT have undergone variable expansion prior to their use in response 
+	  tracking.
+	- Vacation: The ":subject" parameter specifies a subject line to attach to 
+	  any vacation response that is generated. UTF-8 characters can be used in
+	  the string argument; implementations MUST convert the string to [RFC2047] 
+	  encoded words if and only if non-ASCII characters are present.
 * Fix security issues:
 	- Make (configurable) limit on the number of redirects
 	- Impose limitations on the imapflags extension regarding the number of
diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c
index 55c5c38207ba5d5d89d9dfc8e67b241b3db2f592..c11233c5302455ab564486e2a0a54b8000d7399d 100644
--- a/src/lib-sieve/plugins/vacation/cmd-vacation.c
+++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c
@@ -221,6 +221,11 @@ static bool cmd_vacation_validate_number_tag
 		return FALSE;
 	}
 
+	/* Enforce :days > 0 */
+	if ( sieve_ast_argument_number(*arg) == 0 ) {
+		sieve_ast_argument_number_set(*arg, 1);
+	}
+
 	/* Skip parameter */
 	*arg = sieve_ast_argument_next(*arg);
 	
@@ -455,6 +460,10 @@ static int ext_vacation_operation_execute
 						"invalid days operand");
 					return SIEVE_EXEC_BIN_CORRUPT;
 				}
+	
+				/* Enforce days > 0 (just to be sure) */
+				if ( days == 0 )
+					days = 1;
 				break;
 			case OPT_SUBJECT:
 				if ( !sieve_opr_string_read(renv, address, &subject) ) {
@@ -738,7 +747,22 @@ static void act_vacation_hash
 	if ( vctx->handle != NULL && *(vctx->handle) != '\0' ) 
 		md5_update(&ctx, vctx->handle, strlen(vctx->handle));
 	else {
-		md5_update(&ctx, msgdata->to_address, strlen(msgdata->to_address));
+		const char *from;
+		const char *mime;
+
+		if ( vctx->from != NULL && *(vctx->from) != '\0' )
+			from = vctx->from;
+		else
+			from = msgdata->to_address;
+
+		if ( vctx->mime )
+			mime = "MIME";
+		else
+			mime = "NOMIME";
+
+		md5_update(&ctx, vctx->subject, strlen(vctx->subject));
+		md5_update(&ctx, from, strlen(from));
+		md5_update(&ctx, mime, strlen(mime));
 		md5_update(&ctx, vctx->reason, strlen(vctx->reason));
 	}
 
diff --git a/src/lib-sieve/sieve-ast.c b/src/lib-sieve/sieve-ast.c
index 328d2c94671c366d36b425ea182d69b8db19a3aa..c34c1d1ae818ec5e58a170e342436f52e55ab6a3 100644
--- a/src/lib-sieve/sieve-ast.c
+++ b/src/lib-sieve/sieve-ast.c
@@ -593,7 +593,7 @@ struct sieve_ast_argument *sieve_ast_argument_tag_insert
 }
 
 struct sieve_ast_argument *sieve_ast_argument_number_create
-(struct sieve_ast_node *node, int number, unsigned int source_line) 
+(struct sieve_ast_node *node, unsigned int number, unsigned int source_line) 
 {
 	
 	struct sieve_ast_argument *argument = 
@@ -608,6 +608,14 @@ struct sieve_ast_argument *sieve_ast_argument_number_create
 	return argument;
 }
 
+void sieve_ast_argument_number_set
+(struct sieve_ast_argument *argument, unsigned int newnum)
+{
+	i_assert( argument->type == SAAT_NUMBER );
+	argument->_value.number = newnum;
+}
+
+
 struct sieve_ast_argument *sieve_ast_arguments_detach
 (struct sieve_ast_argument *first, unsigned int count) 
 {	
diff --git a/src/lib-sieve/sieve-ast.h b/src/lib-sieve/sieve-ast.h
index a5dfd3997b021f760a3a696d2a882b262e0d7a9f..c9226256836639d40410fc270616492806d59acd 100644
--- a/src/lib-sieve/sieve-ast.h
+++ b/src/lib-sieve/sieve-ast.h
@@ -96,7 +96,7 @@ struct sieve_ast_argument {
 		string_t *str;
 		struct sieve_ast_arg_list *strlist;
 		const char *tag;
-		int number;
+		unsigned int number;
 	} _value;
   
 	unsigned int source_line;
@@ -239,13 +239,16 @@ struct sieve_ast_argument *sieve_ast_argument_string_create
 struct sieve_ast_argument *sieve_ast_argument_tag_create
 	(struct sieve_ast_node *node, const char *tag, unsigned int source_line);
 struct sieve_ast_argument *sieve_ast_argument_number_create
-	(struct sieve_ast_node *node, int number, unsigned int source_line);
+	(struct sieve_ast_node *node, unsigned int number, unsigned int source_line);
 
 void sieve_ast_argument_string_set
 	(struct sieve_ast_argument *argument, string_t *newstr);
 void sieve_ast_argument_string_setc
 	(struct sieve_ast_argument *argument, const char *newstr);
 
+void sieve_ast_argument_number_set
+    (struct sieve_ast_argument *argument, unsigned int newnum);
+
 struct sieve_ast_argument *sieve_ast_argument_tag_insert
 (struct sieve_ast_argument *before, const char *tag, unsigned int source_line);