diff --git a/modules/core/docs/authproc_attributealter.txt b/modules/core/docs/authproc_attributealter.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1efae88bb13e5c27809b31a7480bf26d6dfb1fbe
--- /dev/null
+++ b/modules/core/docs/authproc_attributealter.txt
@@ -0,0 +1,85 @@
+`core:AttributeAlter`
+==========
+
+This filter can be used to substitute and replace different parts of the attribute value based on regular expressions.
+
+Parameters
+----------
+
+`class`
+:   This is the name of the filter.
+    It must be `'core:AttributeAlter'`.
+
+`subject`
+:   The attribute in which the search is preformed.
+    This parameter is REQUIRED and the filter will throw an exception if this parameter is not set.
+    
+`pattern`
+:   The regular expression used.
+    This parameter is REQUIRED and the filter will throw an exception if this parameter is not set.
+    It is not possible to use backreference.
+    
+`replacement`
+:   The value used to replace the searched value.
+    This parameter is REQUIRED if `%replace` is not used.
+    If `%replace` is used and `replacement` is not set, then the matched text is used instead.
+    
+`target`
+:   The target attribute where the replaced attribute value is put.
+    This parameter is OPTIONAL.
+    If this parameter is not set `subject` is used as `target`.
+
+`%replace`
+:   Indicate whether the searched part should be replaced or the whole value.
+    this parameter is OPTIONAL.
+    
+Examples
+--------
+
+Change the domain on the `mail` attribute (when both the new and old domain is known):
+
+    10 => array(
+        'class' => 'core:AttributeAlter',
+        'subject' => 'mail',
+        'pattern' => '/olddomain.com/',
+        'replacement' => 'newdomain.com',
+    ),
+
+Change the domain on the `mail` attribute (when new domain is known):
+
+	10 => array(
+		'class' => 'core:AttributeAlter',
+		'subject' => 'mail',
+		'pattern' => '/(?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,6}$/',
+		'replacement' => 'newdomain.com',
+	),
+    
+Set the eduPersonPrimaryAffiliation based on users distinguishedName:
+
+    10 => array(
+        'class' => 'core:AttributeAlter',
+        'subject' => 'dn',
+        'pattern' => '/OU=Staff/',
+        'replacement' => 'staff',
+        'target' => 'eduPersonPrimaryAffiliation',
+    ),
+    
+Change the eduPersonPrimaryAffiliation:
+
+    10 => array(
+        'class' => 'core:AttributeAlter',
+        'subject' => 'eduPersonPrimaryAffiliation',
+        'pattern' => '/Student in school/',
+        'replacement' => 'student',
+        '%replace',
+    ),
+    
+Get the domain of the email and put it in a seperat attribute:
+
+    10 => array(
+        'class' => 'core:AttributeAlter',
+        'subject' => 'mail',
+        'pattern' => '/(?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,6}$/',
+        'target' => 'domain',
+        '%replace',
+    ),
\ No newline at end of file
diff --git a/modules/core/lib/Auth/Process/AttributeAlter.php b/modules/core/lib/Auth/Process/AttributeAlter.php
index 601d6c58a7f066b8099724a9d46f34bfa6a4e03b..2cbd528b64390d9c18cc91f2748da77f7463871f 100644
--- a/modules/core/lib/Auth/Process/AttributeAlter.php
+++ b/modules/core/lib/Auth/Process/AttributeAlter.php
@@ -1,9 +1,8 @@
 <?php
-
 /**
- * Filter to modify attributes.
+ * Filter to modify attributes using regular expressions
  *
- * This filter can modify attributes given a regular expression.
+ * This filter can modify or replace attributes given a regular expression.
  *
  * @author Jacob Christiansen, WAYF
  * @package simpleSAMLphp
@@ -17,7 +16,7 @@ class sspmod_core_Auth_Process_AttributeAlter extends SimpleSAML_Auth_Processing
 	private $replace = FALSE;
 	
 	/**
-	 * Pattern to besearch for.
+	 * Pattern to be search for.
 	 */
 	private $pattern = '';
 	
