diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSAML2Meta.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSAML2Meta.php
index c62c5e9a0fa9893a9a71af050fce34d86c4ec98f..904a71d4ee445e7b7b5a5edae0d3cc17c2ef13c4 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSAML2Meta.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSAML2Meta.php
@@ -11,6 +11,7 @@
 
 require_once('SimpleSAML/Configuration.php');
 require_once('SimpleSAML/Utilities.php');
+require_once('SimpleSAML/XML/Parser.php');
 require_once('SimpleSAML/Metadata/MetaDataStorageHandler.php');
 
 /**
@@ -19,6 +20,7 @@ require_once('SimpleSAML/Metadata/MetaDataStorageHandler.php');
 class SimpleSAML_Metadata_MetaDataStorageHandlerSAML2Meta extends SimpleSAML_Metadata_MetaDataStorageHandler {
 
 
+	static var $cachedfiles = array();
 
 	/* This constructor is included in case it is needed in the the
 	 * future. Including it now allows us to write parent::__construct() in
@@ -32,65 +34,50 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSAML2Meta extends SimpleSAML_Met
 		$metadata = null;
 		if (!in_array($set, array(
 			'saml20-sp-hosted', 'saml20-sp-remote','saml20-idp-hosted', 'saml20-idp-remote',
-			'shib13-sp-hosted', 'shib13-sp-remote', 'shib13-idp-hosted', 'shib13-idp-remote',
-			'openid-provider'))) {
+			'shib13-sp-hosted', 'shib13-sp-remote', 'shib13-idp-hosted', 'shib13-idp-remote' ))) {
 				throw new Exception('Trying to load illegal set of Meta data [' . $set . ']');
 		}
 		
+		$settofile = array(
+			'saml20-sp-hosted' => 'saml20-hosted',
+			'saml20-idp-hosted' => 'saml20-hosted',
+			'saml20-sp-remote' => 'saml20-remote',
+			'saml20-idp-remote' => 'saml20-remote',
+			'shib13-sp-hosted' => 'shib13-hosted',
+			'shib13-idp-hosted' => 'shib13-hosted',
+			'shib13-sp-remote' => 'shib13-remote',
+			'shib13-idp-remote' => 'shib13-remote'
+		);
+		
 		/* Get the configuration. */
 		$config = SimpleSAML_Configuration::getInstance();
 		assert($config instanceof SimpleSAML_Configuration);
-		
-		$metadatasetfile = $config->getBaseDir() . '/' . 
-			$config->getValue('metadatadir') . '/xml/' . $set . '.xml';
-		
-		
-		if (!file_exists($metadatasetfile)) throw new Exception('Could not find SAML 2.0 Metadata file :'. $metadatasetfile);
-		
-		#$metadata = file_get_contents($metadatasetfile);
-		
-		// for now testing with the shib aai metadata...
-		$metadata = file_get_contents("http://www.switch.ch/aai/federation/SWITCHaai/metadata.switchaai_signed.xml");
-		echo '<pre>';
-		
-		$simplexml_metadata = new SimpleXMLElement($metadata);
-		$simplexml_metadata->registerXPathNamespace('saml2meta', 'urn:oasis:names:tc:SAML:2.0:metadata');
-		
-		$idpentities = $simplexml_metadata->xpath('/saml2meta:EntitiesDescriptor/saml2meta:EntityDescriptor[./saml2meta:IDPSSODescriptor]');
-		
-		if (!$idpentities) throw new Exception('Could not find any entity descriptors in the meta data file: ' . $metadatasetfile);
-		foreach ($idpentities as $idpentity) {
-			echo 'Entity: ' . $idpentity['entityID'][0] . "\n";
-			
-			$newmeta = array('entityid' => (string) $idpentity['entityID']);
-			
-			#$idpentity['xmlns'] = 'urn:oasis:names:tc:SAML:2.0:metadata';
-			
-			$namespaces = $idpentity->getNamespaces();
-			
-			foreach ($namespaces AS $prefix => $ns) {
-				$newmeta[($prefix === '') ? 'xmlns' : 'xmlns:' . $prefix)] = $ns;
-			}
-			
-			$simplexml_metadata_entry = new SimpleXMLElement($idpentity->asXML());
-			$simplexml_metadata_entry->registerXPathNamespace('saml2meta', 'urn:oasis:names:tc:SAML:2.0:metadata');
-			
-			
-			$entry = $simplexml_metadata_entry->xpath("/saml2meta:EntityDescriptor/saml2meta:IDPSSODescriptor/saml2meta:SingleSignOnService[@Binding='urn:mace:shibboleth:1.0:profiles:AuthnRequest']/@Location");
-			
-			$newmeta['SingleSignOnService'] = (string)$entry[0]['Location'];
-			
-			echo 'Entry: ';
-			print_r($newmeta);
 
