diff --git a/src/lib-sieve/plugins/include/cmd-include.c b/src/lib-sieve/plugins/include/cmd-include.c
index c609e3a25e97a25f1f97bdf62551576836e5a033..d6331a599f39f18b7af18dc23799ce4292bad932 100644
--- a/src/lib-sieve/plugins/include/cmd-include.c
+++ b/src/lib-sieve/plugins/include/cmd-include.c
@@ -148,20 +148,6 @@ static bool cmd_include_registered
  * 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, 
 		struct sieve_command_context *cmd)
@@ -209,10 +195,9 @@ static bool cmd_include_validate(struct sieve_validator *validator,
 		sieve_validator_error_handler(validator), NULL);
 	if ( script == NULL ) 
 		return FALSE;	
-		
-	sieve_ast_link_object(cmd->ast_node, &cmd_include_ast_object);
+
+	ext_include_ast_link_included_script(cmd->ast_node->ast, script);		
 	ctx_data->script = script;
-	sieve_script_ref(script);	
 		
 	arg = sieve_ast_arguments_detach(arg, 1);
 	
diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c
index 45d67e8a0b9389ce87c7d5d22e7644672f3cc6e1..a987d9ae40876b432d456eac6f0b7728ce9ca45f 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.c
+++ b/src/lib-sieve/plugins/include/ext-include-common.c
@@ -19,7 +19,7 @@
 /*
  * Forward declarations
  */
- 
+
 /* Generator context */
 
 struct ext_include_generator_context {
@@ -82,6 +82,70 @@ const char *ext_include_get_script_directory
 	return sieve_dir;
 }
 
+/*
+ * AST context management
+ */
+
+static void ext_include_ast_free
+(struct sieve_ast *ast ATTR_UNUSED, void *context)
+{
+	struct ext_include_ast_context *actx = 
+		(struct ext_include_ast_context *) context;
+	struct sieve_script **scripts;
+	unsigned int count, i;
+
+	scripts = array_get_modifiable(&actx->included_scripts, &count);
+    for ( i = 0; i < count; i++ ) {
+		sieve_script_unref(&scripts[i]);
+    }	
+}
+
+static const struct sieve_ast_extension include_ast_extension = {
+	&include_extension,
+	ext_include_ast_free
+};
+
+struct ext_include_ast_context *ext_include_create_ast_context
+(struct sieve_ast *ast, struct sieve_ast *parent)
+{
+    struct ext_include_ast_context *actx;
+
+    pool_t pool = sieve_ast_pool(ast);
+    actx = p_new(pool, struct ext_include_ast_context, 1);
+   	actx->import_vars = sieve_variable_scope_create(pool, &include_extension);
+	p_array_init(&actx->included_scripts, pool, 32);
+
+    if ( parent != NULL ) {
+        struct ext_include_ast_context *parent_ctx =
+            (struct ext_include_ast_context *)
+            sieve_ast_extension_get_context(parent, &include_extension);
+        actx->global_vars = ( parent_ctx == NULL ? NULL : parent_ctx->global_vars );
+    }
+
+	sieve_ast_extension_register(ast, &include_ast_extension, (void *) actx);
+
+    return actx;
+}
+
+struct ext_include_ast_context *ext_include_get_ast_context
+(struct sieve_ast *ast)
+{
+	struct ext_include_ast_context *actx = (struct ext_include_ast_context *)
+        sieve_ast_extension_get_context(ast, &include_extension);
+
+	if ( actx != NULL ) return actx;
+
+	return ext_include_create_ast_context(ast, NULL);
+}
+
+void ext_include_ast_link_included_script
+(struct sieve_ast *ast, struct sieve_script *script) 
+{
+	struct ext_include_ast_context *actx = ext_include_get_ast_context(ast);
+
+	array_append(&actx->included_scripts, &script, 1);
+}
+
 /* 
  * Generator context management 
  */
diff --git a/src/lib-sieve/plugins/include/ext-include-common.h b/src/lib-sieve/plugins/include/ext-include-common.h
index a793d2fc254ea98056b690b6eb1b85e5dba89769..28daa04eb3e0fcfe858552e9a608e748bea45fe9 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.h
+++ b/src/lib-sieve/plugins/include/ext-include-common.h
@@ -43,7 +43,30 @@ enum ext_include_script_location {
 const char *ext_include_get_script_directory
 	(enum ext_include_script_location location, const char *script_name);
 
-/* Generator */
+/* 
+ * AST Context 
+ */
+
+/* AST context */
+
+struct ext_include_ast_context {
+    struct sieve_variable_scope *import_vars;
+    struct sieve_variable_scope *global_vars;
+
+    ARRAY_DEFINE(included_scripts, struct sieve_script *);
+};
+
+struct ext_include_ast_context *ext_include_create_ast_context
+	(struct sieve_ast *ast, struct sieve_ast *parent);
+struct ext_include_ast_context *ext_include_get_ast_context
+	(struct sieve_ast *ast);
+
+void ext_include_ast_link_included_script
+	(struct sieve_ast *ast, struct sieve_script *script);
+
+/* 
+ * Generator context
+ */
 
 void ext_include_register_generator_context
 	(struct sieve_generator *gentr);
@@ -53,7 +76,9 @@ bool ext_include_generate_include
 		enum ext_include_script_location location, struct sieve_script *script, 
 		unsigned *blk_id_r);
 
