diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c
index 2f8d498aeded05b33d74ccf5920bc8817d4e406f..6ed55b5013780292a3ea4fa0892a6bc80db8e364 100644
--- a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c
+++ b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c
@@ -254,12 +254,19 @@ static string_t *_get_flags_string
 
 /* Initialization */
 
-void ext_imapflags_runtime_init(const struct sieve_runtime_env *renv)
+static void ext_imapflags_runtime_init
+	(const struct sieve_runtime_env *renv, void *context ATTR_UNUSED)
 {	
 	sieve_result_add_implicit_side_effect
 		(renv->result, &act_store, &flags_side_effect, NULL);
 }
 
+struct sieve_interpreter_extension imapflags_interpreter_extension = {
+    &imapflags_extension,
+	ext_imapflags_runtime_init,
+    NULL,
+};
+
 /* Flag operations */
 
 /* FIXME: This currently accepts a potentially unlimited number of 
diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h
index b50d7fb82669526fd0fbaeae40a9b47f9187d59d..ed820ea6374b20abbb69bd00a30b217485b67f03 100644
--- a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h
+++ b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h
@@ -45,10 +45,6 @@ void ext_imapflags_attach_flags_tag
 
 const struct sieve_operand flags_side_effect_operand;
 
-/* Initialization */
-
-void ext_imapflags_runtime_init(const struct sieve_runtime_env *renv);
-
 /* Flag registration */
 
 struct ext_imapflags_iter {
diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags.c b/src/lib-sieve/plugins/imapflags/ext-imapflags.c
index 273c7f98765050e5b9f5e01154975a18e1d6e3bf..259949838a80144e45a56877cf60f91196c10b43 100644
--- a/src/lib-sieve/plugins/imapflags/ext-imapflags.c
+++ b/src/lib-sieve/plugins/imapflags/ext-imapflags.c
@@ -25,14 +25,17 @@
 #include "ext-imapflags-common.h"
 
 
-/* Forward declarations */
+/* 
+ * Forward declarations 
+ */
 
 static bool ext_imapflags_load(int ext_id);
 static bool ext_imapflags_validator_load(struct sieve_validator *valdtr);
-static bool ext_imapflags_runtime_load
-	(const struct sieve_runtime_env *renv);
+static bool ext_imapflags_interpreter_load(struct sieve_interpreter *interp);
 
-/* Operations */
+/* 
+ * Operations 
+ */
 
 extern const struct sieve_operation setflag_operation;
 extern const struct sieve_operation addflag_operation;
@@ -42,12 +45,17 @@ extern const struct sieve_operation hasflag_operation;
 const struct sieve_operation *imapflags_operations[] = 
 	{ &setflag_operation, &addflag_operation, &removeflag_operation, &hasflag_operation };
 
-/* Operands */
+/* 
+ * Operands 
+ */
 
-const struct sieve_operand flags_side_effect_operand;
+extern const struct sieve_operand flags_side_effect_operand;
 
 /* Extension definitions */
 
+extern const struct sieve_interpreter_extension 
+	imapflags_interpreter_extension;
+
 int ext_imapflags_my_id;
 
 const struct sieve_extension imapflags_extension = { 
@@ -55,9 +63,9 @@ const struct sieve_extension imapflags_extension = {
 	&ext_imapflags_my_id,
 	ext_imapflags_load,
 	ext_imapflags_validator_load, 
-	NULL, NULL,
-	ext_imapflags_runtime_load, 
-	NULL, NULL,
+	NULL, 
+	ext_imapflags_interpreter_load, 
+	NULL, NULL, NULL,
 	SIEVE_EXT_DEFINE_OPERATIONS(imapflags_operations), 
 	SIEVE_EXT_DEFINE_OPERAND(flags_side_effect_operand)
 };
@@ -92,11 +100,12 @@ static bool ext_imapflags_validator_load
  * Interpreter context
  */
 
-static bool ext_imapflags_runtime_load
-	(const struct sieve_runtime_env *renv)
+static bool ext_imapflags_interpreter_load
+(struct sieve_interpreter *interp)
 {
-	ext_imapflags_runtime_init(renv);
-	
+	sieve_interpreter_extension_register
+        (interp, &imapflags_interpreter_extension, NULL);
+
 	return TRUE;
 }
 
diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c
index e191b8796f2e0f17f35f9f03554f77f55a8bb8cf..e097080e3d2e9f2eaec893655d7ab51beed667c8 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.c
+++ b/src/lib-sieve/plugins/include/ext-include-common.c
@@ -44,6 +44,8 @@ struct ext_include_interpreter_context {
 	unsigned int inc_block_id;
 	bool returned;
 	struct ext_include_interpreter_context *parent;
+
+	struct sieve_variable_storage *global_variables;
 };
 
 /* 
@@ -218,8 +220,24 @@ void ext_include_register_generator_context
  * Interpreter context management 
  */
 
+static void ext_include_runtime_init
+    (const struct sieve_runtime_env *renv, void *context)
+{
+	struct ext_include_interpreter_context *ctx = 
+		(struct ext_include_interpreter_context *) context;
+
+	sieve_ext_variables_set_storage
+		(renv->interp, ctx->global_variables, &include_extension);	
+}
+
+static struct sieve_interpreter_extension include_interpreter_extension = {
+    &include_extension,
+    ext_include_runtime_init,
+    NULL,
+};
+
 static struct ext_include_interpreter_context *
-	ext_include_create_interpreter_context
+	ext_include_interpreter_context_create
 (struct sieve_interpreter *interp, 
 	struct ext_include_interpreter_context *parent, 
 	struct sieve_script *script, unsigned int block_id)
@@ -232,11 +250,15 @@ static struct ext_include_interpreter_context *
 	ctx->interp = interp;
 	ctx->script = script;
 	ctx->block_id = block_id;
-	if ( parent == NULL ) 
+
+	if ( parent == NULL ) {
 		ctx->nesting_level = 0;
-	else
+		ctx->global_variables = sieve_variable_storage_create(pool, NULL);
+	} else {
 		ctx->nesting_level = parent->nesting_level + 1;
-	
+		ctx->global_variables = parent->global_variables;
+	}
+
 	return ctx;
 }
 
@@ -249,15 +271,16 @@ static inline struct ext_include_interpreter_context *
 }
 
 static inline struct ext_include_interpreter_context *
-	ext_include_initialize_interpreter_context
+	ext_include_interpreter_context_init_child
 (struct sieve_interpreter *interp, 
 	struct ext_include_interpreter_context *parent, 
 	struct sieve_script *script, unsigned int block_id)
 {
 	struct ext_include_interpreter_context *ctx = 
-		ext_include_create_interpreter_context(interp, parent, script, block_id);
+		ext_include_interpreter_context_create(interp, parent, script, block_id);
 		
-	sieve_interpreter_extension_set_context(interp, &include_extension, ctx);
+	sieve_interpreter_extension_register
+		(interp, &include_interpreter_extension, ctx);
 	
 	return ctx;
 }
@@ -267,14 +290,18 @@ void ext_include_interpreter_context_init
 {
 	struct ext_include_interpreter_context *ctx = 
 		ext_include_get_interpreter_context(interp);
-	struct sieve_script *script = sieve_interpreter_script(interp);
-	
+
+	/* Is this is the top-level interpreter ? */	
 	if ( ctx == NULL ) {
-		ctx = ext_include_create_interpreter_context
+		struct sieve_script *script;
+
+		/* Initialize top context */
+		script = sieve_interpreter_script(interp);
+		ctx = ext_include_interpreter_context_create
 			(interp, NULL, script, SBIN_SYSBLOCK_MAIN_PROGRAM);
 		
-		sieve_interpreter_extension_set_context
-			(interp, &include_extension, (void *) ctx);		
+		sieve_interpreter_extension_register
+			(interp, &include_interpreter_extension, (void *) ctx);			
 	}
 }
 