-		}
 		
+		$metadatasetfile = $config->getBaseDir() . '' . 
+			$config->getValue('metadatadir') . 'xml/' . $settofile[$set] . '.xml';
 		
-		//echo htmlentities($metadata);
-		echo '</pre>';
-				exit();
+		if (array_key_exists($metadatasetfile, $cachedfiles)) {
+			$metadata = self::$cachedfiles[$metadatasetfile];
+		} else {
+			if (!file_exists($metadatasetfile)) throw new Exception('Could not find SAML 2.0 Metadata file :'. $metadatasetfile);
 		
+			// for now testing with the shib aai metadata...
+			//$metadataxml = file_get_contents("http://www.switch.ch/aai/federation/SWITCHaai/metadata.switchaai_signed.xml");
+			$metadata = file_get_contents($metadatasetfile);
+		}
 
+		$metadata = null;
+		switch ($set) {
+			case 'saml20-idp-remote' : $metadata = $this->getmetadata_saml20idpremote($metadataxml); break;
+			case 'saml20-idp-hosted' : throw new Exception('Meta data parsing for SAML 2.0 IdP Hosted not yet implemented.');
+			case 'saml20-sp-remote' : throw new Exception('Meta data parsing for SAML 2.0 SP Remote not yet implemented.');
+			case 'saml20-sp-hosted' : throw new Exception('Meta data parsing for SAML 2.0 SP Hosted not yet implemented.');
+			case 'shib13-idp-remote' : $metadata = getmetadata_shib13idpremote($metadataxml); break;
+			case 'shib13-idp-hosted' : throw new Exception('Meta data parsing for Shib 1.3 IdP Hosted not yet implemented.');
+			case 'shib13-sp-remote' : throw new Exception('Meta data parsing for Shib 1.3 SP Remote not yet implemented.');
+			case 'shib13-sp-hosted' : throw new Exception('Meta data parsing for Shib 1.3 SP Hosted not yet implemented.');
+		}
 
 		
 		if (!is_array($metadata)) {
@@ -109,6 +96,66 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSAML2Meta extends SimpleSAML_Met
 	}
 	
 	
