diff --git a/attributemap/name2claim.php b/attributemap/name2claim.php
new file mode 100644
index 0000000000000000000000000000000000000000..ba32920ad92a639b60445a1fbc6df21f2a964de3
--- /dev/null
+++ b/attributemap/name2claim.php
@@ -0,0 +1,14 @@
+<?php // Maps AD LDAP to Claims from http://msdn.microsoft.com/en-us/library/hh159803.aspx
+$attributemap = array(
+	'c' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/country',
+	'givenName' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname',
+	'mail' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress',
+	'memberOf' => 'http://schemas.microsoft.com/ws/2008/06/identity/claims/role',
+	'postalcode' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postalcode',
+	'uid' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name',
+	'sn' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname',
+	'st' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/stateorprovince',
+	'streetaddress' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/streetaddress',
+	'telephonenumber' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/otherphone',
+);
+?>
diff --git a/dictionaries/admin.definition.json b/dictionaries/admin.definition.json
index fc9739fc6e3643aa7a51f9dc47c714d690d8eac3..f9e3b2097e3062711939c1ef1a753ae36bac05d2 100644
--- a/dictionaries/admin.definition.json
+++ b/dictionaries/admin.definition.json
@@ -68,6 +68,12 @@
 	"metaover_group_metadata.shib13-idp-remote": {
 		"en": "Shib 1.3 Identity Provider (Remote)"
 	},
+    "metaover_group_metadata.adfs-sp-remote": {
+        "en": "ADFS Service Provider (Remote)"
+    },
+    "metaover_group_metadata.adfs-idp-hosted": {
+        "en": "ADFS Identity Provider (Hosted)"
+    },
 	"metaover_group_metadata.wsfed-sp-hosted": {
 		"en": "WS-Federation Service Provider (Hosted)"
 	},
@@ -95,6 +101,12 @@
 	"metadata_shib13-idp": {
 		"en": "Shib 1.3 IdP Metadata"
 	},
+    "metadata_adfs-sp": {
+        "en": "ADFS SP Metadata"
+    },
+    "metadata_adfs-idp": {
+        "en": "ADFS IdP Metadata"
+    },
 	"metadata_intro": {
 		"en": "Here is the metadata that simpleSAMLphp has generated for you. You may send this metadata document to trusted partners to setup a trusted federation."
 	},
diff --git a/dictionaries/admin.translation.json b/dictionaries/admin.translation.json
index 4808bb510583c92ed4b2d52fae08528d12d73182..d0a17135380ea54e49b551fc4cf4fd202338899f 100644
--- a/dictionaries/admin.translation.json
+++ b/dictionaries/admin.translation.json
@@ -834,6 +834,68 @@
 		"ro": "Furnizor de identitate Shib 1.3 (distant)",
 		"ru": "\u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 Shib 1.3 (\u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435)"
 	},
