diff --git a/Makefile.am b/Makefile.am
index 6d9aeb309679fcd27de717fa3a56b6b6469ca90b..8b9c364ace05af5c6328ad84e0287db43a4c2d9a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -21,6 +21,8 @@ test_cases = \
 	tests/testsuite.svtest\
 	tests/control-structures.svtest \
 	tests/exists.svtest \
+	tests/header.svtest \
+	tests/address.svtest \
 	tests/lexer.svtest \
 	tests/comparators/core.svtest \
 	tests/match-types/is.svtest \
diff --git a/TODO b/TODO
index 1756bdf69c1af220668408e08f475aa12b61ae75..24573eb4e1f752e3deb414c6dffb8c701fa365a7 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,4 @@
 Next (in order of descending priority/precedence):
-* Fix standards compliance issues:
-	- 'If an address is not syntactically valid, then it will not be matched
-	  by tests specifying ":localpart" or ":domain"'.
 * Fix security issues:
 	- Impose limitations on the imapflags extension regarding the number of
 	  set flags and the length of each flag name.
@@ -33,6 +30,7 @@ Next (in order of descending priority/precedence):
 	- Body: contains various issues that need to be resolved for standards
 	  compliance. Body test support currently matches but barely exceeds the
 	  original CMU Sieve implentation in terms of standards compliance.
+	- Improve handling of invalid addresses in headers (requires Dovecot changes)
 * Imapflags: merge execution of setflags, removeflags and addflags into one 
   common implementation. 
 * Warn about the use of syntactically invalid header names. 
diff --git a/src/lib-sieve/mcht-is.c b/src/lib-sieve/mcht-is.c
index dcfa35f902a26404d6f29f9a7aca2f8b19e54dc3..ecba1e8fa12cd5d23d5fe22fe82588c34af8561c 100644
--- a/src/lib-sieve/mcht-is.c
+++ b/src/lib-sieve/mcht-is.c
@@ -44,6 +44,8 @@ static int mcht_is_match
 {
 	if ( (val == NULL || val_size == 0) ) 
 		return ( key_size == 0 );
+
+	printf ("VAL '%s' KEY '%s'\n", val, key);
 	
 	if ( mctx->comparator->compare != NULL )
 		return (mctx->comparator->compare(mctx->comparator, 
diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c
index b30e60cd0c397f041ba8db4f4e1b1fb12ea14ce9..d4206dd92982eb75347c8b2034e1729c0298d29e 100644
--- a/src/lib-sieve/sieve-address-parts.c
+++ b/src/lib-sieve/sieve-address-parts.c
@@ -219,24 +219,46 @@ int sieve_address_match
 	const struct message_address *addr;
 
 	T_BEGIN {
+		bool valid = TRUE;
+		const struct message_address *aitem;
+
 		addr = message_address_parse
 			(pool_datastack_create(), (const unsigned char *) data, 
 				strlen(data), 256, FALSE);
-	
-		while ( result == 0 && addr != NULL) {
-			/* mailbox@domain */
-			struct sieve_address address;
-			const char *part;
+
+		/* Check validity of all addresses simultaneously. Unfortunately,
+		 * errorneous addresses cannot be extracted from the address list
+		 * and therefore :all will match against the whole header value
+		 * which is not entirely standard.
+		 */
+		aitem = addr;
+		while ( aitem != NULL) {
+			if ( aitem->invalid_syntax )
+				valid = FALSE;
+			aitem = aitem->next;
+		}
+
+		if ( !valid || addr == NULL ) {
+			if ( addrp == &all_address_part )
+				result = sieve_match_value(mctx, data, strlen(data));
+			else 
+				result = FALSE;
+		} else {
+			while ( result == 0 && addr != NULL) {
+				/* mailbox@domain */
+				struct sieve_address address;
+				const char *part;
 			
-			address.local_part = addr->mailbox;
-			address.domain = addr->domain;
+				address.local_part = addr->mailbox;
+				address.domain = addr->domain;
 
-			part = addrp->extract_from(&address);
+				part = addrp->extract_from(&address);
 			
-			if ( part != NULL )
-				result=sieve_match_value(mctx, part, strlen(part));
+				if ( part != NULL )
+					result = sieve_match_value(mctx, part, strlen(part));
 
-			addr = addr->next;
+				addr = addr->next;
+			}
 		}
 	} T_END;
 	
diff --git a/tests/address.svtest b/tests/address.svtest
new file mode 100644
index 0000000000000000000000000000000000000000..ef6773b6340950cb7cdbd3e418dccbb1bd8a513e
--- /dev/null
+++ b/tests/address.svtest
@@ -0,0 +1,60 @@
+require "vnd.dovecot.testsuite";
+
+/*
+ * If an address is not syntactically valid, then it will not be matched
+ * by tests specifying ":localpart" or ":domain".
+ */
+
+test_set "message" text:
+From: stephan@
+To: @rename-it.nl
+Cc: nonsense
+Resent-To:
+Subject: Invalid addresses
+
+Test.
+.
+;
+
+test "Invalid single addresses" {
+	if address :localpart "from" "stephan" {
+		test_fail ":localpart matched invalid address";
+	}	
+
+	if address :domain "to" "rename-it.nl" {
+		test_fail ":domain matched invalid address";
+	}	
+
+	if not address :is :all "resent-to" "" {
+		test_fail ":all failed to match empty address";
+	}	
+
+	if not address :is :all "cc" "nonsense" {
+		test_fail ":all failed to match invalid address";
+	}
+}
+
+/*
+ * Errors in address lists
+ */ 
+
+test_set "message" text:
+From: stephan@
+To: nico@vestingbar.nl, @rename-it.nl
+Cc: stephan@rename-it.nl, nonsense
+Subject: Invalid addresses
+
+Test.
+.
+;
+
+test "Invalid address list" {
+	if address :is :localpart "to" "" {
+		test_fail ":localpart matched invalid address";
+	}	
+
+	if address :is :domain "to" "rename-it.nl" {
+		test_fail ":domain matched invalid address";
+	}	
+}
+