+	private function getmetadata_saml20idpremote($metadataxml) {
+		// Create a parser for the metadata document.
+		$metadata_parser = new SimpleSAML_XML_Parser($metadataxml);
+		
+		// Get all entries in the metadata.
+		$idpentities = $metadata_parser->simplexml->xpath('/saml2meta:EntitiesDescriptor/saml2meta:EntityDescriptor[./saml2meta:IDPSSODescriptor]');
+		if (!$idpentities) throw new Exception('Could not find any entity descriptors in the meta data file: ' . $metadatasetfile);
+		
+		// Array to hold the resulting metadata, to return at the end of this function.
+		$metadata = array();
+		
+		// Traverse all entries.
+		foreach ($idpentities as $idpentity) {
+			try {
+				$entityid = (string) $idpentity['entityID'];
+				if (!$entityid) throw new Exception('Could not find entityID in element');
+				
+				$metadata[$entityid] = array('entityid' => $entityid);				
+				$metadata_entry = SimpleSAML_XML_Parser::fromSimpleXMLElement($idpentity);
+				
+				$metadata[$entityid]['SingleSignOnService'] = $metadata_entry->getValue("/saml2meta:EntityDescriptor/saml2meta:IDPSSODescriptor/saml2meta:SingleSignOnService[@Binding='urn:mace:shibboleth:1.0:profiles:AuthnRequest']/@Location", true);
+
+			} catch (Exception $e) {
+				echo 'Error reading one metadata entry: ' . $e;
+			}
+
+		}
+		return $metadata;
+	}
+	
+	private function getmetadata_shib13idpremote($metadataxml) {
+		// Create a parser for the metadata document.
+		$metadata_parser = new SimpleSAML_XML_Parser($metadataxml);
+		
+		// Get all entries in the metadata.
+		$idpentities = $metadata_parser->simplexml->xpath('/saml2meta:EntitiesDescriptor/saml2meta:EntityDescriptor[./saml2meta:IDPSSODescriptor]');
+		if (!$idpentities) throw new Exception('Could not find any entity descriptors in the meta data file: ' . $metadatasetfile);
+		
+		// Array to hold the resulting metadata, to return at the end of this function.
+		$metadata = array();
+		
+		// Traverse all entries.
+		foreach ($idpentities as $idpentity) {
+			try {
+				$entityid = (string) $idpentity['entityID'];
+				if (!$entityid) throw new Exception('Could not find entityID in element');
+				
+				$metadata[$entityid] = array('entityid' => $entityid);				
+				$metadata_entry = SimpleSAML_XML_Parser::fromSimpleXMLElement($idpentity);
+				
+				$metadata[$entityid]['SingleSignOnService'] = $metadata_entry->getValue("/saml2meta:EntityDescriptor/saml2meta:IDPSSODescriptor/saml2meta:SingleSignOnService[@Binding='urn:mace:shibboleth:1.0:profiles:AuthnRequest']/@Location", true);
+
+			} catch (Exception $e) {
+				echo 'Error reading one metadata entry: ' . $e;
+			}
+
+		}
+		return $metadata;
+	}
+	
 	public function getMetaData($entityid = null, $set = 'saml20-sp-hosted') {
 		if (!isset($entityid)) {
 			return $this->getMetaDataCurrent($set);
diff --git a/lib/SimpleSAML/XML/Parser.php b/lib/SimpleSAML/XML/Parser.php
new file mode 100644
index 0000000000000000000000000000000000000000..9bb82e834fd23293a851fa1932989b495023a42f
--- /dev/null
+++ b/lib/SimpleSAML/XML/Parser.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of simpleSAMLphp. See the file COPYING in the
+ * root of the distribution for licence information.
+ *
+ * This file will help doing XPath queries in SAML 2 XML documents.
+ */
+
+
+/**
+ * Configuration of SimpleSAMLphp
+ *
+ * This class should be extending SimpleXMLElement, but it is not because of some bugs:
+ * http://bugs.php.net/bug.php?id=32188&edit=1
+ */
+class SimpleSAML_XML_Parser  {
+
+	var $simplexml = null;
+	
+	function __construct($xml) {
+		#parent::construct($xml);
+		$this->simplexml = new SimpleXMLElement($xml);
+		$this->simplexml->registerXPathNamespace('saml2meta', 'urn:oasis:names:tc:SAML:2.0:metadata');
+	}
+	
+	public static function fromSimpleXMLElement(SimpleXMLElement $element) {
+		
+		// Traverse all existing namespaces in element.
+		$namespaces = $element->getNamespaces();
+		foreach ($namespaces AS $prefix => $ns) {
+			$element[(($prefix === '') ? 'xmlns' : 'xmlns:' . $prefix)] = $ns;
+		}
+		
+		/* Create a new parser with the xml document where the namespace definitions
+		 * are added.
+		 */
+		$parser = new SimpleSAML_XML_Parser($element->asXML());
+		return $parser;
+		
+	}
+	
+	public function getValue($xpath, $required = false) {
+		
+		$result = $this->simplexml->xpath($xpath);
+		if (! $result or !is_array($result)) {
+			if ($required) throw new Exception('Could not get value from XML document using the following XPath expression: ' . $xpath);
+				else return null;
+		}
+		return (string) $result[0];
+	}
+	
+}
+
+?>
\ No newline at end of file
diff --git a/templates/default/en/admin-metadatalist.php b/templates/default/en/admin-metadatalist.php
new file mode 100644
index 0000000000000000000000000000000000000000..22fd84de30cbf13a4ba147f8793ea9c575177a07
--- /dev/null
+++ b/templates/default/en/admin-metadatalist.php
@@ -0,0 +1,91 @@
+<?php $this->includeAtTemplateBase('includes/header.php'); ?>
+
+	<div id="header">
+		<h1>Metadata overview</h1>
+		<div id="poweredby"><img src="/<?php echo $data['baseurlpath']; ?>resources/icons/bino.png" alt="Bino" /></div>
+	</div>
+	
+	<div id="content">
+
+		<h2><?php if (isset($data['header'])) { echo $data['header']; } else { echo "Metadata overview"; } ?></h2>
+		
+		<p>Here is a list of metadata that is configured for your installation.</p>
+		
+		<p>[ <a href="../">Go back to installation main page</a> ]</p>
+		
+		<?php
+		
+		
+		function showEntry($header, $list) {
+		
+			echo '<h3>' . $header . '</h3>';
+		
+			foreach ($list AS $entityid => $entity) {
+				$name = $entityid;
+				if (isset($entity['optional.found']['name'])) $name = $entity['optional.found']['name'];
+
+				//print_r($entity);
+
+				echo '<h4>' . $name . '</h4>';
+				if (isset($entity['optional.found']['description'])) {
+					echo '<p>' . $entity['optional.found']['description'] . '</p>';
+				}
+				
+				echo '<p>Required fields</p>';
+				echo '<table style="width: 100%; border: 1px solid #eee"><tr><th>Key</th><th>Value</th></tr>';
+				foreach ($entity['required.found'] AS $key => $value) {
+					echo '<tr><td>' . $key . '</td><td>' . $value . '</td></tr>';
+				}
+				echo '</table>';
+	
+				if (count($entity['required.notfound']) > 0) {
+					echo '<p>The following required fields was not found:<ul>';
+					foreach ($entity['required.notfound'] AS $key) {
+						echo '<li>' . $key . '</li>';
+					}
+					echo '</ul>';				
+				}
+				
+				if (count($entity['optional.found']) > 0) {
+					echo '<p>Optional fields</p>';
+					echo '<table><tr><th>Key</th><th>Value</th></tr>';
+					foreach ($entity['optional.found'] AS $key => $value) {
+						echo '<tr><td>' . $key . '</td><td>' . $value . '</td></tr>';
+					}
+					echo '</table>';
+				}
+	
+				if (count($entity['optional.notfound']) > 0) {
+					echo '<p>The following optional fields was not found:<ul>';
+					foreach ($entity['optional.notfound'] AS $key) {
+						echo '<li>' . $key . '</li>';
+					}
+					echo '</ul>';				
+				}
+				
+				if (count($entity['leftovers']) > 0) {
+					echo '<p>The following fields was not reckognized:<ul>';
+					foreach ($entity['leftovers'] AS $key => $value) {
+						echo '<li>' . $key . '</li>';
+					}
+					echo '</ul>';				
+				}
+			
+			}
+		}
+		
+		
+		if (array_key_exists('metadata.saml20-sp-hosted', $data)) 
+			showEntry('SAML 2.0 Service Provider (Hosted)', $data['metadata.saml20-sp-hosted']);
+		if (array_key_exists('metadata.saml20-sp-remote', $data)) 
+			showEntry('SAML 2.0 Service Provider (Remote)', $data['metadata.saml20-sp-remote']);
+		if (array_key_exists('metadata.saml20-idp-hosted', $data)) 
+			showEntry('SAML 2.0 Identity Provider (Hosted)', $data['metadata.saml20-idp-hosted']);
+		if (array_key_exists('metadata.saml20-idp-remote', $data)) 
+			showEntry('SAML 2.0 Identity Provider (Remote)', $data['metadata.saml20-idp-remote']);
+
+		
+		?>
+
+		
+<?php $this->includeAtTemplateBase('includes/footer.php'); ?>
diff --git a/www/admin/metadata.php b/www/admin/metadata.php
index 2ce1d3e6c4cbae44fed6bb331a0ab59e73809d97..2c354f6d260d9ee037e41eaccb2ff2857a9d2935 100644
--- a/www/admin/metadata.php
+++ b/www/admin/metadata.php
@@ -25,6 +25,7 @@ try {
 	
 	if ($config->getValue('enable.saml20-sp') === true) {
 		$results = array();	
+		/*
 		$metalist = $metadata->getList('saml20-sp-hosted');
 		foreach ($metalist AS $entityid => $mentry) {
 			$results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry,
@@ -33,7 +34,7 @@ try {
 			);
 		}
 		$et->data['metadata.saml20-sp-hosted'] = $results;
-		
+		*/
 		$metalist = $metadata->getList('saml20-idp-remote');
 		foreach ($metalist AS $entityid => $mentry) {
 			$results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry,