diff --git a/dictionaries/errors.php b/dictionaries/errors.php
index 49a654a64bcee3f3e52a8ff09b4d981b2cfd2616..e94c482178a77c318903743d5575f3f8b109be4f 100644
--- a/dictionaries/errors.php
+++ b/dictionaries/errors.php
@@ -13,6 +13,10 @@ $lang = array(
 		
 		'title_GENERATEAUTHNRESPONSE' => 'Could not create authentication response',
 		'descr_GENERATEAUTHNRESPONSE' => 'When this identity provider tried to create an authentication response, an error occured.',
+
+		'title_GENERATELOGOUTRESPONSE' => 'Could not create logout response',
+		'descr_GENERATELOGOUTRESPONSE' => 'When this SAML entity tried to create an logout response, an error occured.',
+
 		
 		'title_LDAPERROR' => 'LDAP Error',
 		'descr_LDAPERROR' => 'LDAP is the user database, and when you try to login, we need to contact an LDAP database. When we tried it this time an error occured.',
@@ -20,6 +24,9 @@ $lang = array(
 		'title_LOGOUTREQUEST' => 'Error processing Logout Request',
 		'descr_LOGOUTREQUEST' => 'An error occured when trying to process the Logout Request.',
 		
+		'title_GENERATELOGOUTREQUEST' => 'Could not create logout request',
+		'descr_GENERATELOGOUTREQUEST' => 'When this SAML entity tried to create an logout request, an error occured.',
+		
 		'title_LOGOUTRESPONSE' => 'Error processing Logout Response',
 		'descr_LOGOUTRESPONSE' => 'An error occured when trying to process the Logout Response.',
 		
diff --git a/lib/SimpleSAML/Bindings/SAML20/HTTPRedirect.php b/lib/SimpleSAML/Bindings/SAML20/HTTPRedirect.php
index a57bd2270b42e15a56dfc20eeab448bf72a79fad..c7d26d7861c928aaaffcd327255db4f167967bfe 100644
--- a/lib/SimpleSAML/Bindings/SAML20/HTTPRedirect.php
+++ b/lib/SimpleSAML/Bindings/SAML20/HTTPRedirect.php
@@ -67,7 +67,7 @@ class SimpleSAML_Bindings_SAML20_HTTPRedirect {
 		if ($mode == 'IdP') {
 			$metadataset = 'saml20-sp-remote';
 		}
-
+		SimpleSAML_Logger::debug('Library - HTTPRedirect validateQuery(): Looking up metadata issuer:' . $issuer . ' in set '. $metadataset);
 		$md = $this->metadata->getMetaData($issuer, $metadataset);
 		
 		// check wether to validate or not
diff --git a/www/saml2/idp/SingleLogoutService.php b/www/saml2/idp/SingleLogoutService.php
index cbe7f4644f816f58f6e7238634d39c4643c9ba10..ddf7a3d1b288a717618865d64ce3ea969f5d0e72 100644
--- a/www/saml2/idp/SingleLogoutService.php
+++ b/www/saml2/idp/SingleLogoutService.php
@@ -39,6 +39,7 @@ try {
 	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'METADATA', $exception);
 }
 
+SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutService: Got IdP entity id: ' . $idpentityid);
 
 /**
  * If we get an incomming LogoutRequest then we initiate the logout process.
@@ -48,6 +49,8 @@ try {
  */
 if (isset($_GET['SAMLRequest'])) {
 
+	SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutService: Got SAML reuqest');
+
 	$binding = new SimpleSAML_Bindings_SAML20_HTTPRedirect($config, $metadata);
 
 	try {
@@ -58,16 +61,9 @@ if (isset($_GET['SAMLRequest'])) {
 		}
 
 	} catch(Exception $exception) {
-
-		$et = new SimpleSAML_XHTML_Template($config, 'error.php');
-
-		$et->data['header'] = 'Error in received logout request';
-		$et->data['message'] = 'An error occured when trying to read logout request.';
-		$et->data['e'] = $exception;
-
-		$et->show();
-		exit(0);
-
+	
+		SimpleSAML_Utilities::fatalError($session->getTrackID(), 'LOGOUTREQUEST', $exception);
+		
 	}
 	
 	// Extract some parameters from the logout request
@@ -125,6 +121,8 @@ if (isset($_GET['SAMLRequest'])) {
 		$requestcache['RelayState'] = $relaystate;
 		
 	$session->setLogoutRequest($requestcache);
+	SimpleSAML_Logger::debug('SAML2.0 - IDP.SingleLogoutService: Setting cached request with issuer ' . $logoutrequest->getIssuer());
+	
 	$session->set_sp_logout_completed($logoutrequest->getIssuer() );
 	
 
@@ -133,26 +131,23 @@ if (isset($_GET['SAMLRequest'])) {
 	 */
 } elseif (isset($_GET['SAMLResponse'])) {
 
+	SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutService: Got SAML response');
+
 	$binding = new SimpleSAML_Bindings_SAML20_HTTPRedirect($config, $metadata);
 
 	try {
 		$loginresponse = $binding->decodeLogoutResponse($_GET);
+		
+		SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutService: SAML response parsed. Issuer is: ' . $loginresponse->getIssuer());
 
-		if ($binding->validateQuery($loginresponse->getIssuer(),'SP','SAMLResponse')) {
+		if ($binding->validateQuery($loginresponse->getIssuer(),'IdP','SAMLResponse')) {
 			SimpleSAML_Logger::info('SAML2.0 - IDP.SingleLogoutService: Valid signature found');
 		}
 
 
 	} catch(Exception $exception) {
 
-		$et = new SimpleSAML_XHTML_Template($config, 'error.php');
-
-		$et->data['header'] = 'Error in received logout response';
-		$et->data['message'] = 'An error occured when trying to read logout response.';
-		$et->data['e'] = $exception;
-
-		$et->show();
-		exit(0);
+		SimpleSAML_Utilities::fatalError($session->getTrackID(), 'LOGOUTRESPONSE', $exception);
 
 	}
 
@@ -163,6 +158,7 @@ if (isset($_GET['SAMLRequest'])) {
 	SimpleSAML_Logger::info('SAML2.0 - IDP.SingleLogoutService: got LogoutResponse from ' . $loginresponse->getIssuer());
 } else {
 	
+	SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutService: No request or response...');
 	/**
 	 * This error message was removed 2008-02-27, because it interrupts with bridged SLO.
 	 *
@@ -170,15 +166,38 @@ if (isset($_GET['SAMLRequest'])) {
 	 */
 }
 
+$lookformore = true;
+$spentityid = null;
+do {
+	/* Dump the current sessions (for debugging). */
+	$session->dump_sp_sessions();
 
-/* Dump the current sessions (for debugging). */
-$session->dump_sp_sessions();
+	/*
+	 * We proceed to send logout requests to all remaining SPs.
+	 */
+	$spentityid = $session->get_next_sp_logout();
+	
+	
+	// If there are no more SPs left, then we will not look for more SPs.
+	if (empty($spentityid)) $lookformore = false;
+	
+	try {
+		$spmetadata = $metadata->getMetadata($spentityid, 'saml20-sp-remote');
+	} catch (Exception $e) {
+		continue;
+	}
+	
+	// If the SP we found have an SingleLogout endpoint then we will use it, and
+	// hence we do not need to look for more yet.
+	if (array_key_exists('SingleLogoutService', $spmetadata) && 
+		!empty($spmetadata['SingleLogoutService']) ) $lookformore = false;
+		
+	if ($lookformore)
+		SimpleSAML_Logger::info('SAML2.0 - IDP.SingleLogoutService: Will not logout from ' . $spentityid . ' looking for more SPs');
+
+} while ($lookformore);
 
 
-/*
- * We proceed to send logout requests to all remaining SPs.
- */
-$spentityid = $session->get_next_sp_logout();
 if ($spentityid) {
 
 	SimpleSAML_Logger::info('SAML2.0 - IDP.SingleLogoutService: Logout next SP ' . $spentityid);
@@ -203,14 +222,8 @@ if ($spentityid) {
 
 	} catch(Exception $exception) {
 
-		$et = new SimpleSAML_XHTML_Template($config, 'error.php');
-
-		$et->data['header'] = 'Error sending logout request to service';
-		$et->data['message'] = 'Some error occured when trying to issue the logout response, and send it to the SP.';
-		$et->data['e'] = $exception;
+		SimpleSAML_Utilities::fatalError($session->getTrackID(), 'GENERATELOGOUTREQUEST', $exception);
 
-		$et->show();
-		exit(0);
 	}
 
 
@@ -252,6 +265,7 @@ try {
 		throw new Exception('Could not get reference to the logout request.');
 	}
 	
+	SimpleSAML_Logger::debug('SAML2.0 - IdP.SingleLogoutService: Found request cache with these keys: ' . join(',', array_keys($requestcache)));
 	
 	/**
 	 * Clean up session object to save storage.
@@ -265,32 +279,44 @@ try {
 		SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutService: Session Size after cleaning: ' . $session->getSize());
 	
 	
-	/**
-	 * Create a Logot Response.
+	/*
+	 * Check if the Single Logout procedure is initated by an SP (alternatively IdP initiated SLO
 	 */
-	$rg = new SimpleSAML_XML_SAML20_LogoutResponse($config, $metadata);
-
-	// generate($issuer, $receiver, $inresponseto, $mode )
-	$logoutResponseXML = $rg->generate($idpentityid, $requestcache['Issuer'], $requestcache['RequestID'], 'IdP');
-
-	// Create a HTTP-REDIRECT Binding.
-	$httpredirect = new SimpleSAML_Bindings_SAML20_HTTPRedirect($config, $metadata);
-
-	// Find the relaystate if cached.
-	$relayState = isset($requestcache['RelayState']) ? $requestcache['RelayState'] : null;
+	if (array_key_exists('Issuer', $requestcache)) {
+		
+		/**
+		 * Create a Logot Response.
+		 */
+		$rg = new SimpleSAML_XML_SAML20_LogoutResponse($config, $metadata);
+	
+		// generate($issuer, $receiver, $inresponseto, $mode )
+		$logoutResponseXML = $rg->generate($idpentityid, $requestcache['Issuer'], $requestcache['RequestID'], 'IdP');
+	
+		// Create a HTTP-REDIRECT Binding.
+		$httpredirect = new SimpleSAML_Bindings_SAML20_HTTPRedirect($config, $metadata);
+	
+		// Find the relaystate if cached.
+		$relayState = isset($requestcache['RelayState']) ? $requestcache['RelayState'] : null;
+	
+		// Parameters: $request, $remoteentityid, $relayState = null, $endpoint = 'SingleLogoutService', $direction = 'SAMLRequest', $mode = 'SP'
+		$httpredirect->sendMessage($logoutResponseXML, $idpentityid, $requestcache['Issuer'], $relayState, 'SingleLogoutService', 'SAMLResponse', 'IdP');
+		exit;
+		
+	} elseif (array_key_exists('RelayState', $requestcache)) {
 
-	// Parameters: $request, $remoteentityid, $relayState = null, $endpoint = 'SingleLogoutService', $direction = 'SAMLRequest', $mode = 'SP'
-	$httpredirect->sendMessage($logoutResponseXML, $idpentityid, $requestcache['Issuer'], $relayState, 'SingleLogoutService', 'SAMLResponse', 'IdP');
+		SimpleSAML_Utilities::redirect($requestcache['RelayState']);
+		exit;
+		
+	} else {
+	
+		echo 'You are logged out'; exit;
+	
+	}
 
 } catch(Exception $exception) {
-
-	$et = new SimpleSAML_XHTML_Template($config, 'error.php');
-
-	$et->data['header'] = 'Error sending response to service';
-	$et->data['message'] = 'Some error occured when trying to issue the logout response, and send it to the SP.';
-	$et->data['e'] = $exception;
-
-	$et->show();
+	
+	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'GENERATELOGOUTRESPONSE', $exception);
+	
 }
 
-?>
\ No newline at end of file
+
diff --git a/www/saml2/idp/initSLO.php b/www/saml2/idp/initSLO.php
new file mode 100644
index 0000000000000000000000000000000000000000..e3eec8d4b0aa75b228d2704e088eaf856cbef30c
--- /dev/null
+++ b/www/saml2/idp/initSLO.php
@@ -0,0 +1,153 @@
+<?php
+
+require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . '../../../www/_include.php');
+
+require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Utilities.php');
+require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Session.php');
+require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Logger.php');
+require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Metadata/MetaDataStorageHandler.php');
+require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/XML/SAML20/LogoutRequest.php');
+require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/XML/SAML20/LogoutResponse.php');
+require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Bindings/SAML20/HTTPRedirect.php');
+require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/XHTML/Template.php');
+
+
+$config = SimpleSAML_Configuration::getInstance();
+$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$session = SimpleSAML_Session::getInstance();
+
+
+SimpleSAML_Logger::info('SAML2.0 - IdP.initSLO: Accessing SAML 2.0 IdP endpoint init Single Logout');
+
+if (!$config->getValue('enable.saml20-idp', false))
+	SimpleSAML_Utilities::fatalError(isset($session) ? $session->getTrackID() : null, 'NOACCESS');
+
+try {
+	$idpentityid = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
+} catch (Exception $exception) {
+	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'METADATA', $exception);
+}
+
+
+/**
+ * If we get an incomming LogoutRequest then we initiate the logout process.
+ * in this case an SAML 2.0 SP is sending an request, which also is referred to as
+ * SP initiated Single Logout.
+ *
+ */
+if (isset($_GET['RelayState'])) {
+
+	$relaystate = $_GET['RelayState'];
+	
+	/** 
+	 * No session exists. Just go to the RelayState.
+	 */
+	if($session === NULL) {
+		SimpleSAML_Logger::info('SAML2.0 - IdP.initSLO: Did not find a session here, so we redirect to the RelayState');
+		SimpleSAML_Utilities::redirect($relaystate);
+		exit;
+	}
+
+	// Set local IdP session to invalid.
+	$session->setAuthenticated(false, $session->getAuthority() );
+
+
+	/*
+	 * Create an assoc array of the request to store in the session cache.
+	 */
+	$requestcache = array(
+		'RelayState' => $relaystate
+	);
+		
+	$session->setLogoutRequest($requestcache);
+	SimpleSAML_Logger::debug('SAML2.0 - IDP.initSSO: Setting cached request with relay state ' . $relaystate);
+	
+	//$session->set_sp_logout_completed($logoutrequest->getIssuer() );
+	
+
+}
+
+$lookformore = true;
+$spentityid = null;
+do {
+	/* Dump the current sessions (for debugging). */
+	$session->dump_sp_sessions();
+
+	/*
+	 * We proceed to send logout requests to all remaining SPs.
+	 */
+	$spentityid = $session->get_next_sp_logout();
+	
+	
+	// If there are no more SPs left, then we will not look for more SPs.
+	if (empty($spentityid)) $lookformore = false;
+	
+	try {
+		$spmetadata = $metadata->getMetadata($spentityid, 'saml20-sp-remote');
+	} catch (Exception $e) {
+		continue;
+	}
+	
+	// If the SP we found have an SingleLogout endpoint then we will use it, and
+	// hence we do not need to look for more yet.
+	if (array_key_exists('SingleLogoutService', $spmetadata) && 
+		!empty($spmetadata['SingleLogoutService']) ) $lookformore = false;
+		
+	if ($lookformore)
+		SimpleSAML_Logger::info('SAML2.0 - IDP.SingleLogoutService: Will not logout from ' . $spentityid . ' looking for more SPs');
+
+} while ($lookformore);
+
+
+
+/*
+ * We proceed to send logout requests to the first remaining SP.
+ */
+$spentityid = $session->get_next_sp_logout();
+if ($spentityid) {
+
+	SimpleSAML_Logger::info('SAML2.0 - IDP.SingleLogoutService: Logout next SP ' . $spentityid);
+
+	try {
+		$lr = new SimpleSAML_XML_SAML20_LogoutRequest($config, $metadata);
+
+		// ($issuer, $receiver, $nameid, $nameidformat, $sessionindex, $mode) {
+		$req = $lr->generate($idpentityid, $spentityid, $session->getNameID(), $session->getSessionIndex(), 'IdP');
+
+		$httpredirect = new SimpleSAML_Bindings_SAML20_HTTPRedirect($config, $metadata);
+
+		$relayState = SimpleSAML_Utilities::selfURL();
+		if (isset($_GET['RelayState'])) {
+			$relayState = $_GET['RelayState'];
+		}
+
+		//$request, $remoteentityid, $relayState = null, $endpoint = 'SingleLogoutService', $direction = 'SAMLRequest', $mode = 'SP'
+		$httpredirect->sendMessage($req, $idpentityid, $spentityid, $relayState, 'SingleLogoutService', 'SAMLRequest', 'IdP');
+
+		exit();
+
+	} catch(Exception $exception) {
+
+		SimpleSAML_Utilities::fatalError($session->getTrackID(), 'GENERATELOGOUTREQUEST', $exception);
+
+	}
+
+}
+
+if ($config->getValue('debug', false))
+	SimpleSAML_Logger::info('SAML2.0 - IdP.SingleLogoutService: LogoutService: All SPs done ');
+
+
+if (isset($_GET['RelayState'])) {
+
+	$relayState = $_GET['RelayState'];
+	SimpleSAML_Utilities::redirect($relayState);
+
+} else {
+	
+	SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NORELAYSTATE');
+
+}
+
+
+