+    "metaover_group_metadata.adfs-sp-remote": {
+        "no": "ADFS Tjenesteleverand\u00f8r (ekstern)",
+        "nn": "ADFS Service Provider (Remote)",
+        "sv": "ADFS Service Provider (Fj\u00e4rr)",
+        "es": "Proveedor de Servicio ADFS (Remoto)",
+        "nl": "ADFS Service Provider (Remote)",
+        "sl": "ADFS SP (Oddaljeni)",
+        "da": "ADFS tjenesteudbyder (remote)",
+        "hr": "ADFS davatelj usluge (udaljeni)",
+        "hu": "ADFS alkalmaz\u00e1sszolg\u00e1ltat\u00f3 (t\u00e1voli)",
+        "pt-br": "ADFS Service Provider (Remoto)",
+        "pt": "Fornecedor de servi\u00e7o (SP) ADFS (Remoto)",
+        "pl": "ADFS Dostawca Serwisu (Zdalny)",
+        "cs": "SAML 2.O Service Provider (Remote - vzd\u00e1len\u00fd)",
+        "tr": "ADFS Servis Sa\u011flay\u0131c\u0131 (Uzak sistemde sunulan)",
+        "de": "ADFS Service Provider (entfernt)",
+        "fr": "Fournisseur de service ADFS distant",
+        "it": "ADFS Service Provider (Remoto)",
+        "ja": "ADFS\u30b5\u30fc\u30d3\u30b9\u30d7\u30ed\u30d0\u30a4\u30c0(\u30ea\u30e2\u30fc\u30c8)",
+        "lt": "ADFS Paslaugos teik\u0117jas (nutol\u0119s)",
+        "zh-tw": "ADFS \u670d\u52d9\u63d0\u4f9b\u8005(\u9060\u7aef)",
+        "et": "ADFS teenusepakkuja (kaug)",
+        "he": "\u05e1\u05e4\u05e7 \u05e9\u05d9\u05e8\u05d5\u05ea \u05de\u05e8\u05d5\u05d7\u05e7 \u05de\u05e1\u05d5\u05d2 ADFS",
+        "zh": "ADFS \u670d\u52a1\u63d0\u4f9b\u8005 (\u8fdc\u7a0b)",
+        "ar": "\u0645\u0642\u062f\u0645 \u062e\u062f\u0645\u0629 ADFS \u0627\u0644\u0628\u0639\u064a\u062f",
+        "lv": "ADFS servisa pieg\u0101d\u0101t\u0101js (att\u0101lin\u0101ts)",
+        "id": "Service Provider ADFS (Remote)",
+        "sr": "ADFS Davalac Servisa (udaljeni)",
+        "ro": "Furnizor de servicii ADFS (distant)",
+        "ru": "\u0421\u0435\u0440\u0432\u0438\u0441 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 ADFS (\u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435)"
+    },
+    "metaover_group_metadata.adfs-idp-hosted": {
+        "no": "ADFS Identitetsleverand\u00f8r (ekstern)",
+        "nn": "ADFS Identity Provider (Hosted)",
+        "sv": "ADFS Identity Provider (V\u00e4rd)",
+        "es": "Proveedor de Identidad ADFS (Anfitri\u00f3n)",
+        "nl": "ADFS Identity Provider (Hosted)",
+        "sl": "ADFS IdP (Lokalni)",
+        "da": "ADFS identitetsudbyder (hosted)",
+        "hr": "ADFS autentifikacijski servis (lokalni)",
+        "hu": "ADFS szem\u00e9lyazonoss\u00e1g-szolg\u00e1ltat\u00f3 (helyi)",
+        "pt-br": "ADFS Identity Provider (Local)",
+        "pt": "Fornecedor de identidade (IdP) ADFS (Local)",
+        "pl": "ADFS Dostawca To\u017csamo\u015bci (Lokalny)",
+        "cs": "ADFS Identity Provider (Hosted - lok\u00e1ln\u00ed)",
+        "tr": "ADFS Kimlik Sa\u011flay\u0131c\u0131 (Bu sistemde sunulan)",
+        "de": "ADFS Identity Provider (gehosted)",
+        "fr": "Fournisseur d'identit\u00e9 ADFS local",
+        "it": "SAML 2.o Identity Provider (Hosted)",
+        "ja": "ADFS\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30d7\u30ed\u30d0\u30a4\u30c0(\u30db\u30b9\u30c8)",
+        "lt": "ADFS Tapatybi\u0173 teik\u0117jas (vietinis)",
+        "zh-tw": "ADFS \u9a57\u8b49\u63d0\u4f9b\u8005(\u4e3b\u6a5f)",
+        "et": "ADFS identiteedipakkuja (hostitud)",
+        "he": "\u05e1\u05e4\u05e7 \u05d6\u05d4\u05d5\u05ea \u05de\u05e7\u05d5\u05de\u05d9 \u05de\u05e1\u05d5\u05d2 ADFS",
+        "zh": "ADFS \u8eab\u4efd\u63d0\u4f9b\u8005\uff08\u672c\u5730\uff09",
+        "ar": "\u0645\u0642\u062f\u0645 \u0647\u0648\u064a\u0629 ADFS \u0627\u0644\u0645\u0633\u062a\u0636\u0627\u0641",
+        "lv": "ADFS identit\u0101tes pieg\u0101d\u0101t\u0101js (host\u0113ts)",
+        "id": "Identity Provider ADFS (Hosted)",
+        "sr": "ADFS Davalac Identiteta (lokalni)",
+        "ro": "Furnizor de identitate ADFS (g\u0103zduit)",
+        "ru": "\u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 ADFS (\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435)"
+    },
 	"metaover_group_metadata.wsfed-sp-hosted": {
 		"no": "WS-Federation tjenesteleverand\u00f8r (intern)",
 		"nn": "WS-Federation Service Provider (Hosted)",
@@ -1144,7 +1206,69 @@
 		"ro": "Metadate furnizor de identitate (IdP) Shib 1.3",
 		"ru": "\u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 Shib 1.3 IdP"
 	},