@@ -431,7 +458,6 @@ bool ext_include_execute_include
 		struct sieve_error_handler *ehandler = 
 			sieve_interpreter_get_error_handler(renv->interp);
 		struct sieve_interpreter *subinterp;
-		struct sieve_variable_storage *varstrg;
 		unsigned int this_block_id;
 		bool interrupted = FALSE;	
 
@@ -441,13 +467,9 @@ bool ext_include_execute_include
 		 */
 		subinterp = sieve_interpreter_create
 			(renv->sbin, ehandler, renv->trace_stream);			
-		curctx = ext_include_initialize_interpreter_context
+		curctx = ext_include_interpreter_context_init_child
 			(subinterp, ctx, NULL, block_id);
-			
-		/* Create variable storage for global variables */
-		varstrg = sieve_ext_variables_get_storage(renv->interp, &include_extension);
-		sieve_ext_variables_set_storage(subinterp, varstrg, &include_extension);
-	
+				
 		/* Activate and start the top-level included script */
 		if ( sieve_binary_block_set_active(renv->sbin, block_id, &this_block_id) ) 			
 			result = ( sieve_interpreter_start
@@ -496,7 +518,7 @@ bool ext_include_execute_include
 						/* Create sub-interpreter */
 						subinterp = sieve_interpreter_create
 							(renv->sbin, ehandler, renv->trace_stream);			
-						curctx = ext_include_initialize_interpreter_context
+						curctx = ext_include_interpreter_context_init_child
 							(subinterp, curctx, NULL, curctx->inc_block_id);
 													
 						/* Activate the sub-include's block */
diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.c b/src/lib-sieve/plugins/variables/ext-variables-common.c
index dafdec1d85a0c63dd6bb9f86d324d98ac2927adc..10d1f520003a04d8a4388315d39772fc7e0bb9db 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-common.c
+++ b/src/lib-sieve/plugins/variables/ext-variables-common.c
@@ -214,15 +214,18 @@ struct sieve_variable * const *sieve_variable_scope_get_variables
 
 struct sieve_variable_storage {
 	pool_t pool;
+	struct sieve_variable_scope *scope;
 	ARRAY_DEFINE(var_values, string_t *); 
 };
 
-struct sieve_variable_storage *sieve_variable_storage_create(pool_t pool)
+struct sieve_variable_storage *sieve_variable_storage_create
+(pool_t pool, struct sieve_variable_scope *scope)
 {
 	struct sieve_variable_storage *storage;
 	
 	storage = p_new(pool, struct sieve_variable_storage, 1);
 	storage->pool = pool;
+	storage->scope = scope;
 		
 	p_array_init(&storage->var_values, pool, 4);
 
@@ -374,7 +377,7 @@ ext_variables_interpreter_context_create(struct sieve_interpreter *interp)
 	struct ext_variables_interpreter_context *ctx;
 	
 	ctx = p_new(pool, struct ext_variables_interpreter_context, 1);
-	ctx->local_storage = sieve_variable_storage_create(pool);
+	ctx->local_storage = sieve_variable_storage_create(pool, NULL);
 	p_array_init(&ctx->ext_storages, pool, sieve_extensions_get_count());
 
 	sieve_interpreter_extension_set_context
@@ -402,7 +405,8 @@ ext_variables_interpreter_context_get(struct sieve_interpreter *interp)
 }
 
 struct sieve_variable_storage *sieve_ext_variables_get_storage
-	(struct sieve_interpreter *interp, const struct sieve_extension *ext)
+(struct sieve_interpreter *interp, const struct sieve_extension *ext, 
+	bool create)
 {
 	struct ext_variables_interpreter_context *ctx = 
 		ext_variables_interpreter_context_get(interp);
@@ -420,12 +424,17 @@ struct sieve_variable_storage *sieve_ext_variables_get_storage
 	}
 	
 	if ( storage == NULL || *storage == NULL ) {
-		pool_t pool = sieve_interpreter_pool(interp);
-		struct sieve_variable_storage *strg = sieve_variable_storage_create(pool);
+		if ( create ) {
+			pool_t pool = sieve_interpreter_pool(interp);
+			struct sieve_variable_storage *strg = 
+				sieve_variable_storage_create(pool, NULL);
 		
-		array_idx_set(&ctx->ext_storages, (unsigned int) ext_id, &strg);
+			array_idx_set(&ctx->ext_storages, (unsigned int) ext_id, &strg);
 		
-		return strg;		
+			return strg;		
+		}
+
+		return NULL;
 	}
 	
 	return *storage;
diff --git a/src/lib-sieve/plugins/variables/ext-variables-operands.c b/src/lib-sieve/plugins/variables/ext-variables-operands.c
index 1d95e57130753c9f0bbbe0b9a5164e1e30ded8ae..c50ee0e57e8089a477af22009c1eba83df6f21e6 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-operands.c
+++ b/src/lib-sieve/plugins/variables/ext-variables-operands.c
@@ -88,7 +88,7 @@ static bool opr_variable_read_value
 	if ( !sieve_binary_read_extension(renv->sbin, address, &code, &ext) )
 		return FALSE;
 
-	storage = sieve_ext_variables_get_storage(renv->interp, ext);
+	storage = sieve_ext_variables_get_storage(renv->interp, ext, FALSE);
 	if ( storage == NULL ) 
 		return FALSE;
 	
@@ -123,7 +123,7 @@ bool sieve_variable_operand_read_data
 	if ( !sieve_binary_read_extension(renv->sbin, address, &code, &ext) )
         return FALSE;
 		
-	*storage = sieve_ext_variables_get_storage(renv->interp, ext);
+	*storage = sieve_ext_variables_get_storage(renv->interp, ext, FALSE);
 	if ( *storage == NULL )	
 		return FALSE;
 	
diff --git a/src/lib-sieve/plugins/variables/sieve-ext-variables.h b/src/lib-sieve/plugins/variables/sieve-ext-variables.h
index c4540d909140e331d2a4dcf1a6468829c85a0560..d93e602e21ea6ff1257fa42e0c24b7c58ed45ae4 100644
--- a/src/lib-sieve/plugins/variables/sieve-ext-variables.h
+++ b/src/lib-sieve/plugins/variables/sieve-ext-variables.h
@@ -71,7 +71,8 @@ struct sieve_variable * const *sieve_variable_scope_get_variables
 	
 struct sieve_variable_storage;
 
-struct sieve_variable_storage *sieve_variable_storage_create(pool_t pool);
+struct sieve_variable_storage *sieve_variable_storage_create
+	(pool_t pool, struct sieve_variable_scope *scope);
 void sieve_variable_get
 	(struct sieve_variable_storage *storage, unsigned int index, 
 		string_t **value);
@@ -92,7 +93,8 @@ struct sieve_variable_scope *sieve_ext_variables_get_main_scope
 	(struct sieve_validator *validator);
 	
 struct sieve_variable_storage *sieve_ext_variables_get_storage
-	(struct sieve_interpreter *interp, const struct sieve_extension *ext);
+	(struct sieve_interpreter *interp, const struct sieve_extension *ext,
+		bool create);
 void sieve_ext_variables_set_storage
 	(struct sieve_interpreter *interp, struct sieve_variable_storage *storage,
 		const struct sieve_extension *ext);	
diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c
index e5de43fa7ed40e5e72f86ae0852d4a5e1173da03..2d6df31714e14b862efd861a90b056a856a5588c 100644
--- a/src/lib-sieve/sieve-interpreter.c
+++ b/src/lib-sieve/sieve-interpreter.c
@@ -113,7 +113,7 @@ void sieve_interpreter_free(struct sieve_interpreter **interp)
 
 	sieve_error_handler_unref(&(*interp)->ehandler);
 
-	/* Signal registered extensions that the validator is being destroyed */
+	/* Signal registered extensions that the interpreter is being destroyed */
 	extrs = array_get(&(*interp)->extensions, &ext_count);
 	for ( i = 0; i < ext_count; i++ ) {
 		if ( extrs[i].int_ext != NULL && extrs[i].int_ext->free != NULL )
@@ -431,9 +431,8 @@ int sieve_interpreter_start
 	const struct sieve_script_env *senv, struct sieve_message_context *msgctx, 
 	struct sieve_result *result, bool *interrupted) 
 {
-	struct sieve_binary *sbin = interp->runenv.sbin;
-	unsigned int i;
-	int idx;
+    const struct sieve_interpreter_extension_reg *extrs;
+    unsigned int ext_count, i;
 	
 	interp->runenv.msgdata = msgdata;
 	interp->runenv.result = result;		
@@ -445,23 +444,13 @@ int sieve_interpreter_start
 		interp->runenv.msgctx = msgctx;
 		sieve_message_context_ref(msgctx);
 	}
-	
-	/* Pre-load core language features implemented as 'extensions' */
-	for ( i = 0; i < sieve_preloaded_extensions_count; i++ ) {
-		const struct sieve_extension *ext = sieve_preloaded_extensions[i];
-		
-		if ( ext->runtime_load != NULL )
-			(void)ext->runtime_load(&interp->runenv);		
-	}
 
-	/* Load other extensions listed in the binary */
-	for ( idx = 0; idx < sieve_binary_extensions_count(sbin); idx++ ) {
-		const struct sieve_extension *ext = 
-			sieve_binary_extension_get_by_index(sbin, idx);
-		
-		if ( ext->runtime_load != NULL )
-			ext->runtime_load(&interp->runenv);
-	}
+    /* Signal registered extensions that the interpreter is being run */
+    extrs = array_get(&interp->extensions, &ext_count);
+    for ( i = 0; i < ext_count; i++ ) {
+        if ( extrs[i].int_ext != NULL && extrs[i].int_ext->run != NULL )
+            extrs[i].int_ext->run(&interp->runenv, extrs[i].context);
+    }
 
 	return sieve_interpreter_continue(interp, interrupted); 
 }