@@ -27,10 +26,15 @@ class sspmod_core_Auth_Process_AttributeAlter extends SimpleSAML_Auth_Processing
 	private $replacement = '';
 	
 	/**
-	 * Attribute to search in.
+	 * Attribute to search in
 	 */
 	private $subject = '';
 
+	/**
+	 * Attribute to place result in.
+	 */
+	private $target = '';
+	
 	/**
 	 * Initialize this filter.
 	 *
@@ -38,11 +42,11 @@ class sspmod_core_Auth_Process_AttributeAlter extends SimpleSAML_Auth_Processing
 	 * @param mixed $reserved  For future use.
 	 */
 	public function __construct($config, $reserved) {
-		parent::__construct($config, $reserved);
-
 		assert('is_array($config)');
 
-		
+		parent::__construct($config, $reserved);
+
+		// Parse filter configuration		
 		foreach($config as $name => $value) {
 			// Is %replace set?
 			if(is_int($name)) {
@@ -53,26 +57,34 @@ class sspmod_core_Auth_Process_AttributeAlter extends SimpleSAML_Auth_Processing
 				}
 				continue;
 			}
+			
 			// Unknown flag
 			if(!is_string($name)) {
 				throw new Exception('Unknown flag : ' . var_export($name, TRUE));
 			}
+			
 			// Set pattern
 			if($name == 'pattern') {
 				$this->pattern = $value;
 			}
+			
 			// Set replacement
 			if($name == 'replacement') {
 				$this->replacement = $value;
 			}
+			
 			// Set subject
 			if($name == 'subject') {
 				$this->subject = $value;
 			}
+			
+			// Set target
+			if($name == 'target') {
+				$this->target = $value;
+			}
 		}
 	}
 
-
 	/**
 	 * Apply filter to modify attributes.
 	 *
@@ -84,31 +96,38 @@ class sspmod_core_Auth_Process_AttributeAlter extends SimpleSAML_Auth_Processing
 		assert('is_array($request)');
 		assert('array_key_exists("Attributes", $request)');
 
-		/**
-		 * Get attributes from request
-		 */
+		// Get attributes from request
 		$attributes =& $request['Attributes'];
 
+		// Check that all required params are set in config
 		if(empty($this->pattern) || empty($this->subject)) {
 			throw new Exception("Not all params set in config.");
 		}
 
-		/**
-		 * Check if attributes contains subject attribute
-		 */
-		if (array_key_exists($this->subject,$attributes)) {
-			// Replace is TRUE
+		if(!$this->replace && empty($this->replacement)) {
+			throw new Exception("'replacement' must be set if '%replace' is not set");
+		}
+
+		// Use subject as taget if target is not set
+		if(empty($this->target)) {
+			$this->target = $this->subject;		
+		}
+	
+		// Check if attributes contains subject and target attribute
+		if (array_key_exists($this->subject, $attributes) && array_key_exists($this->target, $attributes)) {
 			if($this->replace == TRUE) {
+				$matches = array();
 				// Try to match pattern
-				if(preg_match($this->pattern, $attributes[$this->subject][0])) {
-					$attributes[$this->subject] = array($this->replacement);
+				if(preg_match($this->pattern, $attributes[$this->subject][0], $matches) > 0) {
+					if(empty($this->replacement)) {
+						$attributes[$this->target][0] = $matches[0];	
+					} else {
+						$attributes[$this->target][0] = $this->replacement;
+					}
 				}
-			} else {
-				// Try to match pattern
-				$attributes[$this->subject] = preg_replace($this->pattern, $this->replacement, $attributes[$this->subject]);
+			} else {	
+				$attributes[$this->target] = preg_replace($this->pattern, $this->replacement, $attributes[$this->subject]);
 			}		
 		}
 	}
-}
-
-?>
+}
\ No newline at end of file