-/* Interpreter */
+/* 
+ * Interpreter context
+ */
 
 void ext_include_interpreter_context_init(struct sieve_interpreter *interp);
 
diff --git a/src/lib-sieve/plugins/include/ext-include-variables.c b/src/lib-sieve/plugins/include/ext-include-variables.c
index da749379737d53c7df2f62c7cbc109f964d068b6..0d8d91c73b46c3ae50bba9db9256736b7402a147 100644
--- a/src/lib-sieve/plugins/include/ext-include-variables.c
+++ b/src/lib-sieve/plugins/include/ext-include-variables.c
@@ -10,54 +10,6 @@
 #include "ext-include-common.h"
 #include "ext-include-variables.h"
 
-/*
- * Forward declarations
- */
- 
- 
-/* 
- * AST context 
- */
-
-struct ext_include_ast_context {
-	struct sieve_variable_scope *import_vars;
-	struct sieve_variable_scope *global_vars;
-};
-
-struct ext_include_ast_context *ext_include_create_ast_context
-(struct sieve_ast *ast, struct sieve_ast *parent)
-{	
-	struct ext_include_ast_context *ctx;
-
-	pool_t pool = sieve_ast_pool(ast);
-	ctx = p_new(pool, struct ext_include_ast_context, 1);
-	ctx->import_vars = sieve_variable_scope_create(pool, &include_extension);
-	
-	if ( parent != NULL ) {
-		struct ext_include_ast_context *parent_ctx = 
-			(struct ext_include_ast_context *)
-			sieve_ast_extension_get_context(parent, &include_extension);
-		ctx->global_vars = ( parent_ctx == NULL ? NULL : parent_ctx->global_vars );
-	}
-	
-	sieve_ast_extension_set_context(ast, &include_extension, ctx);
-	
-	return ctx;
-}
-
-static inline struct ext_include_ast_context *
-	ext_include_get_ast_context(struct sieve_ast *ast)
-{
-	struct ext_include_ast_context *ctx = (struct ext_include_ast_context *)
-		sieve_ast_extension_get_context(ast, &include_extension);
-		
-	if ( ctx == NULL ) {
-		ctx = ext_include_create_ast_context(ast, NULL);	
-	}
-	
-	return ctx;
-}
-
 /* 
  * Variable import-export
  */
diff --git a/src/lib-sieve/plugins/include/ext-include-variables.h b/src/lib-sieve/plugins/include/ext-include-variables.h
index e5aea5d86f4384108f786101bc1c993743b007e9..22f5d48539f95495c9bb67edc086f76ed10a67a8 100644
--- a/src/lib-sieve/plugins/include/ext-include-variables.h
+++ b/src/lib-sieve/plugins/include/ext-include-variables.h
@@ -6,13 +6,6 @@
 
 #include "ext-include-common.h"
 
-/* 
- * AST Context
- */
- 
-struct ext_include_ast_context *ext_include_create_ast_context
-	(struct sieve_ast *ast, struct sieve_ast *parent);
-
 /* 
  * Variable import-export
  */
diff --git a/src/lib-sieve/sieve-ast.c b/src/lib-sieve/sieve-ast.c
index e1fb2850be8cda9e4148be5ca10b9d40f2c1aded..6f3a48f8363396f1a151c6bb7fc0d28dd00ed288 100644
--- a/src/lib-sieve/sieve-ast.c
+++ b/src/lib-sieve/sieve-ast.c
@@ -16,11 +16,11 @@ 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) */
+/* Extensions to the AST */
 
