diff --git a/src/lib-sieve/plugins/include/cmd-include.c b/src/lib-sieve/plugins/include/cmd-include.c
index 75c95e00b8f297765944807673aa29ae6e5c4d56..c9eca4896768de8b8fe0ad091592d8e9b7e49f01 100644
--- a/src/lib-sieve/plugins/include/cmd-include.c
+++ b/src/lib-sieve/plugins/include/cmd-include.c
@@ -68,7 +68,7 @@ const struct sieve_operation include_operation = {
 struct cmd_include_context_data {
 	enum ext_include_script_location location;
 	bool location_assigned;
-	const char *script_name;
+	struct sieve_script *script;
 };   
 
 /* Tags */
@@ -122,23 +122,34 @@ static bool cmd_include_validate_location_tag
 
 /* Command registration */
 
-enum cmd_include_optional {
-	OPT_END,
-	OPT_LOCATION
-};
-
 static bool cmd_include_registered
 	(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) 
 {
 	sieve_validator_register_tag
-		(validator, cmd_reg, &include_personal_tag, OPT_LOCATION); 	
+		(validator, cmd_reg, &include_personal_tag, 0); 	
 	sieve_validator_register_tag
-		(validator, cmd_reg, &include_global_tag, OPT_LOCATION); 	
+		(validator, cmd_reg, &include_global_tag, 0); 	
 
 	return TRUE;
 }
 
-/* Command validation */
+/* 
+ * Command validation 
+ */
+
+static void cmd_include_ast_destroy
+(struct sieve_ast *ast ATTR_UNUSED, struct sieve_ast_node *node)
+{
+	struct sieve_command_context *cmd = node->context;
+	struct cmd_include_context_data *ctx_data = 
+		(struct cmd_include_context_data *) cmd->data;
+		
+	sieve_script_unref(&ctx_data->script);
+}
+
+static const struct sieve_ast_node_object cmd_include_ast_object = {
+	cmd_include_ast_destroy
+};
 
 static bool cmd_include_pre_validate
 	(struct sieve_validator *validator ATTR_UNUSED, 
@@ -160,15 +171,28 @@ static bool cmd_include_validate(struct sieve_validator *validator,
 	struct sieve_ast_argument *arg = cmd->first_positional;
 	struct cmd_include_context_data *ctx_data = 
 		(struct cmd_include_context_data *) cmd->data;
+	struct sieve_script *script;
+	const char *script_path, *script_name;
 	
 	if ( !sieve_validate_positional_argument
 		(validator, cmd, arg, "value", 1, SAAT_STRING) ) {
 		return FALSE;
 	}
+		
+	/* Find the script */
+	script_name = sieve_ast_argument_strc(arg);
+	script_path = ext_include_get_script_path(ctx_data->location, script_name);
+	if ( script_path == NULL )
+		return FALSE;
 	
-	/* Get script path */
-
-	ctx_data->script_name = sieve_ast_argument_strc(arg);
+	/* Create script object */
+	if ( (script = sieve_script_create(script_path, script_name, 
+		sieve_validator_error_handler(validator), NULL)) == NULL ) 
+		return FALSE;	
+		
+	sieve_ast_link_object(cmd->ast_node, &cmd_include_ast_object);
+	ctx_data->script = script;
+	sieve_script_ref(script);	
 		
 	arg = sieve_ast_arguments_detach(arg, 1);
 	
@@ -191,7 +215,7 @@ static bool cmd_include_generate
 	 * This yields the id of the binary block containing the compiled byte code.  
 	 */
 	if ( !ext_include_generate_include
-		(gentr, cmd, ctx_data->location, ctx_data->script_name, &block_id) )
+		(gentr, cmd, ctx_data->location, ctx_data->script, &block_id) )
  		return FALSE;
  		
  	sieve_generator_emit_operation_ext	
diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c
index ddb874b6f9e5ce7f9e94ec250cad41dd4803f20f..67aedc331c87141770a06731ee73022e16233d7d 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.c
+++ b/src/lib-sieve/plugins/include/ext-include-common.c
@@ -423,12 +423,10 @@ void ext_include_register_interpreter_context
 
 bool ext_include_generate_include
 (struct sieve_generator *gentr, struct sieve_command_context *cmd,
-	enum ext_include_script_location location, const char *script_name, 
+	enum ext_include_script_location location, struct sieve_script *script, 
 	unsigned *blk_id_r)
 {
 	bool result = TRUE;
-	const char *script_path;
-	struct sieve_script *script;
 	struct sieve_ast *ast;
 	struct sieve_binary *sbin = sieve_generator_get_binary(gentr);
 	struct ext_include_binary_context *binctx;
@@ -455,23 +453,12 @@ bool ext_include_generate_include
 		return FALSE;
 	}
 	
-	/* Find the script */
-	script_path = ext_include_get_script_path(location, script_name);
-	if ( script_path == NULL )
-		return FALSE;
-	
-	/* Create script object */
-	if ( (script = sieve_script_create(script_path, script_name, ehandler, NULL)) 
-		== NULL ) 
-		return FALSE;
-	
 	/* Check for circular include */
 	pctx = ctx;
 	while ( pctx != NULL ) {
 		if ( sieve_script_equals(pctx->script, script) ) {
 			sieve_command_generate_error(gentr, cmd, "circular include");
 				
-			sieve_script_unref(&script);
 			return FALSE;
 		}
 		
@@ -488,14 +475,13 @@ bool ext_include_generate_include
 
 	/* Is the script already compiled into the current binary? */
 	if ( !ext_include_script_is_included(binctx, script, &inc_block_id) )	{	
+		const char *script_name = sieve_script_name(script);
+		
 		/* No, allocate a new block in the binary and mark the script as included.
 		 */
 		inc_block_id = sieve_binary_block_create(sbin);
 		ext_include_script_include(binctx, script, location, inc_block_id);
 		
-		/* Include list now holds a reference, so we can release it here safely */
-		sieve_script_unref(&script);
-		
 		/* Parse */
 		if ( (ast = sieve_parse(script, ehandler)) == NULL ) {
 	 		sieve_command_generate_error(gentr, cmd, 
@@ -532,9 +518,7 @@ bool ext_include_generate_include
 		
 		/* Cleanup */
 		sieve_ast_unref(&ast);		
-	} else 
-		/* Yes, aready compiled and included, so release script object right away */
-		sieve_script_unref(&script);
+	} 
 
 	if ( result ) *blk_id_r = inc_block_id;
 	
diff --git a/src/lib-sieve/plugins/include/ext-include-common.h b/src/lib-sieve/plugins/include/ext-include-common.h
index 4c924a7486354c6ed0299555e7e95540bbd0b021..3440e209a0e5b7e5a8a8661bb633f7ebe78af96f 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.h
+++ b/src/lib-sieve/plugins/include/ext-include-common.h
@@ -55,7 +55,7 @@ void ext_include_register_generator_context
 
 bool ext_include_generate_include
 	(struct sieve_generator *gentr, struct sieve_command_context *cmd,
-		enum ext_include_script_location location, const char *script_name, 
+		enum ext_include_script_location location, struct sieve_script *script, 
 		unsigned *blk_id_r);
 
 /* Binary */
diff --git a/src/lib-sieve/plugins/include/include-error.sieve b/src/lib-sieve/plugins/include/include-error.sieve
new file mode 100644
index 0000000000000000000000000000000000000000..2da67e58152e1dad7724cf8fcff64f380d4204b5
--- /dev/null
+++ b/src/lib-sieve/plugins/include/include-error.sieve
@@ -0,0 +1,3 @@
+require "include";
+
+include "frop.sieve";
diff --git a/src/lib-sieve/sieve-ast.c b/src/lib-sieve/sieve-ast.c
index 0b02aacd12a282b62735db094225e7411a277217..5ab6edde176abd6f185c709d60d8a8f74fdefbdc 100644
--- a/src/lib-sieve/sieve-ast.c
+++ b/src/lib-sieve/sieve-ast.c
@@ -3,6 +3,7 @@
 #include "lib.h"
 #include "str.h"
 #include "mempool.h"
+#include "array.h"
 
 #include "sieve-script.h"
 
@@ -14,6 +15,13 @@ static struct sieve_ast_node *sieve_ast_node_create
 	(struct sieve_ast *ast, struct sieve_ast_node *parent, 
 		enum sieve_ast_type type, unsigned int source_line);
 
+/* Links to other objects (notified if AST is destroyed) */
+
+struct sieve_ast_node_link {
+	struct sieve_ast_node *node;
+	const struct sieve_ast_node_object *object;
+};
+
 /* The AST object */
 
 struct sieve_ast {
@@ -23,6 +31,8 @@ struct sieve_ast {
 	struct sieve_script *script;
 		
 	struct sieve_ast_node *root;
+	
+	ARRAY_DEFINE(node_links, struct sieve_ast_node_link);
 };
 
 struct sieve_ast *sieve_ast_create(struct sieve_script *script) 
@@ -41,21 +51,46 @@ struct sieve_ast *sieve_ast_create(struct sieve_script *script)
 	ast->root = sieve_ast_node_create(ast, NULL, SAT_ROOT, 0);
 	ast->root->identifier = "ROOT";
 	
+	p_array_init(&ast->node_links, pool, 4);
+	
 	return ast;
 }
 
-void sieve_ast_ref(struct sieve_ast *ast) {
+void sieve_ast_link_object
+(struct sieve_ast_node *node, const struct sieve_ast_node_object *obj)
+{
+	struct sieve_ast_node_link link;
+	
+	link.node = node;
+	link.object = obj;
+	array_append(&node->ast->node_links, &link, 1);
+}
+
+void sieve_ast_ref(struct sieve_ast *ast) 
+{
 	ast->refcount++;
 }
 
-void sieve_ast_unref(struct sieve_ast **ast) {
+void sieve_ast_unref(struct sieve_ast **ast) 
+{
+	unsigned int i, lcount;
+	const struct sieve_ast_node_link *node_links;
+	
 	i_assert((*ast)->refcount > 0);
 
 	if (--(*ast)->refcount != 0)
 		return;
 	
+	/* Release script reference */
 	sieve_script_unref(&(*ast)->script);
 	
+	/* Signal linked objects that the AST is being destroyed */
+	node_links = array_get(&(*ast)->node_links, &lcount);
+	for ( i = 0; i < lcount; i++ ) {
+		node_links[i].object->ast_destroy(*ast, node_links[i].node);
+	}
+	
+	/* Destroy AST */
 	pool_unref(&(*ast)->pool);
 	
 	*ast = NULL;
diff --git a/src/lib-sieve/sieve-ast.h b/src/lib-sieve/sieve-ast.h
index 76262be5441d18c1ffc4fdd4a3c5cd831d505957..cfd638b2fa6299d055f49446e991213f5f1e3437 100644
--- a/src/lib-sieve/sieve-ast.h
+++ b/src/lib-sieve/sieve-ast.h
@@ -147,6 +147,10 @@ struct sieve_ast_node {
 	struct sieve_command_context *context;	
 };
 
+struct sieve_ast_node_object {
+	void (*ast_destroy)(struct sieve_ast *ast, struct sieve_ast_node *node);
+};
+
 struct sieve_ast;
 
 /* sieve_ast */
@@ -154,6 +158,9 @@ struct sieve_ast *sieve_ast_create(struct sieve_script *script);
 void sieve_ast_ref(struct sieve_ast *ast);
 void sieve_ast_unref(struct sieve_ast **ast);
 
+void sieve_ast_link_object
+	(struct sieve_ast_node *node, const struct sieve_ast_node_object *obj);
+
 inline struct sieve_ast_node *sieve_ast_root(struct sieve_ast *ast);
 inline pool_t sieve_ast_pool(struct sieve_ast *ast);
 inline struct sieve_script *sieve_ast_script(struct sieve_ast *ast);