diff --git a/modules/aggregator/bin/get.php b/modules/aggregator/bin/get.php
deleted file mode 100755
index 7558f775575b23773a208b1f861a6a2f2e619ee4..0000000000000000000000000000000000000000
--- a/modules/aggregator/bin/get.php
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env php
-<?php
-
-require_once(dirname(dirname(dirname(dirname(__FILE__)))) . '/lib/_autoload.php');
-
-if ($argc < 2) {
-	fwrite(STDERR, "Missing aggregator id.\n");
-	exit(1);
-}
-$id = $argv[1];
-
-$gConfig = SimpleSAML_Configuration::getConfig('module_aggregator.php');
-$aggregators = $gConfig->getConfigItem('aggregators');
-
-$aConfig = $aggregators->getConfigItem($id, NULL);
-if ($aConfig === NULL) {
-	fwrite(STDERR, 'No aggregator with id ' . var_export($id, TRUE) . " found.\n");
-	exit(1);
-}
-
-$aggregator = new sspmod_aggregator_Aggregator($gConfig, $aConfig, $id);
-
-$xml = $aggregator->getMetadataDocument();
-echo($xml->saveXML());
diff --git a/modules/aggregator/config-templates/module_aggregator.php b/modules/aggregator/config-templates/module_aggregator.php
deleted file mode 100644
index f941fa38fe7c10288658d4b8b87f9736ceb31df3..0000000000000000000000000000000000000000
--- a/modules/aggregator/config-templates/module_aggregator.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-/* Configuration for the aggregator module. */
-$config = array(
-
-	/* List of aggregators. */
-	'aggregators' => array(
-		'example' => array(
-			'sources' => array(
-				array('type' => 'flatfile'),  /* Metadata from metadata-directory. */
-				array('type' => 'xml', 'url' => 'https://idp.example.org/Metadata'),
-				array('type' => 'xml', 'file' => 'static-metadata.xml'),
-			),
-		),
-		'example2' => array(
-			'sources' => array(
-				array('type' => 'xml', 'url' => 'https://idp.example.org/Metadata2'),
-			),
-			'set' => 'saml2',
-			'sign.privatekey' => 'server2.key',
-			'sign.certificate' => 'server2.crt',
-		)
-	),
-
-	
-	'maxDuration' 	=> 60*60*24*5, // Maximum 5 days duration on ValidUntil.
-
-	// If base64 encoded for entity is already cached in the entity, should we
-	// reconstruct the XML or re-use.
-	'reconstruct' => FALSE,
-
-	/* Whether metadata should be signed. */
-	'sign.enable' => FALSE,
-
-	/* Private key which should be used when signing the metadata. */
-	'sign.privatekey' => 'server.key',
-
-	/* Password to decrypt private key, or NULL if the private key is unencrypted. */
-	'sign.privatekey_pass' => NULL,
-
-	/* Certificate which should be included in the signature. Should correspond to the private key. */
-	'sign.certificate' => 'server.crt',
-
-);
-
diff --git a/modules/aggregator/default-disable b/modules/aggregator/default-disable
deleted file mode 100644
index fa0bd82e2df7bd79d57593d35bc53c1f9d3ef71f..0000000000000000000000000000000000000000
--- a/modules/aggregator/default-disable
+++ /dev/null
@@ -1,3 +0,0 @@
-This file indicates that the default state of this module
-is disabled. To enable, create a file named enable in the
-same directory as this file.
diff --git a/modules/aggregator/dictionaries/aggregator.definition.json b/modules/aggregator/dictionaries/aggregator.definition.json
deleted file mode 100644
index a5f7b74d12db34fe06413d83ba4acd6e0ffc4834..0000000000000000000000000000000000000000
--- a/modules/aggregator/dictionaries/aggregator.definition.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-	"frontpage_link": {
-		"en": "Metadata aggregator"
-	},
-	"aggregator_header": {
-		"en": "Aggregators"
-	},
-	"no_aggregators": {
-		"en": "No aggregators defined in configuration."
-	},
-	"text": {
-		"en": "text"
-	}
-}
\ No newline at end of file
diff --git a/modules/aggregator/dictionaries/aggregator.translation.json b/modules/aggregator/dictionaries/aggregator.translation.json
deleted file mode 100644
index 91495e2c9907993b7ef06278c24c09bd2ed327f2..0000000000000000000000000000000000000000
--- a/modules/aggregator/dictionaries/aggregator.translation.json
+++ /dev/null
@@ -1,114 +0,0 @@
-{
-	"frontpage_link": {
-		"no": "Metadata aggregator",
-		"de": "Metadaten-Aggregator",
-		"sl": "Agregator metapodatkov",
-		"pt": "Agregador de Metadados",
-		"sv": "Metadatasammanst\u00e4llare",
-		"hr": "Agregator metapodataka",
-		"da": "Metadata aggregator",
-		"fr": "Agr\u00e9gateur de m\u00e9tadonn\u00e9es",
-		"nn": "Oppsamling av metadata",
-		"it": "Aggregatore dei metadati",
-		"es": "Agregador de metadatos",
-		"lt": "Metaduomen\u0173 surink\u0117jas",
-		"nl": "Metadata-aggregator",
-		"ja": "\u30e1\u30bf\u30c7\u30fc\u30bf \u30a2\u30b0\u30ea\u30b1\u30fc\u30bf",
-		"zh-tw": "\u8a6e\u91cb\u8cc7\u6599\u532f\u96c6",
-		"et": "Metaandmete agregeerija",
-		"he": "\u05e9\u05d5\u05dc\u05e3 \u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2 ",
-		"ru": "\u0410\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0440 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445",
-		"zh": "\u5143\u4fe1\u606f\u805a\u5408\u5668",
-		"ar": " \u0645\u062c\u0645\u0639 \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0644\u0648\u0635\u0641\u064a\u0629\/ \u0627\u0644\u0645\u064a\u062a\u0627\u062f\u0627\u062a\u0627",
-		"lv": "Metadatu agregators",
-		"id": "Aggregator metadata",
-		"sr": "Agregator metapodataka",
-		"ro": "Agregator de metadate",
-		"cs": "Metadata agreg\u00e1tor",
-		"eu": "Metadatu eranslea"
-	},
-	"aggregator_header": {
-		"no": "Aggregatorer",
-		"de": "Aggregatoren",
-		"sl": "Agregatorji",
-		"pt": "Agregadores",
-		"sv": "Sammanst\u00e4llare",
-		"hr": "Agregatori",
-		"da": "Aggregatorer",
-		"fr": "Agr\u00e9gateurs",
-		"nn": "Aggregering",
-		"it": "Aggregatori",
-		"es": "Agregadores",
-		"lt": "Surink\u0117jai",
-		"nl": "Aggregatoren",
-		"ja": "\u30a2\u30b0\u30ea\u30b1\u30fc\u30bf",
-		"zh-tw": "\u532f\u96c6",
-		"et": "Agregeerijad",
-		"he": "\u05e9\u05d5\u05dc\u05e4\u05d9 \u05de\u05d9\u05d3\u05e2",
-		"ru": "\u0410\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0440\u044b",
-		"zh": "\u805a\u5408\u5668",
-		"ar": "\u0645\u062c\u0645\u0639\u0627\u062a",
-		"lv": "Agregatori",
-		"id": "Aggregator",
-		"sr": "Agregatori",
-		"ro": "Agregatoare",
-		"cs": "Agreg\u00e1tory",
-		"eu": "Eransleak"
-	},
-	"no_aggregators": {
-		"no": "Ingen aggregator definert i konfigurasjonen",
-		"de": "Keine Aggregatoren in der Konfiguration definiert.",
-		"sl": "V nastavitvah ni definiran noben agregator.",
-		"pt": "N\u00e3o foram definidos agregadores na configura\u00e7\u00e3o.",
-		"sv": "Inga sammanst\u00e4llare (aggregators) definierade i konfigurationen.",
-		"hr": "U konfiguraciji nije definiran niti jedan agregator.",
-		"da": "Ingen aggregator defineret i konfigurationen",
-		"fr": "Aucun agr\u00e9gateur n'a \u00e9t\u00e9 d\u00e9fini dans la configuration.",
-		"nn": "Aggregrering er ikkje definert i konfigurasjonen.",
-		"it": "Non ci sono aggregatori definiti nella configurazione.",
-		"es": "No ha sido definido ning\u00fan agregador en la configuraci\u00f3n.",
-		"lt": "Konfig\u016bracijoje nenurodyti jokie surink\u0117jai.",
-		"nl": "Geen aggregator gedefinieerd in de configuratie.",
-		"ja": "\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306b\u30a2\u30b0\u30ea\u30b1\u30fc\u30bf\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3002",
-		"zh-tw": "\u8a2d\u5b9a\u6a94\u7121\u532f\u96c6\u5b9a\u7fa9",
-		"et": "Seadistustes pole agregeerijaid kirjeldatud.",
-		"he": "\u05dc\u05d0 \u05de\u05d5\u05d2\u05d3\u05e8\u05d9\u05dd \u05e9\u05d5\u05dc\u05e4\u05d9 \u05de\u05d9\u05d3\u05e2.",
-		"ru": "\u0412 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0440\u044b.",
-		"zh": "\u914d\u7f6e\u4e2d\u6ca1\u6709\u5b9a\u4e49\u805a\u5408\u5668",
-		"ar": "\u0644\u0645 \u064a\u062a\u0645 \u062a\u062d\u062f\u064a\u062f \u0627\u0644\u0645\u062c\u0645\u0639\u0627\u062a \u0628\u0627\u0644\u0643\u0648\u0646\u0641\u064a\u063a\u0631\u0627\u0634\u0646",
-		"lv": "Konfigur\u0101cij\u0101 nav defin\u0113ti agregatori.",
-		"id": "Tidak ada aggregator yang didefinisikan di konfigurasi",
-		"sr": "U pode\u0161avanjima nije definisan nijedan agregator.",
-		"ro": "Nu sunt definite agregatoare \u00een configurare.",
-		"cs": "\u017d\u00e1dn\u00e9 agreg\u00e1tory nejsou definov\u00e1ny v konfiguraci.",
-		"eu": "Ez da inolako eranslerik zehaztu konfigurazioan. "
-	},
-	"text": {
-		"no": "tekst",
-		"de": "Text",
-		"sl": "Besedilo",
-		"pt": "Texto",
-		"sv": "Text",
-		"hr": "tekst",
-		"da": "tekst",
-		"fr": "texte",
-		"nn": "Tekst",
-		"it": "testo",
-		"es": "texto",
-		"lt": "Tekstas",
-		"nl": "tekst",
-		"ja": "\u30c6\u30ad\u30b9\u30c8",
-		"zh-tw": "\u6587\u5b57",
-		"et": "tekst",
-		"he": "\u05d8\u05e7\u05d8\u05e1",
-		"ru": "\u0442\u0435\u043a\u0441\u0442",
-		"zh": "\u6587\u672c",
-		"ar": "\u0646\u0635",
-		"lv": "teksts",
-		"id": "teks",
-		"sr": "tekst",
-		"ro": "text",
-		"cs": "text",
-		"eu": "testua"
-	}
-}
diff --git a/modules/aggregator/docs/aggregator.txt b/modules/aggregator/docs/aggregator.txt
deleted file mode 100644
index 23dc8bdbf07245ca0525f7b7279ee327c0e50c6e..0000000000000000000000000000000000000000
--- a/modules/aggregator/docs/aggregator.txt
+++ /dev/null
@@ -1,90 +0,0 @@
-aggregator Module
-=================
-
-<!--
-	This file is written in Markdown syntax.
-	For more information about how to use the Markdown syntax, read here:
-	http://daringfireball.net/projects/markdown/syntax
--->
-
-  * Author: Andreas Ă…kre Solberg <andreas.solberg@uninett.no>, UNINETT AS
-  * Package: simpleSAMLphp
-
-This module, aggregates a set of metadata of SAML entities to SAML 2.0 documents with an `EntitiesDescriptor` with multiple entities inside.
-
-Multiple aggregates can be configured.
-
-
-
-The configuration file: module_aggregate.php
---------------------------------------------
-
-The configuration file includes an option `aggregators`, which includes a indexed list of different aggregator configurations that all can be accessed independently. The structure is as follows:
-
-	'aggregators' => array(
-		'aggr1' => array(
-			'sources' => [...]
-			[...local params...]
-		),
-		'aggr2' => ...
-	)
-	[...global params...]
-
-All of the global parameters can be overriden for each aggregator. Here is a list of the available (global) paramters:
-
-`maxDuration`
-: Max validity of metadata (duration) in seconds.
-
-`reconstruct`
-: Whether simpleSAMLphp should regenerate the metadata XML (TRUE) or pass-through the input metadata XML (FALSE).
-
-`RegistrationInfo`
-:   Allows to specify information about the registrar of this metadata. Please refer to the
-    [MDRPI extension](./simplesamlphp-metadata-extensions-rpi) document for further information.
-
-`set`
-: By default all SAML types are available, including: `array('saml20-idp-remote', 'saml20-sp-remote', 'shib13-idp-remote', 'shib13-sp-remote')`. This list can be reduced by specifying one of the following values:
-
-  * `saml20-idp-remote`
-  * `saml20-sp-remote`
-  * `shib13-idp-remote`
-  * `shib13-sp-remote`
-  * `saml2`
-  * `shib13`
-
-`sign.enable`
-: Enable signing of metadata document
-
-`sign.certificate`
-: Certificate to embed, corresponding to the private key.
-
-`sign.privatekey`
-: Private key to use when signing
-
-`sign.privatekey_pass`
-: Optionally a passphrase to the private key
-
-
-Accessing the aggregate
------------------------
-
-On the SimpleSAMLphp frontpage on the federation tab, there is a link to the aggregator named *Metadata aggregator*.
-
-When accessing the aggregator endpoint without specifying an aggregate ID, a list of available aggregators will be presented, with different options for mime-type presenting the result.
-
-The endpoint supports the following query parameter:
-
-`id`
-: The ID of the aggregator (From configuration file)
-
-`set`
-: Subset the available types of SAML entities. Similar to the `set` parameter described over in the configuration file description.
-
-`exclude`
-: Specify a `tag` that will be excluded from the metadata set. Useful for leaving out your own federation metadata.
-
-`mimetype`
-: Select the Mime-Type that will be used. Default is `application/samlmetadata+xml`.
-
-
-
diff --git a/modules/aggregator/hooks/hook_frontpage.php b/modules/aggregator/hooks/hook_frontpage.php
deleted file mode 100644
index 2bbb5cffea3108d02585d884ca2c46ab6137711c..0000000000000000000000000000000000000000
--- a/modules/aggregator/hooks/hook_frontpage.php
+++ /dev/null
@@ -1,17 +0,0 @@
-<?php
-/**
- * Hook to add the aggregator list to the frontpage.
- *
- * @param array &$links  The links on the frontpage, split into sections.
- */
-function aggregator_hook_frontpage(&$links) {
-	assert('is_array($links)');
-	assert('array_key_exists("links", $links)');
-
-	$links['federation'][] = array(
-		'href' => SimpleSAML_Module::getModuleURL('aggregator/'),
-		'text' => '{aggregator:aggregator:frontpage_link}',
-		);
-
-}
-?>
\ No newline at end of file
diff --git a/modules/aggregator/lib/ARP.php b/modules/aggregator/lib/ARP.php
deleted file mode 100644
index 0847522f32ae36a1fd61e025fa36fb6d19c29a11..0000000000000000000000000000000000000000
--- a/modules/aggregator/lib/ARP.php
+++ /dev/null
@@ -1,106 +0,0 @@
-<?php
-/*
- * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
- * @package simpleSAMLphp
- */
-class sspmod_aggregator_ARP {
-
-
-	private $metadata;
-	private $attributes;
-	private $prefix;
-	private $suffix;
-
-	/**
-	 * Constructor
-	 *
-	 * @param 
-	 */
-	public function __construct($metadata, $attributemap, $prefix, $suffix) {
-		$this->metadata = $metadata;
-		
-		$this->prefix = $prefix;
-		$this->suffix = $suffix;
-		
-		if (isset($attributemap)) $this->loadAttributeMap($attributemap);
-	}
-	
-	private function loadAttributeMap($attributemap) {
-		$config = SimpleSAML_Configuration::getInstance();
-		include($config->getPathValue('attributemap', 'attributemap/') . $attributemap . '.php');
-		$this->attributes = $attributemap;
-		
-	#	print_r($attributemap); exit;
-	}
-
-	private function surround($name) {
-		$ret = '';
-		if (!empty($this->prefix)) $ret .= htmlspecialchars($this->prefix);
-		$ret .= $name;
-		if (!empty($this->suffix)) $ret .= htmlspecialchars($this->suffix);
-		return $ret;
-	}
-
-	private function getAttributeID($name) {
-		if (empty($this->attributes)) {
-			return $this->surround($name);
-		} 
-		if (array_key_exists($name, $this->attributes)) {
-			return $this->surround($this->attributes[$name]);
-		}
-		return $this->surround($name);
-	}
-
-	public function getXML() {
-		
-		$xml = '<?xml version="1.0" encoding="UTF-8"?>
-<AttributeFilterPolicyGroup id="urn:mace:funet.fi:haka:kalmar" xmlns="urn:mace:shibboleth:2.0:afp"
-    xmlns:basic="urn:mace:shibboleth:2.0:afp:mf:basic" xmlns:saml="urn:mace:shibboleth:2.0:afp:mf:saml"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="urn:mace:shibboleth:2.0:afp classpath:/schema/shibboleth-2.0-afp.xsd
-                        urn:mace:shibboleth:2.0:afp:mf:basic classpath:/schema/shibboleth-2.0-afp-mf-basic.xsd
-                        urn:mace:shibboleth:2.0:afp:mf:saml classpath:/schema/shibboleth-2.0-afp-mf-saml.xsd">
-';
-		
-		
-		foreach($this->metadata AS $metadata) {
-			#echo '<pre>'; print_r($metadata); # exit;
-			if (isset($metadata['saml20-sp-remote'])) {
-				#echo '<pre>'; print_r($metadata); exit;
-				$xml .= $this->getEntryXML($metadata['saml20-sp-remote']);
-			}
-			
-		}
-		
-		$xml .= '</AttributeFilterPolicyGroup>';
-		return $xml;
-	}
-
-	private function getEntryXML($entry) {
-		$entityid = $entry['entityid'];
-		return '	<AttributeFilterPolicy id="' . $entityid . '">
-		<PolicyRequirementRule xsi:type="basic:AttributeRequesterString" value="' . $entityid . '" />
-' . $this->getEntryXMLcontent($entry) . '
-	</AttributeFilterPolicy>
-';
-	}
-	
-	private function getEntryXMLcontent($entry) {
-		$ids = array();
-		if (!array_key_exists('attributes', $entry)) 
-			return '';
-		
-		$ret = '';
-		foreach($entry['attributes'] AS $a) {
-			
-			$ret .= '			<AttributeRule attributeID="' . $this->getAttributeID($a) . '">
-				<PermitValueRule xsi:type="basic:ANY" />
-			</AttributeRule>
-';
-			
-		}
-		return $ret;
-	}
-
-}
-
diff --git a/modules/aggregator/lib/Aggregator.php b/modules/aggregator/lib/Aggregator.php
deleted file mode 100644
index 1f41602fa606c0ad67de8d62e6a1793715a0c9bd..0000000000000000000000000000000000000000
--- a/modules/aggregator/lib/Aggregator.php
+++ /dev/null
@@ -1,257 +0,0 @@
-<?php
-
-/**
- * Aggregates metadata for multiple sources into one signed file
- *
- * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
- * @package simpleSAMLphp
- */
-
-class sspmod_aggregator_Aggregator {
-
-	// Configuration for the whole aggregator module
-	private $gConfig;
-	
-	// Configuration for the specific aggregate
-	private $aConfig;
-	
-	private $sets;
-	
-	private $excludeTags = array();
-	
-	private $id;
-
-	/**
-	 * Constructor for the Aggregator.
-	 *
-	 */
-	public function __construct($gConfig, $aConfig, $id) {
-		$this->gConfig = $gConfig;
-		$this->aConfig = $aConfig;
-		$this->id = $id;
-		
-		$this->sets = array('saml20-idp-remote', 'saml20-sp-remote', 'shib13-idp-remote', 'shib13-sp-remote', 'attributeauthority-remote');
-		
-		if ($this->aConfig->hasValue('set')) {
-			$this->limitSets($this->aConfig->getString('set'));
-		}
-	}
-
-
-
-	public function limitSets($set) {
-
-		
-		if (is_array($set)) {
-			$this->sets = array_intersect($this->sets, $set);
-			return;
-		}
-		
-		switch($set) {
-			case 'saml2' :
-				$this->sets = array_intersect($this->sets, array('saml20-idp-remote', 'saml20-sp-remote')); break;
-			case 'shib13' :
-				$this->sets = array_intersect($this->sets, array('shib13-idp-remote', 'shib13-sp-remote')); break;
-			case 'idp' :
-				$this->sets = array_intersect($this->sets, array('saml20-idp-remote', 'shib13-idp-remote', 'attributeauthority-remote')); break;
-			case 'sp' :
-				$this->sets = array_intersect($this->sets, array('saml20-sp-remote', 'shib13-sp-remote')); break;
-
-			default:
-				$this->sets = array_intersect($this->sets, array($set));
-		}
-	}
-
-	/**
-	 * Add tag to excelude when collecting source metadata.
-	 * 
-	 * $exclude 	May be string or array identifying a tag to exclude.
-	 */
-	public function exclude($exclude) {
-		$this->excludeTags = array_merge($this->excludeTags, SimpleSAML_Utilities::arrayize($exclude));
-	}
-	
-	/**
-	 * Returns a list of entities with metadata
-	 */ 
-	public function getSources() {
-		
-		$sourcesDef = $this->aConfig->getArray('sources');
-
-		try {
-			$sources = SimpleSAML_Metadata_MetaDataStorageSource::parseSources($sourcesDef);
-		} catch (Exception $e) {
-			throw new Exception('Invalid aggregator source configuration for aggregator ' .
-				var_export($id, TRUE) . ': ' . $e->getMessage());
-		}
-
-		/* Find list of all available entities. */
-		$entities = array();
-		
-		foreach ($sources as $source) {
-			foreach ($this->sets as $set) {
-				
-				foreach ($source->getMetadataSet($set) as $entityId => $metadata) {
-
-					$metadata['entityid'] = $entityId;
-					$metadata['metadata-set'] = $set;
-
-					if (isset($metadata['tags']) && 
-							count(array_intersect($this->excludeTags, $metadata['tags'])) > 0) {
-						
-						SimpleSAML_Logger::debug('Excluding entity ID [' . $entityId . '] becuase it is tagged with one of [' . 
-							var_export($this->excludeTags, TRUE) . ']');
-						continue;
-					} else {
-						#echo('<pre>'); print_r($metadata); exit;
-					}
-					if (!array_key_exists($entityId, $entities)) 
-						$entities[$entityId] = array();
-
-					if (array_key_exists($set, $entities[$entityId])) {
-						/* Entity already has metadata for the given set. */
-						continue;
-					}
-
-					$entities[$entityId][$set] = $metadata;
-				}
-			}
-		}
-		return $entities;
-		
-	}
-	
-	public function getMaxDuration() {
-		if ($this->aConfig->hasValue('maxDuration'))
-			return $this->aConfig->getInteger('maxDuration');
-		if ($this->gConfig->hasValue('maxDuration'))
-			return $this->gConfig->getInteger('maxDuration');
-		return NULL;
-	}
-	
-	
-	
-	public function getReconstruct() {
-		if ($this->aConfig->hasValue('reconstruct'))
-			return $this->aConfig->getBoolean('reconstruct');
-		if ($this->gConfig->hasValue('reconstruct'))
-			return $this->gConfig->getBoolean('reconstruct');
-		return FALSE;
-	}
-
-	public function shouldSign() {
-		if ($this->aConfig->hasValue('sign.enable'))
-			return $this->aConfig->getBoolean('sign.enable');
-		if ($this->gConfig->hasValue('sign.enable'))
-			return $this->gConfig->getBoolean('sign.enable');
-		return FALSE;
-	}
-	
-	
-	public function getSigningInfo() {
-		if ($this->aConfig->hasValue('sign.privatekey')) {
-			return array(
-				'privatekey' => $this->aConfig->getString('sign.privatekey'),
-				'privatekey_pass' => $this->aConfig->getString('sign.privatekey_pass', NULL),
-				'certificate' => $this->aConfig->getString('sign.certificate'),
-				'id' => 'ID'
-			);
-		}
-		
-		return array(
-			'privatekey' => $this->gConfig->getString('sign.privatekey'),
-			'privatekey_pass' => $this->gConfig->getString('sign.privatekey_pass', NULL),
-			'certificate' => $this->gConfig->getString('sign.certificate'),
-			'id' => 'ID'
-		);
-	}
-	
-
-	
-	public function getMetadataDocument() {
-
-		// Get metadata entries
-		$entities = $this->getSources();
-		$maxDuration = $this->getMaxDuration();
-		$reconstruct = $this->getReconstruct();
-
-		$entitiesDescriptor = new SAML2_XML_md_EntitiesDescriptor();
-		$entitiesDescriptor->Name = $this->id;
-		$entitiesDescriptor->validUntil = time() + $maxDuration;
-
-		// add RegistrationInfo extension if enabled
-		if ($this->gConfig->hasValue('RegistrationInfo')) {
-			$ri = new SAML2_XML_mdrpi_RegistrationInfo();
-			foreach ($this->gConfig->getArray('RegistrationInfo') as $riName => $riValues) {
-				switch ($riName) {
-					case 'authority':
-						$ri->registrationAuthority = $riValues;
-						break;
-					case 'instant':
-						$ri->registrationInstant = SAML2_Utils::xsDateTimeToTimestamp($riValues);
-						break;
-					case 'policies':
-						$ri->RegistrationPolicy = $riValues;
-						break;
-				}
-			}
-			$entitiesDescriptor->Extensions[] = $ri;
-		}
-
-		/* Build EntityDescriptor elements for them. */
-		foreach ($entities as $entity => $sets) {
-
-			$entityDescriptor = NULL;
-			foreach ($sets as $set => $metadata) {
-				if (!array_key_exists('entityDescriptor', $metadata)) {
-					/* One of the sets doesn't contain an EntityDescriptor element. */
-					$entityDescriptor = FALSE;
-					break;
-				}
-
-				if ($entityDescriptor == NULL) {
-					/* First EntityDescriptor elements. */
-					$entityDescriptor = $metadata['entityDescriptor'];
-					continue;
-				}
-
-				assert('is_string($entityDescriptor)');
-				if ($entityDescriptor !== $metadata['entityDescriptor']) {
-					/* Entity contains multiple different EntityDescriptor elements. */
-					$entityDescriptor = FALSE;
-					break;
-				}
-			}
-
-			if (is_string($entityDescriptor) && !$reconstruct) {
-				/* All metadata sets for the entity contain the same entity descriptor. Use that one. */
-				$tmp = new DOMDocument();
-				$tmp->loadXML(base64_decode($entityDescriptor));
-				$entitiesDescriptor->children[] = new SAML2_XML_md_EntityDescriptor($tmp->documentElement);
-			} else {
-				
-				$tmp = new SimpleSAML_Metadata_SAMLBuilder($entity, $maxDuration, $maxDuration);
-
-				$orgmeta = NULL;
-				foreach ($sets as $set => $metadata) {
-					$tmp->addMetadata($set, $metadata);
-					$orgmeta = $metadata;
-				}
-				$tmp->addOrganizationInfo($orgmeta);
-				$entitiesDescriptor->children[] = new SAML2_XML_md_EntityDescriptor($tmp->getEntityDescriptor());
-			}
-		}
-		
-		$document = $entitiesDescriptor->toXML();
-		
-		// sign the metadata if enabled
-		if ($this->shouldSign()) {
-			$signer = new SimpleSAML_XML_Signer($this->getSigningInfo());
-			$signer->sign($document, $document, $document->firstChild);
-		}
-		
-		return $document;
-	}
-	
-
-}
diff --git a/modules/aggregator/templates/list.php b/modules/aggregator/templates/list.php
deleted file mode 100644
index 47362c2c20fbcfecb5de839a7654bff748093bc6..0000000000000000000000000000000000000000
--- a/modules/aggregator/templates/list.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-$this->data['header'] = $this->t('{aggregator:aggregator:aggregator_header}');
-$this->includeAtTemplateBase('includes/header.php');
-
-echo('<h1>'. $this->data['header'] . '</h1>');
-
-if (count($this->data['sources']) === 0) {
-	echo('<p>' . $this->t('{aggregator:aggregator:no_aggregators}') . '</p>');
-} else {
-
-	echo('<ul>');
-
-	foreach ($this->data['sources'] as $source) {
-		$encId = urlencode($source);
-		$encName = htmlspecialchars($source);
-		echo('<li>');
-		echo('<a href="?id=' . $encId . '">' . $encName . '</a>');
-		echo(' <a href="?id=' . $encId . '&amp;mimetype=text/plain">[' . $this->t('{aggregator:aggregator:text}') . ']</a>');
-		echo(' <a href="?id=' . $encId . '&amp;mimetype=application/xml">[xml]</a>');
-		echo('</li>');
-	}
-
-	echo('</ul>');
-}
-
-$this->includeAtTemplateBase('includes/footer.php');
diff --git a/modules/aggregator/www/arp.php b/modules/aggregator/www/arp.php
deleted file mode 100644
index 3c05d225e8f708609c28e1497d728c2c9c9948b0..0000000000000000000000000000000000000000
--- a/modules/aggregator/www/arp.php
+++ /dev/null
@@ -1,86 +0,0 @@
-<?php
-
-$config = SimpleSAML_Configuration::getInstance();
-$gConfig = SimpleSAML_Configuration::getConfig('module_aggregator.php');
-
-
-// Get list of aggregators
-$aggregators = $gConfig->getConfigItem('aggregators');
-
-// If aggregator ID is not provided, show the list of available aggregates
-if (!array_key_exists('id', $_GET)) {
-	$t = new SimpleSAML_XHTML_Template($config, 'aggregator:list.php');
-	$t->data['sources'] = $aggregators->getOptions();
-	$t->show();
-	exit;
-}
-$id = $_GET['id'];
-if (!in_array($id, $aggregators->getOptions()))
-	throw new SimpleSAML_Error_NotFound('No aggregator with id ' . var_export($id, TRUE) . ' found.');
-
-$aConfig = $aggregators->getConfigItem($id);
-
-
-$aggregator = new sspmod_aggregator_Aggregator($gConfig, $aConfig, $id);
-
-if (isset($_REQUEST['set']))
-	$aggregator->limitSets($_REQUEST['set']);
-
-if (isset($_REQUEST['exclude']))
-	$aggregator->exclude($_REQUEST['exclude']);
-
-
-$md = $aggregator->getSources();
-
-
-$attributemap = NULL;
-if (isset($_REQUEST['attributemap'])) $attributemap = $_REQUEST['attributemap'];
-$prefix = '';
-if (isset($_REQUEST['prefix'])) $prefix = $_REQUEST['prefix'];
-$suffix = '';
-if (isset($_REQUEST['suffix'])) $suffix = $_REQUEST['suffix'];
-
-/* Make sure that the request isn't suspicious (contains references to current
- * directory or parent directory or anything like that. Searching for './' in the
- * URL will detect both '../' and './'. Searching for '\' will detect attempts to
- * use Windows-style paths.
- */
-if (strpos($attributemap, '\\') !== FALSE) {
-	throw new SimpleSAML_Error_BadRequest('Requested URL contained a backslash.');
-} elseif (strpos($attributemap, './') !== FALSE) {
-	throw new SimpleSAML_Error_BadRequest('Requested URL contained \'./\'.');
-}
-
-$arp = new sspmod_aggregator_ARP($md, $attributemap, $prefix, $suffix);
-
-$arpxml = $arp->getXML();
-
-$xml = new DOMDocument();
-$xml->loadXML($arpxml);
-
-$firstelement = $xml->firstChild;
-
-if ($aggregator->shouldSign()) {
-	$signinfo = $aggregator->getSigningInfo();
-	$signer = new SimpleSAML_XML_Signer($signinfo);
-	$signer->sign($firstelement, $firstelement, $firstelement->firstChild);
-}
-
-$mimetype = 'application/samlmetadata-xml';
-$allowedmimetypes = array(
-    'text/plain',
-    'application/samlmetadata-xml',
-    'application/xml',
-);
-
-if (isset($_GET['mimetype']) && in_array($_GET['mimetype'], $allowedmimetypes)) {
-    $mimetype = $_GET['mimetype'];
-}
-
-if ($mimetype === 'text/plain') {
-    SimpleSAML_Utilities::formatDOMElement($xml->documentElement);
-}
-
-header('Content-Type: ' . $mimetype);
-
-echo($xml->saveXML());
diff --git a/modules/aggregator/www/index.php b/modules/aggregator/www/index.php
deleted file mode 100644
index 1b1049ab1e591613d26898f3d5d5a22ad6669cc1..0000000000000000000000000000000000000000
--- a/modules/aggregator/www/index.php
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-
-$config = SimpleSAML_Configuration::getInstance();
-$gConfig = SimpleSAML_Configuration::getConfig('module_aggregator.php');
-
-
-// Get list of aggregators
-$aggregators = $gConfig->getConfigItem('aggregators');
-
-// If aggregator ID is not provided, show the list of available aggregates
-if (!array_key_exists('id', $_GET)) {
-	$t = new SimpleSAML_XHTML_Template($config, 'aggregator:list.php');
-	$t->data['sources'] = $aggregators->getOptions();
-	$t->show();
-	exit;
-}
-$id = $_GET['id'];
-if (!in_array($id, $aggregators->getOptions()))
-	throw new SimpleSAML_Error_NotFound('No aggregator with id ' . var_export($id, TRUE) . ' found.');
-
-$aConfig = $aggregators->getConfigItem($id);
-
-
-$aggregator = new sspmod_aggregator_Aggregator($gConfig, $aConfig, $id);
-
-if (isset($_REQUEST['set']))
-	$aggregator->limitSets($_REQUEST['set']);
-
-if (isset($_REQUEST['exclude'])) 
-	$aggregator->exclude($_REQUEST['exclude']);
-
-
-$xml = $aggregator->getMetadataDocument();
-
-$mimetype = 'application/samlmetadata+xml';
-$allowedmimetypes = array(
-    'text/plain',
-    'application/samlmetadata-xml',
-    'application/xml',
-);
-
-if (isset($_GET['mimetype']) && in_array($_GET['mimetype'], $allowedmimetypes)) {
-    $mimetype = $_GET['mimetype'];
-}
-
-if ($mimetype === 'text/plain') {
-    SimpleSAML_Utilities::formatDOMElement($xml);
-}
-
-$metadata = '<?xml version="1.0"?>'."\n".$xml->ownerDocument->saveXML($xml);
-
-header('Content-Type: ' . $mimetype);
-header('Content-Length: ' . strlen($metadata));
-
-echo $metadata;
diff --git a/modules/aggregator2/bin/update.php b/modules/aggregator2/bin/update.php
deleted file mode 100755
index 790f4fd99fc525ac65f6f886a010e39e66536d32..0000000000000000000000000000000000000000
--- a/modules/aggregator2/bin/update.php
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env php
-<?php
-
-require_once(dirname(dirname(dirname(dirname(__FILE__)))) . '/lib/_autoload.php');
-
-$name = basename($argv[0]);
-
-if ($argc < 2) {
-	fprintf(STDERR, "$name: Missing id of aggregator.\n");
-	exit(1);
-}
-
-$id = $argv[1];
-
-$aggregator = sspmod_aggregator2_Aggregator::getAggregator($id);
-$aggregator->updateCache();
diff --git a/modules/aggregator2/config-templates/module_aggregator2.php b/modules/aggregator2/config-templates/module_aggregator2.php
deleted file mode 100644
index da6aae3b295d878397b48ef9ab080fd69dc12021..0000000000000000000000000000000000000000
--- a/modules/aggregator2/config-templates/module_aggregator2.php
+++ /dev/null
@@ -1,113 +0,0 @@
-<?php
-
-/* This is the configuration file for the aggregator2-module. */
-$config = array(
-
-	/*
-	 * 'example' will be one set of aggregated metadata.
-	 * The aggregated metadata can be retrieved from:
-	 *   https://.../simplesaml/module.php/aggregator2/get.php?id=example
-	 */
-	'example' => array(
-
-		/* 'sources' is an array with the places we want to fetch metadata from. */
-		'sources' => array(
-			/* Metadata validated by the https-certificate of the server. */
-			array(
-				/* The URL we should fetch the metadata from. */
-				'url' => 'https://sp.example.org/metadata.xml',
-
-				/*
-				 * To enable validation of the https-certificate, we must
-				 * specify a file with valid CA certificates.
-				 *
-				 * This can be an absolute path, or a path relative to the
-				 * cert-directory.
-				 */
-				'ssl.cafile' => '/etc/ssl/certs/ca-certificates.crt',
-			),
-
-			/* Metadata validated by its signature. */
-			array(
-				/* The URL we should fetch the metadata from. */
-				'url' => 'http://idp.example.org/metadata.xml',
-
-				/*
-				 * To verify the signature in the metadata, we must specify
-				 * a certificate that should be used. Note: This cannot
-				 * be a CA certificate.
-				 *
-				 * This can be an absolute path, or a path relative to the
-				 * cert-directory.
-				 */
-				'cert' => 'idp.example.org.crt',
-			),
-
-			/* Metadata from a file. */
-			array(
-				'url' => '/var/simplesaml/somemetadata.xml',
-			),
-
-		),
-
-		/*
-		 * Update this metadata during this cron tag.
-		 *
-		 * For this option to work, you must configure the cron-module,
-		 * and also add a cache directory.
-		 *
-		 * This option is optional. If cron is not configured, the metadata
-		 * caches will be updated when receiving requests for metadata.
-		 */
-		'cron.tag' => 'hourly',
-
-		/*
-		 * The directory we will store downloaded and generated metadata.
-		 * This directory must be writeable by the web-server.
-		 *
-		 * This option is optional, but if unspecified, every request for the
-		 * aggregated metadata will result in the aggregator fetching and
-		 * parsing all metadata sources.
-		 */
-		'cache.directory' => '/var/cache/simplesaml-aggregator2',
-
-		/*
-		 * This is the number of seconds we will cache the metadata file we generate.
-		 * This should be a longer time than the interval between each time the cron
-		 * job is executed.
-		 *
-		 * This option is optional. If unspecified, the metadata will be generated
-		 * on every request.
-		 */
-		'cache.generated' => 24*60*60,
-
-		/*
-		 * The generated metadata will have a validUntil set to the time it is generated
-		 * plus this number of seconds.
-		 */
-		'valid.length' => 7*24*60*60,
-
-		/*
-		 * The private key we should use to sign the metadata, in pem-format.
-		 *
-		 * This is optional. If it is not specified, the metadata will not be signed.
-		 */
-		'sign.privatekey' => 'metadata.pem',
-
-		/*
-		 * The password for the private key.
-		 *
-		 * Optional, the private key is assumed to be unencrypted if this option
-		 * isn't set.
-		 */
-		'sign.privatekey_pass' => 'secret',
-
-		/*
-		 * The certificate that corresponds to the private key.
-		 *
-		 * If specified, the certificate will be included in the signature in the metadata.
-		 */
-		'sign.certificate' => 'metadata.crt',
-	),
-
-);
diff --git a/modules/aggregator2/default-disable b/modules/aggregator2/default-disable
deleted file mode 100644
index fa0bd82e2df7bd79d57593d35bc53c1f9d3ef71f..0000000000000000000000000000000000000000
--- a/modules/aggregator2/default-disable
+++ /dev/null
@@ -1,3 +0,0 @@
-This file indicates that the default state of this module
-is disabled. To enable, create a file named enable in the
-same directory as this file.
diff --git a/modules/aggregator2/dictionaries/aggregator.definition.json b/modules/aggregator2/dictionaries/aggregator.definition.json
deleted file mode 100644
index 66b9b9804b72b51ea87effb7cbba6463287652f3..0000000000000000000000000000000000000000
--- a/modules/aggregator2/dictionaries/aggregator.definition.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-	"frontpage_link": {
-		"en": "Metadata aggregator"
-	},
-	"header": {
-		"en": "Aggregators"
-	},
-	"no_aggregators": {
-		"en": "No aggregators defined in configuration."
-	},
-	"text": {
-		"en": "text"
-	}
-}
\ No newline at end of file
diff --git a/modules/aggregator2/dictionaries/aggregator.translation.json b/modules/aggregator2/dictionaries/aggregator.translation.json
deleted file mode 100644
index 0caa19b5ce4218fee9addf859137f0cd85ac0157..0000000000000000000000000000000000000000
--- a/modules/aggregator2/dictionaries/aggregator.translation.json
+++ /dev/null
@@ -1,114 +0,0 @@
-{
-	"frontpage_link": {
-		"no": "Metadata aggregator",
-		"de": "Metadaten-Aggregator",
-		"sl": "Agregator metapodatkov",
-		"pt": "Agregador de Metadados",
-		"sv": "Metadatasammanst\u00e4llare",
-		"hr": "Agregator metapodataka",
-		"da": "Metadata aggregator",
-		"fr": "Agr\u00e9gateur de m\u00e9tadonn\u00e9es",
-		"nn": "Oppsamling av metadata",
-		"it": "Aggregatore dei metadati",
-		"es": "Agregador de metadatos",
-		"lt": "Metaduomen\u0173 surink\u0117jas",
-		"nl": "Metadata-aggregator",
-		"ja": "\u30e1\u30bf\u30c7\u30fc\u30bf \u30a2\u30b0\u30ea\u30b1\u30fc\u30bf",
-		"zh-tw": "\u8a6e\u91cb\u8cc7\u6599\u532f\u96c6",
-		"et": "Metaandmete agregeerija",
-		"he": "\u05e9\u05d5\u05dc\u05e3 \u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2 ",
-		"ru": "\u0410\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0440 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445",
-		"zh": "\u5143\u4fe1\u606f\u805a\u5408\u5668",
-		"ar": " \u0645\u062c\u0645\u0639 \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0644\u0648\u0635\u0641\u064a\u0629\/ \u0627\u0644\u0645\u064a\u062a\u0627\u062f\u0627\u062a\u0627",
-		"lv": "Metadatu agregators",
-		"id": "Aggregator metadata",
-		"sr": "Agregator metapodataka",
-		"ro": "Agregator de metadate",
-		"cs": "Metadata agreg\u00e1tor",
-		"eu": "Metadatu eranslea"
-	},
-	"header": {
-		"no": "Aggregatorer",
-		"de": "Aggregatoren",
-		"sl": "Agregatorji",
-		"pt": "Agregadores",
-		"sv": "Sammanst\u00e4llare",
-		"hr": "Agregatori",
-		"da": "Aggregatorer",
-		"fr": "Agr\u00e9gateurs",
-		"nn": "Aggregering",
-		"it": "Aggregatori",
-		"es": "Agregadores",
-		"lt": "Surink\u0117jai",
-		"nl": "Aggregatoren",
-		"ja": "\u30a2\u30b0\u30ea\u30b1\u30fc\u30bf",
-		"zh-tw": "\u532f\u96c6",
-		"et": "Agregeerijad",
-		"he": "\u05e9\u05d5\u05dc\u05e4\u05d9 \u05de\u05d9\u05d3\u05e2",
-		"ru": "\u0410\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0440\u044b",
-		"zh": "\u805a\u5408\u5668",
-		"ar": "\u0645\u062c\u0645\u0639\u0627\u062a",
-		"lv": "Agregatori",
-		"id": "Aggregator",
-		"sr": "Agregatori",
-		"ro": "Agregatoare",
-		"cs": "Agreg\u00e1tory",
-		"eu": "Eransleak"
-	},
-	"no_aggregators": {
-		"no": "Ingen aggregator definert i konfigurasjonen",
-		"de": "Keine Aggregatoren in der Konfiguration definiert.",
-		"sl": "V nastavitvah ni definiran noben agregator.",
-		"pt": "N\u00e3o foram definidos agregadores na configura\u00e7\u00e3o.",
-		"sv": "Inga sammanst\u00e4llare (aggregators) definierade i konfigurationen.",
-		"hr": "U konfiguraciji nije definiran niti jedan agregator.",
-		"da": "Ingen aggregator defineret i konfigurationen",
-		"fr": "Aucun agr\u00e9gateur n'a \u00e9t\u00e9 d\u00e9fini dans la configuration.",
-		"nn": "Aggregrering er ikkje definert i konfigurasjonen.",
-		"it": "Non ci sono aggregatori definiti nella configurazione.",
-		"es": "No ha sido definido ning\u00fan agregador en la configuraci\u00f3n.",
-		"lt": "Konfig\u016bracijoje nenurodyti jokie surink\u0117jai.",
-		"nl": "Geen aggregator gedefinieerd in de configuratie.",
-		"ja": "\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306b\u30a2\u30b0\u30ea\u30b1\u30fc\u30bf\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3002",
-		"zh-tw": "\u8a2d\u5b9a\u6a94\u7121\u532f\u96c6\u5b9a\u7fa9",
-		"et": "Seadistustes pole agregeerijaid kirjeldatud.",
-		"he": "\u05dc\u05d0 \u05de\u05d5\u05d2\u05d3\u05e8\u05d9\u05dd \u05e9\u05d5\u05dc\u05e4\u05d9 \u05de\u05d9\u05d3\u05e2.",
-		"ru": "\u0412 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0440\u044b.",
-		"zh": "\u914d\u7f6e\u4e2d\u6ca1\u6709\u5b9a\u4e49\u805a\u5408\u5668",
-		"ar": "\u0644\u0645 \u064a\u062a\u0645 \u062a\u062d\u062f\u064a\u062f \u0627\u0644\u0645\u062c\u0645\u0639\u0627\u062a \u0628\u0627\u0644\u0643\u0648\u0646\u0641\u064a\u063a\u0631\u0627\u0634\u0646",
-		"lv": "Konfigur\u0101cij\u0101 nav defin\u0113ti agregatori.",
-		"id": "Tidak ada aggregator yang didefinisikan di konfigurasi",
-		"sr": "U pode\u0161avanjima nije definisan nijedan agregator.",
-		"ro": "Nu sunt definite agregatoare \u00een configurare.",
-		"cs": "\u017d\u00e1dn\u00e9 agreg\u00e1tory nejsou definov\u00e1ny v konfiguraci.",
-		"eu": "Ez da inolako eranslerik zehaztu konfigurazioan. "
-	},
-	"text": {
-		"no": "tekst",
-		"de": "Text",
-		"sl": "Besedilo",
-		"pt": "Texto",
-		"sv": "Text",
-		"hr": "tekst",
-		"da": "tekst",
-		"fr": "texte",
-		"nn": "Tekst",
-		"it": "testo",
-		"es": "texto",
-		"lt": "Tekstas",
-		"nl": "tekst",
-		"ja": "\u30c6\u30ad\u30b9\u30c8",
-		"zh-tw": "\u6587\u5b57",
-		"et": "tekst",
-		"he": "\u05d8\u05e7\u05d8\u05e1",
-		"ru": "\u0442\u0435\u043a\u0441\u0442",
-		"zh": "\u6587\u672c",
-		"ar": "\u0646\u0635",
-		"lv": "teksts",
-		"id": "teks",
-		"sr": "tekst",
-		"ro": "text",
-		"cs": "text",
-		"eu": "testua"
-	}
-}
diff --git a/modules/aggregator2/docs/aggregator2.txt b/modules/aggregator2/docs/aggregator2.txt
deleted file mode 100644
index 281b87c4a8c4e3ec97d73f9271c2b72c75ee9cf4..0000000000000000000000000000000000000000
--- a/modules/aggregator2/docs/aggregator2.txt
+++ /dev/null
@@ -1,170 +0,0 @@
-aggregator2 Module
-==================
-
-This is a module for metadata aggregation. It is designed to preserve most of the common metadata items, and it also
-attempts to preserve unknown elements. Metadata sources are parsed and rebuilt, so small differences between the
-original sources and the metadata generated may occur. More specifically:
-
-* Signatures will be removed from every signed metadata source.
-* All sources will be wrapped up in an `EntitiesDescriptor` element.
-
-*Note*: This aggregator works only with XML metadata, and does its work independently of other parts of SimpleSAMLphp,
-such as the `metarefresh` module.
-
-
-Configuration
--------------
-
-This module is configured through the `config/module_aggregator2.php` configuration file.
-An example file is available in `modules/aggregator2/config-templates/`:
-
-    cp modules/aggregator2/config-templates/module_aggregator2.php config/
-
-The configuration file contains one or more aggregators in the configuration array.
-The index for each item in the configuration array gives the identifier of the aggregator.
-
-
-### Aggregator entry configuration
-
-The aggregator can be configured with the following options:
-
-`sources`
-:   Array which describes a source from which we should download metadata.
-
-`cron.tag`
-:   Can be used to run periodical updates. It will only be useful when you have metadata caching enabled.
-
-`cache.directory`
-:   The path to a directory where the aggregator will cache downloaded and generated metadata.
-    This directory must be writable by the web server.
-
-`cache.generated`
-:   The number of seconds the generated metadata will be cached for.
-
-:    *Note*: generated metadata will not be cached if this option is unset.
-
-`valid.length`
-:   The number of seconds the generated metadata should be valid for.
-    This is used to set the `validUntil` attribute on the generated metadata.
-    Defaults to one week..
-
-:   *Note*: The value of the `cache.generated` option must be smaller than the value here, otherwise you would end up
-    returning outdated metadata.
-
-`ssl.cafile`
-:   This option enables validation of the server certificate when fetching metadata over HTTPS. It must be a path
-    pointing to a PEM file which contains one or more valid CA certificates. The path can be either absolute or
-    relative to the `cert` directory.
-
-:   *Note*: This option can be overridden for each metadata source.
-
-`sign.privatekey`
-:   The private key that should be used to sign the resulting metadata, in PEM format. The path to the private key can
-    be either absolute or relative to the `cert` directory. Skip this option or set it to `NULL` if you don't want to
-    sign the generated metadata.
-
-`sign.privatekey_pass`
-:   The password used to encrypt the private key. If this option is unset, the private key is assumed to be unencrypted.
-
-`sign.certificate`
-:   The certificate that contains the public key corresponding to the private key, in PEM format. The path to the
-    certificate can be either absolute or relative to the `cert` directory.
-
-:   *Note*: This certificate will be included in the generated metadata.
-
-`RegistrationInfo`
-:   Allows to specify information about the registrar of the generated metadata. Please refer to the
-    [MDRPI extension](./simplesamlphp-metadata-extensions-rpi) document for further information.
-
-`exclude`
-:   Allows to exclude one or more entities from the generated metadata, represented by their entity IDs. Can be either
-    a string with the entity ID of a single entity, or an array of strings with all the entity IDs to exclude from
-    the result.
-
-:   *Note*: this option will not exclude the entities from the cached metadata sources. It will only act as a default
-    configuration for the generation of the metadata aggregate, and therefore can be overridden per request.
-
-`filter`
-:   One or more sets representing the types of entities that should be included in the generated metadata. Filtering
-    will be performed depending on the role of the entity, as well as the protocols it supports. Can be either a string
-    with the set of entities desired, or an array of strings with all the different sets to filter by. The following
-    sets are available:
-
-: * `saml2`: all the entities that support the SAML 2.0 protocol.
-
-: * `shib13`: all the entities that support the SAML 1.1 protocol.
-
-: * `saml20-idp`: all the identity providers that support the SAML 2.0 protocol.
-
-: * `saml20-sp`: all the service providers that support the SAML 2.0 protocol.
-
-: * `saml20-aa`: all the attribute authorities that support the SAML 2.0 protocol.
-
-: * `shib13-idp`: all the identity providers that support the SAML 1.1 protocol.
-
-: * `shib13-sp`: all the service providers that support the SAML 1.1 protocol.
-
-: * `shib13-aa`: all the attribute authorities that support the SAML 1.1 protocol.
-
-:   *Note*: this option will not filter the entities in the cached metadata sources. It will only act as a default
-    configuration for the generation of the metadata aggregate, and therefore can be overriden per request.
-
-
-### Aggregator source configuration
-
-`url`
-:   The URL the metadata should be fetched from.
-
-`ssl.cafile`
-:   This option enables validation of the server certificate when fetching metadata over HTTPS. It must be a path
-    pointing to a PEM file which contains one or more valid CA certificates. The path can be either absolute or
-    relative to the `cert` directory.
-
-:   *Note*: This option overrides the option with the same name in the root configuration for the an aggregator.
-
-`cert`
-:   The certificate that should be used to check the signature of this metadata document, in PEM format. The path to
-    the certificate can be either absolute or relative to the `cert` directory.
-
-:   *Note*: This cannot be a CA certificate. Validation against CA certificates (PKI) is not supported.
-
-
-Retrieving aggregated metadata
-------------------------------
-
-You will find a link to the aggregator2 module in the *Federation* tab of SimpleSAMLphp's web interface. There you will
-be able to see a list of all the metadata aggregates you have configured, and see or download them in different
-formats.
-
-In general, metadata aggregates can be downloaded from the following location:
-
-    http://<YOUR HOST>/simplesaml/modules.php/aggregator2/get.php?id=<aggregator id>
-
-where the *aggregator id* is the identifier you used as an index for the aggregator configuration array. Additionally,
-you can use the following parameters to customize the resulting metadata aggregate:
-
-`exclude`
-:   Allows to exclude one or more entities from the generated metadata, represented by their entity IDs. If you need to
-    specify more than one entity, use a comma-separated list of entity IDs.
-
-`filter`
-:   Allows to filter by sets specifying the type of entities or the protocols they support. If you need to specify more
-    than one set, use a comma-separated list. See the configuration option with the same name to get a list of all
-    the sets supported.
-
-
-Asynchronous metadata updates
------------------------------
-
-By default, the `aggregator2` module will update the metadata upon receiving a request. For performance reasons, it is
-recommended to run the updates asynchronously. By doing this, the aggregated metadata will be generated in the
-background.
-
-To enable this, you must configure a cache directory with the `cache.directory` option. This directory must be writable
-by the web server. You can then enable caching of generated metadata by setting the `cache.generated` option to the
-number of seconds the metadata should be cached.
-
-You will now have a configuration that caches both downloaded and generated metadata. However, it will still update the
-metadata when the user accesses the aggregator endpoint. To update the generated metadata in the background, you must
-add a `cron.tag` option. This option must reference a cron tag entry configured in `module_cron.php`. Once this is
-done, your aggregated metadata will be updated every time that cron entry is executed.
diff --git a/modules/aggregator2/hooks/hook_cron.php b/modules/aggregator2/hooks/hook_cron.php
deleted file mode 100644
index c052b43e22829b4326cf0e530d0d53292101bc62..0000000000000000000000000000000000000000
--- a/modules/aggregator2/hooks/hook_cron.php
+++ /dev/null
@@ -1,33 +0,0 @@
-<?php
-
-/**
- * cron hook to update aggregator2 metadata.
- *
- * @param array &$croninfo  Output
- */
-function aggregator2_hook_cron(&$croninfo) {
-	assert('is_array($croninfo)');
-	assert('array_key_exists("summary", $croninfo)');
-	assert('array_key_exists("tag", $croninfo)');
-
-	$cronTag = $croninfo['tag'];
-
-	$config = SimpleSAML_Configuration::getConfig('module_aggregator2.php');
-	$config = $config->toArray();
-
-	foreach ($config as $id => $c) {
-		if (!isset($c['cron.tag'])) {
-			continue;
-		}
-		if ($c['cron.tag'] !== $cronTag) {
-			continue;
-		}
-
-		try {
-			$a = sspmod_aggregator2_Aggregator::getAggregator($id);
-			$a->updateCache();
-		} catch (Exception $e) {
-			$croninfo['summary'][] = 'Error during aggregator2 cacheupdate: ' . $e->getMessage();
-		}
-	}
-}
diff --git a/modules/aggregator2/hooks/hook_frontpage.php b/modules/aggregator2/hooks/hook_frontpage.php
deleted file mode 100644
index a0eedf5ddb45975221fb49973ddec6a0c2c1b228..0000000000000000000000000000000000000000
--- a/modules/aggregator2/hooks/hook_frontpage.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-/**
- * Hook to add the aggregator2 lik to the frontpage.
- *
- * @param array &$links The links on the frontpage, split into sections.
- */
-function aggregator2_hook_frontpage(&$links) {
-    assert('is_array($links)');
-    assert('array_key_exists("links", $links)');
-
-    $links['federation'][] = array(
-        'href' => SimpleSAML_Module::getModuleURL('aggregator2/'),
-        'text' => '{aggregator2:aggregator:frontpage_link}',
-    );
-
-}
diff --git a/modules/aggregator2/lib/Aggregator.php b/modules/aggregator2/lib/Aggregator.php
deleted file mode 100644
index 2806980f4bf2787252edcced2e134577432e7b0d..0000000000000000000000000000000000000000
--- a/modules/aggregator2/lib/Aggregator.php
+++ /dev/null
@@ -1,680 +0,0 @@
-<?php
-
-/**
- * Class which implements a basic metadata aggregator.
- *
- * @package SimpleSAMLphp
- */
-class sspmod_aggregator2_Aggregator {
-
-	/**
-	 * The ID of this aggregator.
-	 *
-	 * @var string
-	 */
-	protected $id;
-
-
-	/**
-	 * Our log "location".
-	 *
-	 * @var string
-	 */
-	protected $logLoc;
-
-
-	/**
-	 * Which cron-tag this should be updated in.
-	 *
-	 * @var string|NULL
-	 */
-	protected $cronTag;
-
-
-	/**
-	 * Absolute path to a cache directory.
-	 *
-	 * @var string|NULL
-	 */
-	protected $cacheDirectory;
-
-
-	/**
-	 * The entity sources.
-	 *
-	 * Array of sspmod_aggregator2_EntitySource objects.
-	 *
-	 * @var array
-	 */
-	protected $sources = array();
-
-
-	/**
-	 * How long the generated metadata should be valid, as a number of seconds.
-	 *
-	 * This is used to set the validUntil attribute on the generated EntityDescriptor.
-	 *
-	 * @var int
-	 */
-	protected $validLength;
-
-
-	/**
-	 * Duration we should cache generated metadata.
-	 *
-	 * @var int
-	 */
-	protected $cacheGenerated;
-
-
-    /**
-     * An array of entity IDs to exclude from the aggregate.
-     *
-     * @var string[]|null
-     */
-    protected $excluded;
-
-
-    /**
-     * An indexed array of protocols to filter the aggregate by. keys can be any of:
-     *
-     * - urn:oasis:names:tc:SAML:1.1:protocol
-     * - urn:oasis:names:tc:SAML:2.0:protocol
-     *
-     * Values will be true if enabled, false otherwise.
-     *
-     * @var string[]|null
-     */
-    protected $protocols;
-
-
-    /**
-     * An array of roles to filter the aggregate by. Keys can be any of:
-     *
-     * - SAML2_XML_md_IDPSSODescriptor
-     * - SAML2_XML_md_SPSSODescriptor
-     * - SAML2_XML_md_AttributeAuthorityDescriptor
-     *
-     * Values will be true if enabled, false otherwise.
-     *
-     * @var string[]|null
-     */
-    protected $roles;
-
-
-	/**
-	 * The key we should use to sign the metadata.
-	 *
-	 * @var string|NULL
-	 */
-	protected $signKey;
-
-
-	/**
-	 * The password for the private key.
-	 *
-	 * @var string|NULL
-	 */
-	protected $signKeyPass;
-
-
-	/**
-	 * The certificate of the key we sign the metadata with.
-	 *
-	 * @var string|NULL
-	 */
-	protected $signCert;
-
-
-	/**
-	 * The CA certificate file that should be used to validate https-connections.
-	 *
-	 * @var string|NULL
-	 */
-	protected $sslCAFile;
-
-
-	/**
-	 * The cache ID for our generated metadata.
-	 *
-	 * @var string
-	 */
-	protected $cacheId;
-
-
-	/**
-	 * The cache tag for our generated metadata.
-	 *
-	 * This tag is used to make sure that a config change
-	 * invalidates our cached metadata.
-	 *
-	 * @var string
-	 */
-	protected $cacheTag;
-
-
-	/**
-	 * The registration information for our generated metadata.
-	 *
-	 * @var array
-	 */
-	protected $regInfo;
-
-
-	/**
-	 * Initialize this aggregator.
-	 *
-	 * @param string $id  The id of this aggregator.
-	 * @param SimpleSAML_Configuration $config  The configuration for this aggregator.
-	 */
-	protected function __construct($id, SimpleSAML_Configuration $config) {
-		assert('is_string($id)');
-
-		$this->id = $id;
-		$this->logLoc = 'aggregator2:' . $this->id . ': ';
-
-		$this->cronTag = $config->getString('cron.tag', NULL);
-
-		$this->cacheDirectory = $config->getString('cache.directory', NULL);
-		if ($this->cacheDirectory !== NULL) {
-			$this->cacheDirectory = SimpleSAML_Utilities::resolvePath($this->cacheDirectory);
-		}
-
-		$this->cacheGenerated = $config->getInteger('cache.generated', NULL);
-		if ($this->cacheGenerated !== NULL) {
-			$this->cacheId = sha1($this->id);
-			$this->cacheTag = sha1(serialize($config));
-		}
-
-        // configure entity IDs excluded by default
-        $this->excludeEntities($config->getArrayize('exclude', null));
-
-        // configure filters
-        $this->setFilters($config->getArrayize('filter', null));
-
-		$this->validLength = $config->getInteger('valid.length', 7*24*60*60);
-
-		$globalConfig = SimpleSAML_Configuration::getInstance();
-		$certDir = $globalConfig->getPathValue('certdir', 'cert/');
-
-		$signKey = $config->getString('sign.privatekey', NULL);
-		if ($signKey !== NULL) {
-			$signKey = SimpleSAML_Utilities::resolvePath($signKey, $certDir);
-			$this->signKey = @file_get_contents($signKey);
-			if ($this->signKey === NULL) {
-				throw new SimpleSAML_Error_Exception('Unable to load private key from ' . var_export($signKey, TRUE));
-			}
-		}
-
-		$this->signKeyPass = $config->getString('sign.privatekey_pass', NULL);
-
-		$signCert = $config->getString('sign.certificate', NULL);
-		if ($signCert !== NULL) {
-			$signCert = SimpleSAML_Utilities::resolvePath($signCert, $certDir);
-			$this->signCert = @file_get_contents($signCert);
-			if ($this->signCert === NULL) {
-				throw new SimpleSAML_Error_Exception('Unable to load certificate file from ' . var_export($signCert, TRUE));
-			}
-		}
-
-
-		$this->sslCAFile = $config->getString('ssl.cafile', NULL);
-
-		$this->regInfo = $config->getArray('RegistrationInfo', NULL);
-
-		$this->initSources($config->getConfigList('sources'));
-	}
-
-
-	/**
-	 * Populate the sources array.
-	 *
-	 * This is called from the constructor, and can be overridden in subclasses.
-	 *
-	 * @param array $sources  The sources as an array of SimpleSAML_Configuration objects.
-	 */
-	protected function initSources(array $sources) {
-
-		foreach ($sources as $source) {
-			$this->sources[] = new sspmod_aggregator2_EntitySource($this, $source);
-		}
-	}
-
-
-	/**
-	 * Return an instance of the aggregator with the given id.
-	 *
-	 * @param string $id  The id of the aggregator.
-	 */
-	public static function getAggregator($id) {
-		assert('is_string($id)');
-
-		$config = SimpleSAML_Configuration::getConfig('module_aggregator2.php');
-		return new sspmod_aggregator2_Aggregator($id, $config->getConfigItem($id));
-	}
-
-
-	/**
-	 * Retrieve the ID of the aggregator.
-	 *
-	 * @return string  The ID of this aggregator.
-	 */
-	public function getId() {
-		return $this->id;
-	}
-
-
-	/**
-	 * Add an item to the cache.
-	 *
-	 * @param string $id  The identifier of this data.
-	 * @param string $data  The data.
-	 * @param int $expires  The timestamp the data expires.
-	 * @param string|NULL $tag  An extra tag that can be used to verify the validity of the cached data.
-	 */
-	public function addCacheItem($id, $data, $expires, $tag = NULL) {
-		assert('is_string($id)');
-		assert('is_string($data)');
-		assert('is_int($expires)');
-		assert('is_null($tag) || is_string($tag)');
-
-		$cacheFile = $this->cacheDirectory . '/' . $id;
-		try {
-			SimpleSAML_Utilities::writeFile($cacheFile, $data);
-		} catch (Exception $e) {
-			SimpleSAML_Logger::warning($this->logLoc . 'Unable to write to cache file ' . var_export($cacheFile, TRUE));
-			return;
-		}
-
-		$expireInfo = (string)$expires;
-		if ($tag !== NULL) {
-			$expireInfo .= ':' . $tag;
-		}
-
-		$expireFile = $cacheFile . '.expire';
-		try {
-			SimpleSAML_Utilities::writeFile($expireFile, $expireInfo);
-		} catch (Exception $e) {
-			SimpleSAML_Logger::warning($this->logLoc . 'Unable to write expiration info to ' . var_export($expireFile, TRUE));
-		}
-
-	}
-
-
-	/**
-	 * Check validity of cached data.
-	 *
-	 * @param string $id  The identifier of this data.
-	 * @param string $tag  The tag that was passed to addCacheItem.
-	 * @return bool  TRUE if the data is valid, FALSE if not.
-	 */
-	public function isCacheValid($id, $tag = NULL) {
-		assert('is_string($id)');
-		assert('is_null($tag) || is_string($tag)');
-
-		$cacheFile = $this->cacheDirectory . '/' . $id;
-		if (!file_exists($cacheFile)) {
-			return FALSE;
-		}
-
-		$expireFile = $cacheFile . '.expire';
-		if (!file_exists($expireFile)) {
-			return FALSE;
-		}
-
-		$expireData = @file_get_contents($expireFile);
-		if ($expireData === FALSE) {
-			return FALSE;
-		}
-
-		$expireData = explode(':', $expireData, 2);
-
-		$expireTime = (int)$expireData[0];
-		if ($expireTime <= time()) {
-			return FALSE;
-		}
-
-		if (count($expireData) === 1) {
-			$expireTag = NULL;
-		} else {
-			$expireTag = $expireData[1];
-		}
-		if ($expireTag !== $tag) {
-			return FALSE;
-		}
-
-		return TRUE;
-	}
-
-
-	/**
-	 * Get the cache item.
-	 *
-	 * @param string $id  The identifier of this data.
-	 * @param string $tag  The tag that was passed to addCacheItem.
-	 * @return string|NULL  The cache item, or NULL if it isn't cached or if it is expired.
-	 */
-	public function getCacheItem($id, $tag = NULL) {
-		assert('is_string($id)');
-		assert('is_null($tag) || is_string($tag)');
-
-		if (!$this->isCacheValid($id, $tag)) {
-			return NULL;
-		}
-
-		$cacheFile = $this->cacheDirectory . '/' . $id;
-		return @file_get_contents($cacheFile);
-	}
-
-
-	/**
-	 * Get the cache filename for the specific id.
-	 *
-	 * @param string $id  The identifier of the cached data.
-	 * @return string|NULL  The filename, or NULL if the cache file doesn't exist.
-	 */
-	public function getCacheFile($id) {
-		assert('is_string($id)');
-
-		$cacheFile = $this->cacheDirectory . '/' . $id;
-		if (!file_exists($cacheFile)) {
-			return NULL;
-		}
-
-		return $cacheFile;
-	}
-
-
-	/**
-	 * Retrieve the SSL CA file path, if it is set.
-	 *
-	 * @return string|NULL  The SSL CA file path.
-	 */
-	public function getCAFile() {
-
-		return $this->sslCAFile;
-	}
-
-
-	/**
-	 * Sign the generated EntitiesDescriptor.
-	 */
-	protected function addSignature(SAML2_SignedElement $element) {
-
-		if ($this->signKey === NULL) {
-			return;
-		}
-
-		$privateKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private'));
-		if ($this->signKeyPass !== NULL) {
-			$privateKey->passphrase = $this->signKeyPass;
-		}
-		$privateKey->loadKey($this->signKey, FALSE);
-
-
-		$element->setSignatureKey($privateKey);
-
-		if ($this->signCert !== NULL) {
-			$element->setCertificates(array($this->signCert));
-		}
-	}
-
-
-	/**
-	 * Retrieve all entities as an EntitiesDescriptor.
-	 *
-	 * @return SAML2_XML_md_EntitiesDescriptor  The entities.
-	 */
-	protected function getEntitiesDescriptor() {
-
-		$ret = new SAML2_XML_md_EntitiesDescriptor();
-
-		$now = time();
-
-		// add RegistrationInfo extension if enabled
-		if ($this->regInfo !== NULL) {
-			$ri = new SAML2_XML_mdrpi_RegistrationInfo();
-			$ri->registrationInstant = $now;
-			foreach ($this->regInfo as $riName => $riValues) {
-				switch ($riName) {
-					case 'authority':
-						$ri->registrationAuthority = $riValues;
-						break;
-					case 'instant':
-						$ri->registrationInstant = SAML2_Utils::xsDateTimeToTimestamp($riValues);
-						break;
-					case 'policies':
-						$ri->RegistrationPolicy = $riValues;
-						break;
-				}
-			}
-			$ret->Extensions[] = $ri;
-		}
-
-		foreach ($this->sources as $source) {
-			$m = $source->getMetadata();
-			if ($m === NULL) {
-				continue;
-			}
-			$ret->children[] = $m;
-		}
-
-		$ret->validUntil = $now + $this->validLength;
-
-		return $ret;
-	}
-
-
-    /**
-     * Recursively traverse the children of an EntitiesDescriptor, removing those entities listed in the $entities
-     * property. Returns the EntitiesDescriptor with the entities filtered out.
-     *
-     * @param SAML2_XML_md_EntitiesDescriptor $descriptor The EntitiesDescriptor from where to exclude entities.
-     *
-     * @return SAML2_XML_md_EntitiesDescriptor The EntitiesDescriptor with excluded entities filtered out.
-     */
-    protected function exclude(SAML2_XML_md_EntitiesDescriptor $descriptor)
-    {
-        if (empty($this->excluded)) {
-            return $descriptor;
-        }
-
-        $filtered = array();
-        foreach ($descriptor->children as $child) {
-            if ($child instanceof SAML2_XML_md_EntityDescriptor) {
-                if (in_array($child->entityID, $this->excluded)) {
-                    continue;
-                }
-                $filtered[] = $child;
-            }
-
-            if ($child instanceof SAML2_XML_md_EntitiesDescriptor) {
-                $filtered[] = $this->exclude($child);
-            }
-        }
-
-        $descriptor->children = $filtered;
-        return $descriptor;
-    }
-
-
-    /**
-     * Recursively traverse the children of an EntitiesDescriptor, keeping only those entities with the roles listed in
-     * the $roles property, and support for the protocols listed in the $protocols property. Returns the
-     * EntitiesDescriptor containing only those entities.
-     *
-     * @param SAML2_XML_md_EntitiesDescriptor $descriptor The EntitiesDescriptor to filter.
-     *
-     * @return SAML2_XML_md_EntitiesDescriptor The EntitiesDescriptor with only the entities filtered.
-     */
-    protected function filter(SAML2_XML_md_EntitiesDescriptor $descriptor)
-    {
-        if ($this->roles === null || $this->protocols === null) {
-            return $descriptor;
-        }
-
-        $enabled_roles = array_keys($this->roles, true);
-        $enabled_protos = array_keys($this->protocols, true);
-
-        $filtered = array();
-        foreach ($descriptor->children as $child) {
-            if ($child instanceof SAML2_XML_md_EntityDescriptor) {
-                foreach ($child->RoleDescriptor as $role) {
-                    if (in_array(get_class($role), $enabled_roles)) {
-                        // we found a role descriptor that is enabled by our filters, check protocols
-                        if (array_intersect($enabled_protos, $role->protocolSupportEnumeration) !== array()) {
-                            // it supports some protocol we have enabled, add it
-                            $filtered[] = $child;
-                            break;
-                        }
-                    }
-                }
-
-            }
-
-            if ($child instanceof SAML2_XML_md_EntitiesDescriptor) {
-                $filtered[] = $this->filter($child);
-            }
-        }
-
-        $descriptor->children = $filtered;
-        return $descriptor;
-    }
-
-
-    /**
-     * Set this aggregator to exclude a set of entities from the resulting aggregate.
-     *
-     * @param array|null $entities The entity IDs of the entities to exclude.
-     */
-    public function excludeEntities($entities)
-    {
-        assert('is_array($entities) || is_null($entities)');
-
-        if ($entities === null) {
-            return;
-        }
-        $this->excluded = $entities;
-        sort($this->excluded);
-        $this->cacheId = sha1($this->cacheId . serialize($this->excluded));
-    }
-
-
-    /**
-     * Set the internal filters according to one or more options:
-     *
-     * - 'saml2': all SAML2.0-capable entities.
-     * - 'shib13': all SHIB1.3-capable entities.
-     * - 'saml20-idp': all SAML2.0-capable identity providers.
-     * - 'saml20-sp': all SAML2.0-capable service providers.
-     * - 'saml20-aa': all SAML2.0-capable attribute authorities.
-     * - 'shib13-idp': all SHIB1.3-capable identity providers.
-     * - 'shib13-sp': all SHIB1.3-capable service providers.
-     * - 'shib13-aa': all SHIB1.3-capable attribute authorities.
-     *
-     * @param array|null $set An array of the different roles and protocols to filter by.
-     */
-    public function setFilters($set)
-    {
-        assert('is_array($set) || is_null($set)');
-
-        if ($set === null) {
-            return;
-        }
-
-        // configure filters
-        $this->protocols = array(
-            SAML2_Const::NS_SAMLP                  => TRUE,
-            'urn:oasis:names:tc:SAML:1.1:protocol' => TRUE,
-        );
-        $this->roles = array(
-            'SAML2_XML_md_IDPSSODescriptor'             => TRUE,
-            'SAML2_XML_md_SPSSODescriptor'              => TRUE,
-            'SAML2_XML_md_AttributeAuthorityDescriptor' => TRUE,
-        );
-
-        // now translate from the options we have, to specific protocols and roles
-
-        // check SAML 2.0 protocol
-        $options = array('saml2', 'saml20-idp', 'saml20-sp', 'saml20-aa');
-        $this->protocols[SAML2_Const::NS_SAMLP] = (array_intersect($set, $options) !== array());
-
-        // check SHIB 1.3 protocol
-        $options = array('shib13', 'shib13-idp', 'shib13-sp', 'shib13-aa');
-        $this->protocols['urn:oasis:names:tc:SAML:1.1:protocol'] = (array_intersect($set, $options) !== array());
-
-        // check IdP
-        $options = array('saml2', 'shib13', 'saml20-idp', 'shib13-idp');
-        $this->roles['SAML2_XML_md_IDPSSODescriptor'] = (array_intersect($set, $options) !== array());
-
-        // check SP
-        $options = array('saml2', 'shib13', 'saml20-sp', 'shib13-sp');
-        $this->roles['SAML2_XML_md_SPSSODescriptor'] = (array_intersect($set, $options) !== array());
-
-        // check AA
-        $options = array('saml2', 'shib13', 'saml20-aa', 'shib13-aa');
-        $this->roles['SAML2_XML_md_AttributeAuthorityDescriptor'] = (array_intersect($set, $options) !== array());
-
-        $this->cacheId = sha1($this->cacheId . serialize($this->protocols) . serialize($this->roles));
-    }
-
-	/**
-	 * Retrieve the complete, signed metadata as text.
-	 *
-	 * This function will write the new metadata to the cache file, but will not return
-	 * the cached metadata.
-	 *
-	 * @return string  The metadata, as text.
-	 */
-	public function updateCachedMetadata() {
-
-		$ed = $this->getEntitiesDescriptor();
-        $ed = $this->exclude($ed);
-        $ed = $this->filter($ed);
-		$this->addSignature($ed);
-
-		$xml = $ed->toXML();
-		$xml = $xml->ownerDocument->saveXML($xml);
-
-		if ($this->cacheGenerated !== NULL) {
-			SimpleSAML_Logger::debug($this->logLoc . 'Saving generated metadata to cache.');
-			$this->addCacheItem($this->cacheId, $xml, time() + $this->cacheGenerated, $this->cacheTag);
-		}
-
-		return $xml;
-
-	}
-
-
-	/**
-	 * Retrieve the complete, signed metadata as text.
-	 *
-	 * @return string  The metadata, as text.
-	 */
-	public function getMetadata() {
-
-		if ($this->cacheGenerated !== NULL) {
-			$xml = $this->getCacheItem($this->cacheId, $this->cacheTag);
-			if ($xml !== NULL) {
-				SimpleSAML_Logger::debug($this->logLoc . 'Loaded generated metadata from cache.');
-				return $xml;
-			}
-		}
-
-		return $this->updateCachedMetadata();
-	}
-
-
-	/**
-	 * Update the cached copy of our metadata.
-	 */
-	public function updateCache() {
-
-		foreach ($this->sources as $source) {
-			$source->updateCache();
-		}
-
-		$this->updateCachedMetadata();
-	}
-
-}
diff --git a/modules/aggregator2/lib/EntitySource.php b/modules/aggregator2/lib/EntitySource.php
deleted file mode 100644
index 25f3c784a80cb66f2898e92cdce333ece45da797..0000000000000000000000000000000000000000
--- a/modules/aggregator2/lib/EntitySource.php
+++ /dev/null
@@ -1,259 +0,0 @@
-<?php
-
-/**
- * Class for loading metadata from files and URLs.
- *
- * @package simpleSAMLphp
- */
-class sspmod_aggregator2_EntitySource {
-
-	/**
-	 * Our log "location".
-	 *
-	 * @var string
-	 */
-	protected $logLoc;
-
-
-	/**
-	 * The aggregator we belong to.
-	 *
-	 * @var sspmod_aggregator2_Aggregator
-	 */
-	protected $aggregator;
-
-
-	/**
-	 * The URL we should fetch it from.
-	 *
-	 * @var string
-	 */
-	protected $url;
-
-
-	/**
-	 * The SSL CA file that should be used to validate the connection.
-	 *
-	 * @var string|NULL
-	 */
-	protected $sslCAFile;
-
-
-	/**
-	 * The certificate we should use to validate downloaded metadata.
-	 *
-	 * @var string|NULL
-	 */
-	protected $certificate;
-
-
-	/**
-	 * The parsed metadata.
-	 *
-	 * @var SAML2_XML_md_EntitiesDescriptor|SAML2_XML_md_EntityDescriptor|NULL
-	 */
-	protected $metadata;
-
-
-	/**
-	 * The cache ID.
-	 *
-	 * @var string
-	 */
-	protected $cacheId;
-
-
-	/**
-	 * The cache tag.
-	 *
-	 * @var string
-	 */
-	protected $cacheTag;
-
-
-	/**
-	 * Whether we have attempted to update the cache already.
-	 *
-	 * @var bool
-	 */
-	protected $updateAttempted;
-
-
-	/**
-	 * Initialize this EntitySource.
-	 *
-	 * @param SimpleSAML_Configuration $config  The configuration.
-	 */
-	public function __construct(sspmod_aggregator2_Aggregator $aggregator, SimpleSAML_Configuration $config) {
-
-		$this->logLoc = 'aggregator2:' . $aggregator->getId() . ': ';
-		$this->aggregator = $aggregator;
-
-		$this->url = $config->getString('url');
-		$this->sslCAFile = $config->getString('ssl.cafile', NULL);
-		if ($this->sslCAFile === NULL) {
-			$this->sslCAFile = $aggregator->getCAFile();
-		}
-
-		$this->certificate = $config->getString('cert', NULL);
-
-		$this->cacheId = sha1($this->url);
-		$this->cacheTag = sha1(serialize($config));
-	}
-
-
-	/**
-	 * Retrieve and parse the metadata.
-	 *
-	 * @return SAML2_XML_md_EntitiesDescriptor|SAML2_XML_md_EntityDescriptor|NULL
-	 * The downloaded metadata or NULL if we were unable to download or parse it.
-	 */
-	private function downloadMetadata() {
-
-		SimpleSAML_Logger::debug($this->logLoc . 'Downloading metadata from ' .
-			var_export($this->url, TRUE));
-
-		$context = array('ssl' => array());
-		if ($this->sslCAFile !== NULL) {
-			$context['ssl']['cafile'] = SimpleSAML_Utilities::resolveCert($this->sslCAFile);
-			SimpleSAML_Logger::debug($this->logLoc . 'Validating https connection against CA certificate(s) found in ' .
-				var_export($context['ssl']['cafile'], TRUE));
-			$context['ssl']['verify_peer'] = TRUE;
-			$context['ssl']['CN_match'] = parse_url($this->url, PHP_URL_HOST);
-		}
-
-
-		$data = SimpleSAML_Utilities::fetch($this->url, $context);
-		if ($data === FALSE || $data === NULL) {
-			SimpleSAML_Logger::error($this->logLoc . 'Unable to load metadata from ' .
-				var_export($this->url, TRUE));
-			return NULL;
-		}
-
-		$doc = new DOMDocument();
-		$res = $doc->loadXML($data);
-		if (!$res) {
-			SimpleSAML_Logger::error($this->logLoc . 'Error parsing XML from ' .
-				var_export($this->url, TRUE));
-			return NULL;
-		}
-
-		$root = SAML2_Utils::xpQuery($doc->firstChild, '/saml_metadata:EntityDescriptor|/saml_metadata:EntitiesDescriptor');
-		if (count($root) === 0) {
-			SimpleSAML_Logger::error($this->logLoc . 'No <EntityDescriptor> or <EntitiesDescriptor> in metadata from ' .
-				var_export($this->url, TRUE));
-			return NULL;
-		}
-
-		if (count($root) > 1) {
-			SimpleSAML_Logger::error($this->logLoc . 'More than one <EntityDescriptor> or <EntitiesDescriptor> in metadata from ' .
-				var_export($this->url, TRUE));
-			return NULL;
-		}
-
-		$root = $root[0];
-		try {
-			if ($root->localName === 'EntityDescriptor') {
-				$md = new SAML2_XML_md_EntityDescriptor($root);
-			} else {
-				$md = new SAML2_XML_md_EntitiesDescriptor($root);
-			}
-		} catch (Exception $e) {
-			SimpleSAML_Logger::error($this->logLoc . 'Unable to parse metadata from ' .
-				var_export($this->url, TRUE) . ': ' . $e->getMessage());
-			return NULL;
-		}
-
-
-		if ($this->certificate !== NULL) {
-			$file = SimpleSAML_Utilities::resolveCert($this->certificate);
-			$certData = file_get_contents($file);
-			if ($certData === FALSE) {
-				throw new SimpleSAML_Error_Exception('Error loading certificate from ' . var_export($file, TRUE));
-			}
-
-			/* Extract the public key from the certificate for validation. */
-			$key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type'=>'public'));
-			$key->loadKey($file, TRUE);
-
-			if (!$md->validate($key)) {
-				SimpleSAML_Logger::error($this->logLoc . 'Error validating signature on metadata.');
-				return NULL;
-			}
-			SimpleSAML_Logger::debug($this->logLoc . 'Validated signature on metadata from ' . var_export($this->url, TRUE));
-		}
-
-		return $md;
-	}
-
-
-	/**
-	 * Attempt to update our cache file.
-	 */
-	public function updateCache() {
-
-		if ($this->updateAttempted) {
-			return;
-		}
-		$this->updateAttempted = TRUE;
-
-		$this->metadata = $this->downloadMetadata();
-		if ($this->metadata === NULL) {
-			return;
-		}
-
-		$expires = time() + 24*60*60; /* Default expires in one day. */
-
-		if ($this->metadata->validUntil !== NULL && $this->metadata->validUntil < $expires) {
-			$expires = $this->metadata->validUntil;
-		}
-
-		$metadataSerialized = serialize($this->metadata);
-
-		$this->aggregator->addCacheItem($this->cacheId, $metadataSerialized, $expires, $this->cacheTag);
-	}
-
-
-	/**
-	 * Retrieve the metadata file.
-	 *
-	 * This function will check its cached copy, to see whether it can be used.
-	 *
-	 * @return SAML2_XML_md_EntityDescriptor|SAML2_XML_md_EntitiesDescriptor|NULL  The downloaded metadata.
-	 */
-	public function getMetadata() {
-
-		if ($this->metadata !== NULL) {
-			/* We have already downloaded the metdata. */
-			return $this->metadata;
-		}
-
-		if (!$this->aggregator->isCacheValid($this->cacheId, $this->cacheTag)) {
-			$this->updateCache();
-			if ($this->metadata !== NULL) {
-				return $this->metadata;
-			}
-			/* We were unable to update the cache - use cached metadata. */
-		}
-
-
-		$cacheFile = $this->aggregator->getCacheFile($this->cacheId);
-
-		if (!file_exists($cacheFile)) {
-			SimpleSAML_Logger::error($this->logLoc . 'No cached metadata available.');
-			return NULL;
-		}
-
-		SimpleSAML_Logger::debug($this->logLoc . 'Using cached metadata from ' .
-			var_export($cacheFile, TRUE));
-
-		$metadata = file_get_contents($cacheFile);
-		if ($metadata !== NULL) {
-			$this->metadata = unserialize($metadata);
-			return $this->metadata;
-		}
-
-		return NULL;
-	}
-
-}
diff --git a/modules/aggregator2/templates/list.php b/modules/aggregator2/templates/list.php
deleted file mode 100644
index fbe350c212bb2c0e39e1547125b3034e953b7e7f..0000000000000000000000000000000000000000
--- a/modules/aggregator2/templates/list.php
+++ /dev/null
@@ -1,33 +0,0 @@
-<?php
-$this->includeAtTemplateBase('includes/header.php');
-?>
-    <h1><?php echo $this->t('{aggregator2:aggregator:header}'); ?></h1>
-
-<?php
-if (count($this->data['sources']) === 0) {
-    echo "    <p>".$this->t('{aggregator2:aggregator:no_aggregators}')."</p>\n";
-} else {
-    echo "    <ul>";
-
-    foreach ($this->data['sources'] as $id => $source) {
-        $encId = urlencode($id);
-        $params = array(
-            'id' => $encId,
-        );
-        echo str_repeat(' ', 8)."<li>\n";
-        echo str_repeat(' ', 12).'<a href="';
-        echo SimpleSAML_Module::getModuleURL('aggregator2/get.php', $params).'">'.htmlspecialchars($id)."</a>\n";
-        echo str_repeat(' ', 12).'<a href="';
-        $params['mimetype'] = 'text/plain';
-        echo SimpleSAML_Module::getModuleURL('aggregator2/get.php', $params).'">['.
-            $this->t('{aggregator2:aggregator:text}')."]</a>\n";
-        echo str_repeat(' ', 12).'<a href="';
-        $params['mimetype'] = 'application/xml';
-        echo SimpleSAML_Module::getModuleURL('aggregator2/get.php', $params)."\">[XML]</a>\n";
-        echo str_repeat(' ', 8)."</li>\n";
-    }
-
-    echo "    </ul>\n";
-}
-
-$this->includeAtTemplateBase('includes/footer.php');
diff --git a/modules/aggregator2/www/get.php b/modules/aggregator2/www/get.php
deleted file mode 100644
index 1a07714b65cd3523f12a50032d8fd8db127c8a03..0000000000000000000000000000000000000000
--- a/modules/aggregator2/www/get.php
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-
-if (!isset($_REQUEST['id'])) {
-    throw new SimpleSAML_Error_BadRequest('Missing required parameter "id".');
-}
-$id = (string) $_REQUEST['id'];
-
-$set = null;
-if (isset($_REQUEST['set'])) {
-    $set = explode(',', $_REQUEST['set']);
-}
-
-$excluded_entities = null;
-if (isset($_REQUEST['exclude'])) {
-    $excluded_entities = explode(',', $_REQUEST['exclude']);
-}
-
-$aggregator = sspmod_aggregator2_Aggregator::getAggregator($id);
-$aggregator->setFilters($set);
-$aggregator->excludeEntities($excluded_entities);
-$xml = $aggregator->getMetadata();
-
-$mimetype = 'application/samlmetadata+xml';
-$allowedmimetypes = array(
-    'text/plain',
-    'application/samlmetadata-xml',
-    'application/xml',
-);
-
-if (isset($_GET['mimetype']) && in_array($_GET['mimetype'], $allowedmimetypes)) {
-    $mimetype = $_GET['mimetype'];
-}
-
-if ($mimetype === 'text/plain') {
-    $xml = SimpleSAML_Utilities::formatXMLString($xml);
-}
-
-header('Content-Type: '.$mimetype);
-header('Content-Length: ' . strlen($xml));
-
-/*
- * At this point, if the ID was forged, getMetadata() would
- * have failed to find a valid metadata set, so we can trust it.
- */
-header('Content-Disposition: filename='.$id.'.xml');
-
-echo $xml;
diff --git a/modules/aggregator2/www/index.php b/modules/aggregator2/www/index.php
deleted file mode 100644
index 17764c58e863db47c43af32e4a31b38d5959d604..0000000000000000000000000000000000000000
--- a/modules/aggregator2/www/index.php
+++ /dev/null
@@ -1,11 +0,0 @@
-<?php
-
-$ssp_cf = SimpleSAML_Configuration::getInstance();
-$mod_cf = SimpleSAML_Configuration::getConfig('module_aggregator2.php');
-
-// get list of sources
-$sources = $mod_cf->toArray();
-
-$t = new SimpleSAML_XHTML_Template($ssp_cf, 'aggregator2:list.php');
-$t->data['sources'] = $sources;
-$t->show();