diff --git a/sieve/examples/vivil.sieve b/sieve/examples/vivil.sieve
index 03f78b8ae4bce896ab2ac348251900e5212e3f16..bce750703b0755471fa9b1501e5112aa88213358 100644
--- a/sieve/examples/vivil.sieve
+++ b/sieve/examples/vivil.sieve
@@ -1,9 +1,10 @@
 # Example Sieve Script
 #   Author: Vivil
 #   URL: http://wiki.fastmail.fm/index.php?title=Vivil
+#   Removed unused notify require
 
 # *************************************************************************
-require ["envelope", "fileinto", "reject", "notify", "vacation", "regex", "relational", 
+require ["envelope", "fileinto", "reject", "vacation", "regex", "relational", 
 "comparator-i;ascii-numeric"];
 
 
diff --git a/sieve/tests/stop.sieve b/sieve/tests/stop.sieve
new file mode 100644
index 0000000000000000000000000000000000000000..fe56f5ea1c5cd274b931aebbbf089c8cfdc00af4
--- /dev/null
+++ b/sieve/tests/stop.sieve
@@ -0,0 +1,10 @@
+require "fileinto";
+
+if address :contains "from" "frop" {
+	fileinto "junk";
+	stop;
+}
+
+redirect "me@example.com";
+
+
diff --git a/src/lib-sieve/cmd-if.c b/src/lib-sieve/cmd-if.c
index 9b196f829eaa35084b2a5b0776dbad34b066f4c8..6c09f0cae03e355bda92981c668ee78de5183d41 100644
--- a/src/lib-sieve/cmd-if.c
+++ b/src/lib-sieve/cmd-if.c
@@ -67,6 +67,7 @@ struct cmd_if_context_data {
 	struct cmd_if_context_data *previous;
 	struct cmd_if_context_data *next;
 	
+	bool jump_generated;
 	sieve_size_t exit_jump;
 };
 
@@ -80,6 +81,7 @@ static void cmd_if_initialize_context_data
 	ctx_data->previous = previous;
 	ctx_data->next = NULL;
 	ctx_data->exit_jump = 0;
+	ctx_data->jump_generated = FALSE;
 	
 	if ( previous != NULL )
 		previous->next = ctx_data;
@@ -131,7 +133,8 @@ static void cmd_if_resolve_exit_jumps
 	struct cmd_if_context_data *if_ctx = ctx_data->previous;
 	
 	while ( if_ctx != NULL ) {
-		sieve_binary_resolve_offset(sbin, if_ctx->exit_jump);
+		if ( if_ctx->jump_generated ) 
+			sieve_binary_resolve_offset(sbin, if_ctx->exit_jump);
 		if_ctx = if_ctx->previous;	
 	}
 }