-struct sieve_ast_node_link {
-	struct sieve_ast_node *node;
-	const struct sieve_ast_node_object *object;
+struct sieve_ast_extension_reg {
+	const struct sieve_ast_extension *ast_ext;
+	void *context;
 };
 
 /* The AST object */
@@ -33,9 +33,7 @@ struct sieve_ast {
 		
 	struct sieve_ast_node *root;
 	
-	ARRAY_DEFINE(ext_contexts, void *);
-
-	ARRAY_DEFINE(node_links, struct sieve_ast_node_link);
+	ARRAY_DEFINE(extensions, struct sieve_ast_extension_reg);
 };
 
 struct sieve_ast *sieve_ast_create(struct sieve_script *script) 
@@ -54,22 +52,11 @@ 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);
-	p_array_init(&ast->ext_contexts, pool, sieve_extensions_get_count());
+	p_array_init(&ast->extensions, pool, sieve_extensions_get_count());
 	
 	return 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++;
@@ -77,8 +64,8 @@ void sieve_ast_ref(struct sieve_ast *ast)
 
 void sieve_ast_unref(struct sieve_ast **ast) 
 {
-	unsigned int i, lcount;
-	const struct sieve_ast_node_link *node_links;
+	unsigned int i, ext_count;
+	const struct sieve_ast_extension_reg *extrs;
 	
 	i_assert((*ast)->refcount > 0);
 
@@ -88,12 +75,14 @@ void sieve_ast_unref(struct sieve_ast **ast)
 	/* 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);
+	/* Signal registered extensions that the AST is being destroyed */
+	extrs = array_get(&(*ast)->extensions, &ext_count);
+	for ( i = 0; i < ext_count; i++ ) {
+		if ( extrs[i].ast_ext != NULL && 
+			extrs[i].ast_ext->free != NULL )
+			extrs[i].ast_ext->free(*ast, extrs[i].context);
 	}
-	
+
 	/* Destroy AST */
 	pool_unref(&(*ast)->pool);
 	
@@ -129,24 +118,32 @@ const char *sieve_ast_type_name(enum sieve_ast_type ast_type) {
 
 /* Extension support */
 
-void sieve_ast_extension_set_context
-(struct sieve_ast *ast, const struct sieve_extension *ext, void *context)
+void sieve_ast_extension_register
+(struct sieve_ast *ast, const struct sieve_ast_extension *ast_ext, void *context)
 {
-	array_idx_set(&ast->ext_contexts, (unsigned int) *ext->id, &context);	
+	struct sieve_ast_extension_reg reg;
+	int ext_id = *ast_ext->ext->id;
+
+	if ( ext_id < 0 ) return;
+
+	reg.ast_ext = ast_ext;
+	reg.context = context;
+	
+	array_idx_set(&ast->extensions, (unsigned int) ext_id, &reg);	
 }
 
-const void *sieve_ast_extension_get_context
+void *sieve_ast_extension_get_context
 (struct sieve_ast *ast, const struct sieve_extension *ext) 
 {
 	int ext_id = *ext->id;
-	void * const *ctx;
+	const struct sieve_ast_extension_reg *reg;
 
-	if  ( ext_id < 0 || ext_id >= (int) array_count(&ast->ext_contexts) )
+	if  ( ext_id < 0 || ext_id >= (int) array_count(&ast->extensions) )
 		return NULL;
 	
-	ctx = array_idx(&ast->ext_contexts, (unsigned int) ext_id);		
+	reg = array_idx(&ast->extensions, (unsigned int) ext_id);		
 
-	return *ctx;
+	return reg->context;
 }
 
 /* AST-based error reporting */
diff --git a/src/lib-sieve/sieve-ast.h b/src/lib-sieve/sieve-ast.h
index 55e1b1112dc6c93f27421961932b70fdf21f7dc9..36c5d3cca8ff4b351ac969ae05189725deddff8d 100644
--- a/src/lib-sieve/sieve-ast.h
+++ b/src/lib-sieve/sieve-ast.h
@@ -148,8 +148,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_extension {
+	const struct sieve_extension *ext;	
+
+	void (*free)(struct sieve_ast *ast, void *context);
 };
 
 struct sieve_ast;
@@ -159,9 +161,6 @@ 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);
-
 struct sieve_ast_node *sieve_ast_root(struct sieve_ast *ast);
 pool_t sieve_ast_pool(struct sieve_ast *ast);
 struct sieve_script *sieve_ast_script(struct sieve_ast *ast);
@@ -169,9 +168,10 @@ struct sieve_script *sieve_ast_script(struct sieve_ast *ast);
 const char *sieve_ast_type_name(enum sieve_ast_type ast_type);
 
 /* extension support */
-void sieve_ast_extension_set_context
-	(struct sieve_ast *ast, const struct sieve_extension *ext, void *context);
-const void *sieve_ast_extension_get_context
+void sieve_ast_extension_register
+	(struct sieve_ast *ast, const struct sieve_ast_extension *ast_ext, 
+		void *context);
+void *sieve_ast_extension_get_context
 	(struct sieve_ast *ast, const struct sieve_extension *ext);
 
 /* error reporting */