-	"metadata_intro": {
+    "metadata_adfs-sp": {
+        "no": "ADFS SP metadata",
+        "nn": "ADFS SP Metadata",
+        "sv": "ADFS SP Metadata",
+        "es": "Metadatos SP ADFS",
+        "nl": "ADFS SP Metadata",
+        "sl": "ADFS SP Metapodatki",
+        "da": "Shibboleth 1.3 tjenesteudbyders metadata",
+        "hr": "ADFS metapodaci o davatelju usluge",
+        "hu": "ADFS SP Metaadatok",
+        "pt-br": "ADFS SP Metadata",
+        "pt": "Metadados ADFS SP",
+        "pl": "ADFS SP - Metadane",
+        "cs": "ADFS SP Metadata",
+        "tr": "ADFS SP \u00dcstveri (Metadata)",
+        "de": "ADFS SP Metadaten",
+        "fr": "M\u00e9tadonn\u00e9es de SP ADFS",
+        "it": "Metadati ADFS SP",
+        "ja": "ADFS SP\u30e1\u30bf\u30c7\u30fc\u30bf",
+        "lt": "ADFS SP Metaduomenys",
+        "zh-tw": "ADFS SP \u8a6e\u91cb\u8cc7\u6599",
+        "et": "ADFS SP metaandmed",
+        "he": "\u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2 \u05e9\u05dc \u05e1\u05e9 \u05de\u05e1\u05d5\u05d2 ADFS",
+        "zh": "ADFS SP \u5143\u4fe1\u606f",
+        "ar": "\u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0644\u0648\u0635\u0641\u064a\u0629 \u0644ADFS SP",
+        "lv": "ADFS SP metadati",
+        "id": "Metadata ADFS SP",
+        "sr": "ADFS SP metapodaci",
+        "ro": "Metadate furnizor de servicii (SP) ADFS",
+        "ru": "\u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 ADFS SP"
+    },
+    "metadata_adfs-idp": {
+        "no": "ADFS IdP metadata",
+        "nn": "ADFS IdP Metadata",
+        "sv": "ADFS IdP Metadata",
+        "es": "Metadatos IdP ADFS",
+        "nl": "ADFS IdP Metadata",
+        "sl": "ADFS IdP Metapodatki",
+        "da": "ADFS identitetsudbyders metadata",
+        "hr": "ADFS metapodaci o autentifikacijskom servisu",
+        "hu": "ADFS IdP Metaadatok",
+        "pt-br": "ADFS IdP Metadata",
+        "pt": "Metadados ADFS IdP",
+        "pl": "ADFS IdP - Metadane",
+        "cs": "ADFS IdP Metadata",
+        "tr": "ADFS IdP \u00dcstveri (Metadata)",
+        "de": "ADFS IdP Metadaten",
+        "fr": "M\u00e9tadonn\u00e9es d'IdP ADFS",
+        "it": "Metadati ADFS IdP",
+        "ja": "ADFS IdP\u30e1\u30bf\u30c7\u30fc\u30bf",
+        "lt": "ADFS IdP Metaduomenys",
+        "zh-tw": "ADFS IdP \u8a6e\u91cb\u8cc7\u6599",
+        "et": "ADFS IdP metaandmed",
+        "he": "\u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2 \u05e9\u05dc \u05e1\u05d6 \u05de\u05e1\u05d5\u05d2 ADFS ",
+        "zh": "ADFS IdP \u5143\u4fe1\u606f",
+        "ar": "\u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0644\u0648\u0635\u0641\u064a\u0629 \u0644 ADFS IdP",
+        "lv": "ADFS IdP metadati",
+        "id": "Metadata ADFS IdP",
+        "sr": "ADFS IdP metapodaci",
+        "ro": "Metadate furnizor de identitate (IdP) ADFS",
+        "ru": "\u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 ADFS IdP"
+    },
+    "metadata_intro": {
 		"no": "Her er metadata som simpleSAMLphp har generert for deg. Du m\u00e5 utveksle metadata med de partene du stoler p\u00e5 for \u00e5 sette opp en f\u00f8derasjon.",
 		"nn": "Her er metadata generert av simpleSAMLphp for deg.  Du kan senda dette metadata-dokumentet til dine partnarar, slik at de kan setja opp ein tillitsf\u00f8derasjon.",
 		"sv": "simpleSAMLphp har har genererat f\u00f6ljande metadata. F\u00f6r att s\u00e4tta upp en betrodd federation kan du skicka metadata till de parter du har f\u00f6rtroende f\u00f6r.",
diff --git a/lib/SimpleSAML/Metadata/SAMLBuilder.php b/lib/SimpleSAML/Metadata/SAMLBuilder.php
index 865412f94a6da6b1a60f0aa5d09f0de36e4fcfe8..33cd9bd0e965dc2d75f2a2dbc82f234f933d574f 100644
--- a/lib/SimpleSAML/Metadata/SAMLBuilder.php
+++ b/lib/SimpleSAML/Metadata/SAMLBuilder.php
@@ -85,6 +85,20 @@ class SimpleSAML_Metadata_SAMLBuilder {
 		return $xml->ownerDocument->saveXML();
 	}
 
+	public function addSecurityTokenServiceType($metadata) {
+		assert('is_array($metadata)');
+		assert('isset($metadata["entityid"])');
+		assert('isset($metadata["metadata-set"])');
+
+		$metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
+                $defaultEndpoint = $metadata->getDefaultEndpoint('SingleSignOnService');
+                $e = new sspmod_adfs_SAML2_XML_fed_SecurityTokenServiceType();
+                $e->Location = $defaultEndpoint['Location'];
+
+		$this->addCertificate($e, $metadata);
+
+		$this->entityDescriptor->RoleDescriptor[] = $e;
+	}
 
 	/**
 	 * @param SimpleSAML_Configuration $metadata  Metadata.
diff --git a/metadata-templates/adfs-idp-hosted.php b/metadata-templates/adfs-idp-hosted.php
index 040a199aa2665faa7ebb0f5e5f6c315d5d1cdb96..4360c04ceea7e8729a60277029c53d382b840b85 100644
--- a/metadata-templates/adfs-idp-hosted.php
+++ b/metadata-templates/adfs-idp-hosted.php
@@ -5,6 +5,10 @@ $metadata['__DYNAMIC:1__'] = array(
 	'privatekey' => 'server.pem',
 	'certificate' => 'server.crt',
 	'auth' => 'example-userpass',
+	'authproc' => array(
+		// Convert LDAP names to WS-Fed Claims.
+		100 => array('class' => 'core:AttributeMap', 'name2claim'),
+	),
 );
 
 ?>
diff --git a/modules/adfs/docs/adfs.txt b/modules/adfs/docs/adfs.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a57820a7275b4663d665d172958051748317153d
--- /dev/null
+++ b/modules/adfs/docs/adfs.txt
@@ -0,0 +1,83 @@
+Enables AD FS IdP
+Compatible with VS 2012 Identity and Access
+
+Basic Setup Companion based on:
+http://simplesamlphp.org/docs/stable/simplesamlphp-idp
+
+1. Enabling the Identity Provider functionality
+
+In config/config.php, the option will be:
+'enable.adfs-idp' => true
+
+2. Authentication module
+
+Follow as is.
+
+3. Configuring the authentication module
+
+In addition to enabling authentication module,  enable adfs module by creating a file named 'enable' in modules/adfs
+
+In unix from installation directory:
+touch modules/adfs/enable
+
+4. Configuring the IdP
+
+ADFS IdP is configured by metadata stored in /metadata/adfs-idp-hosted.php and metadata/adfs-sp-remote.php
+
+If they are not present, copy them from /metadata-templates to the metadata
+directory.
+
+5. Using the uri NameFormat on attributes
+
+WS-FED likes a few parameters to be very specifically named. This is
+especially true if .net clients will be treating this as a Microsoft ADFS
+IdP.
+
+The recommended settings for /metadata/adfs-idp-hosted.php is:
+
+'authproc' => array(
+        // Convert LDAP names to WS-Fed Claims.
+        100 => array('class' => 'core:AttributeMap', 'name2claim'),
+),
+
+6. Adding SPs to the IdP
+
+The minimal configuration for /metadata/adfs-sp-remote.php is:
+
+$metadata['urn:federation:localhost'] = array(
+        prp' => 'https://localhost/adfs/ls/',
+);
+
+7. Creating a SSL self signed certificate
+
+Follow as is.
+
+8. Adding this IdP to other SPs
+
+Metadata should be available from /module.php/adfs/idp/metadata.php
+
+9. This module tries its best to emulate a Microsoft ADFS endpoint, and as
+such, it is simplest to test using a .net client.
+
+To build the test client, follow the tutorial at:
+http://code.msdn.microsoft.com/Claims-Aware-Web-d94a89ca
+
+This will build a .net app that uses a dev machine running STS (their name for
+an IdP).
+
+To point to your SimpleSamlPHP ADFS IdP, in VS 2012:
+
+a. Right-click the project in Solution Explorer and select the Identity and
+Access option.
+
+b. In the Identity and Access Window, Select Use a business identity
+provider.
+
+c. Under “Enter the path to the STS metadata document” enter the url you have
+
+from step 8. Something like
+https://.../module.php/adfs/idp/metadata.php
+
+d. Click Ok
+
+For more information in regards to .NET: http://msdn.microsoft.com/en-us/library/hh377151.aspx
diff --git a/modules/adfs/lib/SAML2/XML/fed/Const.php b/modules/adfs/lib/SAML2/XML/fed/Const.php
new file mode 100644
index 0000000000000000000000000000000000000000..cdcd9b203d90229aee966f45a9144acb3a4537fb
--- /dev/null
+++ b/modules/adfs/lib/SAML2/XML/fed/Const.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Class representing fed Constants.
+ *
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+class sspmod_adfs_SAML2_XML_fed_Const {
+        /**
+        * The namespace for WS-FED protocol.
+        */
+        const NS_FED = 'http://docs.oasis-open.org/wsfed/federation/200706';
+}
diff --git a/modules/adfs/lib/SAML2/XML/fed/Endpoint.php b/modules/adfs/lib/SAML2/XML/fed/Endpoint.php
new file mode 100644
index 0000000000000000000000000000000000000000..4c73784938e72885770917ead5fef1c7d44d90db
--- /dev/null
+++ b/modules/adfs/lib/SAML2/XML/fed/Endpoint.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Class representing fed Endpoint.
+ *
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+class sspmod_adfs_SAML2_XML_fed_Endpoint {
+	/**
+	 * Add this endpoint to an XML element.
+	 *
+	 * @param DOMElement $parent  The element we should append this endpoint to.
+	 * @param string $name  The name of the element we should create.
+	 */
+	public static function appendXML(DOMElement $parent, $name, $address) {
+		assert('is_string($name)');
+		assert('is_string($address)');
+
+		$e = $parent->ownerDocument->createElement($name);
+                $parent->appendChild($e);
+
+		$endpoint = $parent->ownerDocument->createElement('EndpointReference');
+                $endpoint->setAttribute('xmlns', 'http://www.w3.org/2005/08/addressing');
+		$e->appendChild($endpoint);
+
+		$address = $parent->ownerDocument->createElement('Address', $address);
+		$endpoint->appendChild($address);
+
+		return $e;
+	}
+
+}
diff --git a/modules/adfs/lib/SAML2/XML/fed/SecurityTokenServiceType.php b/modules/adfs/lib/SAML2/XML/fed/SecurityTokenServiceType.php
new file mode 100644
index 0000000000000000000000000000000000000000..8369b40b4aca314ee9eaf7d7dc13263a683538f4
--- /dev/null
+++ b/modules/adfs/lib/SAML2/XML/fed/SecurityTokenServiceType.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Class representing SecurityTokenServiceType RoleDescriptor.
+ *
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+class sspmod_adfs_SAML2_XML_fed_SecurityTokenServiceType extends SAML2_XML_md_RoleDescriptor {
+
+	/**
+	 * List of supported protocols.
+	 *
+	 * @var array
+	 */
+	public $protocolSupportEnumeration = array(sspmod_adfs_SAML2_XML_fed_Const::NS_FED);
+
+	/**
+	 * The Location of Services.
+	 *
+	 * @var string
+	 */
+	public $Location;
+
+	/**
+	 * Initialize a SecurityTokenServiceType element.
+	 *
+	 * @param DOMElement|NULL $xml  The XML element we should load.
+	 */
+	public function __construct(DOMElement $xml = NULL) {
+
+                parent::__construct('RoleDescriptor', $xml);
+
+		if ($xml === NULL) {
+			return;
+		}
+	}
+
+	/**
+	 * Convert this SecurityTokenServiceType RoleDescriptor to XML.
+	 *
+	 * @param DOMElement $parent  The element we should add this contact to.
+	 * @return DOMElement  The new ContactPerson-element.
+	 */
+	public function toXML(DOMElement $parent) {
+		assert('is_string($this->Location)');
+
+		$e = parent::toXML($parent);
+		$e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:fed', sspmod_adfs_SAML2_XML_fed_Const::NS_FED);
+		$e->setAttributeNS(SAML2_Const::NS_XSI, 'xsi:type', 'fed:SecurityTokenServiceType');
+                sspmod_adfs_SAML2_XML_fed_TokenTypesOffered::appendXML($e);
+                sspmod_adfs_SAML2_XML_fed_Endpoint::appendXML($e, 'SecurityTokenServiceEndpoint', $this->Location);
+                sspmod_adfs_SAML2_XML_fed_Endpoint::appendXML($e, 'fed:PassiveRequestorEndpoint', $this->Location);
+
+		return $e;
+	}
+}
diff --git a/modules/adfs/lib/SAML2/XML/fed/TokenTypesOffered.php b/modules/adfs/lib/SAML2/XML/fed/TokenTypesOffered.php
new file mode 100644
index 0000000000000000000000000000000000000000..598a233c3885411c93c72e2351ec63008c028218
--- /dev/null
+++ b/modules/adfs/lib/SAML2/XML/fed/TokenTypesOffered.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Class representing fed TokenTypesOffered.
+ *
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+class sspmod_adfs_SAML2_XML_fed_TokenTypesOffered {
+	/**
+	 * Add tokentypesoffered to an XML element.
+	 *
+	 * @param DOMElement $parent  The element we should append this endpoint to.
+	 */
+	public static function appendXML(DOMElement $parent) {
+
+		$e = $parent->ownerDocument->createElementNS(sspmod_adfs_SAML2_XML_fed_Const::NS_FED, 'fed:TokenTypesOffered');
+                $parent->appendChild($e);
+
+		$tokentype = $parent->ownerDocument->createElementNS(sspmod_adfs_SAML2_XML_fed_Const::NS_FED, 'fed:TokenType');
+                $tokentype->setAttribute('Uri', 'urn:oasis:names:tc:SAML:1.0:assertion');
+		$e->appendChild($tokentype);
+
+		return $e;
+	}
+
+}
diff --git a/modules/adfs/www/idp/metadata.php b/modules/adfs/www/idp/metadata.php
new file mode 100644
index 0000000000000000000000000000000000000000..fd563ba40200a746d67e4fa117d25d69332a4162
--- /dev/null
+++ b/modules/adfs/www/idp/metadata.php
@@ -0,0 +1,156 @@
+<?php
+
+/* Load simpleSAMLphp, configuration and metadata */
+$config = SimpleSAML_Configuration::getInstance();
+$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+
+if (!$config->getBoolean('enable.adfs-idp', false))
+	throw new SimpleSAML_Error_Error('NOACCESS');
+
+/* Check if valid local session exists.. */
+if ($config->getBoolean('admin.protectmetadata', false)) {
+	SimpleSAML_Utilities::requireAdmin();
+}
+
+
+try {
+	$idpentityid = isset($_GET['idpentityid']) ? $_GET['idpentityid'] : $metadata->getMetaDataCurrentEntityID('adfs-idp-hosted');
+	$idpmeta = $metadata->getMetaDataConfig($idpentityid, 'adfs-idp-hosted');
+
+	$availableCerts = array();
+
+	$keys = array();
+	$certInfo = SimpleSAML_Utilities::loadPublicKey($idpmeta, FALSE, 'new_');
+	if ($certInfo !== NULL) {
+		$availableCerts['new_idp.crt'] = $certInfo;
+		$keys[] = array(
+			'type' => 'X509Certificate',
+			'signing' => TRUE,
+			'encryption' => TRUE,
+			'X509Certificate' => $certInfo['certData'],
+		);
+		$hasNewCert = TRUE;
+	} else {
+		$hasNewCert = FALSE;
+	}
+
+	$certInfo = SimpleSAML_Utilities::loadPublicKey($idpmeta, TRUE);
+	$availableCerts['idp.crt'] = $certInfo;
+	$keys[] = array(
+		'type' => 'X509Certificate',
+		'signing' => TRUE,
+		'encryption' => ($hasNewCert ? FALSE : TRUE),
+		'X509Certificate' => $certInfo['certData'],
+	);
+
+	if ($idpmeta->hasValue('https.certificate')) {
+		$httpsCert = SimpleSAML_Utilities::loadPublicKey($idpmeta, TRUE, 'https.');
+		assert('isset($httpsCert["certData"])');
+		$availableCerts['https.crt'] = $httpsCert;
+		$keys[] = array(
+			'type' => 'X509Certificate',
+			'signing' => TRUE,
+			'encryption' => FALSE,
+			'X509Certificate' => $httpsCert['certData'],
+		);
+	}
+
+        $adfs_service_location = SimpleSAML_Module::getModuleURL('adfs') . '/idp/prp.php';
+	$metaArray = array(
+		'metadata-set' => 'adfs-idp-remote',
+		'entityid' => $idpentityid,
+		'SingleSignOnService' => array(0 => array(
+					'Binding' => SAML2_Const::BINDING_HTTP_REDIRECT,
+					'Location' => $adfs_service_location)),
+		'SingleLogoutService' => array(0 => array(
+					'Binding' => SAML2_Const::BINDING_HTTP_REDIRECT,
+					'Location' => $adfs_service_location)),
+	);
+
+	if (count($keys) === 1) {
+		$metaArray['certData'] = $keys[0]['X509Certificate'];
+	} else {
+		$metaArray['keys'] = $keys;
+	}
+
+	$metaArray['NameIDFormat'] = $idpmeta->getString('NameIDFormat', 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient');
+
+	if ($idpmeta->hasValue('OrganizationName')) {
+		$metaArray['OrganizationName'] = $idpmeta->getLocalizedString('OrganizationName');
+		$metaArray['OrganizationDisplayName'] = $idpmeta->getLocalizedString('OrganizationDisplayName', $metaArray['OrganizationName']);
+
+		if (!$idpmeta->hasValue('OrganizationURL')) {
+			throw new SimpleSAML_Error_Exception('If OrganizationName is set, OrganizationURL must also be set.');
+		}
+		$metaArray['OrganizationURL'] = $idpmeta->getLocalizedString('OrganizationURL');
+	}
+
+	if ($idpmeta->hasValue('scope')) {
+		$metaArray['scope'] = $idpmeta->getArray('scope');
+	}
+
+	if ($idpmeta->hasValue('EntityAttributes')) {
+		$metaArray['EntityAttributes'] = $idpmeta->getArray('EntityAttributes');
+	}
+
+	if ($idpmeta->hasValue('UIInfo')) {
+		$metaArray['UIInfo'] = $idpmeta->getArray('UIInfo');
+	}
+
+	if ($idpmeta->hasValue('DiscoHints')) {
+		$metaArray['DiscoHints'] = $idpmeta->getArray('DiscoHints');
+	}
+
+	if ($idpmeta->hasValue('RegistrationInfo')) {
+		$metaArray['RegistrationInfo'] = $idpmeta->getArray('RegistrationInfo');
+	}
+
+	$metaflat = '$metadata[' . var_export($idpentityid, TRUE) . '] = ' . var_export($metaArray, TRUE) . ';';
+
+	$metaBuilder = new SimpleSAML_Metadata_SAMLBuilder($idpentityid);
+	$metaBuilder->addSecurityTokenServiceType($metaArray);
+	$metaBuilder->addOrganizationInfo($metaArray);
+	$technicalContactEmail = $config->getString('technicalcontact_email', NULL);
+	if ($technicalContactEmail && $technicalContactEmail !== 'na@example.org') {
+		$metaBuilder->addContact('technical', array(
+			'emailAddress' => $technicalContactEmail,
+			'name' => $config->getString('technicalcontact_name', NULL),
+		));
+	}
+	$metaxml = explode("\n", $metaBuilder->getEntityDescriptorText());
+    unset($metaxml[0]);
+    $metaxml = implode("\n", $metaxml);
+
+	/* Sign the metadata if enabled. */
+	$metaxml = SimpleSAML_Metadata_Signer::sign($metaxml, $idpmeta->toArray(), 'ADFS IdP');
+
+	if (array_key_exists('output', $_GET) && $_GET['output'] == 'xhtml') {
+		$defaultidp = $config->getString('default-adfs-idp', NULL);
+
+		$t = new SimpleSAML_XHTML_Template($config, 'metadata.php', 'admin');
+
+		$t->data['available_certs'] = $availableCerts;
+		$t->data['header'] = 'adfs-idp';
+		$t->data['metaurl'] = SimpleSAML_Utilities::selfURLNoQuery();
+		$t->data['metadata'] = htmlspecialchars($metaxml);
+		$t->data['metadataflat'] = htmlspecialchars($metaflat);
+		$t->data['defaultidp'] = $defaultidp;
+		$t->show();
+
+	} else {
+
+		header('Content-Type: application/xml');
+
+		echo $metaxml;
+		exit(0);
+
+	}
+
+
+
+} catch(Exception $exception) {
+
+	throw new SimpleSAML_Error_Error('METADATA', $exception);
+
+}
+
diff --git a/modules/core/templates/frontpage_federation.tpl.php b/modules/core/templates/frontpage_federation.tpl.php
index afe93b08b1284a09d8a6b2b264b322d123bf1fae..243aa4de433bd4f8e4311f07be53e2fed6b5bf0e 100644
--- a/modules/core/templates/frontpage_federation.tpl.php
+++ b/modules/core/templates/frontpage_federation.tpl.php
@@ -42,6 +42,10 @@ function mtype($set) {
 		case 'shib13-sp-hosted': return '{admin:metadata_shib13-sp}';
 		case 'shib13-idp-remote': return '{admin:metadata_shib13-idp}';
 		case 'shib13-idp-hosted': return '{admin:metadata_shib13-idp}';
+        case 'adfs-sp-remote'; return '{admin:metadata_adfs-sp}';
+        case 'adfs-sp-hosted'; return '{admin:metadata_adfs-sp}';
+        case 'adfs-idp-remote'; return '{admin:metadata_adfs-idp}';
+        case 'adfs-idp-hosted'; return '{admin:metadata_adfs-idp}';
 	}
 }
 
diff --git a/modules/core/www/frontpage_federation.php b/modules/core/www/frontpage_federation.php
index addf765d096cf77621c3cfa2cbe4042e2832ca89..072ad6c5ea26bb17dfc2a969f024f4c4779eef3e 100644
--- a/modules/core/www/frontpage_federation.php
+++ b/modules/core/www/frontpage_federation.php
@@ -79,13 +79,15 @@ if ($config->getBoolean('enable.saml20-sp', TRUE) === true) {
 	try {
 		$metaentries['hosted']['saml20-sp'] = $metadata->getMetaDataCurrent('saml20-sp-hosted');
 		$metaentries['hosted']['saml20-sp']['deprecated'] = TRUE;
-		$metaentries['hosted']['saml20-sp']['metadata-url'] = '/' . $config->getBaseURL() . 'saml2/sp/metadata.php?output=xhtml';
+		$metaentries['hosted']['saml20-sp']['metadata-url'] = '/' . $config->getBaseURL() .
+                                                              'saml2/sp/metadata.php?output=xhtml';
 	} catch(Exception $e) {}
 }
 if ($config->getBoolean('enable.saml20-idp', FALSE) === true) {
 	try {
 		$metaentries['hosted']['saml20-idp'] = $metadata->getMetaDataCurrent('saml20-idp-hosted');
-		$metaentries['hosted']['saml20-idp']['metadata-url'] = '/' . $config->getBaseURL() . 'saml2/idp/metadata.php?output=xhtml';
+		$metaentries['hosted']['saml20-idp']['metadata-url'] = '/' . $config->getBaseURL() .
+                                                               'saml2/idp/metadata.php?output=xhtml';
 		if ($isadmin)
 			$metaentries['remote']['saml20-sp-remote'] = $metadata->getList('saml20-sp-remote');
 	} catch(Exception $e) {}
@@ -94,17 +96,28 @@ if ($config->getBoolean('enable.shib13-sp', FALSE) === true) {
 	try {
 		$metaentries['hosted']['shib13-sp'] = $metadata->getMetaDataCurrent('shib13-sp-hosted');
 		$metaentries['hosted']['shib13-sp']['deprecated'] = TRUE;
-		$metaentries['hosted']['shib13-sp']['metadata-url'] = '/' . $config->getBaseURL() . 'shib13/sp/metadata.php?output=xhtml';
+		$metaentries['hosted']['shib13-sp']['metadata-url'] = '/' . $config->getBaseURL() .
+                                                              'shib13/sp/metadata.php?output=xhtml';
 	} catch(Exception $e) {}
 }
 if ($config->getBoolean('enable.shib13-idp', FALSE) === true) {
 	try {
 		$metaentries['hosted']['shib13-idp'] = $metadata->getMetaDataCurrent('shib13-idp-hosted');
-		$metaentries['hosted']['shib13-idp']['metadata-url'] = '/' . $config->getBaseURL() . 'shib13/idp/metadata.php?output=xhtml';
+		$metaentries['hosted']['shib13-idp']['metadata-url'] = '/' . $config->getBaseURL() .
+                                                               'shib13/idp/metadata.php?output=xhtml';
 		if ($isadmin)
 			$metaentries['remote']['shib13-sp-remote'] = $metadata->getList('shib13-sp-remote');
 	} catch(Exception $e) {}
 }
+if ($config->getBoolean('enable.adfs-idp', FALSE) === true) {
+    try {
+        $metaentries['hosted']['adfs-idp'] = $metadata->getMetaDataCurrent('adfs-idp-hosted');
+        $metaentries['hosted']['adfs-idp']['metadata-url'] = SimpleSAML_Module::getModuleURL('adfs/idp/metadata.php',
+                                                                                             array('output' => 'xhtml'));
+        if ($isadmin)
+            $metaentries['remote']['adfs-sp-remote'] = $metadata->getList('adfs-sp-remote');
+    } catch(Exception $e) {}
+}