diff --git a/src/lib-sieve/sieve-interpreter.h b/src/lib-sieve/sieve-interpreter.h
index eae9bdd17903f0dc4b6ff5f72aa8463b357aaa8f..e68e1aaa9ea5c9fd5cdd2ed4f55c5559e52a87f1 100644
--- a/src/lib-sieve/sieve-interpreter.h
+++ b/src/lib-sieve/sieve-interpreter.h
@@ -100,6 +100,7 @@ void _sieve_runtime_trace_error
 struct sieve_interpreter_extension {
 	const struct sieve_extension *ext;	
 
+	void (*run)(const struct sieve_runtime_env *renv, void *context);
 	void (*free)(struct sieve_interpreter *interp, void *context);
 };
 
diff --git a/src/lib-sieve/sieve-match-types.c b/src/lib-sieve/sieve-match-types.c
index 287fc61589da77e22f9800639e03f53e465b9c94..4ccdfde5c81cbd0e8dfa2b27e78497eeb8cbae06 100644
--- a/src/lib-sieve/sieve-match-types.c
+++ b/src/lib-sieve/sieve-match-types.c
@@ -132,6 +132,7 @@ static void mtch_interpreter_free
 
 struct sieve_interpreter_extension mtch_interpreter_extension = {
 	&match_type_extension,
+	NULL,
 	mtch_interpreter_free
 };