@@ -156,9 +159,16 @@ static bool cmd_if_generate
 	
 	/* Are we the final command in this if-elsif-else structure? */
 	if ( ctx_data->next != NULL ) {
-		/* No, generate jump to end of if-elsif-else structure (resolved later) */
-		sieve_operation_emit_code(sbin, SIEVE_OPCODE_JMP);
-		ctx_data->exit_jump = sieve_binary_emit_offset(sbin, 0);
+		/* No, generate jump to end of if-elsif-else structure (resolved later) 
+		 * This of course is not necessary if the {} block contains a command 
+		 * like stop at top level that unconditionally exits the block already
+		 * anyway. 
+		 */
+		if ( !sieve_command_block_exits_unconditionally(ctx) ) {
+			sieve_operation_emit_code(sbin, SIEVE_OPCODE_JMP);
+			ctx_data->exit_jump = sieve_binary_emit_offset(sbin, 0);
+			ctx_data->jump_generated = TRUE;
+		}
 	} else {
 		/* Yes, Resolve previous exit jumps to this point */
 		cmd_if_resolve_exit_jumps(sbin, ctx_data);
diff --git a/src/lib-sieve/sieve-commands.c b/src/lib-sieve/sieve-commands.c
index 9f063177eb32861af73c842d5904d8723398f11d..69eef6e01182ea05d4f0eeb5d8450143622b42f8 100644
--- a/src/lib-sieve/sieve-commands.c
+++ b/src/lib-sieve/sieve-commands.c
@@ -138,6 +138,9 @@ static const struct sieve_command tst_true = {
 static bool cmd_stop_generate
 	(struct sieve_generator *generator, 
 		struct sieve_command_context *ctx ATTR_UNUSED);
+static bool cmd_stop_validate
+	(struct sieve_validator *validator, struct sieve_command_context *ctx);
+	
 static bool cmd_keep_generate
 	(struct sieve_generator *generator, 
 		struct sieve_command_context *ctx ATTR_UNUSED);
@@ -149,7 +152,8 @@ static const struct sieve_command cmd_stop = {
 	"stop", 
 	SCT_COMMAND, 
 	0, 0, FALSE, FALSE,
-	NULL, NULL, NULL, 
+	NULL, NULL,  
+	cmd_stop_validate, 
 	cmd_stop_generate, 
 	NULL 
 };
@@ -193,7 +197,7 @@ const unsigned int sieve_core_commands_count = N_ELEMENTS(sieve_core_commands);
 	
 /* Command context */
 
-struct sieve_command_context *sieve_command_prev_context	
+inline struct sieve_command_context *sieve_command_prev_context	
 	(struct sieve_command_context *context) 
 {
 	struct sieve_ast_node *node = sieve_ast_node_prev(context->ast_node);
@@ -205,6 +209,18 @@ struct sieve_command_context *sieve_command_prev_context
 	return NULL;
 }
 
+inline struct sieve_command_context *sieve_command_parent_context	
+	(struct sieve_command_context *context) 
+{
+	struct sieve_ast_node *node = sieve_ast_node_parent(context->ast_node);
+	
+	if ( node != NULL ) {
+		return node->context;
+	}
+	
+	return NULL;
+}
+
 struct sieve_command_context *sieve_command_context_create
 	(struct sieve_ast_node *cmd_node, const struct sieve_command *command)
 {
@@ -215,6 +231,8 @@ struct sieve_command_context *sieve_command_context_create
 	cmd->ast_node = cmd_node;	
 	cmd->command = command;
 	
+	cmd->block_exit_command = NULL;
+	
 	return cmd;
 }
 
@@ -229,8 +247,33 @@ const char *sieve_command_type_name(const struct sieve_command *command) {
 	return "??COMMAND-TYPE??";
 }
 
+inline void sieve_command_exit_block_unconditionally
+	(struct sieve_command_context *cmd)
+{
+	struct sieve_command_context *parent = sieve_command_parent_context(cmd);
+
+	/* Only the first unconditional exit is of importance */
+	if ( parent != NULL && parent->block_exit_command == NULL ) 
+		parent->block_exit_command = cmd;
+}
+
+inline bool sieve_command_block_exits_unconditionally
+	(struct sieve_command_context *cmd)
+{
+	return ( cmd->block_exit_command != NULL );
+}
+
 /* Code generation for trivial commands and tests */
 
+static bool cmd_stop_validate
+	(struct sieve_validator *validator ATTR_UNUSED, 
+		struct sieve_command_context *ctx)
+{
+	sieve_command_exit_block_unconditionally(ctx);
+	
+	return TRUE;
+}
+
 static bool cmd_stop_generate
 	(struct sieve_generator *generator, 
 		struct sieve_command_context *ctx ATTR_UNUSED) 
diff --git a/src/lib-sieve/sieve-commands.h b/src/lib-sieve/sieve-commands.h
index bc41804e8bc97b024bdb09b51f6efd6ed9c8b1c4..a88a8ef23975a3613e59777791ec159be75946a7 100644
--- a/src/lib-sieve/sieve-commands.h
+++ b/src/lib-sieve/sieve-commands.h
@@ -70,9 +70,12 @@ struct sieve_command_context {
 	/* The ast node of this command */
 	struct sieve_ast_node *ast_node;
 			
-	/* First positional argument */
+	/* First positional argument, found during argument validation */
 	struct sieve_ast_argument *first_positional;
 
+	/* The child ast node that unconditionally exits this command's block */
+	struct sieve_command_context *block_exit_command;
+
 	/* Command-specific context data*/
 	void *data;
 };
@@ -95,7 +98,14 @@ const char *sieve_command_type_name(const struct sieve_command *command);
 #define sieve_command_is_first(context) \
 	( sieve_ast_node_prev((context)->ast_node) == NULL )	
 
-struct sieve_command_context *sieve_command_prev_context	
+inline struct sieve_command_context *sieve_command_prev_context	
 	(struct sieve_command_context *context); 
+inline struct sieve_command_context *sieve_command_parent_context	
+	(struct sieve_command_context *context);
+	
+inline void sieve_command_exit_block_unconditionally
+	(struct sieve_command_context *cmd);
+inline bool sieve_command_block_exits_unconditionally
+	(struct sieve_command_context *cmd);
 
 #endif /* __SIEVE_COMMANDS_H */
diff --git a/src/lib-sieve/sieve-generator.c b/src/lib-sieve/sieve-generator.c
index 180ed5b744a656e7ef3c392840d744323ba9b95c..d295bd132871aac84078d3e28d88edc2177e1c1a 100644
--- a/src/lib-sieve/sieve-generator.c
+++ b/src/lib-sieve/sieve-generator.c
@@ -186,7 +186,8 @@ bool sieve_generate_test
 	return TRUE;
 }
 
-static bool sieve_generate_command(struct sieve_generator *generator, struct sieve_ast_node *cmd_node) 
+static bool sieve_generate_command
+	(struct sieve_generator *generator, struct sieve_ast_node *cmd_node) 
 {
 	i_assert( cmd_node->context != NULL && cmd_node->context->command != NULL );
 
@@ -197,7 +198,8 @@ static bool sieve_generate_command(struct sieve_generator *generator, struct sie
 	return TRUE;		
 }
 
-bool sieve_generate_block(struct sieve_generator *generator, struct sieve_ast_node *block) 
+bool sieve_generate_block
+	(struct sieve_generator *generator, struct sieve_ast_node *block) 
 {
 	struct sieve_ast_node *command;
 
diff --git a/src/lib-sieve/sieve-generator.h b/src/lib-sieve/sieve-generator.h
index 47606e85393fc4bcedf18d3065cf852ac74da6c0..217befe16b35d38ef7ee25d3d08bea9b72c99fe6 100644
--- a/src/lib-sieve/sieve-generator.h
+++ b/src/lib-sieve/sieve-generator.h
@@ -57,9 +57,11 @@ inline void sieve_generator_register_extension
 bool sieve_generate_arguments(struct sieve_generator *generator, 
 	struct sieve_command_context *cmd, struct sieve_ast_argument **arg);
 
-bool sieve_generate_block(struct sieve_generator *generator, struct sieve_ast_node *block);
-bool sieve_generate_test(struct sieve_generator *generator, struct sieve_ast_node *tst_node, 
-	struct sieve_jumplist *jlist, bool jump_true);
+bool sieve_generate_block
+	(struct sieve_generator *generator, struct sieve_ast_node *block);
+bool sieve_generate_test
+	(struct sieve_generator *generator, struct sieve_ast_node *tst_node, 
+		struct sieve_jumplist *jlist, bool jump_true);
 struct sieve_binary *sieve_generator_run(struct sieve_generator *genarator);
 
 #endif /* __SIEVE_GENERATOR_H */