diff --git a/TODO b/TODO
index 07a50b0eadd6f62e63874d573a517b0d5d95283d..a42d9448562778c82c98df16d1a9642f037d4940 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,4 @@
 Next (in order of descending priority/precedence):
-* Resolve problems in variables extension: scope uses hash the wrong way.
-
 * Full standards compliance review for the engine and all fully implemented 
   sieve extensions. Issues discovered so far:
 	- :matches : match values must only be changed when the test 
diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c
index a987d9ae40876b432d456eac6f0b7728ce9ca45f..bb02e59c40ecc6a31720882ebee0ff4af7d4ffb7 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.c
+++ b/src/lib-sieve/plugins/include/ext-include-common.c
@@ -94,10 +94,16 @@ static void ext_include_ast_free
 	struct sieve_script **scripts;
 	unsigned int count, i;
 
+	/* Unreference included scripts */
 	scripts = array_get_modifiable(&actx->included_scripts, &count);
     for ( i = 0; i < count; i++ ) {
 		sieve_script_unref(&scripts[i]);
     }	
+
+	/* Unreference variable scopes */
+	sieve_variable_scope_unref(&actx->import_vars);
+	if ( actx->global_vars != NULL )
+		sieve_variable_scope_unref(&actx->global_vars);
 }
 
 static const struct sieve_ast_extension include_ast_extension = {
@@ -120,6 +126,9 @@ struct ext_include_ast_context *ext_include_create_ast_context
             (struct ext_include_ast_context *)
             sieve_ast_extension_get_context(parent, &include_extension);
         actx->global_vars = ( parent_ctx == NULL ? NULL : parent_ctx->global_vars );
+
+		if ( actx->global_vars != NULL )
+	        sieve_variable_scope_ref(actx->global_vars);
     }
 
 	sieve_ast_extension_register(ast, &include_ast_extension, (void *) actx);
diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.c b/src/lib-sieve/plugins/variables/ext-variables-common.c
index 028b8e08f5f853414aa8334de7dd409bb20da2c2..1459f07e4bc3882adcd839ed6fe05caf22354bbb 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-common.c
+++ b/src/lib-sieve/plugins/variables/ext-variables-common.c
@@ -42,6 +42,8 @@ const unsigned int default_set_modifiers_count =
 
 struct sieve_variable_scope {
 	pool_t pool;
+	int refcount;
+
 	const struct sieve_extension *ext;
 
 	unsigned int next_index;
@@ -55,13 +57,31 @@ struct sieve_variable_scope *sieve_variable_scope_create
 	
 	scope = p_new(pool, struct sieve_variable_scope, 1);
 	scope->pool = pool;
+	scope->refcount = 1;
+
 	scope->ext = ext;
 	scope->variables = hash_create
-		(pool, pool, 0, strcase_hash, (hash_cmp_callback_t *)strcasecmp);
+		(default_pool, pool, 0, strcase_hash, (hash_cmp_callback_t *)strcasecmp);
 		
 	return scope;
 }
 
+void sieve_variable_scope_ref(struct sieve_variable_scope *scope)
+{
+    scope->refcount++;
+}
+
+void sieve_variable_scope_unref(struct sieve_variable_scope **scope)
+{
+    i_assert((*scope)->refcount > 0);
+
+    if (--(*scope)->refcount != 0)
+        return;
+
+	hash_destroy(&(*scope)->variables);
+    *scope = NULL;
+}
+
 struct sieve_variable *sieve_variable_scope_declare
 (struct sieve_variable_scope *scope, const char *identifier)
 {
@@ -159,7 +179,41 @@ void sieve_variable_assign
 	str_append_str(varval, value);
 }
 
-/* Validator context */
+/*
+ * AST Context
+ */
+
+static void ext_variables_ast_free
+(struct sieve_ast *ast ATTR_UNUSED, void *context)
+{
+	struct sieve_variable_scope *main_scope =
+		(struct sieve_variable_scope *) context;
+
+    /* Unreference main variable scope */
+    sieve_variable_scope_unref(&main_scope);
+}
+
+static const struct sieve_ast_extension variables_ast_extension = {
+    &variables_extension,
+    ext_variables_ast_free
+};
+
+static struct sieve_variable_scope *ext_variables_create_main_scope
+(struct sieve_ast *ast)
+{
+    struct sieve_variable_scope *scope;
+    pool_t pool = sieve_ast_pool(ast);
+
+	scope = sieve_variable_scope_create(pool, NULL);
+
+    sieve_ast_extension_register(ast, &variables_ast_extension, (void *) scope);
+
+    return scope;
+}
+
+/*
+ * Validator context 
+ */
 
 static struct ext_variables_validator_context *
 ext_variables_validator_context_create(struct sieve_validator *valdtr)
@@ -170,7 +224,7 @@ ext_variables_validator_context_create(struct sieve_validator *valdtr)
 	
 	ctx = p_new(pool, struct ext_variables_validator_context, 1);
 	ctx->modifiers = sieve_validator_object_registry_create(valdtr);
-	ctx->main_scope = sieve_variable_scope_create(sieve_ast_pool(ast), NULL);
+	ctx->main_scope = ext_variables_create_main_scope(ast);
 
 	sieve_validator_extension_set_context
 		(valdtr, &variables_extension, (void *) ctx);
diff --git a/src/lib-sieve/plugins/variables/sieve-ext-variables.h b/src/lib-sieve/plugins/variables/sieve-ext-variables.h
index e554f410ef166fd268455da00f176a6cf26380d5..65068725b2f93b1c4fd382bed734bb3a969d6347 100644
--- a/src/lib-sieve/plugins/variables/sieve-ext-variables.h
+++ b/src/lib-sieve/plugins/variables/sieve-ext-variables.h
@@ -23,6 +23,11 @@ struct sieve_variable_scope;
 
 struct sieve_variable_scope *sieve_variable_scope_create
 	(pool_t pool, const struct sieve_extension *ext);
+void sieve_variable_scope_ref
+	(struct sieve_variable_scope *scope);
+void sieve_variable_scope_unref
+	(struct sieve_variable_scope **scope);
+
 struct sieve_variable *sieve_variable_scope_declare
 	(struct sieve_variable_scope *scope, const char *identifier);
 struct sieve_variable *sieve_variable_scope_import