diff --git a/TODO b/TODO
index 971b040e81154db17727f4e1e5d7a44949b84aba..52f9d7d9c02d685e6f21587b0363a3a6ab960756 100644
--- a/TODO
+++ b/TODO
@@ -3,8 +3,8 @@ Next (in order of descending priority/precedence):
 * Finish the test suite for the base functionality
 * Improve debugging and error handling:
 	- Variables: dump variable identifiers in stead of storage indexes
-	- Improve argument errors
 * Make sure cmusieve can be replaced seamlessly with the new plugin.
+	- Fileinto must optionally create missing folders.
 * Fix/Report issues listed in 'doc/rfc/RFC Controversy.txt'
 
 * ## MAKE A FIRST RELEASE (0.1.x) ##
diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c
index 3adfee6c2dbbc07ca708bb53dc445ac6b4ad7812..5f6393bcc6925a97764607fa5d536e55af23ac6a 100644
--- a/src/lib-sieve/cmd-redirect.c
+++ b/src/lib-sieve/cmd-redirect.c
@@ -131,7 +131,7 @@ static bool cmd_redirect_validate
 			norm_address = sieve_address_normalize(address, &error);
 		
 			if ( norm_address == NULL ) {
-				sieve_command_validate_error(validator, cmd, 
+				sieve_argument_validate_error(validator, arg, 
 					"specified redirect address '%s' is invalid: %s",
 					str_sanitize(str_c(address),128), error);
 			} else {
diff --git a/src/lib-sieve/cmd-require.c b/src/lib-sieve/cmd-require.c
index f6d25a3a7529ef451145b54c852b69dfd5a0a4ce..bd7ae1bb9be0828c1f85273a636465913eb515ae 100644
--- a/src/lib-sieve/cmd-require.c
+++ b/src/lib-sieve/cmd-require.c
@@ -75,7 +75,7 @@ static bool cmd_require_validate
 		}
 	} else {
 		/* Something else */
-		sieve_command_validate_error(validator, cmd, 
+		sieve_argument_validate_error(validator, arg, 
 			"the require command accepts a single string or string list argument, "
 			"but %s was found", 
 			sieve_ast_argument_name(arg));
diff --git a/src/lib-sieve/ext-encoded-character.c b/src/lib-sieve/ext-encoded-character.c
index 85532885ef7507a3fd36db97218e5c03e46e58c8..2eb6a0552681dbab64285a0fa0b43171fbcdedc6 100644
--- a/src/lib-sieve/ext-encoded-character.c
+++ b/src/lib-sieve/ext-encoded-character.c
@@ -234,7 +234,7 @@ bool arg_encoded_string_validate
 					/* We now know that the substitution is valid */	
 
 					if ( error_hex != 0 ) {
-						sieve_command_validate_error(validator, cmd, 
+						sieve_argument_validate_error(validator, *arg, 
 							"invalid unicode character 0x%08x in encoded character substitution",
 							error_hex);
 						result = FALSE;
diff --git a/src/lib-sieve/ext-envelope.c b/src/lib-sieve/ext-envelope.c
index 7abd09a80b943b70c200be18654f3b7008d86898..f4d59daf31ebf4fe12edeaa7c65033d92d49a0be 100644
--- a/src/lib-sieve/ext-envelope.c
+++ b/src/lib-sieve/ext-envelope.c
@@ -250,7 +250,7 @@ static bool tst_envelope_validate
 	if ( !sieve_ast_stringlist_map(&epart, (void *) &not_address, 
 		_envelope_part_is_supported) ) {		
 		
-		sieve_command_validate_error(validator, tst, 
+		sieve_argument_validate_error(validator, epart, 
 			"specified envelope part '%s' is not supported by the envelope test", 
 				str_sanitize(sieve_ast_strlist_strc(epart), 64));
 		return FALSE;
@@ -261,7 +261,7 @@ static bool tst_envelope_validate
 			sieve_command_find_argument(tst, &address_part_tag);
 
 		if ( addrp_arg != NULL ) {
-			sieve_command_validate_error(validator, tst,
+			sieve_argument_validate_error(validator, addrp_arg,
 				"address part ':%s' specified while non-address envelope part '%s' "
 				"is tested with the envelope test",
                 sieve_ast_argument_tag(addrp_arg), not_address->identifier);
diff --git a/src/lib-sieve/plugins/body/tst-body.c b/src/lib-sieve/plugins/body/tst-body.c
index 9b3c1ed579d1ead31257ea73ddee60116d7639dc..aad6b11ec1c8896ad33c658154c47169bbf56e2e 100644
--- a/src/lib-sieve/plugins/body/tst-body.c
+++ b/src/lib-sieve/plugins/body/tst-body.c
@@ -134,7 +134,7 @@ static bool tag_body_transform_validate
 	 *     / :text
 	 */
 	if ( (bool) cmd->data ) {
-		sieve_command_validate_error(validator, cmd, 
+		sieve_argument_validate_error(validator, *arg, 
 			"the :raw, :content and :text arguments for the body test are mutually "
 			"exclusive, but more than one was specified");
 		return FALSE;
diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c
index bf45d62aee951754dfb0a1278748556b4c19b6e7..1196a850af1747903818d715212cebbf08c2bd30 100644
--- a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c
+++ b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c
@@ -54,7 +54,7 @@ bool ext_imapflags_command_validate
 	if ( sieve_ast_argument_type(arg) != SAAT_STRING && 
 		sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) 
 	{
-		sieve_command_validate_error(validator, cmd, 
+		sieve_argument_validate_error(validator, arg, 
 			"the %s %s expects either a string (variable name) or "
 			"a string-list (list of flags) as first argument, but %s was found", 
 			cmd->command->identifier, sieve_command_type_name(cmd->command),
@@ -70,14 +70,14 @@ bool ext_imapflags_command_validate
 		{
 			if ( cmd->command == &tst_hasflag ) {
 				if ( sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) {
-					sieve_command_validate_error(validator, cmd, 
+					sieve_argument_validate_error(validator, arg, 
 						"if a second argument is specified for the hasflag, the first "
 						"must be a string-list (variable-list), but %s was found",
 						sieve_ast_argument_name(arg));
 					return FALSE;
 				}
 			} else {
-				sieve_command_validate_error(validator, cmd, 
+				sieve_argument_validate_error(validator, arg, 
 					"if a second argument is specified for the %s %s, the first "
 					"must be a string (variable name), but %s was found",
 					cmd->command->identifier, sieve_command_type_name(cmd->command), 
@@ -89,7 +89,7 @@ bool ext_imapflags_command_validate
 		/* Then, check whether the second argument is permitted */
 		
 		if ( !sieve_ext_variables_is_active(validator) )	{
-			sieve_command_validate_error(validator, cmd, 
+			sieve_argument_validate_error(validator,arg, 
 				"the %s %s only allows for the specification of a "
 				"variable name when the variables extension is active",
 				cmd->command->identifier, sieve_command_type_name(cmd->command));
@@ -103,7 +103,7 @@ bool ext_imapflags_command_validate
 		if ( sieve_ast_argument_type(arg2) != SAAT_STRING && 
 			sieve_ast_argument_type(arg2) != SAAT_STRING_LIST ) 
 		{
-			sieve_command_validate_error(validator, cmd, 
+			sieve_argument_validate_error(validator, arg2, 
 				"the %s %s expects a string list (list of flags) as "
 				"second argument when two arguments are specified, "
 				"but %s was found",
@@ -126,7 +126,7 @@ bool ext_imapflags_command_validate
 
 		while ( (flag=ext_imapflags_iter_get_flag(&fiter)) != NULL ) {
 			if ( !flag_is_valid(flag) ) {
-				sieve_command_validate_warning(validator, cmd,
+				sieve_argument_validate_warning(validator, arg,
                 	"IMAP flag '%s' specified for the %s command is invalid "
 					"and will be ignored (only first invalid is reported)",					
 					str_sanitize(flag, 64), cmd->command->identifier);
diff --git a/src/lib-sieve/plugins/include/cmd-import.c b/src/lib-sieve/plugins/include/cmd-import.c
index cacab7da64f95298bd7920f28084c2745a55c48a..bc1e9376c5f4afca628c6bda32f8d6c23b02a098 100644
--- a/src/lib-sieve/plugins/include/cmd-import.c
+++ b/src/lib-sieve/plugins/include/cmd-import.c
@@ -150,7 +150,7 @@ static bool cmd_import_validate
 		}
 	} else {
 		/* Something else */
-		sieve_command_validate_error(validator, cmd, 
+		sieve_argument_validate_error(validator, arg, 
 			"the %s command accepts a single string or string list argument, "
 			"but %s was found", cmd->command->identifier,
 			sieve_ast_argument_name(arg));
@@ -164,6 +164,7 @@ static bool cmd_import_validate
 			(prev_context->first_positional, cmd->first_positional);
 		
 		if ( prev_context->first_positional == NULL ) {
+			/* Not going to happen unless MAXINT stringlist items are specified */
 			sieve_command_validate_error(validator, cmd, 
 				"compiler reached AST limit (script too complex)");
 			return FALSE;
@@ -194,8 +195,8 @@ static bool cmd_import_generate
 		/* Single string */
 		struct sieve_variable *var = (struct sieve_variable *) arg->context;
 		
-		(void)sieve_binary_emit_integer(cgenv->sbin, 1);
-		(void)sieve_binary_emit_integer(cgenv->sbin, var->index);
+		(void)sieve_binary_emit_unsigned(cgenv->sbin, 1);
+		(void)sieve_binary_emit_unsigned(cgenv->sbin, var->index);
 		if ( cmd->command == &cmd_import )
 			(void)sieve_code_source_line_emit(cgenv->sbin, arg->source_line);
 		
@@ -203,12 +204,12 @@ static bool cmd_import_generate
 		/* String list */
 		struct sieve_ast_argument *stritem = sieve_ast_strlist_first(arg);
 		
-		(void)sieve_binary_emit_integer(cgenv->sbin, sieve_ast_strlist_count(arg));
+		(void)sieve_binary_emit_unsigned(cgenv->sbin, sieve_ast_strlist_count(arg));
 						
 		while ( stritem != NULL ) {
 			struct sieve_variable *var = (struct sieve_variable *) stritem->context;
 			
-			(void)sieve_binary_emit_integer(cgenv->sbin, var->index);
+			(void)sieve_binary_emit_unsigned(cgenv->sbin, var->index);
 			
 			if ( cmd->command == &cmd_import )
 				(void)sieve_code_source_line_emit(cgenv->sbin, stritem->source_line);
@@ -234,7 +235,7 @@ static bool opc_import_dump
 	struct sieve_variable_scope *scope;
 	struct sieve_variable * const *vars;
 	
-	if ( !sieve_binary_read_integer(denv->sbin, address, &count) )
+	if ( !sieve_binary_read_unsigned(denv->sbin, address, &count) )
 		return FALSE;
 
 	if ( op == &import_operation )
@@ -251,7 +252,7 @@ static bool opc_import_dump
 		unsigned int index;
 		
 		sieve_code_mark(denv);
-		if ( !sieve_binary_read_integer(denv->sbin, address, &index) ||
+		if ( !sieve_binary_read_unsigned(denv->sbin, address, &index) ||
 			index >= var_count )
 			return FALSE;
 			
@@ -284,7 +285,7 @@ static int opc_import_execute
 	struct sieve_variable * const *vars;
 	unsigned int var_count, count, i;
 		
-	if ( !sieve_binary_read_integer(renv->sbin, address, &count) ) {
+	if ( !sieve_binary_read_unsigned(renv->sbin, address, &count) ) {
 		sieve_runtime_trace_error(renv, "invalid count operand");
 		return SIEVE_EXEC_BIN_CORRUPT;
 	}
@@ -296,13 +297,14 @@ static int opc_import_execute
 	for ( i = 0; i < count; i++ ) {
 		unsigned int index, source_line;
 		
-		if ( !sieve_binary_read_integer(renv->sbin, address, &index) ) {
+		if ( !sieve_binary_read_unsigned(renv->sbin, address, &index) ) {
 			sieve_runtime_trace_error(renv, "invalid global variable operand");
 			return SIEVE_EXEC_BIN_CORRUPT;
 		}
 		
 		if ( index >= var_count ) {
-			sieve_runtime_trace_error(renv, "invalid global variable index");
+			sieve_runtime_trace_error(renv, "invalid global variable index (%u > %u)",
+				index, var_count);
 			return SIEVE_EXEC_BIN_CORRUPT;
 		}
 		
diff --git a/src/lib-sieve/plugins/include/cmd-include.c b/src/lib-sieve/plugins/include/cmd-include.c
index f76bf90a474b69ee15cdd22008738840d9d5fa91..ca1a329e2997953a3c80dcaf10ba2168114f27c7 100644
--- a/src/lib-sieve/plugins/include/cmd-include.c
+++ b/src/lib-sieve/plugins/include/cmd-include.c
@@ -113,7 +113,7 @@ static bool cmd_include_validate_location_tag
 		(struct cmd_include_context_data *) cmd->data;
 	
 	if ( ctx_data->location_assigned) {
-		sieve_command_validate_error(validator, cmd, 
+		sieve_argument_validate_error(validator, *arg, 
 			"include: cannot use location tags ':personal' and ':global' "
 			"multiple times");
 		return FALSE;
@@ -186,7 +186,7 @@ static bool cmd_include_validate(struct sieve_validator *validator,
 	script_name = sieve_ast_argument_strc(arg);
 
 	if ( strchr(script_name, '/') != NULL ) {
- 		sieve_command_validate_error(validator, cmd,
+ 		sieve_argument_validate_error(validator, arg,
 			"include: '/' not allowed in script name (%s)",
 			str_sanitize(script_name, 80));
 		return FALSE;
@@ -195,7 +195,7 @@ static bool cmd_include_validate(struct sieve_validator *validator,
 	script_dir = ext_include_get_script_directory
 		(ctx_data->location, script_name);
 	if ( script_dir == NULL ) {
-		sieve_command_validate_error(validator, cmd,
+		sieve_argument_validate_error(validator, arg,
 			"include: specified location for included script '%s' is unavailable "
 			"(system logs should provide more information)",
 			str_sanitize(script_name, 80));
@@ -235,7 +235,7 @@ static bool cmd_include_generate
  		return FALSE;
  		
  	(void)sieve_operation_emit_code(cgenv->sbin, &include_operation);
-	(void)sieve_binary_emit_integer(cgenv->sbin, included->id); 
+	(void)sieve_binary_emit_unsigned(cgenv->sbin, included->id); 
  	 		
 	return TRUE;
 }
@@ -255,7 +255,7 @@ static bool opc_include_dump
 	sieve_code_dumpf(denv, "INCLUDE:");
 	
 	sieve_code_mark(denv);
-	if ( !sieve_binary_read_integer(denv->sbin, address, &include_id) )
+	if ( !sieve_binary_read_unsigned(denv->sbin, address, &include_id) )
 		return FALSE;
 
 	binctx = ext_include_binary_get_context(denv->sbin);
@@ -280,7 +280,7 @@ static int opc_include_execute
 {
 	unsigned int include_id;
 		
-	if ( !sieve_binary_read_integer(renv->sbin, address, &include_id) ) {
+	if ( !sieve_binary_read_unsigned(renv->sbin, address, &include_id) ) {
 		sieve_runtime_trace_error(renv, "invalid include-id operand");
 		return SIEVE_EXEC_BIN_CORRUPT;
 	}
diff --git a/src/lib-sieve/plugins/include/ext-include-binary.c b/src/lib-sieve/plugins/include/ext-include-binary.c
index cf1b4bc5246cf75b829a2cee2c6779db90ee4659..34e759a52ceb41bfe348fc225f31a8b0738fc6b0 100644
--- a/src/lib-sieve/plugins/include/ext-include-binary.c
+++ b/src/lib-sieve/plugins/include/ext-include-binary.c
@@ -207,12 +207,12 @@ static bool ext_include_binary_save(struct sieve_binary *sbin)
 
 	scripts = array_get(&binctx->include_index, &script_count);
 
-	sieve_binary_emit_integer(sbin, script_count);
+	sieve_binary_emit_unsigned(sbin, script_count);
 
 	for ( i = 0; i < script_count; i++ ) {
 		struct ext_include_script_info *incscript = scripts[i];
 
-		sieve_binary_emit_integer(sbin, incscript->block_id);
+		sieve_binary_emit_unsigned(sbin, incscript->block_id);
 		sieve_binary_emit_byte(sbin, incscript->location);
 		sieve_binary_emit_cstring(sbin, sieve_script_name(incscript->script));
 	}
@@ -237,7 +237,7 @@ static bool ext_include_binary_open(struct sieve_binary *sbin)
 		
 	offset = 0;	
 		
-	if ( !sieve_binary_read_integer(sbin, &offset, &depcount) ) {
+	if ( !sieve_binary_read_unsigned(sbin, &offset, &depcount) ) {
 		sieve_sys_error("include: failed to read include count "
 			"for dependency block %d of binary %s", block, sieve_binary_path(sbin)); 
 		return FALSE;
@@ -261,7 +261,7 @@ static bool ext_include_binary_open(struct sieve_binary *sbin)
 		struct sieve_script *script;
 		
 		if ( 
-			!sieve_binary_read_integer(sbin, &offset, &block_id) ||
+			!sieve_binary_read_unsigned(sbin, &offset, &block_id) ||
 			!sieve_binary_read_byte(sbin, &offset, &location) ||
 			!sieve_binary_read_string(sbin, &offset, &script_name) ) {
 			/* Binary is corrupt, recompile */
diff --git a/src/lib-sieve/plugins/include/ext-include-variables.c b/src/lib-sieve/plugins/include/ext-include-variables.c
index 6726fc8130e4c48e50eb3ca9ff886cf2770c3b9f..bae0048063e9b43fd6a058fc467d8d312850fe8b 100644
--- a/src/lib-sieve/plugins/include/ext-include-variables.c
+++ b/src/lib-sieve/plugins/include/ext-include-variables.c
@@ -124,7 +124,7 @@ bool ext_include_variables_save
 {
 	unsigned int count = sieve_variable_scope_size(global_vars);
 
-	sieve_binary_emit_integer(sbin, count);
+	sieve_binary_emit_unsigned(sbin, count);
 
 	if ( count > 0 ) {
 		unsigned int size, i;
@@ -149,14 +149,14 @@ bool ext_include_variables_load
 (struct sieve_binary *sbin, sieve_size_t *offset, unsigned int block,
 	struct sieve_variable_scope **global_vars_r)
 {
-	sieve_size_t count = 0;
+	unsigned int count = 0;
 	unsigned int i;
 	pool_t pool;
 
 	/* Sanity assert */
 	i_assert( *global_vars_r == NULL );
 
-	if ( !sieve_binary_read_integer(sbin, offset, &count) ) {
+	if ( !sieve_binary_read_unsigned(sbin, offset, &count) ) {
 		sieve_sys_error("include: failed to read global variables count "
 			"from dependency block %d of binary %s", block, sieve_binary_path(sbin));
 		return FALSE;
diff --git a/src/lib-sieve/plugins/regex/mcht-regex.c b/src/lib-sieve/plugins/regex/mcht-regex.c
index cd4b41b44afcebc46278e158880fc96ee350d7eb..77536621db0044fe97433fbc315e1d0643be24a6 100644
--- a/src/lib-sieve/plugins/regex/mcht-regex.c
+++ b/src/lib-sieve/plugins/regex/mcht-regex.c
@@ -85,14 +85,15 @@ static const char *_regexp_error(regex_t *regexp, int errorcode)
 }
 
 static int mcht_regex_validate_regexp
-(struct sieve_validator *validator, struct sieve_match_type_context *ctx,
+(struct sieve_validator *validator, 
+	struct sieve_match_type_context *ctx ATTR_UNUSED,
 	struct sieve_ast_argument *key, int cflags) 
 {
 	int ret;
 	regex_t regexp;
 
 	if ( (ret=regcomp(&regexp, sieve_ast_argument_strc(key), cflags)) != 0 ) {
-		sieve_command_validate_error(validator, ctx->command_ctx,
+		sieve_argument_validate_error(validator, key,
 			"invalid regular expression for regex match: %s", 
 			_regexp_error(&regexp, ret));
 
@@ -116,7 +117,7 @@ static int mcht_regex_validate_key_argument
 	struct _regex_key_context *keyctx = (struct _regex_key_context *) context;
 
 	if ( !sieve_argument_is_string_literal(key) ) {
-		sieve_command_validate_error(keyctx->valdtr, keyctx->mctx->command_ctx,
+		sieve_argument_validate_error(keyctx->valdtr, key,
 			"this sieve implementation currently does not accept variable strings "
 			"as regular expression");
 		return FALSE;
@@ -141,7 +142,7 @@ bool mcht_regex_validate_context
 		else if ( cmp == &i_octet_comparator )
 			cflags =  REG_EXTENDED | REG_NOSUB;
 		else {
-			sieve_command_validate_error(validator, ctx->command_ctx, 
+			sieve_argument_validate_error(validator, ctx->match_type_arg, 
 				"regex match type only supports "
 				"i;octet and i;ascii-casemap comparators" );
 			return FALSE;	
diff --git a/src/lib-sieve/plugins/relational/ext-relational-common.c b/src/lib-sieve/plugins/relational/ext-relational-common.c
index 88c80a0db3c3003e215150c7f4ccfaebe1070ac6..92c6dc39697054afe4862271982459a5bf13361e 100644
--- a/src/lib-sieve/plugins/relational/ext-relational-common.c
+++ b/src/lib-sieve/plugins/relational/ext-relational-common.c
@@ -52,7 +52,7 @@ bool mcht_relational_validate
 	 
 	/* Did we get a string in the first place ? */ 
 	if ( (*arg)->type != SAAT_STRING ) {
-		sieve_command_validate_error(validator, ctx->command_ctx, 
+		sieve_argument_validate_error(validator, *arg, 
 			"the :%s match-type requires a constant string argument being "
 			"one of \"gt\", \"ge\", \"lt\", \"le\", \"eq\" or \"ne\", "
 			"but %s was found", 
@@ -114,7 +114,7 @@ bool mcht_relational_validate
 	}
 	
 	if ( rel_match >= REL_MATCH_INVALID ) {
-		sieve_command_validate_error(validator, ctx->command_ctx, 
+		sieve_argument_validate_error(validator, *arg, 
 			"the :%s match-type requires a constant string argument being "
 			"one of \"gt\", \"ge\", \"lt\", \"le\", \"eq\" or \"ne\", "
 			"but \"%s\" was found", 
diff --git a/src/lib-sieve/plugins/relational/mcht-count.c b/src/lib-sieve/plugins/relational/mcht-count.c
index 0616488275312fe5fe9ec7323468c88cb615f563..fcc8f25238c4b9fba9caf89f938747cd34256a95 100644
--- a/src/lib-sieve/plugins/relational/mcht-count.c
+++ b/src/lib-sieve/plugins/relational/mcht-count.c
@@ -65,9 +65,16 @@ COUNT_MATCH_TYPE(ne, REL_MATCH_NOT_EQUAL);
  * Match-type implementation 
  */
 
+struct mcht_count_context {
+	unsigned int count;
+};
+
 static void mcht_count_match_init(struct sieve_match_context *mctx)
 {
-	mctx->data = (void *) 0;
+	struct mcht_count_context *cctx = t_new(struct mcht_count_context, 1);
+
+	cctx->count = 0;
+	mctx->data = (void *) cctx;
 }
 
 static int mcht_count_match
@@ -81,7 +88,10 @@ static int mcht_count_match
 
 	/* Count values */
 	if ( key_index == -1 ) {
-		mctx->data = (void *) (((int) mctx->data) + 1);
+		struct mcht_count_context *cctx = 
+			(struct mcht_count_context *) mctx->data;
+
+		cctx->count++;
 	}
 
 	return FALSE;
@@ -89,14 +99,15 @@ static int mcht_count_match
 
 static int mcht_count_match_deinit(struct sieve_match_context *mctx)
 {
-	unsigned int val_count = (unsigned int) mctx->data;
+	struct mcht_count_context *cctx =
+            (struct mcht_count_context *) mctx->data;
 	int key_index;
 	string_t *key_item;
     sieve_coded_stringlist_reset(mctx->key_list);
 	bool ok = TRUE;
 
 	string_t *value = t_str_new(20);
-	str_printfa(value, "%d", val_count);
+	str_printfa(value, "%d", cctx->count);
 
     /* Match to all key values */
     key_index = 0;
diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c
index 5ee5257faee996853f5925591c3f3743ce9bb140..57c3343ce73e6452f929c6e2232768ea6b920244 100644
--- a/src/lib-sieve/plugins/vacation/cmd-vacation.c
+++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c
@@ -198,7 +198,7 @@ const struct sieve_action act_vacation = {
 struct act_vacation_context {
 	const char *reason;
 
-	sieve_size_t days;
+	sieve_number_t days;
 	const char *subject;
 	const char *handle;
 	bool mime;
@@ -282,7 +282,7 @@ static bool cmd_vacation_validate_string_tag
 	 			result = sieve_address_validate(address, &error);
 	 
 				if ( !result ) {
-					sieve_command_validate_error(validator, cmd, 
+					sieve_argument_validate_error(validator, *arg, 
 						"specified :from address '%s' is invalid for vacation action: %s", 
 						str_sanitize(str_c(address), 128), error);
 				}
@@ -542,7 +542,7 @@ static int ext_vacation_operation_execute
 	struct act_vacation_context *act;
 	pool_t pool;
 	int opt_code = 1;
-	sieve_size_t days = 7;
+	sieve_number_t days = 7;
 	bool mime = FALSE;
 	struct sieve_coded_stringlist *addresses = NULL;
 	string_t *reason, *subject = NULL, *from = NULL, *handle = NULL; 
diff --git a/src/lib-sieve/plugins/variables/cmd-set.c b/src/lib-sieve/plugins/variables/cmd-set.c
index 084d4bc0596a9a3c54a4edd13ebd6eea2317e4a0..759f9d2c8935aa250c9dd84749c7e96a66c2095d 100644
--- a/src/lib-sieve/plugins/variables/cmd-set.c
+++ b/src/lib-sieve/plugins/variables/cmd-set.c
@@ -133,7 +133,7 @@ static bool tag_modifier_validate
 			array_idx(&sctx->modifiers, i);
 	
 		if ( (*smdf)->precedence == modf->precedence ) {
-			sieve_command_validate_error(validator, cmd, 
+			sieve_argument_validate_error(validator, *arg, 
 				"modifiers :%s and :%s specified for the set command conflict "
 				"having equal precedence", 
 				(*smdf)->object.identifier, modf->object.identifier);
diff --git a/src/lib-sieve/plugins/variables/ext-variables-arguments.c b/src/lib-sieve/plugins/variables/ext-variables-arguments.c
index 9cdebcf3070994b820eb4e73ec66c26183873ffc..67ff4fbed4e9817125012de49fd2d7e238749bce 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-arguments.c
+++ b/src/lib-sieve/plugins/variables/ext-variables-arguments.c
@@ -25,20 +25,20 @@
  */
 
 static inline void _ext_variables_scope_size_error
-(struct sieve_validator *valdtr, struct sieve_command_context *cmd,
+(struct sieve_validator *valdtr, struct sieve_ast_argument *arg,
 	const char *variable)
 {
-	sieve_command_validate_error(valdtr, cmd, 
+	sieve_argument_validate_error(valdtr, arg, 
 		"(implicit) declaration of new variable '%s' exceeds the limit "
 		"(max variables: %u)", variable, 
 		SIEVE_VARIABLES_MAX_SCOPE_SIZE);
 }
 
 static inline void _ext_variables_match_index_error
-(struct sieve_validator *valdtr, struct sieve_command_context *cmd,
+(struct sieve_validator *valdtr, struct sieve_ast_argument *arg,
 	unsigned int variable_index)
 {
-	sieve_command_validate_error(valdtr, cmd, 
+	sieve_argument_validate_error(valdtr, arg, 
 		"match value index %u out of range (max: %u)", variable_index, 
 		SIEVE_VARIABLES_MAX_MATCH_INDEX);
 }
@@ -78,7 +78,7 @@ static struct sieve_ast_argument *ext_variables_variable_argument_create
 }
 
 static bool _sieve_variable_argument_activate
-(struct sieve_validator *validator, struct sieve_command_context *cmd, 
+(struct sieve_validator *validator, struct sieve_command_context *cmd ATTR_UNUSED, 
 	struct sieve_ast_argument *arg, bool assignment)
 {
 	bool result = FALSE;
@@ -99,7 +99,7 @@ static bool _sieve_variable_argument_activate
 		/* Check whether name parsing succeeded */	
 		if ( nelements < 0 || varstr != varend ) {
 			/* Parse failed */
-			sieve_command_validate_error(validator, cmd, 
+			sieve_argument_validate_error(validator, arg, 
 				"invalid variable name '%s'", str_sanitize(str_c(variable),80));
 		} else if ( nelements == 1 ) {
 			/* Normal (match) variable */
@@ -114,7 +114,7 @@ static bool _sieve_variable_argument_activate
 
 				if ( var == NULL ) {
 					_ext_variables_scope_size_error
-						(validator, cmd, str_c(cur_element->identifier));
+						(validator, arg, str_c(cur_element->identifier));
 				} else {
 					arg->argument = &variable_argument;
 					arg->context = (void *) var;
@@ -126,15 +126,15 @@ static bool _sieve_variable_argument_activate
 				if ( !assignment ) {
 					if ( cur_element->num_variable > SIEVE_VARIABLES_MAX_MATCH_INDEX ) {
 						_ext_variables_match_index_error
-							(validator, cmd, cur_element->num_variable);
+							(validator, arg, cur_element->num_variable);
 					} else {
 						arg->argument = &match_value_argument;
-						arg->context = (void *) cur_element->num_variable;
+						arg->context = POINTER_CAST(cur_element->num_variable);
 										
 						result = TRUE;
 					}
 				} else {		
-					sieve_command_validate_error(validator, cmd, 
+					sieve_argument_validate_error(validator, arg, 
 						"cannot assign to match variable");
 				}
 			}
@@ -150,7 +150,7 @@ static bool _sieve_variable_argument_activate
 			 * the relevant extension MUST cause an error.
 			 */
 
-			sieve_command_validate_error(validator, cmd, 
+			sieve_argument_validate_error(validator, arg, 
 				"cannot %s to variable in unknown namespace '%s'", 
 				assignment ? "assign" : "refer", str_c(cur_element->identifier));
 		}
@@ -180,6 +180,7 @@ bool sieve_variable_argument_activate
 				return FALSE;
 			
 			stritem = sieve_ast_strlist_next(stritem);
+
 		}
 		
 		arg->argument = &string_list_argument;
@@ -224,7 +225,7 @@ static struct sieve_ast_argument *ext_variables_match_value_argument_create
 	arg = sieve_ast_argument_create(ast, source_line);
 	arg->type = SAAT_STRING;
 	arg->argument = &match_value_argument;
-	arg->context = (void *) index;
+	arg->context = POINTER_CAST(index);
 	
 	return arg;
 }
@@ -233,7 +234,7 @@ static bool arg_match_value_generate
 (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, 
 	struct sieve_command_context *context ATTR_UNUSED)
 {
-	unsigned int index = (unsigned int) arg->context;
+	unsigned int index = POINTER_CAST_TO(arg->context, unsigned int);
 	
 	ext_variables_opr_match_value_emit(cgenv->sbin, index);
 
@@ -374,7 +375,7 @@ static bool arg_variable_string_validate
 								sieve_ast_arg_list_add(arglist, strarg);
 							else {
 								_ext_variables_scope_size_error
-									(validator, cmd, str_c(cur_element->identifier));
+									(validator, *arg, str_c(cur_element->identifier));
 								result = FALSE;
 								break;
 							}
@@ -382,7 +383,7 @@ static bool arg_variable_string_validate
 							/* Add match value argument '${000}' */
 							if ( cur_element->num_variable > SIEVE_VARIABLES_MAX_MATCH_INDEX ) {
 								_ext_variables_match_index_error
-									(validator, cmd, cur_element->num_variable);
+									(validator, *arg, cur_element->num_variable);
 								result = FALSE;
 								break;
 							}
@@ -402,7 +403,7 @@ static bool arg_variable_string_validate
 						/* References to namespaces without a prior require 
 						 * statement for thecrelevant extension MUST cause an error.
 					 	 */
-						sieve_command_validate_error(validator, cmd, 
+						sieve_argument_validate_error(validator, *arg, 
 							"referring to variable in unknown namespace '%s'", 
 							str_c(cur_element->identifier));
 						result = FALSE;
diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.c b/src/lib-sieve/plugins/variables/ext-variables-common.c
index f54a132e77ad13d0a72514bcbf41ff8ca9651797..f5bf51f288540bd50da909ccc9bb7bd2fd6ea519 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-common.c
+++ b/src/lib-sieve/plugins/variables/ext-variables-common.c
@@ -409,7 +409,7 @@ bool ext_variables_generator_load(const struct sieve_codegen_env *cgenv)
 	unsigned int count = sieve_variable_scope_size(main_scope);
 	sieve_size_t jump;
 
-	sieve_binary_emit_integer(cgenv->sbin, count);
+	sieve_binary_emit_unsigned(cgenv->sbin, count);
 
 	jump = sieve_binary_emit_offset(cgenv->sbin, 0);
 
@@ -440,15 +440,15 @@ bool ext_variables_code_dump
 	int end_offset;
 	
 	sieve_code_mark(denv);
-	if ( !sieve_binary_read_integer(denv->sbin, address, &scope_size) )
+	if ( !sieve_binary_read_unsigned(denv->sbin, address, &scope_size) )
 		return FALSE;
 		
 	pc = *address;	
 	if ( !sieve_binary_read_offset(denv->sbin, address, &end_offset) )
 		return FALSE;
 	
-	sieve_code_dumpf(denv, "SCOPE [%d] (end: %08x)", 
-		scope_size, pc + end_offset);
+	sieve_code_dumpf(denv, "SCOPE [%u] (end: %08x)", 
+		scope_size, (unsigned int) (pc + end_offset));
 	
 	/* Read global variable scope */
 	for ( i = 0; i < scope_size; i++ ) {
@@ -500,7 +500,7 @@ bool ext_variables_interpreter_load
 	sieve_size_t pc;
 	int end_offset;
 		
-	if ( !sieve_binary_read_integer(renv->sbin, address, &scope_size) ) {
+	if ( !sieve_binary_read_unsigned(renv->sbin, address, &scope_size) ) {
 		sieve_sys_error("variables: failed to read main scope size");
 		return FALSE;
 	}
diff --git a/src/lib-sieve/plugins/variables/ext-variables-modifiers.c b/src/lib-sieve/plugins/variables/ext-variables-modifiers.c
index 9713122e9b9654c2fc06e3c3eec9979cd9b0357f..98fbb5ffc2f83816dadd77c8cd0aff13d208fc98 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-modifiers.c
+++ b/src/lib-sieve/plugins/variables/ext-variables-modifiers.c
@@ -209,7 +209,7 @@ bool mod_lower_modify(string_t *in, string_t **result)
 bool mod_length_modify(string_t *in, string_t **result)
 {
 	*result = t_str_new(64);
-	str_printfa(*result, "%d", str_len(in));
+	str_printfa(*result, "%llu", (unsigned long long) str_len(in));
 
 	return TRUE;
 }
diff --git a/src/lib-sieve/plugins/variables/ext-variables-operands.c b/src/lib-sieve/plugins/variables/ext-variables-operands.c
index c551bcd0db942b62cd80de65e991194450037695..7b303999fed62e627dce32b2a693fd50c62bcc26 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-operands.c
+++ b/src/lib-sieve/plugins/variables/ext-variables-operands.c
@@ -52,27 +52,27 @@ void ext_variables_opr_variable_emit
 		/* Default variable storage */
 		(void) sieve_operand_emit_code(sbin, &variable_operand);
 		(void) sieve_binary_emit_byte(sbin, 0);
-		(void) sieve_binary_emit_integer(sbin, var->index);
+		(void) sieve_binary_emit_unsigned(sbin, var->index);
 		return;
 	} 
 
 	(void) sieve_operand_emit_code(sbin, &variable_operand);
 	(void) sieve_binary_emit_extension(sbin, var->ext, 1);
-	(void) sieve_binary_emit_integer(sbin, var->index);
+	(void) sieve_binary_emit_unsigned(sbin, var->index);
 }
 
 static bool opr_variable_dump
 (const struct sieve_dumptime_env *denv, sieve_size_t *address,
 	const char *field_name) 
 {
-	sieve_size_t index = 0;
+	unsigned int index = 0;
 	const struct sieve_extension *ext;
 	unsigned int code = 1; /* Initially set to offset value */
 
 	if ( !sieve_binary_read_extension(denv->sbin, address, &code, &ext) )
 		return FALSE;
 	
-	if ( !sieve_binary_read_integer(denv->sbin, address, &index) )
+	if ( !sieve_binary_read_unsigned(denv->sbin, address, &index) )
 		return FALSE;
 		
 	if ( ext == NULL ) {
@@ -97,7 +97,7 @@ static bool opr_variable_read_value
 	const struct sieve_extension *ext;
 	unsigned int code = 1; /* Initially set to offset value */
 	struct sieve_variable_storage *storage;
-	sieve_size_t index = 0;
+	unsigned int index = 0;
 	
 	if ( !sieve_binary_read_extension(renv->sbin, address, &code, &ext) )
 		return FALSE;
@@ -106,7 +106,7 @@ static bool opr_variable_read_value
 	if ( storage == NULL ) 
 		return FALSE;
 	
-	if (sieve_binary_read_integer(renv->sbin, address, &index) ) {
+	if (sieve_binary_read_unsigned(renv->sbin, address, &index) ) {
 		/* Parameter str can be NULL if we are requested to only skip and not 
 		 * actually read the argument.
 		 */
@@ -129,7 +129,7 @@ bool sieve_variable_operand_read_data
 {
 	const struct sieve_extension *ext;
 	unsigned int code = 1; /* Initially set to offset value */
-	sieve_size_t idx = 0;
+	unsigned int idx = 0;
 
 	if ( operand != &variable_operand ) {
 		return FALSE;
@@ -142,7 +142,7 @@ bool sieve_variable_operand_read_data
 	if ( *storage == NULL )	
 		return FALSE;
 	
-	if ( !sieve_binary_read_integer(renv->sbin, address, &idx) )
+	if ( !sieve_binary_read_unsigned(renv->sbin, address, &idx) )
 		return FALSE;		
 
 	*var_index = idx;
@@ -186,20 +186,20 @@ void ext_variables_opr_match_value_emit
 (struct sieve_binary *sbin, unsigned int index) 
 {
 	(void) sieve_operand_emit_code(sbin, &match_value_operand);
-	(void) sieve_binary_emit_integer(sbin, index);
+	(void) sieve_binary_emit_unsigned(sbin, index);
 }
 
 static bool opr_match_value_dump
 (const struct sieve_dumptime_env *denv, sieve_size_t *address,
 	const char *field_name) 
 {
-	sieve_size_t index = 0;
+	unsigned int index = 0;
 	
-	if (sieve_binary_read_integer(denv->sbin, address, &index) ) {
+	if (sieve_binary_read_unsigned(denv->sbin, address, &index) ) {
 		if ( field_name != NULL )
-			sieve_code_dumpf(denv, "%s: MATCHVAL %ld", field_name, (long) index);
+			sieve_code_dumpf(denv, "%s: MATCHVAL %lu", field_name, (unsigned long) index);
 		else
-			sieve_code_dumpf(denv, "MATCHVAL %ld", (long) index);
+			sieve_code_dumpf(denv, "MATCHVAL %lu", (unsigned long) index);
 
 		return TRUE;
 	}
@@ -210,14 +210,14 @@ static bool opr_match_value_dump
 static bool opr_match_value_read
 (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str)
 { 
-	sieve_size_t index = 0;
+	unsigned int index = 0;
 			
-	if (sieve_binary_read_integer(renv->sbin, address, &index) ) {
+	if (sieve_binary_read_unsigned(renv->sbin, address, &index) ) {
 		/* Parameter str can be NULL if we are requested to only skip and not 
 		 * actually read the argument.
 		 	*/
 		if ( str != NULL ) {
-			sieve_match_values_get(renv->interp, (unsigned int) index, str);
+			sieve_match_values_get(renv->interp, index, str);
 		
 			if ( *str == NULL ) 
 				*str = t_str_new(0);
@@ -257,17 +257,17 @@ void ext_variables_opr_variable_string_emit
 (struct sieve_binary *sbin, unsigned int elements) 
 {
 	(void) sieve_operand_emit_code(sbin, &variable_string_operand);
-	(void) sieve_binary_emit_integer(sbin, elements);
+	(void) sieve_binary_emit_unsigned(sbin, elements);
 }
 
 static bool opr_variable_string_dump
 (const struct sieve_dumptime_env *denv, sieve_size_t *address,
 	const char *field_name) 
 {
-	sieve_size_t elements = 0;
+	unsigned int elements = 0;
 	unsigned int i;
 	
-	if (!sieve_binary_read_integer(denv->sbin, address, &elements) )
+	if (!sieve_binary_read_unsigned(denv->sbin, address, &elements) )
 		return FALSE;
 	
 	if ( field_name != NULL ) 
@@ -288,10 +288,10 @@ static bool opr_variable_string_dump
 static bool opr_variable_string_read
 (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str)
 { 
-	sieve_size_t elements = 0;
+	unsigned int elements = 0;
 	unsigned int i;
 		
-	if ( !sieve_binary_read_integer(renv->sbin, address, &elements) )
+	if ( !sieve_binary_read_unsigned(renv->sbin, address, &elements) )
 		return FALSE;
 
 	/* Parameter str can be NULL if we are requested to only skip and not 
diff --git a/src/lib-sieve/sieve-ast.c b/src/lib-sieve/sieve-ast.c
index ea271fe633a74f3e5dc3b673680bf02eb52e8f80..5e57d31a02dbdd4d658dd9e58456f9665fb17499 100644
--- a/src/lib-sieve/sieve-ast.c
+++ b/src/lib-sieve/sieve-ast.c
@@ -177,23 +177,6 @@ void *sieve_ast_extension_get_context
 	return reg->context;
 }
 
-/* 
- * Error reporting 
- */
-
-void sieve_ast_error
-(struct sieve_error_handler *ehandler, sieve_error_vfunc_t vfunc, 
-	struct sieve_ast_node *node, const char *fmt, va_list args) 
-{ 
-	struct sieve_script *script = node->ast->script;
-	
-	T_BEGIN {
-		vfunc(ehandler,
-			sieve_error_script_location(script, sieve_ast_node_line(node)), 
-			fmt, args);
-	} T_END; 
-}
-
 /*
  * AST list implementations
  */
diff --git a/src/lib-sieve/sieve-ast.h b/src/lib-sieve/sieve-ast.h
index 564bd5f8b034759785f3b70861e85d8de7b3c676..7e4b424cb1a44f5b429de82614616dc59e5b4376 100644
--- a/src/lib-sieve/sieve-ast.h
+++ b/src/lib-sieve/sieve-ast.h
@@ -200,12 +200,6 @@ void sieve_ast_extension_register
 void *sieve_ast_extension_get_context
 	(struct sieve_ast *ast, const struct sieve_extension *ext);
 
-/* Error reporting */
-
-void sieve_ast_error
-(struct sieve_error_handler *ehandler, sieve_error_vfunc_t vfunc, 
-	struct sieve_ast_node *node, const char *fmt, va_list args);
-	
 /* 
  * AST node manipulation
  */
diff --git a/src/lib-sieve/sieve-binary.c b/src/lib-sieve/sieve-binary.c
index a30b9914bfa9cc407280b9d83715bdecdeb92cb6..0c48faa404d824ac4af2651c9b401581f85dcb37 100644
--- a/src/lib-sieve/sieve-binary.c
+++ b/src/lib-sieve/sieve-binary.c
@@ -562,14 +562,14 @@ static bool _sieve_binary_save
 		return FALSE;
 		
 	ext_count = array_count(&sbin->linked_extensions);
-	sieve_binary_emit_integer(sbin, ext_count);
+	sieve_binary_emit_unsigned(sbin, ext_count);
 	
 	for ( i = 0; i < ext_count; i++ ) {
 		struct sieve_binary_extension_reg * const *ext
 			= array_idx(&sbin->linked_extensions, i);
 		
 		sieve_binary_emit_cstring(sbin, (*ext)->extension->name);
-		sieve_binary_emit_integer(sbin, (*ext)->block_id);
+		sieve_binary_emit_unsigned(sbin, (*ext)->block_id);
 	}
 	
 	if ( !sieve_binary_block_set_active(sbin, SBIN_SYSBLOCK_MAIN_PROGRAM, NULL) )
@@ -979,14 +979,13 @@ static bool _load_block_index_record
 static bool _sieve_binary_load_extensions(struct sieve_binary *sbin)
 {
 	sieve_size_t offset = 0;
-	sieve_size_t count = 0;
+	unsigned int i, count;
 	bool result = TRUE;
-	unsigned int i;
 	
 	if ( !sieve_binary_block_set_active(sbin, SBIN_SYSBLOCK_EXTENSIONS, NULL) ) 
 		return FALSE;
 
-	if ( !sieve_binary_read_integer(sbin, &offset, &count) )
+	if ( !sieve_binary_read_unsigned(sbin, &offset, &count) )
 		return FALSE;
 	
 	for ( i = 0; result && i < count; i++ ) {
@@ -1005,7 +1004,7 @@ static bool _sieve_binary_load_extensions(struct sieve_binary *sbin)
 					struct sieve_binary_extension_reg *ereg = NULL;
 					
 					(void) sieve_binary_extension_register(sbin, ext, &ereg);
-					if ( !sieve_binary_read_integer(sbin, &offset, &ereg->block_id) )
+					if ( !sieve_binary_read_unsigned(sbin, &offset, &ereg->block_id) )
 						result = FALSE;
 				}
 			}	else
@@ -1471,11 +1470,11 @@ void sieve_binary_resolve_offset
  */
 
 sieve_size_t sieve_binary_emit_integer
-(struct sieve_binary *binary, sieve_size_t integer)
+(struct sieve_binary *binary, sieve_number_t integer)
 {
 	sieve_size_t address = _sieve_binary_get_code_size(binary);
 	int i;
-	char buffer[sizeof(sieve_size_t) + 1];
+	char buffer[sizeof(sieve_number_t) + 1];
 	int bufpos = sizeof(buffer) - 1;
   
 	buffer[bufpos] = integer & 0x7F;
@@ -1500,9 +1499,9 @@ sieve_size_t sieve_binary_emit_integer
 }
 
 static inline sieve_size_t sieve_binary_emit_dynamic_data
-	(struct sieve_binary *binary, const void *data, size_t size)
+	(struct sieve_binary *binary, const void *data, sieve_size_t size)
 {
-	sieve_size_t address = sieve_binary_emit_integer(binary, size);
+	sieve_size_t address = sieve_binary_emit_integer(binary, (sieve_number_t) size);
 
 	_sieve_binary_emit_data(binary, data, size);
   
@@ -1513,7 +1512,7 @@ sieve_size_t sieve_binary_emit_cstring
 	(struct sieve_binary *binary, const char *str)
 {
 	sieve_size_t address = sieve_binary_emit_dynamic_data
-		(binary, (void *) str, strlen(str));
+		(binary, (void *) str, (sieve_size_t) strlen(str));
 	_sieve_binary_emit_byte(binary, 0);
   
 	return address;
@@ -1523,7 +1522,7 @@ sieve_size_t sieve_binary_emit_string
 	(struct sieve_binary *binary, const string_t *str)
 {
 	sieve_size_t address = sieve_binary_emit_dynamic_data
-		(binary, (void *) str_data(str), str_len(str));
+		(binary, (void *) str_data(str), (sieve_size_t) str_len(str));
 	_sieve_binary_emit_byte(binary, 0);
 	
 	return address;
@@ -1565,38 +1564,38 @@ void sieve_binary_emit_extension_object
 /* Literals */
 
 bool sieve_binary_read_byte
-	(struct sieve_binary *binary, sieve_size_t *address, unsigned int *byte_val) 
+	(struct sieve_binary *binary, sieve_size_t *address, unsigned int *byte_r) 
 {	
 	if ( ADDR_BYTES_LEFT(binary, address) >= 1 ) {
-		if ( byte_val != NULL )
-			*byte_val = ADDR_DATA_AT(binary, address);
+		if ( byte_r != NULL )
+			*byte_r = ADDR_DATA_AT(binary, address);
 		ADDR_JUMP(address, 1);
 			
 		return TRUE;
 	}
 	
-	*byte_val = 0;
+	*byte_r = 0;
 	return FALSE;
 }
 
 bool sieve_binary_read_code
-	(struct sieve_binary *binary, sieve_size_t *address, int *code) 
+	(struct sieve_binary *binary, sieve_size_t *address, int *code_r) 
 {	
 	if ( ADDR_BYTES_LEFT(binary, address) >= 1 ) {
-		if ( code != NULL )
-			*code = ADDR_CODE_AT(binary, address);
+		if ( code_r != NULL )
+			*code_r = ADDR_CODE_AT(binary, address);
 		ADDR_JUMP(address, 1);
 			
 		return TRUE;
 	}
 	
-	*code = 0;
+	*code_r = 0;
 	return FALSE;
 }
 
 
 bool sieve_binary_read_offset
-	(struct sieve_binary *binary, sieve_size_t *address, int *offset) 
+	(struct sieve_binary *binary, sieve_size_t *address, int *offset_r) 
 {
 	uint32_t offs = 0;
 	
@@ -1608,8 +1607,8 @@ bool sieve_binary_read_offset
 			ADDR_JUMP(address, 1);
 		}
 	  
-		if ( offset != NULL )
-			*offset = (int) offs;
+		if ( offset_r != NULL )
+			*offset_r = (int) offs;
 			
 		return TRUE;
 	}
@@ -1617,21 +1616,22 @@ bool sieve_binary_read_offset
 	return FALSE;
 }
 
+/* FIXME: might need negative numbers in the future */
 bool sieve_binary_read_integer
-  (struct sieve_binary *binary, sieve_size_t *address, sieve_size_t *integer) 
+  (struct sieve_binary *binary, sieve_size_t *address, sieve_number_t *int_r) 
 {
-	int bits = sizeof(sieve_size_t) * 8;
-	*integer = 0;
+	int bits = sizeof(sieve_number_t) * 8;
+	*int_r = 0;
   
 	if ( ADDR_BYTES_LEFT(binary, address) == 0 )
 		return FALSE;
   
 	while ( (ADDR_DATA_AT(binary, address) & 0x80) > 0 ) {
 		if ( ADDR_BYTES_LEFT(binary, address) > 0 && bits > 0) {
-			*integer |= ADDR_DATA_AT(binary, address) & 0x7F;
+			*int_r |= ADDR_DATA_AT(binary, address) & 0x7F;
 			ADDR_JUMP(address, 1);
     
-			*integer <<= 7;
+			*int_r <<= 7;
 			bits -= 7;
 		} else {
 			/* This is an error */
@@ -1639,7 +1639,7 @@ bool sieve_binary_read_integer
 		}
 	}
   
-	*integer |= ADDR_DATA_AT(binary, address) & 0x7F;
+	*int_r |= ADDR_DATA_AT(binary, address) & 0x7F;
 	ADDR_JUMP(address, 1);
   
 	return TRUE;
@@ -1652,18 +1652,18 @@ static string_t *t_str_new_const(const char *str, size_t len)
 }
 
 bool sieve_binary_read_string
-(struct sieve_binary *binary, sieve_size_t *address, string_t **str) 
+(struct sieve_binary *binary, sieve_size_t *address, string_t **str_r) 
 {
-	sieve_size_t strlen = 0;
+	unsigned int strlen = 0;
   
-	if ( !sieve_binary_read_integer(binary, address, &strlen) ) 
+	if ( !sieve_binary_read_unsigned(binary, address, &strlen) ) 
 		return FALSE;
     	  
 	if ( strlen > ADDR_BYTES_LEFT(binary, address) ) 
 		return FALSE;
  
- 	if ( str != NULL )  
-		*str = t_str_new_const(&ADDR_CODE_AT(binary, address), strlen);
+ 	if ( str_r != NULL )  
+		*str_r = t_str_new_const(&ADDR_CODE_AT(binary, address), strlen);
 	ADDR_JUMP(address, strlen);
 	
 	if ( ADDR_CODE_AT(binary, address) != 0 )
diff --git a/src/lib-sieve/sieve-binary.h b/src/lib-sieve/sieve-binary.h
index d2fd7cc565b9f734a4a123fa44cc551cc30811d3..d934c86cabd40dd4bf59cf9e8e4ed862fd265b66 100644
--- a/src/lib-sieve/sieve-binary.h
+++ b/src/lib-sieve/sieve-binary.h
@@ -125,12 +125,19 @@ void sieve_binary_resolve_offset
 /* Literal emission functions */
 
 sieve_size_t sieve_binary_emit_integer
-	(struct sieve_binary *binary, sieve_size_t integer);
+	(struct sieve_binary *binary, sieve_number_t integer);
 sieve_size_t sieve_binary_emit_string
 	(struct sieve_binary *binary, const string_t *str);
 sieve_size_t sieve_binary_emit_cstring
 	(struct sieve_binary *binary, const char *str);
 
+static inline sieve_size_t sieve_binary_emit_unsigned
+	(struct sieve_binary *binary, unsigned int count)
+{
+	return sieve_binary_emit_integer(binary, count);
+}
+
+
 /* Extension emission functions */
 
 sieve_size_t sieve_binary_emit_extension
@@ -146,15 +153,28 @@ void sieve_binary_emit_extension_object
 
 /* Literals */
 bool sieve_binary_read_byte
-	(struct sieve_binary *binary, sieve_size_t *address, unsigned int *byte_val);
+	(struct sieve_binary *binary, sieve_size_t *address, unsigned int *byte_r);
 bool sieve_binary_read_code
-	(struct sieve_binary *binary, sieve_size_t *address, int *code);
+	(struct sieve_binary *binary, sieve_size_t *address, int *code_r);
 bool sieve_binary_read_offset
-	(struct sieve_binary *binary, sieve_size_t *address, int *offset);
+	(struct sieve_binary *binary, sieve_size_t *address, int *offset_r);
 bool sieve_binary_read_integer
-  (struct sieve_binary *binary, sieve_size_t *address, sieve_size_t *integer); 
+  (struct sieve_binary *binary, sieve_size_t *address, sieve_number_t *int_r); 
 bool sieve_binary_read_string
-  (struct sieve_binary *binary, sieve_size_t *address, string_t **str);
+  (struct sieve_binary *binary, sieve_size_t *address, string_t **str_r);
+
+static inline bool sieve_binary_read_unsigned
+  (struct sieve_binary *binary, sieve_size_t *address, unsigned int *count_r)
+{
+	sieve_number_t integer;
+
+	if ( !sieve_binary_read_integer(binary, address, &integer) )
+		return FALSE;
+
+	*count_r = integer;
+
+	return TRUE;
+}
 
 /* Extension */
 bool sieve_binary_read_extension
diff --git a/src/lib-sieve/sieve-code-dumper.c b/src/lib-sieve/sieve-code-dumper.c
index ec693a05e272de9a63c2de709abb7465a515f49d..5a6f966f18e779bd769fee41d479098be6fde4f2 100644
--- a/src/lib-sieve/sieve-code-dumper.c
+++ b/src/lib-sieve/sieve-code-dumper.c
@@ -74,7 +74,7 @@ void sieve_code_dumpf
 	va_list args;
 	
 	va_start(args, fmt);	
-	str_printfa(outbuf, "%08x: ", cdumper->mark_address);
+	str_printfa(outbuf, "%08llx: ", (unsigned long long) cdumper->mark_address);
 	
 	while ( tab > 0 )	{
 		str_append(outbuf, "  ");
@@ -178,7 +178,7 @@ void sieve_code_dumper_run(struct sieve_code_dumper *dumper)
 	/* Load and dump extensions listed in code */
 	sieve_code_mark(denv);
 	
-	if ( sieve_binary_read_integer(sbin, &dumper->pc, &ext_count) ) {
+	if ( sieve_binary_read_unsigned(sbin, &dumper->pc, &ext_count) ) {
 		unsigned int i;
 		
 		sieve_code_dumpf(denv, "EXTENSIONS [%d]:", ext_count);
diff --git a/src/lib-sieve/sieve-code.c b/src/lib-sieve/sieve-code.c
index a77441583e7efdc750f183eb81366059403c209b..7155f987bac88b380abbbf2264ed2f028444a8f1 100644
--- a/src/lib-sieve/sieve-code.c
+++ b/src/lib-sieve/sieve-code.c
@@ -26,13 +26,13 @@ struct sieve_coded_stringlist {
 	sieve_size_t start_address;
 	sieve_size_t end_address;
 	sieve_size_t current_offset;
-	int length;
-	int index;
+	unsigned int length;
+	unsigned int index;
 };
 
 static struct sieve_coded_stringlist *sieve_coded_stringlist_create
 (const struct sieve_runtime_env *renv, 
-	 sieve_size_t start_address, sieve_size_t length, sieve_size_t end)
+	 sieve_size_t start_address, unsigned int length, sieve_size_t end)
 {
 	struct sieve_coded_stringlist *strlist;
 	
@@ -51,17 +51,17 @@ static struct sieve_coded_stringlist *sieve_coded_stringlist_create
 }
 
 bool sieve_coded_stringlist_next_item
-(struct sieve_coded_stringlist *strlist, string_t **str) 
+(struct sieve_coded_stringlist *strlist, string_t **str_r) 
 {
 	sieve_size_t address;
-	*str = NULL;
+	*str_r = NULL;
   
 	if ( strlist->index >= strlist->length ) 
 		return TRUE;
 	else {
 		address = strlist->current_offset;
   	
-		if ( sieve_opr_string_read(strlist->runenv, &address, str) ) {
+		if ( sieve_opr_string_read(strlist->runenv, &address, str_r) ) {
 			strlist->index++;
 			strlist->current_offset = address;
 			return TRUE;
@@ -77,7 +77,7 @@ void sieve_coded_stringlist_reset(struct sieve_coded_stringlist *strlist)
 	strlist->index = 0;
 }
 
-int sieve_coded_stringlist_get_length
+unsigned int sieve_coded_stringlist_get_length
 (struct sieve_coded_stringlist *strlist)
 {
 	return strlist->length;
@@ -123,18 +123,19 @@ bool sieve_coded_stringlist_read_all
 
 static bool sieve_coded_stringlist_dump
 (const struct sieve_dumptime_env *denv, sieve_size_t *address, 
-	sieve_size_t length, sieve_size_t end, const char *field_name)
+	unsigned int length, sieve_size_t end, const char *field_name)
 {
 	unsigned int i;
 	
 	if ( end > sieve_binary_get_code_size(denv->sbin) ) 
   		return FALSE;
     
-  if ( field_name != NULL )
-		sieve_code_dumpf(denv, "%s: STRLIST [%d] (end: %08x)", 
-			field_name, length, end);
+	if ( field_name != NULL )
+		sieve_code_dumpf(denv, "%s: STRLIST [%u] (end: %08llx)", 
+			field_name, length, (unsigned long long) end);
 	else
-		sieve_code_dumpf(denv, "STRLIST [%d] (end: %08x)", length, end);
+		sieve_code_dumpf(denv, "STRLIST [%u] (end: %08llx)", 
+			length, (unsigned long long) end);
 	
 	sieve_code_descend(denv);
 	
@@ -160,17 +161,17 @@ static bool sieve_coded_stringlist_dump
 void sieve_code_source_line_emit
 (struct sieve_binary *sbin, unsigned int source_line)
 {
-    (void)sieve_binary_emit_integer(sbin, source_line);
+    (void)sieve_binary_emit_unsigned(sbin, source_line);
 }
 
 bool sieve_code_source_line_dump
 (const struct sieve_dumptime_env *denv, sieve_size_t *address)
 {
-    sieve_size_t number = 0;
+    unsigned int number = 0;
 
 	sieve_code_mark(denv);
-    if (sieve_binary_read_integer(denv->sbin, address, &number) ) {
-        sieve_code_dumpf(denv, "(source line: %ld)", (long) number);
+    if (sieve_binary_read_unsigned(denv->sbin, address, &number) ) {
+        sieve_code_dumpf(denv, "(source line: %lu)", (unsigned long) number);
 
         return TRUE;
     }
@@ -180,15 +181,9 @@ bool sieve_code_source_line_dump
 
 bool sieve_code_source_line_read
 (const struct sieve_runtime_env *renv, sieve_size_t *address,
-	unsigned int *source_line)
+	unsigned int *source_line_r)
 {
-	sieve_size_t number;
-
-	if ( !sieve_binary_read_integer(renv->sbin, address, &number) )
-		return FALSE;
-
-	*source_line = number;
-	return TRUE;
+	return sieve_binary_read_unsigned(renv->sbin, address, source_line_r);
 }
 
 /*
@@ -291,7 +286,7 @@ static bool opr_number_dump
 		const char *field_name);
 static bool opr_number_read
 	(const struct sieve_runtime_env *renv, sieve_size_t *address, 
-		sieve_size_t *number);
+		sieve_number_t *number_r);
 
 const struct sieve_opr_number_interface number_interface = { 
 	opr_number_dump, 
@@ -314,7 +309,7 @@ static bool opr_string_dump
 	(const struct sieve_dumptime_env *denv, sieve_size_t *address,
 		const char *field_name);
 static bool opr_string_read
-	(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str);
+	(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r);
 
 const struct sieve_opr_string_interface string_interface ={ 
 	opr_string_dump,
@@ -360,7 +355,7 @@ const struct sieve_operand stringlist_operand =	{
  
 /* Number */
 
-void sieve_opr_number_emit(struct sieve_binary *sbin, sieve_size_t number) 
+void sieve_opr_number_emit(struct sieve_binary *sbin, sieve_number_t number) 
 {
 	(void) sieve_operand_emit_code(sbin, &number_operand);
 	(void) sieve_binary_emit_integer(sbin, number);
@@ -398,7 +393,7 @@ bool sieve_opr_number_dump
 
 bool sieve_opr_number_read_data
 (const struct sieve_runtime_env *renv, const struct sieve_operand *operand,
-	sieve_size_t *address, sieve_size_t *number)
+	sieve_size_t *address, sieve_number_t *number_r)
 {
 	const struct sieve_opr_number_interface *intf;
 		
@@ -410,29 +405,29 @@ bool sieve_opr_number_read_data
 	if ( intf->read == NULL )
 		return FALSE;
 
-	return intf->read(renv, address, number);  
+	return intf->read(renv, address, number_r);  
 }
 
 bool sieve_opr_number_read
 (const struct sieve_runtime_env *renv, sieve_size_t *address, 
-	sieve_size_t *number)
+	sieve_number_t *number_r)
 {
 	const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address);
 		
-	return sieve_opr_number_read_data(renv, operand, address, number);
+	return sieve_opr_number_read_data(renv, operand, address, number_r);
 }
 
 static bool opr_number_dump
 (const struct sieve_dumptime_env *denv, sieve_size_t *address,
 	const char *field_name) 
 {
-	sieve_size_t number = 0;
+	sieve_number_t number = 0;
 	
 	if (sieve_binary_read_integer(denv->sbin, address, &number) ) {
 		if ( field_name != NULL ) 
-			sieve_code_dumpf(denv, "%s: NUM %llu", field_name, (long long) number);
+			sieve_code_dumpf(denv, "%s: NUM %llu", field_name, (unsigned long long) number);
 		else
-			sieve_code_dumpf(denv, "NUM %llu", (long long) number);
+			sieve_code_dumpf(denv, "NUM %llu", (unsigned long long) number);
 
 		return TRUE;
 	}
@@ -442,9 +437,9 @@ static bool opr_number_dump
 
 static bool opr_number_read
 (const struct sieve_runtime_env *renv, sieve_size_t *address, 
-	sieve_size_t *number)
+	sieve_number_t *number_r)
 { 
-	return sieve_binary_read_integer(renv->sbin, address, number);
+	return sieve_binary_read_integer(renv->sbin, address, number_r);
 }
 
 /* String */
@@ -486,21 +481,21 @@ bool sieve_opr_string_dump
 
 bool sieve_opr_string_dump_ex
 (const struct sieve_dumptime_env *denv, sieve_size_t *address, 
-	const char *field_name, bool *literal)
+	const char *field_name, bool *literal_r)
 {
 	const struct sieve_operand *operand;
 	
 	sieve_code_mark(denv);
 	operand = sieve_operand_read(denv->sbin, address);
 
-	*literal = ( operand == &string_operand );	
+	*literal_r = ( operand == &string_operand );	
 
 	return sieve_opr_string_dump_data(denv, operand, address, field_name);
 } 
 
 bool sieve_opr_string_read_data
 (const struct sieve_runtime_env *renv, const struct sieve_operand *operand,
-	sieve_size_t *address, string_t **str)
+	sieve_size_t *address, string_t **str_r)
 {
 	const struct sieve_opr_string_interface *intf;
 	
@@ -512,26 +507,26 @@ bool sieve_opr_string_read_data
 	if ( intf->read == NULL )
 		return FALSE;
 
-	return intf->read(renv, address, str);  
+	return intf->read(renv, address, str_r);  
 }
 
 bool sieve_opr_string_read
-(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str)
+(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r)
 {
 	const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address);
 
-	return sieve_opr_string_read_data(renv, operand, address, str);
+	return sieve_opr_string_read_data(renv, operand, address, str_r);
 }
 
 bool sieve_opr_string_read_ex
-(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str,
-	bool *literal)
+(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r,
+	bool *literal_r)
 {
 	const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address);
 
-	*literal = ( operand == &string_operand );
+	*literal_r = ( operand == &string_operand );
 
-	return sieve_opr_string_read_data(renv, operand, address, str);
+	return sieve_opr_string_read_data(renv, operand, address, str_r);
 }
 
 static void _dump_string
@@ -571,9 +566,9 @@ bool opr_string_dump
 }
 
 static bool opr_string_read
-(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str)
+(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r)
 { 	
-	return sieve_binary_read_string(renv->sbin, address, str);
+	return sieve_binary_read_string(renv->sbin, address, str_r);
 }
 
 /* String list */
@@ -591,7 +586,7 @@ void sieve_opr_stringlist_emit_start
 	*context = (void *) end_offset;
 
 	/* Emit the length of the list */
-	(void) sieve_binary_emit_integer(sbin, (int) listlen);
+	(void) sieve_binary_emit_unsigned(sbin, listlen);
 }
 
 void sieve_opr_stringlist_emit_item
@@ -693,7 +688,7 @@ static bool opr_stringlist_dump
 {
 	sieve_size_t pc = *address;
 	sieve_size_t end; 
-	sieve_size_t length = 0; 
+	unsigned int length = 0; 
  	int end_offset;
 
 	if ( !sieve_binary_read_offset(denv->sbin, address, &end_offset) )
@@ -701,7 +696,7 @@ static bool opr_stringlist_dump
 
 	end = pc + end_offset;
 
-	if ( !sieve_binary_read_integer(denv->sbin, address, &length) ) 
+	if ( !sieve_binary_read_unsigned(denv->sbin, address, &length) ) 
 		return FALSE;	
   	
 	return sieve_coded_stringlist_dump(denv, address, length, end, field_name); 
@@ -713,7 +708,7 @@ static struct sieve_coded_stringlist *opr_stringlist_read
 	struct sieve_coded_stringlist *strlist;
 	sieve_size_t pc = *address;
 	sieve_size_t end; 
-	sieve_size_t length = 0;  
+	unsigned int length = 0;  
 	int end_offset;
 	
 	if ( !sieve_binary_read_offset(renv->sbin, address, &end_offset) )
@@ -721,10 +716,10 @@ static struct sieve_coded_stringlist *opr_stringlist_read
 
 	end = pc + end_offset;
 
-	if ( !sieve_binary_read_integer(renv->sbin, address, &length) ) 
-  	return NULL;	
+	if ( !sieve_binary_read_unsigned(renv->sbin, address, &length) ) 
+	  	return NULL;	
   	
-	strlist = sieve_coded_stringlist_create(renv, *address, length, end); 
+	strlist = sieve_coded_stringlist_create(renv, *address, (unsigned int) length, end); 
 
 	/* Skip over the string list for now */
 	*address = end;
diff --git a/src/lib-sieve/sieve-code.h b/src/lib-sieve/sieve-code.h
index 9b8c2ccf4cf547a515444194081eeb51898ce285..9f1be317bf08e4969cf99b45fd5bad4194e073ad 100644
--- a/src/lib-sieve/sieve-code.h
+++ b/src/lib-sieve/sieve-code.h
@@ -18,14 +18,14 @@
 struct sieve_coded_stringlist;
 
 bool sieve_coded_stringlist_next_item
-	(struct sieve_coded_stringlist *strlist, string_t **str);
+	(struct sieve_coded_stringlist *strlist, string_t **str_r);
 void sieve_coded_stringlist_reset
 	(struct sieve_coded_stringlist *strlist);
 bool sieve_coded_stringlist_read_all
 	(struct sieve_coded_stringlist *strlist, pool_t pool,
 		const char * const **list_r);
 
-int sieve_coded_stringlist_get_length
+unsigned int sieve_coded_stringlist_get_length
 	(struct sieve_coded_stringlist *strlist);
 sieve_size_t sieve_coded_stringlist_get_end_address
 	(struct sieve_coded_stringlist *strlist);
@@ -42,7 +42,7 @@ bool sieve_code_source_line_dump
 	(const struct sieve_dumptime_env *denv, sieve_size_t *address);
 bool sieve_code_source_line_read
 	(const struct sieve_runtime_env *renv, sieve_size_t *address, 
-    	unsigned int *source_line);
+    	unsigned int *source_line_r);
 
 /* 
  * Operand object
@@ -113,7 +113,7 @@ struct sieve_opr_number_interface {
 			const char *field_name);
 	bool (*read)
 	  (const struct sieve_runtime_env *renv, sieve_size_t *address, 
-	  	sieve_size_t *number);
+	  	sieve_number_t *number_r);
 };
 
 struct sieve_opr_string_interface {
@@ -122,7 +122,7 @@ struct sieve_opr_string_interface {
 			const char *field_name);
 	bool (*read)
 		(const struct sieve_runtime_env *renv, sieve_size_t *address, 
-			string_t **str);
+			string_t **str_r);
 };
 
 struct sieve_opr_stringlist_interface {
@@ -139,7 +139,7 @@ struct sieve_opr_stringlist_interface {
 
 /* Number */
 
-void sieve_opr_number_emit(struct sieve_binary *sbin, sieve_size_t number);
+void sieve_opr_number_emit(struct sieve_binary *sbin, sieve_number_t number);
 bool sieve_opr_number_dump_data	
 	(const struct sieve_dumptime_env *denv, const struct sieve_operand *operand,
 		sieve_size_t *address, const char *field_name); 
@@ -148,10 +148,10 @@ bool sieve_opr_number_dump
 		const char *field_name); 
 bool sieve_opr_number_read_data
 	(const struct sieve_runtime_env *renv, const struct sieve_operand *operand,
-		sieve_size_t *address, sieve_size_t *number);
+		sieve_size_t *address, sieve_number_t *number_r);
 bool sieve_opr_number_read
 	(const struct sieve_runtime_env *renv, sieve_size_t *address, 
-		sieve_size_t *number);
+		sieve_number_t *number_r);
 
 static inline bool sieve_operand_is_number
 (const struct sieve_operand *operand)
@@ -170,15 +170,15 @@ bool sieve_opr_string_dump
 		const char *field_name); 
 bool sieve_opr_string_dump_ex
 	(const struct sieve_dumptime_env *denv, sieve_size_t *address, 
-		const char *field_name, bool *literal); 
+		const char *field_name, bool *literal_r); 
 bool sieve_opr_string_read_data
 	(const struct sieve_runtime_env *renv, const struct sieve_operand *operand,
-		sieve_size_t *address, string_t **str);
+		sieve_size_t *address, string_t **str_r);
 bool sieve_opr_string_read
-	(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str);
+	(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r);
 bool sieve_opr_string_read_ex
-	(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str,
-		bool *literal);
+	(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r,
+		bool *literal_r);
 
 static inline bool sieve_operand_is_string
 (const struct sieve_operand *operand)
diff --git a/src/lib-sieve/sieve-commands.h b/src/lib-sieve/sieve-commands.h
index 07012983a02eb5c6833a01efb5789a709ef84743..c3a112762927d521e8fd1877bbad1400aac64a8e 100644
--- a/src/lib-sieve/sieve-commands.h
+++ b/src/lib-sieve/sieve-commands.h
@@ -31,6 +31,18 @@ struct sieve_argument {
 			struct sieve_command_context *context);
 };
 
+/* Utility macros */
+
+#define sieve_argument_is_string_literal(arg) \
+	( (arg)->argument == &string_argument )
+
+/* Error handling */
+
+#define sieve_argument_validate_error(validator, arg_node, ...) \
+	sieve_validator_error(validator, (arg_node)->source_line, __VA_ARGS__)
+#define sieve_argument_validate_warning(validator, arg_node, ...) \
+	sieve_validator_warning(validator, (arg_node)->source_line, __VA_ARGS__)
+
 /* Literal arguments */
 
 extern const struct sieve_argument number_argument;
@@ -94,26 +106,45 @@ struct sieve_command_context {
 	void *data;
 };
 
+/* Context API */
+
 struct sieve_command_context *sieve_command_context_create
 	(struct sieve_ast_node *cmd_node, const struct sieve_command *command,
 		struct sieve_command_registration *reg);
 		
 const char *sieve_command_type_name(const struct sieve_command *command);		
 
-#define sieve_argument_is_string_literal(arg) \
-	( (arg)->argument == &string_argument )
+struct sieve_command_context *sieve_command_prev_context	
+	(struct sieve_command_context *context); 
+struct sieve_command_context *sieve_command_parent_context	
+	(struct sieve_command_context *context);
+	
+struct sieve_ast_argument *sieve_command_add_dynamic_tag
+	(struct sieve_command_context *cmd, const struct sieve_argument *tag,
+		int id_code);
+struct sieve_ast_argument *sieve_command_find_argument
+	(struct sieve_command_context *cmd, const struct sieve_argument *argument);	
+	
+void sieve_command_exit_block_unconditionally
+	(struct sieve_command_context *cmd);
+bool sieve_command_block_exits_unconditionally
+	(struct sieve_command_context *cmd);
+	
+/* Error handling */
 		
 #define sieve_command_validate_error(validator, context, ...) \
-	sieve_validator_error(validator, (context)->ast_node, __VA_ARGS__)
+	sieve_validator_error(validator, (context)->ast_node->source_line, __VA_ARGS__)
 #define sieve_command_validate_warning(validator, context, ...) \
-	sieve_validator_warning(validator, (context)->ast_node, __VA_ARGS__)
+	sieve_validator_warning(validator, (context)->ast_node->source_line, __VA_ARGS__)
 #define sieve_command_validate_critical(validator, context, ...) \
-	sieve_validator_critical(validator, (context)->ast_node, __VA_ARGS__)
+	sieve_validator_critical(validator, (context)->ast_node->source_line, __VA_ARGS__)
 
 #define sieve_command_generate_error(gentr, context, ...) \
-	sieve_generator_error(gentr, (context)->ast_node, __VA_ARGS__)
+	sieve_generator_error(gentr, (context)->ast_node->source_line, __VA_ARGS__)
 #define sieve_command_generate_critical(gentr, context, ...) \
-	sieve_generator_critical(gentr, (context)->ast_node, __VA_ARGS__)
+	sieve_generator_critical(gentr, (context)->ast_node->source_line, __VA_ARGS__)
+
+/* Utility macros */
 
 #define sieve_command_pool(context) \
 	sieve_ast_node_pool((context)->ast_node)
@@ -129,22 +160,6 @@ const char *sieve_command_type_name(const struct sieve_command *command);
 #define sieve_command_is_first(context) \
 	( sieve_ast_node_prev((context)->ast_node) == NULL )	
 
-struct sieve_command_context *sieve_command_prev_context	
-	(struct sieve_command_context *context); 
-struct sieve_command_context *sieve_command_parent_context	
-	(struct sieve_command_context *context);
-	
-struct sieve_ast_argument *sieve_command_add_dynamic_tag
-	(struct sieve_command_context *cmd, const struct sieve_argument *tag,
-		int id_code);
-struct sieve_ast_argument *sieve_command_find_argument
-	(struct sieve_command_context *cmd, const struct sieve_argument *argument);	
-	
-void sieve_command_exit_block_unconditionally
-	(struct sieve_command_context *cmd);
-bool sieve_command_block_exits_unconditionally
-	(struct sieve_command_context *cmd);
-	
 /*
  * Core commands
  */
diff --git a/src/lib-sieve/sieve-comparators.c b/src/lib-sieve/sieve-comparators.c
index 706b8ca64bc3d17bb091d32b64c96e8a0a6501bf..038f858928ca63cecb5c8f860dd993a049fc7b99 100644
--- a/src/lib-sieve/sieve-comparators.c
+++ b/src/lib-sieve/sieve-comparators.c
@@ -152,7 +152,7 @@ static bool tag_comparator_validate
 	 *   ":comparator" <comparator-name: string>
 	 */
 	if ( (*arg)->type != SAAT_STRING ) {
-		sieve_command_validate_error(validator, cmd, 
+		sieve_argument_validate_error(validator, *arg, 
 			":comparator tag requires one string argument, but %s was found", 
 			sieve_ast_argument_name(*arg) );
 		return FALSE;
@@ -162,7 +162,7 @@ static bool tag_comparator_validate
 	cmp = sieve_comparator_find(validator, sieve_ast_argument_strc(*arg));
 	
 	if ( cmp == NULL ) {
-		sieve_command_validate_error(validator, cmd, 
+		sieve_argument_validate_error(validator, *arg, 
 			"unknown comparator '%s'", 
 			str_sanitize(sieve_ast_argument_strc(*arg),80));
 
diff --git a/src/lib-sieve/sieve-error.c b/src/lib-sieve/sieve-error.c
index ce2a2bc7047ff40f5c88bf5609f8910c5587f84f..c43d698c1ecc599bf08a59b758130f93f12552d9 100644
--- a/src/lib-sieve/sieve-error.c
+++ b/src/lib-sieve/sieve-error.c
@@ -352,6 +352,8 @@ static void sieve_logfile_vprintf
 	const char *prefix,	const char *fmt, va_list args) 
 {
 	string_t *outbuf;
+	ssize_t ret = 0, remain;
+	const char *data;
 	
 	if ( ehandler->stream == NULL ) return;
 	
@@ -363,8 +365,22 @@ static void sieve_logfile_vprintf
 		str_vprintfa(outbuf, fmt, args);
 		str_append(outbuf, ".\n");
 	
-		o_stream_send(ehandler->stream, str_data(outbuf), str_len(outbuf));
+		remain = str_len(outbuf);
+		data = (const char *) str_data(outbuf);
+
+		while ( remain > 0 ) { 
+			if ( (ret=o_stream_send(ehandler->stream, data, remain)) < 0 )
+				break;
+
+			remain -= ret;
+			data += ret;
+		}
 	} T_END;
+
+	if ( ret < 0 ) {
+		sieve_sys_error(
+			"o_stream_send() failed on logfile %s: %m",	ehandler->logfile);		
+	}
 }
 
 inline static void sieve_logfile_printf
@@ -431,7 +447,7 @@ static void sieve_logfile_start(struct sieve_logfile_ehandler *ehandler)
 			}
 			
 			/* Open clean logfile (overwrites existing if rename() failed earlier) */
-			fd = open(ehandler->logfile, O_CREAT | O_WRONLY, 0600);
+			fd = open(ehandler->logfile, O_CREAT | O_WRONLY | O_TRUNC, 0600);
 			if (fd == -1) {
 				sieve_sys_error("failed to open logfile %s (logging to STDERR): %m", 
 					ehandler->logfile);
diff --git a/src/lib-sieve/sieve-generator.c b/src/lib-sieve/sieve-generator.c
index fb5cf2c93bd29ff0e8c3cbd272de382340936113..1db9d9b1dc6c3e7c478e980ba3e361fa3185b3b3 100644
--- a/src/lib-sieve/sieve-generator.c
+++ b/src/lib-sieve/sieve-generator.c
@@ -141,35 +141,41 @@ struct sieve_binary *sieve_generator_get_binary
  */
 
 void sieve_generator_warning
-(struct sieve_generator *gentr, struct sieve_ast_node *node, 
+(struct sieve_generator *gentr, unsigned int source_line, 
 	const char *fmt, ...) 
 { 
 	va_list args;
 	
 	va_start(args, fmt);
-	sieve_ast_error(gentr->ehandler, sieve_vwarning, node, fmt, args);
+	sieve_vwarning(gentr->ehandler,
+        sieve_error_script_location(gentr->genenv.script, source_line),
+        fmt, args);
 	va_end(args);
 }
  
 void sieve_generator_error
-(struct sieve_generator *gentr, struct sieve_ast_node *node, 
+(struct sieve_generator *gentr, unsigned int source_line, 
 	const char *fmt, ...) 
 {
 	va_list args;
 	
 	va_start(args, fmt);
-	sieve_ast_error(gentr->ehandler, sieve_verror, node, fmt, args);
+	sieve_verror(gentr->ehandler,
+        sieve_error_script_location(gentr->genenv.script, source_line),
+        fmt, args);
 	va_end(args);
 }
 
 void sieve_generator_critical
-(struct sieve_generator *gentr, struct sieve_ast_node *node, 
+(struct sieve_generator *gentr, unsigned int source_line, 
 	const char *fmt, ...) 
 {
 	va_list args;
 	
 	va_start(args, fmt);
-	sieve_ast_error(gentr->ehandler, sieve_vcritical, node, fmt, args);
+	sieve_vwarning(gentr->ehandler,
+        sieve_error_script_location(gentr->genenv.script, source_line),
+        fmt, args);
 	va_end(args);
 }
 
@@ -376,7 +382,7 @@ bool sieve_generator_run
 		
 	/* Load extensions linked to the AST and emit a list in code */
 	extensions = sieve_ast_extensions_get(gentr->genenv.ast, &ext_count);
-	(void) sieve_binary_emit_integer(*sbin, ext_count);
+	(void) sieve_binary_emit_unsigned(*sbin, ext_count);
 	for ( i = 0; i < ext_count; i++ ) {
 		const struct sieve_extension *ext = extensions[i];
 
diff --git a/src/lib-sieve/sieve-generator.h b/src/lib-sieve/sieve-generator.h
index 5ab6f651a1191e6f9da69685b6616dc9f2a1ce11..bc7921b46b62e19d6fe751ca2ce3f6428fc3f665 100644
--- a/src/lib-sieve/sieve-generator.h
+++ b/src/lib-sieve/sieve-generator.h
@@ -41,13 +41,13 @@ struct sieve_binary *sieve_generator_get_binary
  */
 
 void sieve_generator_warning
-(struct sieve_generator *gentr, struct sieve_ast_node *node, 
+(struct sieve_generator *gentr, unsigned int source_line, 
 	const char *fmt, ...) ATTR_FORMAT(3, 4);; 
 void sieve_generator_error
-(struct sieve_generator *gentr, struct sieve_ast_node *node, 
+(struct sieve_generator *gentr, unsigned int source_line, 
 	const char *fmt, ...) ATTR_FORMAT(3, 4);
 void sieve_generator_critical
-(struct sieve_generator *gentr, struct sieve_ast_node *node, 
+(struct sieve_generator *gentr, unsigned int source_line, 
 	const char *fmt, ...) ATTR_FORMAT(3, 4); 
 
 /* 
diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c
index 40f9582754be4acd58db95ac5fdd961a283949bf..d02a8195cfaba6249606e614920b108a8a007250 100644
--- a/src/lib-sieve/sieve-interpreter.c
+++ b/src/lib-sieve/sieve-interpreter.c
@@ -100,15 +100,15 @@ struct sieve_interpreter *sieve_interpreter_create
 	}
 
 	/* Load other extensions listed in code */
-	if ( sieve_binary_read_integer(sbin, &interp->pc, &ext_count) ) {
+	if ( sieve_binary_read_unsigned(sbin, &interp->pc, &ext_count) ) {
 		for ( i = 0; i < ext_count; i++ ) {
 			unsigned int code = 0;
 			const struct sieve_extension *ext;
 			
 			if ( !sieve_binary_read_extension(sbin, &interp->pc, &code, &ext) ) {
-        success = FALSE;
-        break;
-      }
+				success = FALSE;
+				break;
+			}
  
 			if ( ext->interpreter_load != NULL && 
 				!ext->interpreter_load(&interp->runenv, &interp->pc) ) {
@@ -182,8 +182,8 @@ const char *sieve_runtime_location(const struct sieve_runtime_env *runenv)
 {
 	const char *op = runenv->interp->current_op == NULL ?
 		"<<NOOP>>" : runenv->interp->current_op->mnemonic;
-	return t_strdup_printf("%s: #%08x: %s", sieve_script_name(runenv->script),
-		runenv->interp->current_op_addr, op);
+	return t_strdup_printf("%s: #%08llx: %s", sieve_script_name(runenv->script),
+		(unsigned long long) runenv->interp->current_op_addr, op);
 }
 
 void sieve_runtime_error
@@ -237,7 +237,7 @@ void _sieve_runtime_trace
 	va_list args;
 	
 	va_start(args, fmt);	
-	str_printfa(outbuf, "%08x: ", runenv->interp->current_op_addr); 
+	str_printfa(outbuf, "%08llx: ", (unsigned long long) runenv->interp->current_op_addr); 
 	str_vprintfa(outbuf, fmt, args); 
 	str_append_c(outbuf, '\n');
 	va_end(args);
@@ -252,8 +252,9 @@ void _sieve_runtime_trace_error
 	va_list args;
 
 	va_start(args, fmt);
-	str_printfa(outbuf, "%08x: [[ERROR: %s: ", runenv->interp->pc
-		, runenv->interp->current_op->mnemonic);
+	str_printfa(outbuf, "%08llx: [[ERROR: %s: ", 
+		(unsigned long long) runenv->interp->pc, 
+		runenv->interp->current_op->mnemonic);
 	str_vprintfa(outbuf, fmt, args);
     str_append(outbuf, "]]\n");
 	va_end(args);
diff --git a/src/lib-sieve/sieve-match-types.c b/src/lib-sieve/sieve-match-types.c
index 23d8c65b3089ad596d5f39352689e6e4034845a0..f30c95c2e0c1386e5d8660c291a7fbc4d7f320da 100644
--- a/src/lib-sieve/sieve-match-types.c
+++ b/src/lib-sieve/sieve-match-types.c
@@ -366,6 +366,7 @@ static bool tag_match_type_is_instance_of
 	/* Create context */
 	mtctx = p_new(sieve_command_pool(cmd), struct sieve_match_type_context, 1);
 	mtctx->match_type = mtch;
+	mtctx->match_type_arg = arg;
 	mtctx->command_ctx = cmd;
 	mtctx->comparator = NULL; /* Can be filled in later */
 	
@@ -498,7 +499,7 @@ const struct sieve_operand match_type_operand = {
  */
 
 bool sieve_match_substring_validate_context
-(struct sieve_validator *validator, struct sieve_ast_argument *arg ATTR_UNUSED,
+(struct sieve_validator *validator, struct sieve_ast_argument *arg,
 	struct sieve_match_type_context *ctx,
 	struct sieve_ast_argument *key_arg ATTR_UNUSED)
 {
@@ -508,7 +509,7 @@ bool sieve_match_substring_validate_context
 		return TRUE;
 			
 	if ( (cmp->flags & SIEVE_COMPARATOR_FLAG_SUBSTRING_MATCH) == 0 ) {
-		sieve_command_validate_error(validator, ctx->command_ctx,
+		sieve_argument_validate_error(validator, arg,
 			"the specified %s comparator does not support "
 			"sub-string matching as required by the :%s match type",
 			cmp->object.identifier, ctx->match_type->object.identifier );
diff --git a/src/lib-sieve/sieve-match-types.h b/src/lib-sieve/sieve-match-types.h
index 775d67a6bce48de43a3e5602a26b4888342f42e5..a501952fe80d4218beb200f5ffb9549087d89553 100644
--- a/src/lib-sieve/sieve-match-types.h
+++ b/src/lib-sieve/sieve-match-types.h
@@ -75,6 +75,8 @@ struct sieve_match_type {
 
 struct sieve_match_type_context {
 	struct sieve_command_context *command_ctx;
+	struct sieve_ast_argument *match_type_arg;
+
 	const struct sieve_match_type *match_type;
 	
 	/* Only filled in when match_type->validate_context() is called */
diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c
index c134acf7afcd268ddf5b821cbcd6bae8aa483a6f..c8093812a206eee9a58c620c2c13390753ab14a5 100644
--- a/src/lib-sieve/sieve-validator.c
+++ b/src/lib-sieve/sieve-validator.c
@@ -98,35 +98,42 @@ struct sieve_validator {
  */
 
 void sieve_validator_warning
-(struct sieve_validator *validator, struct sieve_ast_node *node, 
+(struct sieve_validator *validator, unsigned int source_line, 
 	const char *fmt, ...) 
 { 
 	va_list args;
 	
 	va_start(args, fmt);
-	sieve_ast_error(validator->ehandler, sieve_vwarning, node, fmt, args);
+	sieve_vwarning(validator->ehandler, 
+		sieve_error_script_location(validator->script, source_line),
+		fmt, args);
 	va_end(args);
+	
 }
  
 void sieve_validator_error
-(struct sieve_validator *validator, struct sieve_ast_node *node, 
+(struct sieve_validator *validator, unsigned int source_line, 
 	const char *fmt, ...) 
 {
 	va_list args;
 	
 	va_start(args, fmt);
-	sieve_ast_error(validator->ehandler, sieve_verror, node, fmt, args);
+	sieve_verror(validator->ehandler, 
+		sieve_error_script_location(validator->script, source_line),
+		fmt, args);
 	va_end(args);
 }
 
 void sieve_validator_critical
-(struct sieve_validator *validator, struct sieve_ast_node *node, 
+(struct sieve_validator *validator, unsigned int source_line, 
 	const char *fmt, ...) 
 {
 	va_list args;
 	
 	va_start(args, fmt);
-	sieve_ast_error(validator->ehandler, sieve_vcritical, node, fmt, args);
+	sieve_vcritical(validator->ehandler, 
+		sieve_error_script_location(validator->script, source_line),
+		fmt, args);
 	va_end(args);
 }
 
@@ -668,7 +675,7 @@ bool sieve_validate_positional_argument
 		(sieve_ast_argument_type(arg) != SAAT_STRING || 
 			req_type != SAAT_STRING_LIST) ) 
 	{
-		sieve_command_validate_error(validator, cmd, 
+		sieve_argument_validate_error(validator, arg, 
 			"the %s %s expects %s as argument %d (%s), but %s was found", 
 			cmd->command->identifier, sieve_command_type_name(cmd->command), 
 			sieve_ast_argument_type_name(req_type),
@@ -688,7 +695,7 @@ bool sieve_validate_tag_parameter
 		(sieve_ast_argument_type(param) != SAAT_STRING || 
 			req_type != SAAT_STRING_LIST) ) 
 	{
-		sieve_command_validate_error(validator, cmd, 
+		sieve_argument_validate_error(validator, param, 
 			"the :%s tag for the %s %s requires %s as parameter, "
 			"but %s was found", sieve_ast_argument_tag(tag), 
 			cmd->command->identifier, sieve_command_type_name(cmd->command),
@@ -724,7 +731,7 @@ static bool sieve_validate_command_arguments
 			sieve_validator_find_tag(validator, cmd, arg, &id_code);
 		
 		if ( tag == NULL ) {
-			sieve_command_validate_error(validator, cmd, 
+			sieve_argument_validate_error(validator, arg, 
 				"unknown tagged argument ':%s' for the %s %s "
 				"(reported only once at first occurence)",
 				sieve_ast_argument_tag(arg), cmd->command->identifier, 
@@ -756,7 +763,7 @@ static bool sieve_validate_command_arguments
 					t_strdup_printf("%s argument (:%s)", tag->identifier, tag_id) : 
 					t_strdup_printf(":%s argument", tag->identifier); 	 
 				
-				sieve_command_validate_error(validator, cmd, 
+				sieve_argument_validate_error(validator, arg, 
 					"encountered duplicate %s for the %s %s",
 					tag_desc, cmd->command->identifier, 
 					sieve_command_type_name(cmd->command));
@@ -784,7 +791,7 @@ static bool sieve_validate_command_arguments
 	
 	while ( arg != NULL ) {
 		if ( sieve_ast_argument_type(arg) == SAAT_TAG ) {
-			sieve_command_validate_error(validator, cmd, 
+			sieve_argument_validate_error(validator, arg, 
 				"encountered an unexpected tagged argument ':%s' "
 				"while validating positional arguments for the %s %s",
 				sieve_ast_argument_tag(arg), cmd->command->identifier, 
@@ -858,7 +865,8 @@ static bool sieve_validate_command_subtests
 	case 0:
 	 	if ( sieve_ast_test_count(cmd->ast_node) > 0 ) {
 			sieve_command_validate_error(validator, cmd, 
-				"the %s %s accepts no sub-tests, but tests are specified anyway", 
+				"the %s %s accepts no sub-tests, but tests are specified anyway "
+				"(forgot semicolon?)", 
 				cmd->command->identifier, sieve_command_type_name(cmd->command));
 			
 			return FALSE;
@@ -968,7 +976,7 @@ static bool sieve_validate_command
 				(command->type == SCT_TEST && ast_type == SAT_COMMAND) ) 
 			{
 				sieve_validator_error(
-					valdtr, cmd_node, "attempted to use %s '%s' as %s", 
+					valdtr, cmd_node->source_line, "attempted to use %s '%s' as %s", 
 					sieve_command_type_name(command), cmd_node->identifier,
 					sieve_ast_type_name(ast_type));
 			
@@ -1011,7 +1019,7 @@ static bool sieve_validate_command
 				
 	} else {
 		sieve_validator_error(
-			valdtr, cmd_node, 
+			valdtr, cmd_node->source_line, 
 			"unknown %s '%s' (only reported once at first occurence)", 
 			sieve_ast_type_name(ast_type), cmd_node->identifier);
 			
diff --git a/src/lib-sieve/sieve-validator.h b/src/lib-sieve/sieve-validator.h
index 041336c7fd9caa0b74e7322822cf2195d31b4af6..a48dbd8c72b9d60aff27416f7b568eca04e108e7 100644
--- a/src/lib-sieve/sieve-validator.h
+++ b/src/lib-sieve/sieve-validator.h
@@ -52,13 +52,13 @@ struct sieve_script *sieve_validator_script
  */
 
 void sieve_validator_warning
-	(struct sieve_validator *validator, struct sieve_ast_node *node, 
+	(struct sieve_validator *validator, unsigned int source_line, 
 		const char *fmt, ...) ATTR_FORMAT(3, 4);
 void sieve_validator_error
-	(struct sieve_validator *validator, struct sieve_ast_node *node, 
+	(struct sieve_validator *validator, unsigned int source_line, 
 		const char *fmt, ...) ATTR_FORMAT(3, 4);
 void sieve_validator_critical
-	(struct sieve_validator *validator, struct sieve_ast_node *node, 
+	(struct sieve_validator *validator, unsigned int source_line, 
 		const char *fmt, ...) ATTR_FORMAT(3, 4);
 		
 /* 
diff --git a/src/lib-sieve/tst-address.c b/src/lib-sieve/tst-address.c
index 9a44da4300cf60e0e818b45ecbd78108ef5000d0..e6d01d0bbfb5426eae22e40102b70d5c2f3d142a 100644
--- a/src/lib-sieve/tst-address.c
+++ b/src/lib-sieve/tst-address.c
@@ -147,7 +147,7 @@ static bool tst_address_validate
 	 */
 	header = arg;
 	if ( !sieve_ast_stringlist_map(&header, NULL, _header_is_allowed) ) {		
-		sieve_command_validate_error(validator, tst, 
+		sieve_argument_validate_error(validator, header, 
 			"specified header '%s' is not allowed for the address test", 
 			str_sanitize(sieve_ast_strlist_strc(header), 64));
 		return FALSE;
diff --git a/src/lib-sieve/tst-size.c b/src/lib-sieve/tst-size.c
index 8ff7e355d9083ec039c53ee7a45e62b005784ab1..c4249429db11ab0b2380483012df5f11ae16bbb0 100644
--- a/src/lib-sieve/tst-size.c
+++ b/src/lib-sieve/tst-size.c
@@ -87,7 +87,7 @@ static bool tst_size_validate_over_tag
 	struct tst_size_context_data *ctx_data = (struct tst_size_context_data *) tst->data;	
 	
 	if ( ctx_data->type != SIZE_UNASSIGNED ) {
-		sieve_command_validate_error(validator, tst, TST_SIZE_ERROR_DUP_TAG);
+		sieve_argument_validate_error(validator, *arg, TST_SIZE_ERROR_DUP_TAG);
 		return FALSE;		
 	}
 	
@@ -106,7 +106,7 @@ static bool tst_size_validate_under_tag
 	struct tst_size_context_data *ctx_data = (struct tst_size_context_data *) tst->data;	
 	
 	if ( ctx_data->type != SIZE_UNASSIGNED ) {
-		sieve_command_validate_error(validator, tst, TST_SIZE_ERROR_DUP_TAG);
+		sieve_argument_validate_error(validator, *arg, TST_SIZE_ERROR_DUP_TAG);
 		return FALSE;		
 	}
 	
@@ -224,7 +224,7 @@ static bool tst_size_operation_dump
  */
 
 static inline bool tst_size_get
-(const struct sieve_runtime_env *renv, sieve_size_t *size) 
+(const struct sieve_runtime_env *renv, sieve_number_t *size) 
 {
 	uoff_t psize;
 
@@ -240,7 +240,7 @@ static int tst_size_operation_execute
 (const struct sieve_operation *op,
 	const struct sieve_runtime_env *renv, sieve_size_t *address)
 {
-	sieve_size_t mail_size, limit;
+	sieve_number_t mail_size, limit;
 		
 	/* Read size limit */
 	if ( !sieve_opr_number_read(renv, address, &limit) ) {
diff --git a/src/testsuite/testsuite-objects.c b/src/testsuite/testsuite-objects.c
index 3b4bd6cda5a4ba78c988f202350b4cfcfb6f39a0..3371c8815a2aeeaf6e41902bc1a7e5f3463f7a6f 100644
--- a/src/testsuite/testsuite-objects.c
+++ b/src/testsuite/testsuite-objects.c
@@ -207,7 +207,7 @@ bool testsuite_object_argument_activate
 	
 	object = testsuite_object_find(valdtr, objname);
 	if ( object == NULL ) {
-		sieve_command_validate_error(valdtr, cmd, 
+		sieve_argument_validate_error(valdtr, arg, 
 			"unknown testsuite object '%s'", objname);
 		return FALSE;
 	}
@@ -218,7 +218,7 @@ bool testsuite_object_argument_activate
 	if ( member != NULL ) {
 		if ( object->get_member_id == NULL || 
 			(member_id=object->get_member_id(member)) == -1 ) {
-			sieve_command_validate_error(valdtr, cmd, 
+			sieve_argument_validate_error(valdtr, arg, 
 				"member '%s' does not exist for testsuite object '%s'", member, objname);
 			return FALSE;
 		}
diff --git a/src/testsuite/tst-test-error.c b/src/testsuite/tst-test-error.c
index 607ceb7dbaf1c18ef1f9e4dc4ea7c854f6f87988..e7d23afe1ca380ac4f4746b8bb0e1c8ef782879e 100644
--- a/src/testsuite/tst-test-error.c
+++ b/src/testsuite/tst-test-error.c
@@ -229,7 +229,7 @@ static int tst_test_error_operation_execute
 
 	/* Handle optional operands */
 	do {
-		sieve_size_t number; 
+		sieve_number_t number; 
 
 		if ( (ret=sieve_match_read_optional_operands
 			(renv, address, &opt_code, &cmp, &mtch)) <= 0 )
diff --git a/tests/address.svtest b/tests/address.svtest
index ef6773b6340950cb7cdbd3e418dccbb1bd8a513e..8842c058c99141051f02faae1d8f4d57f531b253 100644
--- a/tests/address.svtest
+++ b/tests/address.svtest
@@ -58,3 +58,29 @@ test "Invalid address list" {
 	}	
 }
 
+/*
+ * Strange
+ */
+
+test_set "message" text:
+From: SPAM@MYDOMAIN
+To: stephan@renane-it.nl
+Subject: Spam
+
+Spam!
+.
+;
+
+test "Questionable address" {
+	if address :domain :is "from" "MYDOMAIN" {
+		if address :localpart :is "from" "SPAM" {
+			
+		} elsif header :contains "subject" "Cron" {
+			test_fail "message erroneously recognized as cron";
+		} else {
+			test_fail "message erroneously recognized as normal";
+		}
+	} else {
+		test_fail "message domain not recognized";
+	}
+}