struct sieve_variable *ext_include_variable_import_global
(struct sieve_validator *valdtr, struct sieve_command *cmd,
	const char *variable)
{
	const struct sieve_extension *this_ext = cmd->ext;
	struct sieve_ast *ast = cmd->ast_node->ast;
	struct ext_include_ast_context *ctx =
		ext_include_get_ast_context(this_ext, ast);
	struct ext_include_context *ectx = ext_include_get_context(this_ext);
	struct sieve_variable_scope *local_scope;
	struct sieve_variable_scope *global_scope = ctx->global_vars;
	struct sieve_variable *global_var = NULL, *local_var;

	/* Sanity safeguard */
	i_assert ( ctx->global_vars != NULL );

	if ( !sieve_variable_identifier_is_valid(variable) ) {
		sieve_command_validate_error(valdtr, cmd,
			"invalid variable identifier '%s'", str_sanitize(variable,80));
		return NULL;
	}

	/* Get/Declare the variable in the global scope */
	global_var = sieve_variable_scope_get_variable(global_scope, variable, TRUE);

	/* Check whether scope is over its size limit */
	if ( global_var == NULL ) {
		sieve_command_validate_error(valdtr, cmd,
			"declaration of new global variable '%s' exceeds the limit "
			"(max variables: %u)",
			variable, sieve_variables_get_max_scope_size());
		return NULL;
	}

	/* Import the global variable into the local script scope */
	local_scope = sieve_ext_variables_get_local_scope(ectx->var_ext, valdtr);

	local_var = sieve_variable_scope_get_variable(local_scope, variable, FALSE);
	if ( local_var != NULL && local_var->ext != this_ext ) {
		/* FIXME: indicate location of conflicting set statement */
		sieve_command_validate_error(valdtr, cmd,
			"declaration of new global variable '%s' conflicts with earlier local "
			"use", variable);
		return NULL;
	}

	return sieve_variable_scope_import(local_scope, global_var);
}
struct ext_include_binary_context *ext_include_binary_init
(const struct sieve_extension *this_ext, struct sieve_binary *sbin,
	struct sieve_ast *ast)
{
	struct ext_include_ast_context *ast_ctx =
		ext_include_get_ast_context(this_ext, ast);
	struct ext_include_binary_context *ctx;

	/* Get/create our context from the binary we are working on */
	ctx = ext_include_binary_get_context(this_ext, sbin);

	/* Create dependency block */
	if ( ctx->dependency_block == 0 )
		ctx->dependency_block =
			sieve_binary_extension_create_block(sbin, this_ext);

	if ( ctx->global_vars == NULL ) {
		ctx->global_vars =
			sieve_variable_scope_binary_create(ast_ctx->global_vars);
		sieve_variable_scope_binary_ref(ctx->global_vars);
	}

	return ctx;
}
	vnspc_global_variables_generate,
	NULL, NULL
};


bool vnspc_global_variables_validate
(struct sieve_validator *valdtr,
	const struct sieve_variables_namespace *nspc, struct sieve_ast_argument *arg,
	struct sieve_command *cmd ATTR_UNUSED,
	ARRAY_TYPE(sieve_variable_name) *var_name, void **var_data,
	bool assignment ATTR_UNUSED)
{
	const struct sieve_extension *this_ext = SIEVE_OBJECT_EXTENSION(nspc);
	struct sieve_ast *ast = arg->ast;
	struct ext_include_ast_context *ctx =
		ext_include_get_ast_context(this_ext, ast);
	struct sieve_variable *var = NULL;
	const struct sieve_variable_name *name_element;
	const char *variable;

	/* Sanity safeguard */
	i_assert ( ctx->global_vars != NULL );

	/* Check variable name */

	if ( array_count(var_name) != 2 ) {
		sieve_argument_validate_error(valdtr, arg,
			"invalid variable name within global namespace: "
			"encountered sub-namespace");
		return FALSE;
	}