diff --git a/TODO b/TODO
index e4bc25e80c82441197e19856413cd5873cb4afc0..b0ccb34adbd3d7087c58ef4152028de08cd0d897 100644
--- a/TODO
+++ b/TODO
@@ -46,7 +46,9 @@ Next (in order of descending priority/precedence):
 	- add support for testing the content of result actions
 	- test as many error/warning/info conditions as possible. 
 	- review the specification documents and check whether the given conditions
-	  are tested at least once. 
+	  are tested at least once.
+* Code cleanup:
+	- Make address handling more uniform. 
 
 * Build a sieve tool to filter an entire existing mailbox through a sieve 
   script.
diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c
index 1692ae3c5a7e42653709e11d7d0973318e6f752f..1efff576c36179fac65a05100606b495604e6a46 100644
--- a/src/lib-sieve/cmd-redirect.c
+++ b/src/lib-sieve/cmd-redirect.c
@@ -251,8 +251,9 @@ static bool act_redirect_equals
 	struct act_redirect_context *rd_ctx2 = 
 		(struct act_redirect_context *) ctx2;
 
-	/* Address is already normalized, strcmp suffices to assess duplicates */
-	return ( strcmp(rd_ctx1->to_address, rd_ctx2->to_address) == 0 );
+	/* Address is already normalized */
+	return ( sieve_address_compare
+		(rd_ctx1->to_address, rd_ctx2->to_address, TRUE) == 0 );
 }
  
 static int act_redirect_check_duplicate
diff --git a/src/lib-sieve/plugins/enotify/ntfy-mailto.c b/src/lib-sieve/plugins/enotify/ntfy-mailto.c
index 87262bf62cb17eb1d75be969ae94ff8a6dc0a083..aeb5560953eda52223d3c18d67dd7440e0172ad2 100644
--- a/src/lib-sieve/plugins/enotify/ntfy-mailto.c
+++ b/src/lib-sieve/plugins/enotify/ntfy-mailto.c
@@ -284,7 +284,8 @@ static bool _uri_add_valid_recipient
 		
 		/* Check for duplicate first */
 		for ( i = 0; i < count; i++ ) {
-			if ( strcmp(rcpts[i].normalized, normalized) == 0 ) {
+			if ( sieve_address_compare(rcpts[i].normalized, normalized, TRUE) == 0 ) 
+				{
 				/* Upgrade existing Cc: recipient to a To: recipient if possible */
 				rcpts[i].carbon_copy = ( rcpts[i].carbon_copy && cc );
 				
@@ -772,8 +773,9 @@ static int ntfy_mailto_action_check_duplicates
 
 	for ( i = 0; i < new_count; i++ ) {
 		for ( j = 0; j < old_count; j++ ) {
-			if ( strcmp(new_rcpts[i].normalized, old_rcpts[j].normalized) == 0 )
-				 break;				
+			if ( sieve_address_compare
+				(new_rcpts[i].normalized, old_rcpts[j].normalized, TRUE) == 0 )
+				break;				
 		}
 
 		if ( j == old_count ) {
diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c
index f62c189e787595c7d61f68049d1af2673c071754..5ecaac59f7e7a09129ed1abdd9419f577c75af99 100644
--- a/src/lib-sieve/plugins/vacation/cmd-vacation.c
+++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c
@@ -834,10 +834,12 @@ static inline bool _contains_my_address
 
 			while ( addr != NULL && !result ) {
 				if (addr->domain != NULL) {
+					const char *hdr_address; 
+					
 					i_assert(addr->mailbox != NULL);
 
-					if ( strcasecmp(t_strconcat(addr->mailbox, "@", addr->domain, NULL),
-						my_address) == 0 ) {
+					hdr_address = t_strconcat(addr->mailbox, "@", addr->domain, NULL);
+					if ( sieve_address_compare(hdr_address, my_address, TRUE) == 0 ) {
 						result = TRUE;
 						break;
 					}
@@ -975,7 +977,8 @@ static bool act_vacation_commit
 	/* Are we perhaps trying to respond to ourselves ? 
 	 * (FIXME: verify this to :addresses as well?)
 	 */
-	if ( strcasecmp(msgdata->return_path, msgdata->to_address) == 0 ) {
+	if ( sieve_address_compare(msgdata->return_path, msgdata->to_address, TRUE) 
+		== 0 ) {
 		sieve_result_log(aenv, "discarded vacation reply to own address");	
 		return TRUE;
 	}
diff --git a/src/lib-sieve/sieve-address.c b/src/lib-sieve/sieve-address.c
index e46fe5b7710d0cd62d5769e071f3e68eaaa1220f..1666180c9271f868c1dcd9914e4f169976337ba0 100644
--- a/src/lib-sieve/sieve-address.c
+++ b/src/lib-sieve/sieve-address.c
@@ -350,6 +350,21 @@ bool sieve_address_validate
 	return TRUE;
 }
 
+int sieve_address_compare
+(const char *address1, const char *address2, bool normalized ATTR_UNUSED)
+{
+	/* NOTE: this deviates from RFC specification in that it compares the local 
+	 * part of the address case-insensitively. This however conforms to the 
+	 * consensus in mail software.
+	 */
+	 
+	/* FIXME: provided addresses are currently assumed to be normalized to 
+	 * local_part@domain
+	 */
+	 
+	return strcasecmp(address1, address2);
+}
+
 /*
  * RFC 2821 addresses (envelope paths)
  */
diff --git a/src/lib-sieve/sieve-address.h b/src/lib-sieve/sieve-address.h
index 200bcb811a085d8608a0ef5fe012c96594f4b841..8593ce8becf577fb4c987d3b46423cbf41ed60ab 100644
--- a/src/lib-sieve/sieve-address.h
+++ b/src/lib-sieve/sieve-address.h
@@ -27,6 +27,9 @@ const char *sieve_address_normalize
 	(string_t *address, const char **error_r);
 bool sieve_address_validate
 	(string_t *address, const char **error_r);
+	
+int sieve_address_compare
+	(const char *address1, const char *address2, bool normalized);
 
 /*
  * RFC 2821 addresses (paths)