diff --git a/.travis.yml b/.travis.yml
index 9bf4d39c1cc2cf8b533ee1d5123b548b11fe53d3..d97ff3a7e1652584fda54f15953d87217a291ff5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,20 +5,21 @@ php:
 - 5.6
 - 7.0
 - 7.1
+- 7.2
 - hhvm
 matrix:
   allow_failures:
   - php: hhvm
 before_script:
 - composer update
-- if [[ "$TRAVIS_PHP_VERSION" == "7.0" ]]; then composer require --dev vimeo/psalm:0.3.72; fi
+- if [[ "$TRAVIS_PHP_VERSION" == "7.0" ]]; then composer require --dev vimeo/psalm:0.3.92; fi
 - if [[ "$TRAVIS_PHP_VERSION" == "5.6" ]]; then composer require --dev php-coveralls/php-coveralls; fi
 script:
 - bin/check-syntax.sh
 - if [[ "$TRAVIS_PHP_VERSION" == "5.6" ]]; then php vendor/phpunit/phpunit/phpunit --configuration tools/phpunit; else php vendor/phpunit/phpunit/phpunit --configuration tools/phpunit --no-coverage; fi
-#- if [[ "$TRAVIS_PHP_VERSION" == "7.0" ]]; then vendor/bin/psalm --find-dead-code; fi
+- if [[ "$TRAVIS_PHP_VERSION" == "7.0" ]]; then vendor/bin/psalm; fi
 after_success:
-- if [[ "$TRAVIS_PHP_VERSION" == "5.6" ]]; then php vendor/bin/coveralls -v; fi
+- if [[ "$TRAVIS_PHP_VERSION" == "5.6" ]]; then php vendor/bin/php-coveralls -v; fi
 notifications:
   slack:
     secure: h5YiO7tAk5bzAQBkUZ3crnOFAOBkNqHp0nc2cxvGauogVfCLE9K8bME512uTeu9QWMht2D30uyTOHFKQ7sPEW4omHNF4qYl4p9L037oQFfEwZPBzJFo9QUzviT3mvKHTN4HSQOkq/08ZoMhh1i3p/OhyFS56J28IDJWDqGZkEUE=
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8a16e72314880d702ba0368ed4cfd9bb09d23881..d16eec4696968af1e18c93acdf4a5227584b1667 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,15 +1,11 @@
 # Contribution guidelines
+**SimpleSAMLphp welcomes all contributions**. It is impossible to make a product like this without the efforts of many people, so please don't be shy and share your help with us. Even the tiniest contribution can make a difference!
 
-**SimpleSAMLphp welcomes all contributions**. It is impossible to make a product like this without the efforts of many
-people, so please don't be shy and share your help with us. Even the tiniest contribution can make a difference!
-
-This guidelines briefly explain how to contribute to SimpleSAMLphp in an effective manner, making sure to keep high
-quality standards and making it easier for your contributions to make through.
+These guidelines briefly explain how to contribute to SimpleSAMLphp effectively and consistently, making sure to keep high quality standards and making it easier for you to contribute.
 
 <!-- {{TOC}} -->
 
 ## Team members
-
 Currently, the core team members are:
 
 * Jaime Pérez Crespo, *main developer and release manager*, UNINETT <jaime.perez@uninett.no>
@@ -17,83 +13,64 @@ Currently, the core team members are:
 * Andreas Ă…kre Solberg, *architect and original developer*, UNINETT <andreas.solberg@uninett.no>
 * Hanne Moa, *developer*, UNINETT <hanne.moa@uninett.no>
 
-We've been lucky to have the help of many people through the years. SimpleSAMLphp wouldn't have reached so far without
-them, and we want to thank them from here. Unfortunately, they are so many it is nearly impossible to mention all of
-them. [Github can offer a good summary on who has contributed to the project](https://github.com/simplesamlphp/simplesamlphp/graphs/contributors?from=2007-09-09&to=2015-09-06&type=c).
-Big thanks to you all!
+We have been lucky enough to have so many people help us through the years. SimpleSAMLphp wouldn't have reached so far without them. We want to thank them from here, but unfortunately they are so many it is nearly impossible to mention all of them. [Here is a Github page that summarizes everyone's contributions](https://github.com/simplesamlphp/simplesamlphp/graphs/contributors?from=2007-09-09&to=2015-09-06&type=c).
 
-## First things first
+***Big thanks to you all!***
 
-Before embarking yourself in a contribution, please make sure you are familiar with the way SimpleSAMLphp is written,
-the way it works, and what is required or not.
+## First things first
+Before embarking yourself in a contribution, please make sure you are familiar with the way SimpleSAMLphp is written, the way it works, and what is required or not.
 
-* Make sure to read [the documentation](https://simplesamlphp.org/docs/stable/). If you use the search engine in the
-website, please verify that you are reading the latest stable version. If you want to develop something, check [the
-development branch of the documentation](https://simplesamlphp.org/docs/development/).
+* Make sure to read [the documentation](https://simplesamlphp.org/docs/stable/). If you use the search engine in the website, please verify that you are reading the latest stable version. If you want to make a change, check [the development branch of the documentation](https://simplesamlphp.org/docs/development/).
 * If you have a question about **using SimpleSAMLphp**, please use [the mailing list](http://groups.google.com/group/simplesamlphp).
 * If you have a question about **developing SimpleSAMLphp**, please ask in the [development mailing list](http://groups.google.com/group/simplesamlphp-dev).
-* If you think you have discovered a bug, please check the [issue tracker](https://github.com/simplesamlphp/simplesamlphp/issues)
-and the [pull requests](https://github.com/simplesamlphp/simplesamlphp/pulls) to verify it hasn't been reported before.
+* If you think you have discovered a bug, please check the [issue tracker](https://github.com/simplesamlphp/simplesamlphp/issues) and the [pull requests](https://github.com/simplesamlphp/simplesamlphp/pulls) to verify it hasn't been reported already.
 
 ## Contributing code
-
-New features are always welcome provided they will be useful to someone apart from yourself. Please take a look at the
-[list of issues](https://github.com/simplesamlphp/simplesamlphp/issues) to see what people is demanding. Our
-[roadmap](https://simplesamlphp.org/releaseplan) might also be a good place to start if you don't know exactly what
-you can contribute with.
-
-When contributing your code, please make sure to:
-
-* Respect the coding standards. We try to comply with PHP's [PSR-2](http://www.php-fig.org/psr/psr-2/). Pay special
-attention to:
-   * Lines should not be longer than 80 characters.
-   * Use **4 spaces** instead of tabs.
-   * Keep the keywords in **lowercase**, including `true`, `false` and `null`.
-   * Make sure your classes work with *autoloading*.
-   * Never include a trailing `?>` in your files.
-   * The first line of every file must be `<?php`.
-   * Use namespaces if you are adding new files.
-* Do not include many changes in every commit. Commits should be focused and address one single problem or feature. By
-having **multiple, small commits** instead of few large ones, it is easier to track what you are doing, revert changes
-in case of an error and help you out if needed.
+New features are always welcome, provided they will be useful to someone apart from yourself. Please take a look at the [list of issues](https://github.com/simplesamlphp/simplesamlphp/issues) to see what people are asking for. Our [roadmap](https://simplesamlphp.org/releaseplan) might also be a good place to start if you do not know exactly how you can contribute.
+
+When submitting a pull request, please make sure to account for:
+
+### Coding standards
+* Respect the coding standards. We try to comply with PHP's [PSR-2](http://www.php-fig.org/psr/psr-2/). Pay special attention to the rules below:
+    * Lines should not be longer than 80 characters.
+    * Use **4 spaces** instead of tabs.
+    * Keep the keywords in **lowercase**, including `true`, `false` and `null`.
+    * Make sure your classes work with *autoloading*.
+    * Never include a trailing `?>` in your files.
+    * The first line of every file must be `<?php`.
+    * Use namespaces if you are adding new files.
+* Do not include too many changes in every commit. Commits should be focused and address one single problem or feature. By having **multiple, small commits** instead of fewer large ones, it is easier to track what you are doing, revert changes in case of an error and help you make changes if needed.
 * Try to write clean **commit messages**, largely based on the [seven rules](http://chris.beams.io/posts/git-commit/):
-   * Write a **short** subject line, followed by a blank line and a longer explanation.
-   * Prefix the subject line with the component(s) changed, e.g. "docs: Update foo", or "SAML: Don't log bar twice",
-     or "tests: Add tests for quux".
-   * Explain **what and why** in the commit message, not just _how_. Things obvious now might become quite confusing
-     when rediscovered years later.
-* **Be explicit**. Add comments. Use strict comparison operators like `===` and check for specific values when testing
-conditions.
-* **Keep things simple**. Avoid big functions, long nested loops or `if` statements.
-* Include complete **phpdoc** documentation for every property and method you add. If you change a method or property,
-make sure to update the existing *phpdoc* accordingly. Do not forget to document all parameters, returned values and
-exceptions thrown.
-* Try to keep **backwards-compatibility**. Code that breaks current configurations and installations is difficult to
-deploy, and therefore we try to avoid it.
-* Add **unit tests** to verify that your code not only works but also keeps working over time. When adding tests, keep
-the same directory structure used for regular classes. Try to cover **all your code** with tests. The bigger the test
-coverage, the more reliable and better our library is. Read our [guidelines](TESTING.md) to learn more about tests.
-* Add proper **documentation** explaining your how to use your new feature or how your code changes things.
-* Submit your code as a **pull request** in github, from a branch with a descriptive name in your own fork of the
-repository. Add a meaningful, short title, and explain in detail what you did and why in the description of the *PR*.
-Add instructions on how to test your code. We appreciate branch names like `feature/whatever-new-feature` for new
-features and `bug/something-not-working` for bug fixes, but this is not carved in stone.
-
-Sometimes it can take a long time until we are able to process your pull requests. Don't get discouraged, we'll
-eventually reach up to you. And remember that following this guidelines you are making it easier for us to analyze your
-request so the process will be smoother and faster. We really appreciate you helping us out, not only with your code,
-but also by following this guidelines.
+    * Write a **short** subject line, followed by a blank line and a longer explanation.
+    * Prefix the subject line with the component(s) changed, e.g. "docs: Update foo", or "SAML: Don't log bar twice", or "tests: Add tests for quux".
+    * Explain **what and why** in the commit message, not just _how_. Things that seem obvious now might become quite confusing when rediscovered years later.
 
-## Reporting bugs
+### Comments, comparisons, and simplicity
+* Add comments that describe why/how your code works.
+* Include complete **phpdoc** documentation for every property and method you add. If you change a method or property, make sure to update the existing *phpdoc* accordingly. Do not forget to document all parameters, returned values and exceptions thrown.
+* Use strict comparison operators like `===` and check for specific values when writing tests.
+* Avoid big functions, long nested loops or `if` statements.
+* Try to keep **backwards-compatibility**. Code that breaks current configurations and installations is difficult to deploy, and therefore we try to avoid that as much as possible.
+
+### Unit tests
+Add **unit tests** to verify that your code not only works but also keeps working over time. When adding tests, keep the same directory structure used for regular classes. Try to cover **all your code** with tests. The bigger the test coverage, the more reliable and better our library is. Read our [guidelines](TESTING.md) to learn more about tests.
+
+### Documentation
+In order to keep this library user-friendly, we ask that you add proper **documentation** explaining how to use your new feature or how your code changes things.
 
-Before reporting a bug, please make sure it is indeed a bug. Check [the documentation](https://simplesamlphp.org/docs/stable/)
-to verify what the intended behaviour is. Review the [list of issues](https://github.com/simplesamlphp/simplesamlphp/issues)
-and the [pull requests](https://github.com/simplesamlphp/simplesamlphp/pulls) to see if someone has already reported the
-same issue.
+### Pull requests
+Please follow all instructions below:
 
-Pull requests are definitely more appreciated than plain issue reports, as they are easier and faster to address, but
-please, do not hesitate to open an issue if you don't have coding skills or just can't find the bug. It's better to have
-just an issue report than nothing!
+1. Submit your code as a **pull request** in github from a branch with a descriptive name in your own fork of the repository.
+2. Add a meaningful, short title, and explain in detail what you did and why in the description of the *PR*.
+3. Add instructions on how to test your code. We appreciate branch names like `feature/whatever-new-feature` for new features and `bug/something-not-working` for bug fixes, but this is not required.
+
+Sometimes it can take a long time before we are able to process your pull requests. Do not get discouraged, we will eventually reach your change. Remember that by following these guidelines, you are making it easier for us to analyze your request so the process will be smooth and fast. We really appreciate you helping us out, not only with your code, but also by following these guidelines.
+
+## Reporting bugs
+Before reporting a bug, please make sure it is indeed a bug. Check [the documentation](https://simplesamlphp.org/docs/stable/) to verify what the intended behaviour is. Review the [issue tracker](https://github.com/simplesamlphp/simplesamlphp/issues) and the [pull requests](https://github.com/simplesamlphp/simplesamlphp/pulls) to see if someone has already reported the same issue.
+
+If you are able, a pull request is much more appreciated than just a new issue. If not, please do not hesitate to open one. It is better to have just an issue report than nothing!
 
 You can help us diagnose and fix bugs by asking and providing answers to the following questions:
 
@@ -102,18 +79,12 @@ You can help us diagnose and fix bugs by asking and providing answers to the fol
 * Are the steps to reproduce the bug clear? If not, can you describe how you might reproduce it?
 * What tags should the bug have?
 * How critical is this bug? Does it impact a large amount of users?
-* Is this a security issue? If so, how severe is it? How can an attacker exploit it? Read more about security issues in
-the next section.
+* Is this a security issue? If so, how severe is it? How can an attacker exploit it? Read more about security issues in the next section.
 
 ## Reporting vulnerabilities
+In case you find a vulnerability in SimpleSAMLphp, or you want to confirm a possible security issue in the software, please get in touch with us through [UNINETT's CERT team](https://www.uninett.no/cert). Please use our PGP public key to encrypt any possibly sensitive data that you may need to submit. We will get back to you as soon as possible according to our working hours in Central European Time.
 
-In case you find a vulnerability in SimpleSAMLphp, or you want to confirm a possible security issue in the software, please
-get in touch with us through [UNINETT's CERT team](https://www.uninett.no/cert). Please use our PGP public key to encrypt
-any possible sensitive data that you may need to submit. We will get back to you as soon as possible according to our
-working hours in Central European Time.
-
-When reporting a security issue, please add as much information as possible to help us identify, confirm, replicate and
-fix the problem. In particular, remember to include the following information in your report:
+When reporting a security issue, please add as much information as possible to help us identify, confirm, replicate and fix the problem. In particular, remember to include the following information in your report:
 
 * The version or versions of SimpleSAMLphp affected.
 * An exact version that can be used to replicate the issue.
@@ -125,42 +96,23 @@ fix the problem. In particular, remember to include the following information in
 * Context on how you discovered the issue.
 * Your own name and whether you want to be credited for the discovery or not.
 
-Please **DO NOT** report security incidents related to systems that use SimpleSAMLphp, where this software is not the
-cause of the incident. Issues related to the use (or misuse) of infrastructure, misconfiguration of the software,
-malfunction of a particular system or user-related errors should not be reported either. If you are using SimpleSAMLphp
-to authenticate or login to services, but you don't know what SimpleSAMLphp is or you are not sure about the nature of
-the issue, please contact the organization running the service for you.
+Please **DO NOT** report security incidents related to systems that use SimpleSAMLphp, where this software is not the cause of the incident. Issues related to the use (or misuse) of infrastructure, misconfiguration of the software, malfunction of a particular system or user-related errors should not be reported either. If you are using SimpleSAMLphp to authenticate or login to services, but you don't know what SimpleSAMLphp is or you are not sure about the nature of the issue, please contact the organization running the service for you.
 
-Finally, be reasonable. We'll do our best to resolve the issue according to our principles of security and transparency.
-Every confirmed vulnerability will be published and resolved in a timely manner. All we ask in return is that you
-contact us privately first in order to avoid any potential damage to those using the software.
+Finally, be reasonable. We'll do our best to resolve the issue according to our principles of security and transparency. Every confirmed vulnerability will be published and resolved in a timely manner. All we ask in return is that you contact us privately first in order to avoid any potential damage to those using the software.
 
 You can find the list of security advisories we have published [here](https://simplesamlphp.org/security).
 
 ## Translations
+SimpleSAMLphp is translated to many languages, though it needs constant updates from translators, as well as new translations to other languages. For the moment, translations can be contributed as **pull requests**. We are looking at better ways to translate the software that would make your life easier, so stay tuned! You can also join the [translators mailing list](http://groups.google.com/group/simplesamlphp-translation) to keep up to date on the latest news.
 
-SimpleSAMLphp is translated to many languages, though it needs constant updates from translators, as well as new
-translations to other languages. For the moment, translations can be contributed as **pull requests**. We are looking
-at better ways to translate the software that would make your life easier, so stay tuned! You can also join the
-[translators mailing list](http://groups.google.com/group/simplesamlphp-translation) to keep up to date on the
-latest news.
-
-Before starting a new translation, decide what style you want to use, whether you want to address the user in a polite
-manner or not, etc. Be coherent and keep that style through all your translations. If there is already a translation and
-you want to complete it, make sure to keep the same style used by your fellow translators.
+Before starting a new translation, decide what style you want to use, whether you want to address the user in a polite manner or not, etc. Be coherent and keep that style through all your translations. If there is already a translation and you want to complete it, make sure to keep the same style used by your fellow translators.
 
 ## Documentation
+Did you find a typo in the documentation? Does something make no sense? Did we use poor english? Tell us!
 
-Did you find a typo in the documentation? Does something make no sense? Did we use very poor english? Tell us!
-
-Documentation is included in our own repository in *markdown* format. You can submit pull requests with fixes. If you
-encounter some feature that's not documented, or the documentation does not reflect the real behaviour of the library,
-please do not hesitate to open an issue.
+Documentation is included in our own repository in *markdown* format. You can submit pull requests with fixes. If you encounter some feature that is not documented, or the documentation does not reflect the real behaviour of the library, please do not hesitate to open an issue.
 
 Good documentation is key to make things easier for our users!
 
 ## Community
-
-You don't feel capable of contributing with your code, but are using SimpleSAMLphp and can share your knowledge and
-experience? Please, do so! Join our [users mailing list](http://groups.google.com/group/simplesamlphp) and help other
-users when you can. Your experience might be valuable for many!
+You do not feel capable of contributing with your code, but are using SimpleSAMLphp and can share your knowledge and experience? Please, do so! Join our [users mailing list](http://groups.google.com/group/simplesamlphp) and help other users when you can. Your experience might be valuable for many!
diff --git a/attributemap/myspace2name.php b/attributemap/myspace2name.php
deleted file mode 100644
index 6111f61d051d84713edc412f2fba8e2183091b00..0000000000000000000000000000000000000000
--- a/attributemap/myspace2name.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-$attributemap = array(
-
-    // See http://developerwiki.myspace.com/index.php?title=People_API for attributes
-
-    // Generated MySpace Attributes
-    'myspace_user'            => 'eduPersonPrincipalName', // username OR uid @ myspace.com
-    'myspace_targetedID'      => 'eduPersonTargetedID', // http://myspace.com!uid
-    'myspace_username'        => 'uid', // myspace username (maybe numeric uid)
-
-    // Attributes Returned by MySpace
-    'myspace.name.givenName'  => 'givenName',
-    'myspace.name.familyName' => 'sn',
-    'myspace.displayName'     => 'displayName',
-    'myspace.profileUrl'      => 'labeledURI',
-);
diff --git a/bin/importPdoMetadata.php b/bin/importPdoMetadata.php
index 79e4b504a2326208616469f7e1f9cc7bac31c531..b930b99f2169324759c3a6a0632e752328d3d77b 100755
--- a/bin/importPdoMetadata.php
+++ b/bin/importPdoMetadata.php
@@ -3,14 +3,14 @@
 $baseDir = dirname(dirname(__FILE__));
 
 require_once $baseDir.DIRECTORY_SEPARATOR.'lib'.DIRECTORY_SEPARATOR.'_autoload.php';
-require_once SimpleSAML\Utils\Config::getConfigDir().DIRECTORY_SEPARATOR.'config.php';
+require_once \SimpleSAML\Utils\Config::getConfigDir().DIRECTORY_SEPARATOR.'config.php';
 
 # Iterate through configured metadata sources and ensure
 # that a PDO source exists.
 foreach ($config['metadata.sources'] as $s) {
     # If pdo is configured, create the new handler and add in the metadata sets.
     if ($s['type'] === "pdo") {
-        $mdshp = new SimpleSAML_Metadata_MetaDataStorageHandlerPdo($s);
+        $mdshp = new \SimpleSAML\Metadata\MetaDataStorageHandlerPdo($s);
         $mdshp->initDatabase();
 
         foreach (glob("metadata/*.php") as $filename) {
diff --git a/bin/initMDSPdo.php b/bin/initMDSPdo.php
index b68a5b22f6ccc2bfe311a8f9dc0fd67528eeb850..403b4d2de00ce3ac8fdd9267b31cecf77b8abea1 100755
--- a/bin/initMDSPdo.php
+++ b/bin/initMDSPdo.php
@@ -6,7 +6,7 @@ $baseDir = dirname(dirname(__FILE__));
 
 // Add library autoloader and configuration
 require_once $baseDir.DIRECTORY_SEPARATOR.'lib'.DIRECTORY_SEPARATOR.'_autoload.php';
-require_once SimpleSAML\Utils\Config::getConfigDir().DIRECTORY_SEPARATOR.'config.php';
+require_once \SimpleSAML\Utils\Config::getConfigDir().DIRECTORY_SEPARATOR.'config.php';
 
 echo "Initializing Metadata Database...".PHP_EOL;
 
@@ -15,7 +15,7 @@ echo "Initializing Metadata Database...".PHP_EOL;
 foreach ($config['metadata.sources'] as $source) {
     # If pdo is configured, create the new handler and initialize the DB.
     if ($source['type'] === "pdo") {
-        $metadataStorageHandler = new SimpleSAML_Metadata_MetaDataStorageHandlerPdo($source);
+        $metadataStorageHandler = new \SimpleSAML\Metadata\MetaDataStorageHandlerPdo($source);
         $result = $metadataStorageHandler->initDatabase();
 
         if ($result === false) {
diff --git a/bin/memcacheSync.php b/bin/memcacheSync.php
index 64605a952aa94ff89d4e9a57e4ba36df16149cd9..278cd0f6dcb3bf62d84e00360185741b27a0b654 100755
--- a/bin/memcacheSync.php
+++ b/bin/memcacheSync.php
@@ -26,14 +26,14 @@ require_once($baseDir.'/lib/_autoload.php');
 
 // Initialize the configuration
 $configdir = SimpleSAML\Utils\Config::getConfigDir();
-SimpleSAML_Configuration::setConfigDir($configdir);
+\SimpleSAML\Configuration::setConfigDir($configdir);
 
 // Things we should warn the user about
 $warnServerDown = 0;
 $warnBigSlab = 0;
 
 // We use the stats interface to determine which servers exists
-$stats = SimpleSAML_Memcache::getRawStats();
+$stats = \SimpleSAML\Memcache::getRawStats();
 
 $keys = array();
 foreach ($stats as $group) {
@@ -61,7 +61,7 @@ echo("Starting synchronization.\n");
 $skipped = 0;
 $sync = 0;
 foreach ($keys as $key) {
-    $res = SimpleSAML_Memcache::get($key);
+    $res = \SimpleSAML\Memcache::get($key);
     if ($res === null) {
         $skipped += 1;
     } else {
diff --git a/composer.json b/composer.json
index 6424ead7122481cf61bc15cf284e0f0e27802bad..a837f10218ea42537d30ca92852e9ab6042e7e62 100644
--- a/composer.json
+++ b/composer.json
@@ -4,7 +4,7 @@
     "type": "project",
     "keywords": [ "saml2", "shibboleth","oauth","ws-federation","sp","idp" ],
     "homepage": "http://simplesamlphp.org",
-    "license": "LGPL-2.1",
+    "license": "LGPL-2.1-or-later",
     "authors": [
         {
             "name": "Andreas Ă…kre Solberg",
@@ -36,7 +36,7 @@
         "ext-hash": "*",
         "ext-json": "*",
         "ext-mbstring": "*",
-        "simplesamlphp/saml2": "~3.0",
+        "simplesamlphp/saml2": "~3.1.4",
         "robrichards/xmlseclibs": "~3.0",
         "whitehat101/apr1-md5": "~1.0",
         "twig/twig": "~1.0",
@@ -44,7 +44,6 @@
         "jaimeperez/twig-configurable-i18n": "^1.2"
     },
     "require-dev": {
-        "ext-pdo_sqlite": "*",
         "phpunit/phpunit": "~4.8.35",
         "mikey179/vfsStream": "~1.6",
         "friendsofphp/php-cs-fixer": "^2.2"
diff --git a/composer.lock b/composer.lock
index d889ae0365f64648906802db8eb296da1245809b..c62015b7caed35608a30b7f5f5b21d0b4720b8e1 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1,10 +1,10 @@
 {
     "_readme": [
         "This file locks the dependencies of your project to a known state",
-        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "b4321ba6aa21f1dfd919f942037f2692",
+    "content-hash": "429c28dc40717fc389a01b58acdbfa6b",
     "packages": [
         {
             "name": "gettext/gettext",
@@ -260,36 +260,40 @@
         },
         {
             "name": "simplesamlphp/saml2",
-            "version": "v3.0.3",
+            "version": "v3.1.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/simplesamlphp/saml2.git",
-                "reference": "bdafe52d52adb32c926c12c5139401546b4dc57b"
+                "reference": "d809ffbe2aa7260a0b3e72bf5be8cd6de0325d7c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/simplesamlphp/saml2/zipball/bdafe52d52adb32c926c12c5139401546b4dc57b",
-                "reference": "bdafe52d52adb32c926c12c5139401546b4dc57b",
+                "url": "https://api.github.com/repos/simplesamlphp/saml2/zipball/d809ffbe2aa7260a0b3e72bf5be8cd6de0325d7c",
+                "reference": "d809ffbe2aa7260a0b3e72bf5be8cd6de0325d7c",
                 "shasum": ""
             },
             "require": {
                 "ext-dom": "*",
                 "ext-openssl": "*",
                 "ext-zlib": "*",
-                "php": ">=5.3.3",
+                "php": ">=5.4",
                 "psr/log": "~1.0",
-                "robrichards/xmlseclibs": "^2.0|^3.0"
+                "robrichards/xmlseclibs": "^3.0"
             },
             "require-dev": {
                 "mockery/mockery": "~0.9",
                 "phpmd/phpmd": "~1.5",
-                "phpunit/phpunit": "~3.7",
-                "satooshi/php-coveralls": "~0.6.1",
+                "phpunit/phpunit": "~4",
                 "sebastian/phpcpd": "~1.4",
                 "sensiolabs/security-checker": "~1.1",
                 "squizlabs/php_codesniffer": "~1.4"
             },
             "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "v3.1.x-dev"
+                }
+            },
             "autoload": {
                 "psr-0": {
                     "SAML2\\": "src/"
@@ -300,7 +304,7 @@
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
-                "LGPL-2.1"
+                "LGPL-2.1-or-later"
             ],
             "authors": [
                 {
@@ -309,7 +313,7 @@
                 }
             ],
             "description": "SAML2 PHP library from SimpleSAMLphp",
-            "time": "2017-08-31T11:24:42+00:00"
+            "time": "2018-05-04T12:03:18+00:00"
         },
         {
             "name": "twig/extensions",
@@ -369,16 +373,16 @@
         },
         {
             "name": "twig/twig",
-            "version": "v1.34.4",
+            "version": "v1.35.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/twigphp/Twig.git",
-                "reference": "f878bab48edb66ad9c6ed626bf817f60c6c096ee"
+                "reference": "9c24f2cd39dc1906b76879e099970b7e53724601"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/twigphp/Twig/zipball/f878bab48edb66ad9c6ed626bf817f60c6c096ee",
-                "reference": "f878bab48edb66ad9c6ed626bf817f60c6c096ee",
+                "url": "https://api.github.com/repos/twigphp/Twig/zipball/9c24f2cd39dc1906b76879e099970b7e53724601",
+                "reference": "9c24f2cd39dc1906b76879e099970b7e53724601",
                 "shasum": ""
             },
             "require": {
@@ -392,7 +396,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.34-dev"
+                    "dev-master": "1.35-dev"
                 }
             },
             "autoload": {
@@ -430,7 +434,7 @@
             "keywords": [
                 "templating"
             ],
-            "time": "2017-07-04T13:19:31+00:00"
+            "time": "2018-03-03T16:21:29+00:00"
         },
         {
             "name": "whitehat101/apr1-md5",
@@ -542,35 +546,35 @@
         },
         {
             "name": "doctrine/annotations",
-            "version": "v1.2.7",
+            "version": "v1.4.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/annotations.git",
-                "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535"
+                "reference": "54cacc9b81758b14e3ce750f205a393d52339e97"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535",
-                "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535",
+                "url": "https://api.github.com/repos/doctrine/annotations/zipball/54cacc9b81758b14e3ce750f205a393d52339e97",
+                "reference": "54cacc9b81758b14e3ce750f205a393d52339e97",
                 "shasum": ""
             },
             "require": {
                 "doctrine/lexer": "1.*",
-                "php": ">=5.3.2"
+                "php": "^5.6 || ^7.0"
             },
             "require-dev": {
                 "doctrine/cache": "1.*",
-                "phpunit/phpunit": "4.*"
+                "phpunit/phpunit": "^5.7"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.3.x-dev"
+                    "dev-master": "1.4.x-dev"
                 }
             },
             "autoload": {
-                "psr-0": {
-                    "Doctrine\\Common\\Annotations\\": "lib/"
+                "psr-4": {
+                    "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -606,7 +610,7 @@
                 "docblock",
                 "parser"
             ],
-            "time": "2015-08-31T12:32:49+00:00"
+            "time": "2017-02-24T16:22:25+00:00"
         },
         {
             "name": "doctrine/instantiator",
@@ -718,16 +722,16 @@
         },
         {
             "name": "friendsofphp/php-cs-fixer",
-            "version": "v2.2.8",
+            "version": "v2.10.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
-                "reference": "aca23e791784eade7b377d578d6dfc6fcf1398d2"
+                "reference": "1634a2c250bf4640f1c5c963f63b413c2d966c8a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/aca23e791784eade7b377d578d6dfc6fcf1398d2",
-                "reference": "aca23e791784eade7b377d578d6dfc6fcf1398d2",
+                "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/1634a2c250bf4640f1c5c963f63b413c2d966c8a",
+                "reference": "1634a2c250bf4640f1c5c963f63b413c2d966c8a",
                 "shasum": ""
             },
             "require": {
@@ -735,30 +739,31 @@
                 "doctrine/annotations": "^1.2",
                 "ext-json": "*",
                 "ext-tokenizer": "*",
-                "gecko-packages/gecko-php-unit": "^2.0",
-                "php": "^5.3.6 || >=7.0 <7.3",
-                "sebastian/diff": "^1.4",
-                "symfony/console": "^2.4 || ^3.0",
-                "symfony/event-dispatcher": "^2.1 || ^3.0",
-                "symfony/filesystem": "^2.4 || ^3.0",
-                "symfony/finder": "^2.2 || ^3.0",
-                "symfony/options-resolver": "^2.6 || ^3.0",
-                "symfony/polyfill-php54": "^1.0",
-                "symfony/polyfill-php55": "^1.3",
+                "php": "^5.6 || >=7.0 <7.3",
+                "php-cs-fixer/diff": "^1.2",
+                "symfony/console": "^3.2 || ^4.0",
+                "symfony/event-dispatcher": "^3.0 || ^4.0",
+                "symfony/filesystem": "^3.0 || ^4.0",
+                "symfony/finder": "^3.0 || ^4.0",
+                "symfony/options-resolver": "^3.0 || ^4.0",
                 "symfony/polyfill-php70": "^1.0",
                 "symfony/polyfill-php72": "^1.4",
-                "symfony/process": "^2.3 || ^3.0",
-                "symfony/stopwatch": "^2.5 || ^3.0"
+                "symfony/process": "^3.0 || ^4.0",
+                "symfony/stopwatch": "^3.0 || ^4.0"
             },
             "conflict": {
-                "hhvm": "<3.18"
+                "hhvm": "*"
             },
             "require-dev": {
-                "johnkary/phpunit-speedtrap": "^1.0.1",
+                "johnkary/phpunit-speedtrap": "^1.1 || ^2.0@dev",
                 "justinrainbow/json-schema": "^5.0",
-                "phpunit/phpunit": "^4.8.35 || ^5.4.3",
-                "satooshi/php-coveralls": "^1.0",
-                "symfony/phpunit-bridge": "^3.2.2"
+                "keradus/cli-executor": "^1.0",
+                "mikey179/vfsstream": "^1.6",
+                "php-coveralls/php-coveralls": "^2.0",
+                "php-cs-fixer/accessible-object": "^1.0",
+                "phpunit/phpunit": "^5.7.23 || ^6.4.3",
+                "phpunitgoodpractices/traits": "^1.0",
+                "symfony/phpunit-bridge": "^3.2.2 || ^4.0"
             },
             "suggest": {
                 "ext-mbstring": "For handling non-UTF8 characters in cache signature.",
@@ -768,20 +773,21 @@
                 "php-cs-fixer"
             ],
             "type": "application",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "2.2-dev"
-                }
-            },
             "autoload": {
                 "psr-4": {
                     "PhpCsFixer\\": "src/"
                 },
                 "classmap": [
                     "tests/Test/AbstractFixerTestCase.php",
+                    "tests/Test/AbstractIntegrationCaseFactory.php",
                     "tests/Test/AbstractIntegrationTestCase.php",
+                    "tests/Test/Assert/AssertTokensTrait.php",
+                    "tests/Test/Constraint/SameStringsConstraint.php",
                     "tests/Test/IntegrationCase.php",
-                    "tests/Test/IntegrationCaseFactory.php"
+                    "tests/Test/IntegrationCaseFactory.php",
+                    "tests/Test/IntegrationCaseFactoryInterface.php",
+                    "tests/Test/InternalIntegrationCaseFactory.php",
+                    "tests/TestCase.php"
                 ]
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -799,93 +805,7 @@
                 }
             ],
             "description": "A tool to automatically fix PHP code style",
-            "time": "2017-09-29T15:07:49+00:00"
-        },
-        {
-            "name": "gecko-packages/gecko-php-unit",
-            "version": "v2.2",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/GeckoPackages/GeckoPHPUnit.git",
-                "reference": "ab525fac9a9ffea219687f261b02008b18ebf2d1"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/GeckoPackages/GeckoPHPUnit/zipball/ab525fac9a9ffea219687f261b02008b18ebf2d1",
-                "reference": "ab525fac9a9ffea219687f261b02008b18ebf2d1",
-                "shasum": ""
-            },
-            "require": {
-                "php": "^5.3.6 || ^7.0"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "^4.8.35 || ^5.4.3"
-            },
-            "suggest": {
-                "ext-dom": "When testing with xml.",
-                "ext-libxml": "When testing with xml.",
-                "phpunit/phpunit": "This is an extension for it so make sure you have it some way."
-            },
-            "type": "library",
-            "autoload": {
-                "psr-4": {
-                    "GeckoPackages\\PHPUnit\\": "src/PHPUnit"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "description": "Additional PHPUnit asserts and constraints.",
-            "homepage": "https://github.com/GeckoPackages",
-            "keywords": [
-                "extension",
-                "filesystem",
-                "phpunit"
-            ],
-            "time": "2017-08-23T07:39:54+00:00"
-        },
-        {
-            "name": "ircmaxell/password-compat",
-            "version": "v1.0.4",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/ircmaxell/password_compat.git",
-                "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c",
-                "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c",
-                "shasum": ""
-            },
-            "require-dev": {
-                "phpunit/phpunit": "4.*"
-            },
-            "type": "library",
-            "autoload": {
-                "files": [
-                    "lib/password.php"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Anthony Ferrara",
-                    "email": "ircmaxell@php.net",
-                    "homepage": "http://blog.ircmaxell.com"
-                }
-            ],
-            "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash",
-            "homepage": "https://github.com/ircmaxell/password_compat",
-            "keywords": [
-                "hashing",
-                "password"
-            ],
-            "time": "2014-11-20T16:49:30+00:00"
+            "time": "2018-02-22T16:49:33+00:00"
         },
         {
             "name": "mikey179/vfsStream",
@@ -981,18 +901,69 @@
             ],
             "time": "2017-09-27T21:40:39+00:00"
         },
+        {
+            "name": "php-cs-fixer/diff",
+            "version": "v1.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/PHP-CS-Fixer/diff.git",
+                "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/78bb099e9c16361126c86ce82ec4405ebab8e756",
+                "reference": "78bb099e9c16361126c86ce82ec4405ebab8e756",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.6 || ^7.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^5.7.23 || ^6.4.3",
+                "symfony/process": "^3.3"
+            },
+            "type": "library",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Kore Nordmann",
+                    "email": "mail@kore-nordmann.de"
+                },
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                },
+                {
+                    "name": "SpacePossum"
+                }
+            ],
+            "description": "sebastian/diff v2 backport support for PHP5.6",
+            "homepage": "https://github.com/PHP-CS-Fixer",
+            "keywords": [
+                "diff"
+            ],
+            "time": "2018-02-15T16:58:55+00:00"
+        },
         {
             "name": "phpdocumentor/reflection-common",
-            "version": "1.0",
+            "version": "1.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
-                "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
+                "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
-                "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
+                "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
                 "shasum": ""
             },
             "require": {
@@ -1033,25 +1004,25 @@
                 "reflection",
                 "static analysis"
             ],
-            "time": "2015-12-27T11:43:31+00:00"
+            "time": "2017-09-11T18:02:19+00:00"
         },
         {
             "name": "phpdocumentor/reflection-docblock",
-            "version": "3.2.0",
+            "version": "3.3.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
-                "reference": "46f7e8bb075036c92695b15a1ddb6971c751e585"
+                "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/46f7e8bb075036c92695b15a1ddb6971c751e585",
-                "reference": "46f7e8bb075036c92695b15a1ddb6971c751e585",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bf329f6c1aadea3299f08ee804682b7c45b326a2",
+                "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.5",
-                "phpdocumentor/reflection-common": "^1.0@dev",
+                "php": "^5.6 || ^7.0",
+                "phpdocumentor/reflection-common": "^1.0.0",
                 "phpdocumentor/type-resolver": "^0.4.0",
                 "webmozart/assert": "^1.0"
             },
@@ -1078,7 +1049,7 @@
                 }
             ],
             "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
-            "time": "2017-07-15T11:38:20+00:00"
+            "time": "2017-11-10T14:09:06+00:00"
         },
         {
             "name": "phpdocumentor/type-resolver",
@@ -1129,33 +1100,33 @@
         },
         {
             "name": "phpspec/prophecy",
-            "version": "v1.7.0",
+            "version": "1.7.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpspec/prophecy.git",
-                "reference": "93d39f1f7f9326d746203c7c056f300f7f126073"
+                "reference": "dfd6be44111a7c41c2e884a336cc4f461b3b2401"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073",
-                "reference": "93d39f1f7f9326d746203c7c056f300f7f126073",
+                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/dfd6be44111a7c41c2e884a336cc4f461b3b2401",
+                "reference": "dfd6be44111a7c41c2e884a336cc4f461b3b2401",
                 "shasum": ""
             },
             "require": {
                 "doctrine/instantiator": "^1.0.2",
                 "php": "^5.3|^7.0",
-                "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
+                "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
                 "sebastian/comparator": "^1.1|^2.0",
                 "sebastian/recursion-context": "^1.0|^2.0|^3.0"
             },
             "require-dev": {
                 "phpspec/phpspec": "^2.5|^3.2",
-                "phpunit/phpunit": "^4.8 || ^5.6.5"
+                "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.6.x-dev"
+                    "dev-master": "1.7.x-dev"
                 }
             },
             "autoload": {
@@ -1188,7 +1159,7 @@
                 "spy",
                 "stub"
             ],
-            "time": "2017-03-02T20:05:34+00:00"
+            "time": "2018-02-19T10:16:54+00:00"
         },
         {
             "name": "phpunit/php-code-coverage",
@@ -1254,16 +1225,16 @@
         },
         {
             "name": "phpunit/php-file-iterator",
-            "version": "1.4.2",
+            "version": "1.4.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
-                "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
+                "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
-                "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4",
+                "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4",
                 "shasum": ""
             },
             "require": {
@@ -1297,7 +1268,7 @@
                 "filesystem",
                 "iterator"
             ],
-            "time": "2016-10-03T07:40:28+00:00"
+            "time": "2017-11-27T13:52:08+00:00"
         },
         {
             "name": "phpunit/php-text-template",
@@ -1391,16 +1362,16 @@
         },
         {
             "name": "phpunit/php-token-stream",
-            "version": "1.4.11",
+            "version": "1.4.12",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-token-stream.git",
-                "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7"
+                "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7",
-                "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16",
+                "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16",
                 "shasum": ""
             },
             "require": {
@@ -1436,7 +1407,7 @@
             "keywords": [
                 "tokenizer"
             ],
-            "time": "2017-02-27T10:12:30+00:00"
+            "time": "2017-12-04T08:55:13+00:00"
         },
         {
             "name": "phpunit/phpunit",
@@ -1940,44 +1911,45 @@
         },
         {
             "name": "symfony/console",
-            "version": "v3.3.10",
+            "version": "v3.4.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/console.git",
-                "reference": "116bc56e45a8e5572e51eb43ab58c769a352366c"
+                "reference": "067339e9b8ec30d5f19f5950208893ff026b94f7"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/console/zipball/116bc56e45a8e5572e51eb43ab58c769a352366c",
-                "reference": "116bc56e45a8e5572e51eb43ab58c769a352366c",
+                "url": "https://api.github.com/repos/symfony/console/zipball/067339e9b8ec30d5f19f5950208893ff026b94f7",
+                "reference": "067339e9b8ec30d5f19f5950208893ff026b94f7",
                 "shasum": ""
             },
             "require": {
                 "php": "^5.5.9|>=7.0.8",
-                "symfony/debug": "~2.8|~3.0",
+                "symfony/debug": "~2.8|~3.0|~4.0",
                 "symfony/polyfill-mbstring": "~1.0"
             },
             "conflict": {
-                "symfony/dependency-injection": "<3.3"
+                "symfony/dependency-injection": "<3.4",
+                "symfony/process": "<3.3"
             },
             "require-dev": {
                 "psr/log": "~1.0",
-                "symfony/config": "~3.3",
-                "symfony/dependency-injection": "~3.3",
-                "symfony/event-dispatcher": "~2.8|~3.0",
-                "symfony/filesystem": "~2.8|~3.0",
-                "symfony/process": "~2.8|~3.0"
+                "symfony/config": "~3.3|~4.0",
+                "symfony/dependency-injection": "~3.4|~4.0",
+                "symfony/event-dispatcher": "~2.8|~3.0|~4.0",
+                "symfony/lock": "~3.4|~4.0",
+                "symfony/process": "~3.3|~4.0"
             },
             "suggest": {
                 "psr/log": "For using the console logger",
                 "symfony/event-dispatcher": "",
-                "symfony/filesystem": "",
+                "symfony/lock": "",
                 "symfony/process": ""
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.3-dev"
+                    "dev-master": "3.4-dev"
                 }
             },
             "autoload": {
@@ -2004,20 +1976,20 @@
             ],
             "description": "Symfony Console Component",
             "homepage": "https://symfony.com",
-            "time": "2017-10-02T06:42:24+00:00"
+            "time": "2018-02-26T15:46:28+00:00"
         },
         {
             "name": "symfony/debug",
-            "version": "v3.3.10",
+            "version": "v3.4.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/debug.git",
-                "reference": "eb95d9ce8f18dcc1b3dfff00cb624c402be78ffd"
+                "reference": "9b1071f86e79e1999b3d3675d2e0e7684268b9bc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/debug/zipball/eb95d9ce8f18dcc1b3dfff00cb624c402be78ffd",
-                "reference": "eb95d9ce8f18dcc1b3dfff00cb624c402be78ffd",
+                "url": "https://api.github.com/repos/symfony/debug/zipball/9b1071f86e79e1999b3d3675d2e0e7684268b9bc",
+                "reference": "9b1071f86e79e1999b3d3675d2e0e7684268b9bc",
                 "shasum": ""
             },
             "require": {
@@ -2028,12 +2000,12 @@
                 "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
             },
             "require-dev": {
-                "symfony/http-kernel": "~2.8|~3.0"
+                "symfony/http-kernel": "~2.8|~3.0|~4.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.3-dev"
+                    "dev-master": "3.4-dev"
                 }
             },
             "autoload": {
@@ -2060,20 +2032,20 @@
             ],
             "description": "Symfony Debug Component",
             "homepage": "https://symfony.com",
-            "time": "2017-10-02T06:42:24+00:00"
+            "time": "2018-02-28T21:49:22+00:00"
         },
         {
             "name": "symfony/event-dispatcher",
-            "version": "v3.3.10",
+            "version": "v3.4.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher.git",
-                "reference": "d7ba037e4b8221956ab1e221c73c9e27e05dd423"
+                "reference": "58990682ac3fdc1f563b7e705452921372aad11d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d7ba037e4b8221956ab1e221c73c9e27e05dd423",
-                "reference": "d7ba037e4b8221956ab1e221c73c9e27e05dd423",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/58990682ac3fdc1f563b7e705452921372aad11d",
+                "reference": "58990682ac3fdc1f563b7e705452921372aad11d",
                 "shasum": ""
             },
             "require": {
@@ -2084,10 +2056,10 @@
             },
             "require-dev": {
                 "psr/log": "~1.0",
-                "symfony/config": "~2.8|~3.0",
-                "symfony/dependency-injection": "~3.3",
-                "symfony/expression-language": "~2.8|~3.0",
-                "symfony/stopwatch": "~2.8|~3.0"
+                "symfony/config": "~2.8|~3.0|~4.0",
+                "symfony/dependency-injection": "~3.3|~4.0",
+                "symfony/expression-language": "~2.8|~3.0|~4.0",
+                "symfony/stopwatch": "~2.8|~3.0|~4.0"
             },
             "suggest": {
                 "symfony/dependency-injection": "",
@@ -2096,7 +2068,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.3-dev"
+                    "dev-master": "3.4-dev"
                 }
             },
             "autoload": {
@@ -2123,20 +2095,20 @@
             ],
             "description": "Symfony EventDispatcher Component",
             "homepage": "https://symfony.com",
-            "time": "2017-10-02T06:42:24+00:00"
+            "time": "2018-02-14T10:03:57+00:00"
         },
         {
             "name": "symfony/filesystem",
-            "version": "v3.3.10",
+            "version": "v3.4.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/filesystem.git",
-                "reference": "90bc45abf02ae6b7deb43895c1052cb0038506f1"
+                "reference": "253a4490b528597aa14d2bf5aeded6f5e5e4a541"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/filesystem/zipball/90bc45abf02ae6b7deb43895c1052cb0038506f1",
-                "reference": "90bc45abf02ae6b7deb43895c1052cb0038506f1",
+                "url": "https://api.github.com/repos/symfony/filesystem/zipball/253a4490b528597aa14d2bf5aeded6f5e5e4a541",
+                "reference": "253a4490b528597aa14d2bf5aeded6f5e5e4a541",
                 "shasum": ""
             },
             "require": {
@@ -2145,7 +2117,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.3-dev"
+                    "dev-master": "3.4-dev"
                 }
             },
             "autoload": {
@@ -2172,20 +2144,20 @@
             ],
             "description": "Symfony Filesystem Component",
             "homepage": "https://symfony.com",
-            "time": "2017-10-03T13:33:10+00:00"
+            "time": "2018-02-22T10:48:49+00:00"
         },
         {
             "name": "symfony/finder",
-            "version": "v3.3.10",
+            "version": "v3.4.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/finder.git",
-                "reference": "773e19a491d97926f236942484cb541560ce862d"
+                "reference": "6a615613745cef820d807443f32076bb9f5d0a38"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/finder/zipball/773e19a491d97926f236942484cb541560ce862d",
-                "reference": "773e19a491d97926f236942484cb541560ce862d",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/6a615613745cef820d807443f32076bb9f5d0a38",
+                "reference": "6a615613745cef820d807443f32076bb9f5d0a38",
                 "shasum": ""
             },
             "require": {
@@ -2194,7 +2166,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.3-dev"
+                    "dev-master": "3.4-dev"
                 }
             },
             "autoload": {
@@ -2221,20 +2193,20 @@
             ],
             "description": "Symfony Finder Component",
             "homepage": "https://symfony.com",
-            "time": "2017-10-02T06:42:24+00:00"
+            "time": "2018-02-11T17:15:12+00:00"
         },
         {
             "name": "symfony/options-resolver",
-            "version": "v3.3.10",
+            "version": "v3.4.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/options-resolver.git",
-                "reference": "ee4e22978fe885b54ee5da8c7964f0a5301abfb6"
+                "reference": "f3109a6aedd20e35c3a33190e932c2b063b7b50e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/options-resolver/zipball/ee4e22978fe885b54ee5da8c7964f0a5301abfb6",
-                "reference": "ee4e22978fe885b54ee5da8c7964f0a5301abfb6",
+                "url": "https://api.github.com/repos/symfony/options-resolver/zipball/f3109a6aedd20e35c3a33190e932c2b063b7b50e",
+                "reference": "f3109a6aedd20e35c3a33190e932c2b063b7b50e",
                 "shasum": ""
             },
             "require": {
@@ -2243,7 +2215,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.3-dev"
+                    "dev-master": "3.4-dev"
                 }
             },
             "autoload": {
@@ -2275,20 +2247,20 @@
                 "configuration",
                 "options"
             ],
-            "time": "2017-07-29T21:54:42+00:00"
+            "time": "2018-01-11T07:56:07+00:00"
         },
         {
             "name": "symfony/polyfill-mbstring",
-            "version": "v1.6.0",
+            "version": "v1.7.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-mbstring.git",
-                "reference": "2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296"
+                "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296",
-                "reference": "2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296",
+                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/78be803ce01e55d3491c1397cf1c64beb9c1b63b",
+                "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b",
                 "shasum": ""
             },
             "require": {
@@ -2300,7 +2272,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.6-dev"
+                    "dev-master": "1.7-dev"
                 }
             },
             "autoload": {
@@ -2334,134 +2306,20 @@
                 "portable",
                 "shim"
             ],
-            "time": "2017-10-11T12:05:26+00:00"
-        },
-        {
-            "name": "symfony/polyfill-php54",
-            "version": "v1.6.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/symfony/polyfill-php54.git",
-                "reference": "d7810a14b2c6c1aff415e1bb755f611b3d5327bc"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/d7810a14b2c6c1aff415e1bb755f611b3d5327bc",
-                "reference": "d7810a14b2c6c1aff415e1bb755f611b3d5327bc",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.3"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.6-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Symfony\\Polyfill\\Php54\\": ""
-                },
-                "files": [
-                    "bootstrap.php"
-                ],
-                "classmap": [
-                    "Resources/stubs"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Nicolas Grekas",
-                    "email": "p@tchwork.com"
-                },
-                {
-                    "name": "Symfony Community",
-                    "homepage": "https://symfony.com/contributors"
-                }
-            ],
-            "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions",
-            "homepage": "https://symfony.com",
-            "keywords": [
-                "compatibility",
-                "polyfill",
-                "portable",
-                "shim"
-            ],
-            "time": "2017-10-11T12:05:26+00:00"
-        },
-        {
-            "name": "symfony/polyfill-php55",
-            "version": "v1.6.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/symfony/polyfill-php55.git",
-                "reference": "b64e7f0c37ecf144ecc16668936eef94e628fbfd"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/b64e7f0c37ecf144ecc16668936eef94e628fbfd",
-                "reference": "b64e7f0c37ecf144ecc16668936eef94e628fbfd",
-                "shasum": ""
-            },
-            "require": {
-                "ircmaxell/password-compat": "~1.0",
-                "php": ">=5.3.3"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.6-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Symfony\\Polyfill\\Php55\\": ""
-                },
-                "files": [
-                    "bootstrap.php"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Nicolas Grekas",
-                    "email": "p@tchwork.com"
-                },
-                {
-                    "name": "Symfony Community",
-                    "homepage": "https://symfony.com/contributors"
-                }
-            ],
-            "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions",
-            "homepage": "https://symfony.com",
-            "keywords": [
-                "compatibility",
-                "polyfill",
-                "portable",
-                "shim"
-            ],
-            "time": "2017-10-11T12:05:26+00:00"
+            "time": "2018-01-30T19:27:44+00:00"
         },
         {
             "name": "symfony/polyfill-php70",
-            "version": "v1.6.0",
+            "version": "v1.7.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-php70.git",
-                "reference": "0442b9c0596610bd24ae7b5f0a6cdbbc16d9fcff"
+                "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/0442b9c0596610bd24ae7b5f0a6cdbbc16d9fcff",
-                "reference": "0442b9c0596610bd24ae7b5f0a6cdbbc16d9fcff",
+                "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/3532bfcd8f933a7816f3a0a59682fc404776600f",
+                "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f",
                 "shasum": ""
             },
             "require": {
@@ -2471,7 +2329,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.6-dev"
+                    "dev-master": "1.7-dev"
                 }
             },
             "autoload": {
@@ -2507,20 +2365,20 @@
                 "portable",
                 "shim"
             ],
-            "time": "2017-10-11T12:05:26+00:00"
+            "time": "2018-01-30T19:27:44+00:00"
         },
         {
             "name": "symfony/polyfill-php72",
-            "version": "v1.6.0",
+            "version": "v1.7.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-php72.git",
-                "reference": "6de4f4884b97abbbed9f0a84a95ff2ff77254254"
+                "reference": "8eca20c8a369e069d4f4c2ac9895144112867422"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/6de4f4884b97abbbed9f0a84a95ff2ff77254254",
-                "reference": "6de4f4884b97abbbed9f0a84a95ff2ff77254254",
+                "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/8eca20c8a369e069d4f4c2ac9895144112867422",
+                "reference": "8eca20c8a369e069d4f4c2ac9895144112867422",
                 "shasum": ""
             },
             "require": {
@@ -2529,7 +2387,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.6-dev"
+                    "dev-master": "1.7-dev"
                 }
             },
             "autoload": {
@@ -2562,20 +2420,20 @@
                 "portable",
                 "shim"
             ],
-            "time": "2017-10-11T12:05:26+00:00"
+            "time": "2018-01-31T17:43:24+00:00"
         },
         {
             "name": "symfony/process",
-            "version": "v3.3.10",
+            "version": "v3.4.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/process.git",
-                "reference": "fdf89e57a723a29baf536e288d6e232c059697b1"
+                "reference": "cc4aea21f619116aaf1c58016a944e4821c8e8af"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/process/zipball/fdf89e57a723a29baf536e288d6e232c059697b1",
-                "reference": "fdf89e57a723a29baf536e288d6e232c059697b1",
+                "url": "https://api.github.com/repos/symfony/process/zipball/cc4aea21f619116aaf1c58016a944e4821c8e8af",
+                "reference": "cc4aea21f619116aaf1c58016a944e4821c8e8af",
                 "shasum": ""
             },
             "require": {
@@ -2584,7 +2442,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.3-dev"
+                    "dev-master": "3.4-dev"
                 }
             },
             "autoload": {
@@ -2611,20 +2469,20 @@
             ],
             "description": "Symfony Process Component",
             "homepage": "https://symfony.com",
-            "time": "2017-10-02T06:42:24+00:00"
+            "time": "2018-02-12T17:55:00+00:00"
         },
         {
             "name": "symfony/stopwatch",
-            "version": "v3.3.10",
+            "version": "v3.4.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/stopwatch.git",
-                "reference": "170edf8b3247d7b6779eb6fa7428f342702ca184"
+                "reference": "eb17cfa072cab26537ac37e9c4ece6c0361369af"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/stopwatch/zipball/170edf8b3247d7b6779eb6fa7428f342702ca184",
-                "reference": "170edf8b3247d7b6779eb6fa7428f342702ca184",
+                "url": "https://api.github.com/repos/symfony/stopwatch/zipball/eb17cfa072cab26537ac37e9c4ece6c0361369af",
+                "reference": "eb17cfa072cab26537ac37e9c4ece6c0361369af",
                 "shasum": ""
             },
             "require": {
@@ -2633,7 +2491,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.3-dev"
+                    "dev-master": "3.4-dev"
                 }
             },
             "autoload": {
@@ -2660,27 +2518,30 @@
             ],
             "description": "Symfony Stopwatch Component",
             "homepage": "https://symfony.com",
-            "time": "2017-10-02T06:42:24+00:00"
+            "time": "2018-02-17T14:55:25+00:00"
         },
         {
             "name": "symfony/yaml",
-            "version": "v3.3.10",
+            "version": "v3.4.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/yaml.git",
-                "reference": "8c7bf1e7d5d6b05a690b715729cb4cd0c0a99c46"
+                "reference": "6af42631dcf89e9c616242c900d6c52bd53bd1bb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/8c7bf1e7d5d6b05a690b715729cb4cd0c0a99c46",
-                "reference": "8c7bf1e7d5d6b05a690b715729cb4cd0c0a99c46",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/6af42631dcf89e9c616242c900d6c52bd53bd1bb",
+                "reference": "6af42631dcf89e9c616242c900d6c52bd53bd1bb",
                 "shasum": ""
             },
             "require": {
                 "php": "^5.5.9|>=7.0.8"
             },
+            "conflict": {
+                "symfony/console": "<3.4"
+            },
             "require-dev": {
-                "symfony/console": "~2.8|~3.0"
+                "symfony/console": "~3.4|~4.0"
             },
             "suggest": {
                 "symfony/console": "For validating YAML files using the lint command"
@@ -2688,7 +2549,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.3-dev"
+                    "dev-master": "3.4-dev"
                 }
             },
             "autoload": {
@@ -2715,20 +2576,20 @@
             ],
             "description": "Symfony Yaml Component",
             "homepage": "https://symfony.com",
-            "time": "2017-10-05T14:43:42+00:00"
+            "time": "2018-02-16T09:50:28+00:00"
         },
         {
             "name": "webmozart/assert",
-            "version": "1.2.0",
+            "version": "1.3.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/webmozart/assert.git",
-                "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f"
+                "reference": "0df1908962e7a3071564e857d86874dad1ef204a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f",
-                "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f",
+                "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a",
+                "reference": "0df1908962e7a3071564e857d86874dad1ef204a",
                 "shasum": ""
             },
             "require": {
@@ -2765,7 +2626,7 @@
                 "check",
                 "validate"
             ],
-            "time": "2016-11-23T20:04:58+00:00"
+            "time": "2018-01-29T19:49:41+00:00"
         }
     ],
     "aliases": [],
@@ -2785,7 +2646,5 @@
         "ext-json": "*",
         "ext-mbstring": "*"
     },
-    "platform-dev": {
-        "ext-pdo_sqlite": "*"
-    }
+    "platform-dev": []
 }
diff --git a/config-templates/authmemcookie.php b/config-templates/authmemcookie.php
index b8e8df8f98a32f021dc994a48dbbbe4f885cba22..6fa872061d9e7580efadba42b56a67d36b11755e 100644
--- a/config-templates/authmemcookie.php
+++ b/config-templates/authmemcookie.php
@@ -33,7 +33,7 @@ $config = array(
 	 * Default:
 	 *  No default value.
 	 */
-	'username' => NULL,
+	'username' => null,
 
 	/*
 	 * This option specifies the name of the attribute which contains the groups of the user. Set this option to
@@ -43,9 +43,9 @@ $config = array(
 	 *  'groups' => 'edupersonaffiliation',
 	 *
 	 * Default:
-	 *  'groups' => NULL,
+	 *  'groups' => null,
 	 */
-	'groups' => NULL,
+	'groups' => null,
 
 	/*
 	 * This option contains the hostnames or IP addresses of the memcache servers where we should store the
diff --git a/config-templates/authsources.php b/config-templates/authsources.php
index 643c33221fd9095dd5aa14a4b511cf26c792bb89..5550b6d557b11c068fe534fc445c02ce409400b5 100644
--- a/config-templates/authsources.php
+++ b/config-templates/authsources.php
@@ -28,26 +28,6 @@ $config = array(
         // Can be NULL/unset, in which case a builtin discovery service will be used.
         'discoURL' => null,
 
-        /*
-         * WARNING: SHA-1 is disallowed starting January the 1st, 2014.
-         *
-         * Uncomment the following option to start using SHA-256 for your signatures.
-         * Currently, SimpleSAMLphp defaults to SHA-1, which has been deprecated since
-         * 2011, and will be disallowed by NIST as of 2014. Please refer to the following
-         * document for more information:
-         *
-         * http://csrc.nist.gov/publications/nistpubs/800-131A/sp800-131A.pdf
-         *
-         * If you are uncertain about identity providers supporting SHA-256 or other
-         * algorithms of the SHA-2 family, you can configure it individually in the
-         * IdP-remote metadata set for those that support it. Once you are certain that
-         * all your configured IdPs support SHA-2, you can safely remove the configuration
-         * options in the IdP-remote metadata set and uncomment the following option.
-         *
-         * Please refer to the hosted SP configuration reference for more information.
-          */
-        //'signature.algorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
-
         /*
          * The attributes parameter must contain an array of desired attributes by the SP.
          * The attributes can be expressed as an array of names or as an associative array
@@ -148,53 +128,6 @@ $config = array(
     ),
     */
 
-    /*
-    'openid' => array(
-        'openid:OpenIDConsumer',
-        'attributes.required' => array('nickname'),
-        'attributes.optional' => array('fullname', 'email',),
-        // 'sreg.validate' => FALSE,
-        'attributes.ax_required' => array('http://axschema.org/namePerson/friendly'),
-        'attributes.ax_optional' => array('http://axschema.org/namePerson','http://axschema.org/contact/email'),
-        // Prefer HTTP redirect over POST
-        // 'prefer_http_redirect' => FALSE,
-    ),
-    */
-
-    /*
-    // Example of an authsource that authenticates against Google.
-    // See: http://code.google.com/apis/accounts/docs/OpenID.html
-    'google' => array(
-        'openid:OpenIDConsumer',
-        // Googles OpenID endpoint.
-        'target' => 'https://www.google.com/accounts/o8/id',
-        // Custom realm
-        // 'realm' => 'http://*.example.org',
-        // Attributes that google can supply.
-        'attributes.ax_required' => array(
-            //'http://axschema.org/namePerson/first',
-            //'http://axschema.org/namePerson/last',
-            //'http://axschema.org/contact/email',
-            //'http://axschema.org/contact/country/home',
-            //'http://axschema.org/pref/language',
-        ),
-        // custom extension arguments
-        'extension.args' => array(
-            //'http://specs.openid.net/extensions/ui/1.0' => array(
-            //	'mode' => 'popup',
-            //	'icon' => 'true',
-            //),
-        ),
-    ),
-    */
-
-    /*
-    'papi' => array(
-        'authpapi:PAPI',
-    ),
-    */
-
-
     /*
     'facebook' => array(
         'authfacebook:Facebook',
@@ -242,17 +175,6 @@ $config = array(
     ),
     */
 
-    /*
-    // MySpace OAuth Authentication API.
-    // Register your application to get an API key here:
-    //  http://developer.myspace.com/
-    'myspace' => array(
-        'authmyspace:MySpace',
-        'key' => 'xxxxxxxxxxxxxxxx',
-        'secret' => 'xxxxxxxxxxxxxxxx',
-    ),
-    */
-
     /*
     // Microsoft Account (Windows Live ID) Authentication API.
     // Register your application to get an API key here:
diff --git a/config-templates/config.php b/config-templates/config.php
index ec3f97d3fe870db10189e8623af2da76679b2b32..f358b1bb9cc4283a5eae61f47bf507b2dfc6cd69 100644
--- a/config-templates/config.php
+++ b/config-templates/config.php
@@ -1,7 +1,7 @@
 <?php
-/* 
+/*
  * The configuration of SimpleSAMLphp
- * 
+ *
  */
 
 $config = array(
@@ -19,7 +19,6 @@ $config = array(
      * baseurlpath is a *URL path* (not a filesystem path).
      * A valid format for 'baseurlpath' is:
      * [(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/]
-     * (note that it must end with a '/')
      *
      * The full url format is useful if your SimpleSAMLphp setup is hosted behind
      * a reverse proxy. In that case you can specify the external url here.
@@ -49,7 +48,7 @@ $config = array(
          * need to compute the right URLs yourself and pass them dynamically
          * to SimpleSAMLphp's API.
          */
-        //'baseURL' => 'https://example.com'
+        //'baseURL' => 'https://example.com',
     //),
 
     /*
@@ -61,7 +60,7 @@ $config = array(
      * - 'temdir': Saving temporary files. SimpleSAMLphp will attempt to create
      *   this directory if it doesn't exist.
      * When specified as a relative path, this is relative to the SimpleSAMLphp
-     * root directory. 
+     * root directory.
      */
     'certdir' => 'cert/',
     'loggingdir' => 'log/',
@@ -104,7 +103,7 @@ $config = array(
      * 'secretsalt' can be any valid string of any length.
      *
      * A possible way to generate a random salt is by running the following command from a unix shell:
-     * tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' </dev/urandom | dd bs=32 count=1 2>/dev/null;echo
+     * LC_CTYPE=C tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' </dev/urandom | dd bs=32 count=1 2>/dev/null;echo
      */
     'secretsalt' => 'defaultsecretsalt',
 
@@ -232,11 +231,11 @@ $config = array(
     'errorreporting' => true,
 
     /*
-     * Custom error show function called from SimpleSAML_Error_Error::show.
+     * Custom error show function called from SimpleSAML\Error\Error::show.
      * See docs/simplesamlphp-errorhandling.txt for function code example.
      *
      * Example:
-     *   'errors.show_function' => array('sspmod_example_Error_Show', 'show'),
+     *   'errors.show_function' => array('SimpleSAML\Module\example\Error', 'show'),
      */
 
 
@@ -352,7 +351,7 @@ $config = array(
      * Example:
      *   'proxy.auth' = 'myuser:password'
      */
-    'proxy.auth' => false,
+    //'proxy.auth' => 'myuser:password',
 
 
 
@@ -378,6 +377,7 @@ $config = array(
      */
     'database.username' => 'simplesamlphp',
     'database.password' => 'secret',
+    'database.options' => array(),
 
     /*
      * (Optional) Table prefix
@@ -563,7 +563,7 @@ $config = array(
      * See docs/simplesamlphp-advancedfeatures.txt for function code example.
      *
      * Example:
-     *   'session.check_function' => array('sspmod_example_Util', 'checkSession'),
+     *   'session.check_function' => array('\SimpleSAML\Module\example\Util', 'checkSession'),
      */
 
 
@@ -740,7 +740,7 @@ $config = array(
      * the default language for the user.
      *
      * Example:
-     *   'language.get_language_function' => array('sspmod_example_Template', 'getLanguage'),
+     *   'language.get_language_function' => array('\SimpleSAML\Module\example\Template', 'getLanguage'),
      */
 
     /*
diff --git a/dictionaries/disco.translation.json b/dictionaries/disco.translation.json
index 8fea4c86f66085692a8be988c259f610109c63a4..6bdc2997250d8e38c39c433ae1796a8df68fe636 100644
--- a/dictionaries/disco.translation.json
+++ b/dictionaries/disco.translation.json
@@ -38,7 +38,7 @@
 		"no": "Vennligst velg hvilken identitetsleverand\u00f8r du vil bruke for \u00e5 logge inn:",
 		"nn": "Vel innloggingsteneste (IdP) der du \u00f8nskjer \u00e5 logga inn.",
 		"sv": "V\u00e4lj vilken identitetsleverant\u00f6r du vill logga in med:",
-		"es": "Por favor, seleccione el proveedor de identidad donde desea autenticarse",
+		"es": "Por favor, seleccione el proveedor de identidad que desea usar para autenticarse",
 		"fr": "S\u00e9lectionnez le fournisseur d'identit\u00e9 aupr\u00e8s duquel vous souhaitez vous authentifier :",
 		"de": "Bitte w\u00e4hlen Sie den Identity Provider, bei dem Sie sich authentifizieren m\u00f6chten:",
 		"nl": "Selecteer de Identity Provider waar je wil authenticeren:",
@@ -142,7 +142,7 @@
 	"icon_prefered_idp": {
 		"no": "[Foretrukket valg]",
 		"sv": "Prioriterat val",
-		"es": "[Opci\u00f3n preference]",
+		"es": "[Opci\u00f3n preferida]",
 		"de": "[Bevorzugte Auswahl]",
 		"nl": "[Voorkeurskeuze]",
 		"sl": "Prioritetna izbira",
@@ -177,7 +177,7 @@
 	"previous_auth": {
 		"no": "Du har tidligere valg \u00e5 autentisere deg hos",
 		"sv": "Du har  tidigare valt att logga in med",
-		"es": "Previamente solicit\u00f3 autenticarse en",
+		"es": "Previamente eligi\u00f3 autenticarse con",
 		"nl": "Je hebt eerder gekozen voor authenticatie bij",
 		"sl": "Predhodnje ste se prijavljali \u017ee pri",
 		"da": "Du har tidligere valgt at logge ind hos",
@@ -211,7 +211,7 @@
 	"login_at": {
 		"no": "Logg inn hos",
 		"sv": "Logga in med",
-		"es": "Identificarse en",
+		"es": "Iniciar sesi\u00f3n en",
 		"nl": "Inloggen bij",
 		"sl": "Prijavi se pri",
 		"da": "Login hos",
diff --git a/dictionaries/general.translation.json b/dictionaries/general.translation.json
index 8d36241bceeb72b1f361b8b5dd16728c77d57dad..b9c9cfb87724421b2bf56f35fa4e95dfb70f14e3 100644
--- a/dictionaries/general.translation.json
+++ b/dictionaries/general.translation.json
@@ -75,7 +75,7 @@
     "no": "Godta ogs\u00e5 for fremtiden",
     "nn": "Godta ogs\u00e5 for framtida",
     "sv": "Spara samtycke",
-    "es": "Recordar el consentimiento",
+    "es": "Recordar",
     "fr": "Se souvenir du consentement",
     "de": "Zustimmung merken",
     "nl": "Bewaar toestemming",
@@ -111,7 +111,7 @@
     "no": "Ja, fortsett",
     "nn": "Ja, fortsett",
     "sv": "Ja",
-    "es": "S\u00ed",
+    "es": "S\u00ed, continuar",
     "fr": "Oui",
     "de": "Ja, ich stimme zu",
     "nl": "Ja, ik ga akkoord",
@@ -147,7 +147,7 @@
     "no": "Nei, avbryt",
     "nn": "Nei, avbryt",
     "sv": "Nej",
-    "es": "No",
+    "es": "No, cancelar",
     "fr": "Non",
     "de": "Nein, ich stimme nicht zu",
     "nl": "Nee, ik weiger",
diff --git a/dictionaries/login.translation.json b/dictionaries/login.translation.json
index ac03e326cc5ba2f484c0afd01e3bd552fcf57ebc..0ba81bb79287829f7dd041018fa6a8705bbad9fa 100644
--- a/dictionaries/login.translation.json
+++ b/dictionaries/login.translation.json
@@ -3,7 +3,7 @@
 		"no": "Feil",
 		"nn": "Feil",
 		"sv": "Fel",
-		"es": "Los datos que ha suministrado no son v\u00e1lidos",
+		"es": "Error",
 		"fr": "Erreur",
 		"de": "Fehler",
 		"nl": "Fout",
@@ -40,7 +40,7 @@
 		"no": "Skriv inn brukernavn og passord",
 		"nn": "Skriv inn brukarnamn og passord",
 		"sv": "Ange ditt anv\u00e4ndarnamn och l\u00f6senord",
-		"es": "Indique su nombre de usuario y clave de acceso",
+		"es": "Introduzca su nombre de usuario y contrase\u00f1a",
 		"fr": "Entrez votre identifiant et votre mot de passe",
 		"de": "Bitten geben Sie ihren Nutzernamen und Passwort ein",
 		"nl": "Geef je gebruikersnaam en wachtwoord",
@@ -77,7 +77,7 @@
 		"no": "En tjeneste har bedt om bekreftelse p\u00e5 din identitet. Skriv inn ditt brukernavn og passord for \u00e5 autentisere deg.",
 		"nn": "Ei webteneste har spurt etter autentisering av deg. Skriv inn brukarnamnet ditt og passordet ditt for \u00e5 autentisera deg.",
 		"sv": "En webbtj\u00e4nst har beg\u00e4rt att du ska logga in. Detta betyder att du beh\u00f6ver ange ditt anv\u00e4ndarnamn och ditt l\u00f6senord i formul\u00e4ret nedan.",
-		"es": "Un servicio solicita que se autentique. Esto significa que debe indicar su nombre de usuario y su clave de acceso en el siguiente formulario.",
+		"es": "Un servicio solicita que se autentique. Por favor, introduzca su nombre de usuario y contrase\u00f1a en el siguiente formulario.",
 		"fr": "Un service a demand\u00e9 \u00e0 ce que vous vous authentifiez.  Cela signifie que vous devez entrer votre identifiant et votre mot de passe dans le formulaire ci-dessous.",
 		"de": "Um diesen Dienst zu nutzen, m\u00fcssen Sie sich authentifizieren. Bitte geben sie daher unten Nutzernamen und Passwort ein.",
 		"nl": "Voor deze dienst is authenticatie vereist. Geef je gebruikersnaam en wachtwoord in onderstaand formulier.",
@@ -113,7 +113,7 @@
 		"no": "Logg inn",
 		"nn": "Logg inn",
 		"sv": "Logga in",
-		"es": "Login",
+		"es": "Iniciar sesi\u00f3n",
 		"fr": "S'identifier",
 		"de": "Anmelden",
 		"nl": "Inloggen",
@@ -148,6 +148,7 @@
 		"el": "\u0395\u03af\u03c3\u03bf\u03b4\u03bf\u03c2"
 	},
 	"processing": {
+		"es": "Procesando...",
 		"zh-tw": "\u8655\u7406\u4e2d..."
 	},
 	"username": {
@@ -230,7 +231,7 @@
 		"no": "Passord",
 		"nn": "Passord",
 		"sv": "L\u00f6senord",
-		"es": "Clave de acceso",
+		"es": "Contrase\u00f1a",
 		"fr": "Mot de passe",
 		"de": "Passwort",
 		"nl": "Wachtwoord",
@@ -268,7 +269,7 @@
 		"no": "Hjelp! Jeg har glemt passordet mitt.",
 		"nn": "Hjelp! Eg har gl\u00f8ymd passordet mitt",
 		"sv": "Hj\u00e4lp! Jag kommer inte ih\u00e5g mitt l\u00f6senord.",
-		"es": "&iexcl;Socorro! Se me ha olvidado mi clave de acceso.",
+		"es": "\u00a1Ayuda! Se me ha olvidado la contrase\u00f1a.",
 		"fr": "\u00c0 l'aide!  Je ne me souviens plus de mon mot de passe.",
 		"de": "Hilfe, ich habe mein Passwort vergessen.",
 		"nl": "Help! Ik weet mijn wachtwoord niet meer.",
@@ -304,7 +305,7 @@
 		"no": "Synd! - Uten riktig brukernavn og passord kan du ikke autentisere deg. Det kan v\u00e6re noen som kan hjelpe deg. Fors\u00f8k \u00e5 kontakt brukerst\u00f8tte ved din vertsorganisasjon.",
 		"nn": "Synd! - Utan riktig brukarnamn og passord kan du ikkje autentisera deg.  Ta kontakt med brukarst\u00f8tte hos din organisasjon.",
 		"sv": "Tyv\u00e4rr kan du inte logga in i tj\u00e4nsten om du inte har ditt anv\u00e4ndarnamn och ditt l\u00f6senord. Ta kontakt med din organisations support eller helpdesk f\u00f6r att f\u00e5 hj\u00e4lp.",
-		"es": "&iexcl;Muy mal! - Sin su nombre de usuario y su clave de acceso usted no se puede identificar y acceder al servicio. A lo mejor hay alguien que puede ayudarle. &iexcl;P&oacute;ngase en contacto con el centro de ayuda de su universidad!",
+		"es": "Sin su nombre de usuario y contrase\u00f1a no se puede identificar y acceder al servicio. Quiz\u00e1s haya alguien que pueda ayudarle. \u00a1Contacte con el centro de atenci\u00f3n al usuario de su organizaci\u00f3n!",
 		"fr": "Pas de chance! Sans votre identifiant et votre mot de passe vous ne pouvez pas vous authentifier et acc\u00e9der au service. Il y a peut-\u00eatre quelqu'un pour vous aider.  Contactez le help desk de votre universit\u00e9!",
 		"de": "Tut uns leid - Ohne Nutzername und Passwort k\u00f6nnen Sie sich nicht authentifizieren und somit den Dienst nicht nutzen. M\u00f6glicherweise kann ihnen jemand helfen, kontaktieren Sie dazu den Helpdesk ihrer Einrichtung.",
 		"nl": "Zonder je gebruikersnaam en wachtwoord kun je je niet authenticeren en dus niet gebruikmaken van deze dienst.",
@@ -340,7 +341,7 @@
 		"no": "Du kontaktet loginsiden, men passordet ble ikke sendt med. Fors\u00f8k igjen.",
 		"nn": "Passordet blei ikkje sendt. Pr\u00f8v p\u00e5 nytt.",
 		"sv": "Du skicka in en inloggningsf\u00f6rfr\u00e5gan men det verkar som om ditt l\u00f6senord inte fanns med i f\u00f6rfr\u00e5gan. F\u00f6rs\u00f6k igen!",
-		"es": "Usted envi\u00f3 algo a la p\u00e1gina de acceso pero, por alg\u00fan motivo, la clave no fue enviada. Int\u00e9ntelo de nuevo, por favor.",
+		"es": "Usted envi\u00f3 algo a la p\u00e1gina de acceso pero, por alguna raz\u00f3n, no se envi\u00f3 la contrase\u00f1a. Int\u00e9ntelo de nuevo, por favor.",
 		"fr": "Vous avez envoy\u00e9 quelque chose sur la page d'identification mais pour une raison inconnue votre mot de passe n'a pas \u00e9t\u00e9 transmis. Veuillez r\u00e9essayer.",
 		"de": "Sie haben etwas an die Anmeldeseite geschickt, aber aus irgendeinem Grund ist das Passwort nicht \u00fcbermittelt worden. Bitte versuchen Sie es erneut.",
 		"nl": "Je hebt wel iets ingetikt, maar blijkbaar is je wachtwoord niet verstuurd. Probeer het opnieuw AUB.",
@@ -376,7 +377,7 @@
 		"no": "Feil brukernavn eller passord.",
 		"nn": "Feil brukarnamn eller passord.",
 		"sv": "Fel anv\u00e4ndarnamn eller l\u00f6senord.",
-		"es": "Nombre de usuario o contrase\u00f1a err\u00f3neos",
+		"es": "Nombre de usuario o contrase\u00f1a incorrectos",
 		"fr": "Mauvais identifiant ou mot de passe.",
 		"de": "Falscher Nutzername oder Passwort.",
 		"nl": "Gebruikersnaam of wachtwoord niet bekend.",
@@ -449,7 +450,7 @@
 		"no": "Velg vertsorganisasjon",
 		"nn": "Vel vertsorganisasjon",
 		"sv": "V\u00e4lj vilken organisation du kommer ifr\u00e5n",
-		"es": "Seleccione su organizaci\u00f3n origen",
+		"es": "Seleccione su organizaci\u00f3n de origen",
 		"fr": "Choisissez votre fournisseur.",
 		"de": "W\u00e4hlen sie die Einrichtung, von der Sie ihre Zugangsdaten beziehen",
 		"nl": "Kies je organisatie",
@@ -484,7 +485,7 @@
 		"no": "Endre din vertsorganisasjon",
 		"nn": "Endra vertsorganisasjon",
 		"sv": "\u00c4ndra vilken organisation du kommer ifr\u00e5n",
-		"es": "Cambiar su organizaci\u00f3n origen",
+		"es": "Cambiar la organizaci\u00f3n de origen",
 		"fr": "Changez votre fournisseur",
 		"de": "Eine andere Einrichtung, von der Sie Zugangsdaten erhalten, ausw\u00e4hlen",
 		"nl": "Verander je organisatie",
@@ -519,7 +520,7 @@
 		"no": "Du har valgt <b>%HOMEORG%<\/b> som din vertsorganisasjon. Dersom dette er feil kan du velge en annen.",
 		"nn": "Du har vald <b>%HOMEORG%<\/b> som din vertsorganisasjon.  Dersom dette er feil, kan du velja ein annan organisasjon fr\u00e5 menyen.",
 		"sv": "Du har valt <b>%HOMEORG%<\/b> som organisation du kommer ifr\u00e5n. Om detta \u00e4r fel s\u00e5 kan du v\u00e4lja en annan.",
-		"es": "Ha seleccionado <b>%HOMEORG%<\/b> como organizaci\u00f3n origen. Si esta informaci\u00f3n es incorrecta puede seleccionar otra.",
+		"es": "Ha seleccionado <b>%HOMEORG%<\/b> como organizaci\u00f3n de origen. Si esta informaci\u00f3n es incorrecta, puede seleccionar otra.",
 		"fr": "Vous avez choisi <b>%HOMEORG%<\/b> comme votre fournisseur. Si ce n'est pas correct, vous pouvez le changer.",
 		"de": "Sie haben <b>%HOMEORG%<\/b> als ihre Einrichtung gew\u00e4hlt, k\u00f6nnen diese Auswahl aber noch \u00e4ndern.",
 		"nl": "Je hebt <b>%HOMEORG%<\/b> gekozen als je organisatie. Als dit niet correct is kun je een andere keuze maken.",
@@ -554,7 +555,7 @@
 		"no": "Velg vertsorganisasjon",
 		"nn": "Vel vertsorganisasjon",
 		"sv": "\u00c4ndra organisation",
-		"es": "Seleccionar la organizaci\u00f3n origen",
+		"es": "Seleccione su organizaci\u00f3n de origen",
 		"fr": "Choisissez votre fournisseur.",
 		"de": "Einrichtung ausw\u00e4hlen",
 		"nl": "Kies je organisatie",
@@ -589,7 +590,7 @@
 		"no": "Hjemmesiden til brukerst\u00f8tte",
 		"nn": "Heimeside for brukarst\u00f8tte",
 		"sv": "Hemsida f\u00f6r helpdesk",
-		"es": "P\u00e1gina de soporte t\u00e9cnico",
+		"es": "P\u00e1gina del centro de atenci\u00f3n al usuario",
 		"fr": "Page web de l'assistance technique",
 		"de": "Seite des Helpdesk",
 		"nl": "Helpdesk homepage",
@@ -624,7 +625,7 @@
 		"no": "Send e-post til brukerst\u00f8tte",
 		"nn": "Send epost til brukarst\u00f8tte",
 		"sv": "Skicka e-post till helpdesk",
-		"es": "Enviar correo electr\u00f3nico al soporte t\u00e9cnico",
+		"es": "Enviar correo electr\u00f3nico al centro de atenci\u00f3n al usuario",
 		"fr": "Assistance technique par courriel",
 		"de": "Email an den Helpdesk senden",
 		"nl": "Stuur een e-mail naar de helpdesk",
diff --git a/dictionaries/logout.translation.json b/dictionaries/logout.translation.json
index dd7e2ead5e218163061b0da4104bf418b41e31dd..8cfb40d2a8e01a10861a5bf92f1c8a477a23e437 100644
--- a/dictionaries/logout.translation.json
+++ b/dictionaries/logout.translation.json
@@ -3,7 +3,7 @@
 		"no": "Utlogget",
 		"nn": "Utlogga",
 		"sv": "Utloggad",
-		"es": "Desconectado",
+		"es": "SesiĂłn cerrada",
 		"fr": "D\u00e9connect\u00e9",
 		"de": "Abgemeldet",
 		"nl": "Uitgelogd",
@@ -38,7 +38,7 @@
 		"no": "Du er n\u00e5 utlogget.",
 		"nn": "Du har blitt logga ut.  Takk for at du brukte denne tenesta.",
 		"sv": "Du har blivit uloggad. Tack f\u00f6r att du anv\u00e4nde denna tj\u00e4nst.",
-		"es": "Ha sido desconectado. Gracias por usar este servicio.",
+		"es": "Se ha cerrado la sesiĂłn.",
 		"fr": "Vous avez \u00e9t\u00e9 d\u00e9connect\u00e9. Merci d'avoir utilis\u00e9 ce service.",
 		"de": "Sie wurden abgemeldet. Danke, dass Sie diesen Dienst verwendet haben.",
 		"nl": "U bent uitgelogd. Dank u voor het gebruiken van deze dienst.",
@@ -178,7 +178,7 @@
 		"no": "Logger ut...",
 		"nn": "Loggar ut...",
 		"sv": "Loggar ut...",
-		"es": "Desconectando...",
+		"es": "Cerrando la sesi\u00f3n...",
 		"fr": "D\u00e9connexion...",
 		"de": "Abmeldung l\u00e4uft...",
 		"nl": "Uitloggen...",
@@ -213,7 +213,7 @@
 		"no": "Utlogging feilet",
 		"nn": "Utlogging feila",
 		"sv": "Utloggning misslyckades",
-		"es": "Proceso de desconexi\u00f3n fallido",
+		"es": "El cierre de sesi\u00f3n ha fallado",
 		"fr": "\u00c9chec de la d\u00e9connexion",
 		"de": "Abmeldung fehlgeschlagen",
 		"nl": "Uitloggen mislukt",
@@ -283,7 +283,7 @@
 		"no": "Du har n&aring; logget ut fra alle tjenestene listet ovenfor.",
 		"nn": "Du er ferdig utlogga fr\u00e5 alle tenestene",
 		"sv": "Du har loggat ut fr\u00e5n alla nedanst\u00e5ende tj\u00e4nster.",
-		"es": "Ha sido correctamente desconectado de todo los servicios listados a continuaci\u00f3n",
+		"es": "Ha cerrado las sesiones de todos los servicios listados m\u00e1s arriba",
 		"fr": "Vous avez \u00e9t\u00e9 d\u00e9connect\u00e9 avec succ\u00e8s des services list\u00e9s ci dessus",
 		"de": "Sie haben sich erfolgreich von allen obenstehenden Diensten abgemeldet.",
 		"nl": "Je bent succesvol uitgelogd van de bovenvermelde services.",
@@ -318,7 +318,7 @@
 		"no": "Du er n\u00e5 logget ut fra %SP%.",
 		"nn": "Du er ferdig utlogga fr\u00e5 %SP%.",
 		"sv": "Du har nu loggat ut fr\u00e5n %SP%.",
-		"es": "Ha sido desconectado correctamente de %SP%.",
+		"es": "Ha cerrado correctamente la sesiĂłn en %SP%.",
 		"fr": "Vous avez \u00e9t\u00e9 d\u00e9connect\u00e9 de %SP%.",
 		"de": "Sie wurden nun erfolgreich von %SP% abgemeldet",
 		"nl": "Je bent nu succesvol uitgelogd van %SP%.",
@@ -388,7 +388,7 @@
 		"no": "Vil du logge ut fra alle tjenestene ovenfor?",
 		"nn": "Vil du logga ut fr\u00e5 alle tenestene?",
 		"sv": "Vill du logga ut fr\u00e5n alla ovanst\u00e5ende tj\u00e4nster?",
-		"es": "\u00bfDesea desconectarse de todos los servicios que se muestran m\u00e1s arriba?",
+		"es": "\u00bfDesea cerrar las sesiones de todos los servicios que se muestran m\u00e1s arriba?",
 		"fr": "Voulez vous r\u00e9ellement terminer les connexions \u00e0 tout ces services?",
 		"de": "Wollen Sie sich von allen obenstehenden Diensten abmelden?",
 		"nl": "Wil je uitloggen van alle bovenvermelde diensten?",
@@ -423,7 +423,7 @@
 		"no": "Ja, alle tjenestene over",
 		"nn": "Ja, logg ut fr\u00e5 alle",
 		"sv": "Ja, alla tj\u00e4nster",
-		"es": "Si, todos los servicios",
+		"es": "S\u00ed, de todos los servicios",
 		"fr": "Oui, de tous les services",
 		"de": "Ja, alle Dienste",
 		"nl": "Ja, alle diensten",
@@ -458,7 +458,7 @@
 		"no": "Nei, bare %SP%",
 		"nn": "Nei, logg berre ut fr\u00e5 %SP%",
 		"sv": "Nej, endast %SP%",
-		"es": "No, s\u00f3lo %SPS",
+		"es": "No, s\u00f3lo de %SP%",
 		"fr": "Non, seulement de %SP%",
 		"de": "Nein, nur %SP%",
 		"nl": "Nee, alleen %SP%",
@@ -493,7 +493,7 @@
 		"no": "En eller flere av tjenestene du er logget inn p\u00e5 <i>st\u00f8tter ikke logout<\/i>. Lukk nettleseren, dersom du \u00f8nsker \u00e5 logge ut fra disse tjenestene.",
 		"nn": "Ei eller fleire av tenestene du er innlogga p\u00e5 <i>st\u00f8tter ikkje utlogging<\/i>.  Lukk weblesaren din for \u00e5 sikra at alle sesjonar blir lukka",
 		"sv": "En eller flera av tj\u00e4nsterna du \u00e4r inloggad i <i>kan inte hantera utloggning<\/i>. F\u00f6r att s\u00e4kerst\u00e4lla att du inte l\u00e4ngre \u00e4r inloggad i n\u00e5gon tj\u00e4nst ska du <i>st\u00e4nga din webbl\u00e4sare<\/i>.",
-		"es": "Uno o m\u00e1s de los servicios en los que est\u00e1 autenticado <i>no permite desconexi\u00f3n<\/i>. Para asegurarse de que todas sus sesiones se cierran, se le recomienda que <i>cierre todas las ventanas de su navegador<\/i>.",
+		"es": "Uno o m\u00e1s de los servicios en los que est\u00e1 autenticado <i>no permite desconexi\u00f3n<\/i>. Para asegurarse de que todas sus sesiones se cierran, se le recomienda que <i>cierre su navegador<\/i>.",
 		"fr": "Un ou plusieurs des services auxquels vous \u00eates connect\u00e9 <i>ne g\u00e8rent pas la d\u00e9connexion<\/i>. Pour terminer les sessions sur ces services, vous devrez <i>fermer votre navigateur<\/i>.",
 		"de": "Einer oder mehrere Dienste an denen Sie angemeldet sind, <i>unterst\u00fctzen keine Abmeldung<\/i>. Um sicherzustellen, dass Sie abgemeldet sind, <i>schlie\u00dfen Sie bitte Ihren Webbrowser<\/i>.",
 		"nl": "Een of meer diensten waarop je bent inlogd hebben <i>geen ondersteuning voor uitloggen<\/i>. Om er zeker van te zijn dat al je sessies zijn be\u00ebindigd, kun je het beste <i>je webbrowser afsluiten<\/i>.",
@@ -571,7 +571,7 @@
 		"fr": "D\u00e9connexion des services suivants :",
 		"lt": "Vyksta atjungimas nuo \u0161i\u0173 paslaug\u0173:",
 		"it": "Disconnessione in corso dai seguenti servizi:",
-		"es": "Desconectarse de los siguientes servicios:",
+		"es": "Cerrando las sesiones de los siguientes servicios:",
 		"hu": "Kil\u00e9p\u00e9s az al\u00e1bbi szolg\u00e1ltat\u00e1sokb\u00f3l:",
 		"ja": "\u4ee5\u4e0b\u306e\u30b5\u30fc\u30d3\u30b9\u304b\u3089\u30ed\u30b0\u30a2\u30a6\u30c8\u3057\u307e\u3057\u305f:",
 		"nl": "Uitloggen van de volgende diensten:",
@@ -605,7 +605,7 @@
 		"fr": "Impossible de se d\u00e9connecter d'un ou plusieurs services. Pour \u00eatre certain de clore vos sessions, il vous est recommand\u00e9 de <i>fermer votre navigateur<\/i>.",
 		"lt": "Nepavyksta atsijungti nuo vienos ar daugiau paslaug\u0173. Siekiant u\u017etikrinti s\u0117kming\u0105 darbo pabaig\u0105, rekomenduojame <i>u\u017edaryti nar\u0161ykl\u0119<\/i>.",
 		"it": "Impossibile disconnettersi da uno o pi\u00f9 servizi. Per assicurarsi di chiudere tutte le sessioni si consiglia di <i>chiudere il browser<\/i>",
-		"es": "Imposible desconectarse de uno o m\u00e1s servicios. Para asegurar que todas sus sesiones han sido cerradas, se recomienda que <i>cierre su navegador web<\/i>.",
+		"es": "No fue posible desconectarse de uno o m\u00e1s servicios. Para garantizar que todas sus sesiones han sido cerradas, se recomienda que <i>cierre su navegador web<\/i>.",
 		"hu": "Legal\u00e1bb egy szolg\u00e1ltat\u00e1sb\u00f3l nem siker\u00fclt kil\u00e9pni. Ahhoz, hogy biztosan lez\u00e1rja a megkezdett munkamenetet, k\u00e9rj\u00fck, <i>z\u00e1rja be b\u00f6ng\u00e9sz\u0151j\u00e9t<\/i>.",
 		"ja": "\u4e00\u3064\u4ee5\u4e0a\u306e\u30b5\u30fc\u30d3\u30b9\u304b\u305f\u30ed\u30b0\u30a2\u30a6\u30c8\u51fa\u6765\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u78ba\u5b9f\u306b\u30bb\u30c3\u30b7\u30e7\u30f3\u3092\u7d42\u4e86\u3055\u305b\u308b\u306b\u306f\u3001<i>WEB\u30d6\u30e9\u30a6\u30b6\u3092\u9589\u3058\u308b<\/i>\u4e8b\u3092\u63a8\u5968\u3057\u307e\u3059\u3002",
 		"nl": "Het was niet mogelijk bij een of meerdere diensten uit te loggen. Om alle sessies te sluiten, raden wij u aan uw <i>webbrowser te af te sluiten<\/i>.",
diff --git a/dictionaries/status.definition.json b/dictionaries/status.definition.json
index 57030aaab4db1ee8fb8ce483d492548e2b83ed39..a82c97fcbe51e94ed24241089cac7efe86b9a226 100644
--- a/dictionaries/status.definition.json
+++ b/dictionaries/status.definition.json
@@ -37,5 +37,11 @@
 	},
 	"logout": {
 		"en": "Logout"
+	},
+	"authData_header": {
+		"en": "AuthData"
+	},
+	"authData_summary": {
+		"en": "Click to view AuthData"
 	}
 }
diff --git a/docs/index.md b/docs/index.md
index 8bb3cea2220587b33c7e990cb242a027614953f2..e9e48e3691d31631680f87500cb2169ca6711ec7 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -2,6 +2,7 @@ SimpleSAMLphp Documentation
 ===========================
 
  * [Installing SimpleSAMLphp](simplesamlphp-install)
+    * [Upgrade notes for version 1.16](simplesamlphp-upgrade-notes-1.16)
     * [Upgrade notes for version 1.15](simplesamlphp-upgrade-notes-1.15)
     * [Upgrade notes for version 1.14](simplesamlphp-upgrade-notes-1.14)
     * [Upgrade notes for version 1.13](simplesamlphp-upgrade-notes-1.13)
diff --git a/docs/simplesamlphp-advancedfeatures.md b/docs/simplesamlphp-advancedfeatures.md
index 71abf8f56072b624191d758697b6f1bbe314f520..adb7c2486569474a69930c1dc1117b1b3de6fbfc 100644
--- a/docs/simplesamlphp-advancedfeatures.md
+++ b/docs/simplesamlphp-advancedfeatures.md
@@ -93,11 +93,12 @@ SimpleSAMLphp supports signing of the metadata it generates. Metadata signing is
 - `metadata.sign.privatekey`: Name of the file with the private key which should be used to sign the metadata. This file must exist in in the `cert` directory.
 - `metadata.sign.privatekey_pass`: Passphrase which should be used to open the private key. This parameter is optional, and should be left out if the private key is unencrypted.
 - `metadata.sign.certificate`: Name of the file with the certificate which matches the private key. This file must exist in in the `cert` directory.
-- `metadata.sign.algorithm`: The algorithm to use when signing metadata for this entity. Defaults to RSA-SHA1. Possible values:
+- `metadata.sign.algorithm`: The algorithm to use when signing metadata for this entity. Defaults to RSA-SHA256. Possible values:
 
     * `http://www.w3.org/2000/09/xmldsig#rsa-sha1`
        *Note*: the use of SHA1 is **deprecated** and will be disallowed in the future.
     * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha256`
+      The default.
     * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha384`
     * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha512`
 
@@ -126,7 +127,7 @@ Example code for the function with GeoIP country check:
         }
 
         if ($init) {
-            $session->setData($data_type, $data_key, $remote_addr, SimpleSAML_Session::DATA_TIMEOUT_SESSION_END);
+            $session->setData($data_type, $data_key, $remote_addr, \SimpleSAML\Session::DATA_TIMEOUT_SESSION_END);
             return;
         }
 
@@ -146,7 +147,7 @@ Example code for the function with GeoIP country check:
 
         if ($country_a === $country_b) {
             if ($stored_remote_addr !== $remote_addr) {
-                $session->setData($data_type, $data_key, $remote_addr, SimpleSAML_Session::DATA_TIMEOUT_SESSION_END);
+                $session->setData($data_type, $data_key, $remote_addr, \SimpleSAML\Session::DATA_TIMEOUT_SESSION_END);
             }
 
             return TRUE;
diff --git a/docs/simplesamlphp-authproc.md b/docs/simplesamlphp-authproc.md
index d8523d10ddad98831e784c7b48f32dd633ab6f40..be91c42071ab10070e6f8fcb3e45c19c253ef64f 100644
--- a/docs/simplesamlphp-authproc.md
+++ b/docs/simplesamlphp-authproc.md
@@ -61,7 +61,7 @@ The configuration of *Auth Proc Filters* is a list of filters with priority as *
 
 This configuration will execute *Auth Proc Filters* one by one, with the priority value in increasing order. When *Auth Proc Filters* is configured in multiple places, in example both globally, in the hosted IdP and remote SP metadata, then the list is interleaved sorted by priority.
 
-The most important parameter of each item on the list is the *class* of the *Auth Proc Filter*. The syntax of the class is `modulename:classname`. As an example the class definition `core:AttributeLimit` will be expanded to look for the class `sspmod_core_Auth_Process_AttributeLimit`. The location of this class file *must* then be: `modules/core/lib/Auth/Process/AttributeLimit.php`.
+The most important parameter of each item on the list is the *class* of the *Auth Proc Filter*. The syntax of the class is `modulename:classname`. As an example the class definition `core:AttributeLimit` will be expanded to look for the class `\SimpleSAML\Module\core\Auth\Process\AttributeLimit`. The location of this class file *must* then be: `modules/core/lib/Auth/Process/AttributeLimit.php`.
 
 You will see that a bunch of useful filters is included in the `core` module. In addition the `consent` module that is included in the SimpleSAMLphp distribution implements a filter. Beyond that, you are encouraged to create your own filters and share with the community. If you have created a cool *Auth Proc Filter* that does something useful, let us know, and we may share it on the [SimpleSAMLphp web site][].
 
@@ -151,6 +151,8 @@ The following filters are included in the SimpleSAMLphp distribution:
 - [`saml:TransientNameID`](./saml:nameid): Generate transient NameID.
 - [`smartattributes:SmartID`](./smartattributes:smartattributes): Generate user ID attribute based on several attributes.
 
+See the [Third-party modules](https://simplesamlphp.org/modules) page on the SimpleSAMLphp website
+for externally hosted modules that may provide a processing filter.
 
 
 Writing your own Auth Proc Filter
@@ -158,16 +160,16 @@ Writing your own Auth Proc Filter
 
 Look at the included *Auth Proc Filters* as examples. Copy the classes into your own module and start playing around.
 
-Authentication processing filters are created by creating a class under `Auth/Process/` in a module. This class is expected to subclass `SimpleSAML_Auth_ProcessingFilter`. A filter must implement at least one function - the `process(&$request)`-function. This function can access the `$request`-array to add, delete and modify attributes, and can also do more advanced processing based on the SP/IdP metadata (which is also included in the `$request`-array). When this function returns, it is assumed that the filter has finished processing.
+Authentication processing filters are created by creating a class under `Auth/Process/` in a module. This class is expected to subclass `\SimpleSAML\Auth\ProcessingFilter`. A filter must implement at least one function - the `process(&$request)`-function. This function can access the `$request`-array to add, delete and modify attributes, and can also do more advanced processing based on the SP/IdP metadata (which is also included in the `$request`-array). When this function returns, it is assumed that the filter has finished processing.
 
-If a filter for some reason needs to redirect the user, for example to show a web page, it should save the current request. Upon completion it should retrieve the request, update it with the changes it is going to make, and call `SimpleSAML_Auth_ProcessingChain::resumeProcessing`. This function will continue processing the next configured filter.
+If a filter for some reason needs to redirect the user, for example to show a web page, it should save the current request. Upon completion it should retrieve the request, update it with the changes it is going to make, and call `\SimpleSAML\Auth\ProcessingChain::resumeProcessing`. This function will continue processing the next configured filter.
 
 Requirements for authentication processing filters:
 
- - Must be derived from the `SimpleSAML_Auth_ProcessingFilter`-class.
+ - Must be derived from the `\SimpleSAML\Auth\ProcessingFilter`-class.
  - If a constructor is implemented, it must first call the parent constructor, passing along all parameters, before accessing any of the parameters. In general, only the $config parameter should be accessed.
  - The `process(&$request)`-function must be implemented. If this function completes, it is assumed that processing is completed, and that the $request array has been updated.
- - If the `process`-function does not return, it must at a later time call `SimpleSAML_Auth_ProcessingChain::resumeProcessing` with the new request state. The request state must be an update of the array passed to the `process`-function.
+ - If the `process`-function does not return, it must at a later time call `\SimpleSAML\Auth\ProcessingChain::resumeProcessing` with the new request state. The request state must be an update of the array passed to the `process`-function.
  - No pages may be shown to the user from the `process`-function. Instead, the request state should be saved, and the user should be redirected to a new page. This must be done to prevent unpredictable events if the user for example reloads the page.
  - No state information should be stored in the filter object. It must instead be stored in the request state array. Any changes to variables in the filter object may be lost.
  - The filter object must be serializable. It may be serialized between being constructed and the call to the `process`-function. This means that, for example, no database connections should be created in the constructor and later used in the `process`-function.
diff --git a/docs/simplesamlphp-authsource.md b/docs/simplesamlphp-authsource.md
index 514b96f3614fb83a39688f6069770c23f04853f5..4ffd228ec7fea3b1b0b1659176d6c6dd309b4af3 100644
--- a/docs/simplesamlphp-authsource.md
+++ b/docs/simplesamlphp-authsource.md
@@ -1,8 +1,8 @@
 Creating authentication sources
 ===============================
 
-All authentication sources are located in the `lib/Auth/Source/` directory in a module, and the class name is `sspmod_<module>_Auth_Source_<name>`.
-The authentication source must extend the `SimpleSAML_Auth_Source` class or one of its subclasses.
+All authentication sources are located in the `lib/Auth/Source/` directory in a module, and the class name is `\SimpleSAML\Module\<module>\Auth\Source\<name>`.
+The authentication source must extend the `\SimpleSAML\Auth\Source` class or one of its subclasses.
 
 The "entry point" of an authentication source is the `authenticate()`-function.
 Once that function is called, the authentication module can do whatever it wishes to do.
@@ -13,18 +13,18 @@ There are only two requirements:
 
 - Return control to SimpleSAMLphp after authenticating the user.
   If the module is able to authenticate the user without doing any redirects, it should just update the state-array and return.
-  If the module does a redirect, it must call `SimpleSAML_Auth_Source::completeAuth()` with the updated state array.
+  If the module does a redirect, it must call `\SimpleSAML\Auth\Source::completeAuth()` with the updated state array.
 
 Everything else is up to the module.
 If the module needs to redirect the user, for example because it needs to show the user a page asking for credentials, it needs to save the state array.
-For that we have the `SimpleSAML_Auth_State` class.
+For that we have the `\SimpleSAML\Auth\State` class.
 This is only a convenience class, and you are not required to use it (but its use is encouraged, since it handles some potential pitfalls).
 
 
 Saving state
 ------------
 
-The `SimpleSAML_Auth_State` class has two functions that you should use:
+The `\SimpleSAML\Auth\State` class has two functions that you should use:
 `saveState($state, $stage)`, and `loadState($id, $stage)`.
 The `$stage` parameter must be an unique identifier for the current position in the authentication.
 It is used to prevent a malicious user from taking a state you save in one location, and give it to a different location.
@@ -36,13 +36,13 @@ Username/password authentication
 --------------------------------
 
 Since username/password authentication is quite a common operation, a base class has been created for this.
-This is the `sspmod_core_Auth_UserPassBase` class, which is can be found as `modules/core/lib/Auth/UserPassBase.php`.
+This is the `\SimpleSAML\Module\core\Auth\UserPassBase` class, which is can be found as `modules/core/lib/Auth/UserPassBase.php`.
 
 The only function you need to implement is the `login($username, $password)`-function.
 This function receives the username and password the user entered, and is expected to return the attributes of that user.
 If the username or password is incorrect, it should throw an error saying so:
 
-    throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+    throw new \impleSAML\Error\Error('WRONGUSERPASS');
 
 "[Implementing custom username/password authentication](./simplesamlphp-customauth)" describes how to implement username/password authentication using that base class.
 
@@ -51,7 +51,7 @@ Generic rules & requirements
 ----------------------------
 
 -  
-    Must be derived from the `SimpleSAML_Auth_Source`-class.
+    Must be derived from the `\SimpleSAML\Auth\Source`-class.
 
     **Rationale**:
      - Deriving all authentication sources from a single base class allows us extend all authentication sources by extending the base class.
@@ -62,7 +62,7 @@ Generic rules & requirements
 
     **Rationale**:
      - PHP doesn't automatically call any parent constructor, so it needs to be done manually.
-     - The `$info`-array is used to provide information to the `SimpleSAML_Auth_Source` base class, and therefore needs to be included.
+     - The `$info`-array is used to provide information to the `\SimpleSAML\Auth\Source` base class, and therefore needs to be included.
      - Including the `$config`-array makes it possible to add generic configuration options that are valid for all authentication sources.
 
 -  
@@ -74,7 +74,7 @@ Generic rules & requirements
        This can be used if the authentication doesn't require user input, for example if the authentication can be done based on the IP-address of the user.
 
 -  
-    If the `authenticate`-function does not return, it must at a later time call `SimpleSAML_Auth_Source::completeAuth` with the new state array.
+    If the `authenticate`-function does not return, it must at a later time call `\SimpleSAML\Auth\Source::completeAuth` with the new state array.
     The state array must be an update of the array passed to the `authenticate`-function.
 
     **Rationale**:
diff --git a/docs/simplesamlphp-changelog.md b/docs/simplesamlphp-changelog.md
index 9c4184c6e5ed668fd16cadd947d361ca157b13be..707d1fb397a08bf3f4529d1fc8b77ddc1d566f97 100644
--- a/docs/simplesamlphp-changelog.md
+++ b/docs/simplesamlphp-changelog.md
@@ -6,6 +6,140 @@ SimpleSAMLphp changelog
 This document lists the changes between versions of SimpleSAMLphp.
 See the upgrade notes for specific information about upgrading.
 
+## Version 1.16.0
+
+Released TBD
+
+### Changes
+  * Default signature algorithm is now SHA-256.
+  * Renamed class `SimpleSAML_Error_BadUserInnput` to `SimpleSAML_Error_BadUserInput`
+  * PHP 7.2 compatibility, including removing deprecated use of assert with string.
+  * Avoid logging database credentials in backtraces.
+  * Updated Spanish translation.
+  * Improvements to documentation, testsuite, code quality and coding style.
+
+### New features
+  * Added support for SAML "Enhanced Client or Proxy" (ECP) protocol,
+    IdP side with HTTP Basic Authentcation as authentication method.
+    See the [ECP IdP documentation](./simplesamlphp-ecp-idp) for details.
+  * New option `sendmail_from`, the from address for email sent by SSP.
+  * New option `options` for PDO database connections, e.g. for TLS setup.
+  * New option `search.scope` for LDAP authsources.
+  * Add support for the DiscoHints IPHint metadata property.
+  * Add support to specify metadata XML in config with the `xml` parameter,
+    next to the exising `file` and `url` options.
+  * Also support CGI/RewriteRule setups that set the `REDIRECT_SIMPLESAMLPHP_CONFIG_DIR`
+    environment variable next to regular `SIMPLESAMLPHP_CONFIG_DIR`.
+  * Support creating an AuthSource via factory, for example useful in tests.
+  * Support preloading of a virtual config file via `SimpleSAML_Configuration::setPreLoadedConfig`
+    to allow for dynamic population of authsources.php.
+  * Fix edge case in getServerPort.
+  * Add basic documentation on Nginx configuration.
+  * Test authentication: optionally show AuthData array.
+  * Improve performance of PDO Metadata Storage handler entity lookup.
+
+### adfs
+  * Make signature algorithm configurable with `signature.algorithm`.
+  * Use configuration assertion lifetime when available.
+  * Use `adfs:wreply` parameter when available.
+
+### authmyspace
+  * Module removed because service is no longer available.
+
+### cas
+  * Respect all LDAP options in LDAP call.
+
+### consent
+  * Sort attribute values for consent.
+  * Fix table layout for MySQL > 5.6.
+  * Rename `noconsentattributes` to `attributes.exclude`; the former
+    is now considered deprecated.
+
+### consentAdmin
+  * Work better with TargetedIDs when operating as a proxy.
+  * Add `attributes.exclude` option to correspond to the same option
+    in the Consent module.
+
+### core
+  * StatisticsWithAttribute: add `passive-` prefix when logging passive
+    requests, set new option `skipPassive` to skip logging these altogether.
+  * Replace deprecated `create_function` with an anonymous function.
+  * New authproc filter Cardinality to enforce attribute cardinality.
+  * SQLPermanentStorage: proper expiration of stored values.
+  * AttributeLimit: new options `regex` and `ignoreCase`.
+  * AttributeMap: prevent possible infinite loop with some PHP versions.
+
+### ldap
+  * AttributeAddUsersGroups: if attribute.groupname is set, use the
+    configured attribute as the group name rather than the DN.
+  * Also base64encode the `ms-ds-consistencyguid` attribute.
+
+### metarefresh
+  * Return XML parser error for better debugging of problems.
+  * Only actually parse metadata types that have been enabled.
+  * Fix missing translation.
+
+### Oauth
+  * Make module HTTP proxy-aware.
+  * Remove unused demo app.
+
+### saml
+  * AttributeConsumingService: allow to set isDefault and index options.
+  * Encrypted attributes in an assertion are now decrypted correctly.
+
+### smartattributes
+  * Fix to make the `add_authority` option work.
+
+### sqlauth
+  * Changed from default-enabled to default-disabled.
+
+### statistics
+  * Show decent error message when no data is available.
+
+## Version 1.15.4
+
+Released 2018-03-02
+
+  * Resolved a security issue related to signature validation in the SAML2 library. See [SSPSA 201803-01](https://simplesamlphp.org/security/201803-01).
+
+## Version 1.15.3
+
+Released 2018-02-27
+
+  * Resolved a security issue related to signature validation in the SAML2 library. See [SSPSA 201802-01](https://simplesamlphp.org/security/201802-01).
+  * Fixed edge-case scenario where an application uses one of the known LoggingHandlers' name as a defined class
+  * Fixed issue #793 in the PHP logging handler.
+
+## Version 1.15.2
+
+Released 2018-01-31
+
+  * Resolved a Denial of Service security issue when validating timestamps in the SAML2 library. See [SSPSA 201801-01](https://simplesamlphp.org/security/201801-01).
+  * Resolved a security issue with the open redirect protection mechanism. See [SSPSA 201801-02](https://simplesamlphp.org/security/201801-02).
+  * Fix _undefined method_ error when using memcacheD.
+
+### `authfacebook`
+  * Fix compatibility with Facebook strict URI match.
+
+### `consent`
+  * Fix statistics not being gathered.
+
+### `sqlauth`
+  * Prevented a security issue with the connection charset used for MySQL backends. See [SSPSA 201801-03](https://simplesamlphp.org/security/201801-03).
+
+## Version 1.15.1
+
+Released 2018-01-12
+
+### Bug fixes
+  * AuthX509 error messages were broken.
+  * Properly calculate supported protocols based on config.
+  * NameIDAttribute filter: update to use SAML2\XML\saml\NameID.
+  * Replace remaining uses of SimpleSAML_Logger with namespace version.
+  * Statistics: prevent mixed content errors.
+  * Add 'no-store' to the cache-control header to avoid Chrome
+    caching redirects.
+
 ## Version 1.15.0
 
 Released 2017-11-20
@@ -134,6 +268,12 @@ Released 2017-11-20
 ### `sqlauth`
   * Fixed SQL schema for usergroups table.
 
+## Version 1.14.17
+
+Released 2017-10-25
+
+  * Resolved a security issue with the SAML 1.1 Service Provider. See [SSPSA 201710-01](https://simplesamlphp.org/security/201710-01).
+
 ## Version 1.14.16
 
 Released 2017-09-04
diff --git a/docs/simplesamlphp-customauth.md b/docs/simplesamlphp-customauth.md
index 8f7c30f9fd5e3826307cb70d758ac80933438377..d3df73277a925af8aa9b3f80ee66a0ed39863253 100644
--- a/docs/simplesamlphp-customauth.md
+++ b/docs/simplesamlphp-customauth.md
@@ -40,10 +40,10 @@ To begin with, we will create a very simple authentication source, where the use
 Create the file `modules/mymodule/lib/Auth/Source/MyAuth.php` with the following contents:
 
     <?php
-    class sspmod_mymodule_Auth_Source_MyAuth extends sspmod_core_Auth_UserPassBase {
+    class MyAuth extends \SimpleSAML\Module\core\Auth\UserPassBase {
         protected function login($username, $password) {
             if ($username !== 'theusername' || $password !== 'thepassword') {
-                throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+                throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
             }
             return array(
                 'uid' => array('theusername'),
@@ -55,16 +55,16 @@ Create the file `modules/mymodule/lib/Auth/Source/MyAuth.php` with the following
 
 Some things to note:
 
-  - The classname is `sspmod_mymodule_Auth_Source_MyAuth`.
+  - The classname is `\SimpleSAML\Module\mymodule\Auth\Source\MyAuth`.
     This tells SimpleSAMLphp to look for the class in `modules/mymodule/lib/Auth/Source/MyAuth.php`.
 
-  - Our authentication source subclassese `sspmod_core_Auth_UserPassBase`.
+  - Our authentication source subclassese `\SimpleSAML\Module\core\Auth\UserPassBase`.
     This is a helper-class that implements much of the common code needed for username/password authentication.
 
   - The `login` function receives the username and password the user enters.
     It is expected to authenticate the user.
     If the username or password is correct, it must return a set of attributes for the user.
-    Otherwise, it must throw the `SimpleSAML_Error_Error('WRONGUSERPASS');` exception.
+    Otherwise, it must throw the `\SimpleSAML\Error\Error('WRONGUSERPASS');` exception.
 
   - Attributes are returned as an associative array of `name => values` pairs.
     All attributes can have multiple values, so the values are always stored in an array.
@@ -97,7 +97,7 @@ You can add it to the beginning of the list, so that the file looks something li
 The instance name is used to refer to this authentication source in other configuration files.
 
 The first element of the configuration of the authentication source must be `'mymodule:MyAuth'`.
-This tells SimpleSAMLphp to look for the `sspmod_mymodule_Auth_Source_MyAuth` class.
+This tells SimpleSAMLphp to look for the `\SimpleSAML\Module\mymodule\Auth\Source\MyAuth` class.
 
 
 Testing our authentication source
@@ -168,7 +168,7 @@ We can then use the properties in the `login` function.
 The complete class file should look like this:
 
     <?php
-    class sspmod_mymodule_Auth_Source_MyAuth extends sspmod_core_Auth_UserPassBase {
+    class MyAuth extends \SimpleSAML\Module\core\Auth\UserPassBase {
 
         private $username;
         private $password;
@@ -187,7 +187,7 @@ The complete class file should look like this:
 
         protected function login($username, $password) {
             if ($username !== $this->username || $password !== $this->password) {
-                throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+                throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
             }
             return array(
                 'uid' => array($this->username),
@@ -245,7 +245,7 @@ A SSHA password is created like this:
 The class follows:
 
     <?php
-    class sspmod_mymodule_Auth_Source_MyAuth extends sspmod_core_Auth_UserPassBase {
+    class MyAuth extends \SimpleSAML\Module\core\Auth\UserPassBase {
 
         /* The database DSN.
          * See the documentation for the various database drivers for information about the syntax:
@@ -253,9 +253,10 @@ The class follows:
          */
         private $dsn;
 
-        /* The database username & password. */
+        /* The database username, password & options. */
         private $username;
         private $password;
+        private $options;
 
         public function __construct($info, $config) {
             parent::__construct($info, $config);
@@ -272,6 +273,12 @@ The class follows:
                 throw new Exception('Missing or invalid password option in config.');
             }
             $this->password = $config['password'];
+            if (isset($config['options']) {
+                if (!is_array($config['options])) {
+                    throw new Exception('Missing or invalid options option in config.');
+                }
+                $this->options = $config['options'];
+            }
         }
 
         /**
@@ -294,7 +301,7 @@ The class follows:
         protected function login($username, $password) {
 
             /* Connect to the database. */
-            $db = new PDO($this->dsn, $this->username, $this->password);
+            $db = new PDO($this->dsn, $this->username, $this->password, $this->options);
             $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 
             /* Ensure that we are operating with UTF-8 encoding.
@@ -316,14 +323,14 @@ The class follows:
             if (!$row) {
                 /* User not found. */
                 SimpleSAML\Logger::warning('MyAuth: Could not find user ' . var_export($username, TRUE) . '.');
-                throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+                throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
             }
 
             /* Check the password. */
             if (!$this->checkPassword($row['password_hash'], $password)) {
                 /* Invalid password. */
                 SimpleSAML\Logger::warning('MyAuth: Wrong password for user ' . var_export($username, TRUE) . '.');
-                throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+                throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
             }
 
             /* Create the attribute array of the user. */
diff --git a/docs/simplesamlphp-database.md b/docs/simplesamlphp-database.md
index 663fdce150e357cb51cced7c87a38ee0b933b600..01fbd5d9421491514722d9295c8780572f8b1b53 100644
--- a/docs/simplesamlphp-database.md
+++ b/docs/simplesamlphp-database.md
@@ -20,12 +20,12 @@ Getting Started
 ---------------
 If you are just using the already configured database, which would normally be the case, all you need to do is get the global instance of the Database class.
 
-	$db = SimpleSAML\Database::getInstance();
+	$db = \SimpleSAML\Database::getInstance();
 
 If there is a requirement to connect to an alternate database server (ex. authenticating users that exist on a different SQL server or database) you can specify an alternate configuration.
 
-	$config = new SimpleSAML_Configuration($myconfigarray, "mymodule/lib/Auth/Source/myauth.php");
-	$db = SimpleSAML\Database::getInstance($config);
+	$config = new \SimpleSAML\Configuration($myconfigarray, "mymodule/lib/Auth/Source/myauth.php");
+	$db = \SimpleSAML\Database::getInstance($config);
 
 That will create a new instance of the database, separate from the global instance, specific to the configuration defined in $myconfigarray. If you are going to specify an alternate config, your configuration array must contain the same keys that exist in the master config (database.dsn, database.username, database.password, database.prefix, etc).
 
diff --git a/docs/simplesamlphp-ecp-idp.md b/docs/simplesamlphp-ecp-idp.md
new file mode 100644
index 0000000000000000000000000000000000000000..28ac7f90a125dc2b14c1915cfa46755d82009453
--- /dev/null
+++ b/docs/simplesamlphp-ecp-idp.md
@@ -0,0 +1,74 @@
+Adding Enhanced Client or Proxy (ECP) Profile support to the IdP
+===============================================================
+
+This document describes the necessary steps to enable support for the [SAML V2.0 Enhanced Client or Proxy Profile Version 2.0](http://docs.oasis-open.org/security/saml/Post2.0/saml-ecp/v2.0/cs01/saml-ecp-v2.0-cs01.pdf) on a simpleSAMLphp Identity Provider (IdP).
+
+The SAML V2.0 Enhanced Client or Proxy (ECP) profile is a SSO profile for use with HTTP, and clients with the capability to directly contact a principal's identity provider(s) without requiring discovery and redirection by the service provider, as in the case of a browser. It is particularly useful for desktop or server-side HTTP clients.
+
+Limitations
+-----------
+* Authentication must be done via [HTTP Basic authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#Basic_authentication_scheme).
+* Authentication must not require user interaction (e.g. auth filters that require user input).
+* Channel Bindings are unsupported.
+* "Holder of Key" Subject Confirmation is unsupported.
+
+This feature has been tested to work with Microsoft Office 365, but other service providers may require features of the ECP profile that are currently unsupported!
+
+Enabling ECP Profile on the IdP
+-----------------------------------
+
+To enable the IdP to send ECP assertions you must add the `saml20.ecp` option to the `saml20-idp-hosted` metadata file:
+
+    $metadata['__DYNAMIC:1__'] = array(
+        [....]
+        'auth' => 'example-userpass',
+        'saml20.ecp' => true,
+    );
+
+Note: authentication filters that require interaction with the user will not work with ECP.
+
+Add new metadata to SPs
+-----------------------
+
+After enabling the ECP Profile your IdP metadata will change. An additional ECP `SingleSignOnService` endpoint is added.
+You therefore need to update the metadata for your IdP at your SPs.
+The `saml20-idp-remote` metadata for simpleSAMLphp SPs should contain something like the following code:
+
+	'SingleSignOnService' =>
+	  array (
+	    0 =>
+	    array (
+	      'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
+	      'Location' => 'https://idp.example.org/simplesaml/saml2/idp/SSOService.php',
+	    ),
+	    1 =>
+	    array (
+	      'index' => 0,
+	      'Location' => 'https://didp.example.org/simplesaml/saml2/idp/SSOService.php',
+	      'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP',
+	    ),
+	  ),
+
+SP metadata on the IdP
+----------------------
+
+A SP using the ECP Profile must have an `AssertionConsumerService` endpoint supporting that profile.
+This means that you have to use the complex endpoint format in `saml20-sp-remote` metadata.
+In general, this should look like the following code:
+
+	'AssertionConsumerService' =>
+	  array (
+	    0 =>
+	    array (
+	      'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
+	      'Location' => 'https://sp.example.org/Shibboleth.sso/SAML2/POST',
+	      'index' => 1,
+	    ),
+	    1 =>
+	    array (
+	      'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:PAOS',
+	      'Location' => 'https://sp.example.org/ECP',
+	      'index' => 2,
+	    ),
+	  ),
+
diff --git a/docs/simplesamlphp-errorhandling.md b/docs/simplesamlphp-errorhandling.md
index 278cad2c24b7d03b5b5704d2f039c3f20445dce5..1c9c8097c824cc265c0e7e9c6acd12cfc268b955 100644
--- a/docs/simplesamlphp-errorhandling.md
+++ b/docs/simplesamlphp-errorhandling.md
@@ -14,7 +14,7 @@ This document describes the way errors and exceptions are handled in authenticat
 The basic goal is to be able to throw an exception during authentication, and then have that exception transported back to the SP in a way that the SP understands.
 
 This means that internal SimpleSAMLphp exceptions must be mapped to transport specific error codes for the various transports that are supported by SimpleSAMLphp.
-E.g.: When a `SimpleSAML_Error_NoPassive` error is thrown by an authentication processing filter in a SAML 2.0 IdP, we want to map that exception to the `urn:oasis:names:tc:SAML:2.0:status:NoPassive` status code.
+E.g.: When a `\SimpleSAML\Error\NoPassive` error is thrown by an authentication processing filter in a SAML 2.0 IdP, we want to map that exception to the `urn:oasis:names:tc:SAML:2.0:status:NoPassive` status code.
 That status code should then be returned to the SP.
 
 
@@ -26,34 +26,34 @@ The simplest case is if you want to throw it during the `authenticate()`-method
 In those methods, you can just throw an exception:
 
     public function process(&$state) {
-        if ($state['something'] === FALSE) {
-            throw new SimpleSAML_Error_Exception('Something is wrong...');
+        if ($state['something'] === false) {
+            throw new \SimpleSAML\Error\Exception('Something is wrong...');
         }
     }
 
 Exceptions thrown at this stage will be caught and delivered to the appropriate error handler.
 
-If you want to throw an exception outside of those methods, i.e. after you have done a redirect, you need to use the `SimpleSAML_Auth_State::throwException()` function:
+If you want to throw an exception outside of those methods, i.e. after you have done a redirect, you need to use the `\SimpleSAML\Auth\State::throwException()` function:
 
     <?php
     $id = $_REQUEST['StateId'];
-    $state = SimpleSAML_Auth_State::loadState($id, 'somestage...');
-    SimpleSAML_Auth_State::throwException($state,
-        new SimpleSAML_Error_Exception('Something is wrong...'));
+    $state = \SimpleSAML\Auth\State::loadState($id, 'somestage...');
+    \SimpleSAML\Auth\State::throwException($state,
+        new \SimpleSAML\Error\Exception('Something is wrong...'));
     ?>
 
-The `SimpleSAML_Auth_State::throwException` function will then transfer your exception to the appropriate error handler.
+The `\SimpleSAML\Auth\State::throwException` function will then transfer your exception to the appropriate error handler.
 
 
 ### Note
 
-Note that we use the `SimpleSAML_Error_Exception` class in both cases.
+Note that we use the `\SimpleSAML\Error\Exception` class in both cases.
 This is because the delivery of the exception may require a redirect to a different web page.
 In those cases, the exception needs to be serialized.
 The normal `Exception` class in PHP isn't always serializable.
 
-If you throw an exception that isn't a subclass of the `SimpleSAML_Error_Exception` class, your exception will be converted to an instance of `SimpleSAML_Error_UnserializableException`.
-The `SimpleSAML_Auth_State::throwException` function does not accept any exceptions that does not subclass the `SimpleSAML_Error_Exception` class.
+If you throw an exception that isn't a subclass of the `\SimpleSAML\Error\Exception` class, your exception will be converted to an instance of `\SimpleSAML\Error\UnserializableException`.
+The `\SimpleSAML\Auth\State::throwException` function does not accept any exceptions that does not subclass the `\SimpleSAML\Error\Exception` class.
 
 
 Returning specific SAML 2 errors
@@ -61,24 +61,24 @@ Returning specific SAML 2 errors
 
 By default, all thrown exceptions will be converted to a generic SAML 2 error.
 In some cases, you may want to convert the exception to a specific SAML 2 status code.
-For example, the `SimpleSAML_Error_NoPassive` exception should be converted to a SAML 2 status code with the following properties:
+For example, the `\SimpleSAML\Error\NoPassive` exception should be converted to a SAML 2 status code with the following properties:
 
 * The top-level status code should be `urn:oasis:names:tc:SAML:2.0:status:Responder`.
 * The second-level status code should be `urn:oasis:names:tc:SAML:2.0:status:NoPassive`.
 * The status message should contain the cause of the exception.
 
-The `sspmod_saml_Error` class represents SAML 2 errors.
+The `\SimpleSAML\Module\saml\Error` class represents SAML 2 errors.
 It represents a SAML 2 status code with three elements: the top-level status code, the second-level status code and the status message.
 The second-level status code and the status message is optional, and can be `NULL`.
 
-The `sspmod_saml_Error` class contains a helper function named `fromException`.
+The `\SimpleSAML\Module\saml\Error` class contains a helper function named `fromException`.
 The `fromException()` function is used by `www/saml2/idp/SSOService.php` to return SAML 2 errors to the SP.
 The function contains a list which maps various exceptions to specific SAML 2 errors.
 If it is unable to convert the exception, it will return a generic SAML 2 error describing the original exception in its status message.
 
 To return a specific SAML 2 error, you should:
 
-* Create a new exception class for your error. This exception class must subclass `SimpleSAML_Error_Exception`.
+* Create a new exception class for your error. This exception class must subclass `\SimpleSAML\Error\Exception`.
 * Add that exception to the list in `fromException()`.
 * Consider adding the exception to `toException()` in the same file. (See the next section.)
 
@@ -93,11 +93,11 @@ Converting SAML 2 errors to normal exceptions
 ---------------------------------------------
 
 On the SP side, we want to convert SAML 2 errors to SimpleSAMLphp exceptions again.
-This is handled by the `toException()` method in `sspmod_saml_Error`.
+This is handled by the `toException()` method in `\SimpleSAML\Module\saml\Error`.
 The assertion consumer script of the SAML 2 authentication source (`modules/saml2/sp/acs.php`) uses this method.
 The result is that generic exceptions are thrown from that authentication source.
 
-For example, `NoPassive` errors will be converted back to instances of `SimpleSAML_Error_NoPassive`.
+For example, `NoPassive` errors will be converted back to instances of `\SimpleSAML\Error\NoPassive`.
 
 
 Other protocols
@@ -113,9 +113,9 @@ Technical details
 This section attempts to describe the internals of the error handling framework.
 
 
-### `SimpleSAML_Error_Exception`
+### `\SimpleSAML\Error\Exception`
 
-The `SimpleSAML_Error_Exception` class extends the normal PHP `Exception` class.
+The `\SimpleSAML\Error\Exception` class extends the normal PHP `Exception` class.
 It makes the exceptions serializable by overriding the `__sleep()` method.
 The `__sleep()` method returns all variables in the class which should be serialized when saving the class.
 
@@ -136,7 +136,7 @@ This may be confusing since the new stack trace leads into the `unserialize()` f
 It is therefore recommended to use the getBacktrace() method.
 
 
-### `SimpleSAML_Auth_State`
+### `\SimpleSAML\Auth\State`
 
 There are two methods in this class that deals with exceptions:
 
@@ -147,44 +147,44 @@ There are two methods in this class that deals with exceptions:
 #### `throwException`
 
 This method delivers the exception to the code that initialized the exception handling in the authentication state.
-That would be `SimpleSAML_Auth_Default` for authtentication sources, and `www/saml2/idp/SSOService.php` for processing filters.
+That would be `\SimpleSAML\Auth\DefaultAuth` for authtentication sources, and `www/saml2/idp/SSOService.php` for processing filters.
 To configure how and where the exception should be delivered, there are two fields in the state-array which can be set:
 
-* `SimpleSAML_Auth_State::EXCEPTION_HANDLER_FUNC`, in which case the exception will be delivered by a function call to the function specified in that field.
-* `SimpleSAML_Auth_State::EXCEPTION_HANDLER_URL`, in which case the exception will be delivered by a redirect to the URL specified in that field.
+* `\SimpleSAML\Auth\State::EXCEPTION_HANDLER_FUNC`, in which case the exception will be delivered by a function call to the function specified in that field.
+* `\SimpleSAML\Auth\State::EXCEPTION_HANDLER_URL`, in which case the exception will be delivered by a redirect to the URL specified in that field.
 
 If the exception is delivered by a function call, the function will be called with two parameters: The exception and the state array.
 
-If the exception is delivered by a redirect, SimpleSAML_Auth_State will save the exception in a field in the state array, pass a parameter with the id of the state array to the URL.
-The `SimpleSAML_Auth_State::EXCEPTION_PARAM` constant contains the name of that parameter, while the `SimpleSAML_Auth_State::EXCEPTION_DATA` constant holds the name of the field where the exception is saved.
+If the exception is delivered by a redirect, \SimpleSAML\Auth\State will save the exception in a field in the state array, pass a parameter with the id of the state array to the URL.
+The `\SimpleSAML\Auth\State::EXCEPTION_PARAM` constant contains the name of that parameter, while the `\SimpleSAML\Auth\State::EXCEPTION_DATA` constant holds the name of the field where the exception is saved.
 
 
 #### `loadException`
 
-To retrieve the exception, the application should check for the state parameter in the request, and then retrieve the state array by calling `SimpleSAML_Auth_State::loadExceptionState()`.
-The exception can be located in a field named `SimpleSAML_Auth_State::EXCEPTION_DATA`.
+To retrieve the exception, the application should check for the state parameter in the request, and then retrieve the state array by calling `\SimpleSAML\Auth\State::loadExceptionState()`.
+The exception can be located in a field named `\SimpleSAML\Auth\State::EXCEPTION_DATA`.
 The following code illustrates this behaviour:
 
-    if (array_key_exists(SimpleSAML_Auth_State::EXCEPTION_PARAM, $_REQUEST)) {
-        $state = SimpleSAML_Auth_State::loadExceptionState();
-        $exception = $state[SimpleSAML_Auth_State::EXCEPTION_DATA];
+    if (array_key_exists(\SimpleSAML\Auth\State::EXCEPTION_PARAM, $_REQUEST)) {
+        $state = \SimpleSAML\Auth\State::loadExceptionState();
+        $exception = $state[\SimpleSAML\Auth\State::EXCEPTION_DATA];
 
         /* Process exception. */
     }
 
 
-### `SimpleSAML_Auth_Default`
+### `\SimpleSAML\Auth\DefaultAuth`
 
 This class accepts an `$errorURL` parameter to the `initLogin()` function.
-This parameter is stored in the `SimpleSAML_Auth_State::EXCEPTION_HANDLER_URL` of the state array.
+This parameter is stored in the `\SimpleSAML\Auth\State::EXCEPTION_HANDLER_URL` of the state array.
 Exceptions thrown by the authentication source will be delivered to that URL.
 
 It also wraps the call to the `authenticate()` function inside a try-catch block.
 Any exceptions thrown during that function call will be delivered to the URL specified in the `$errorURL` parameter.
-This is done for consistency, since `SimpleSAML_Auth_Default` never transfers control back to the caller by returning.
+This is done for consistency, since `\SimpleSAML\Auth\DefaultAuth` never transfers control back to the caller by returning.
 
 
-### `SimpleSAML_Auth_ProcessingChain`
+### `\SimpleSAML\Auth\ProcessingChain`
 
 This class requires the caller to add the error handler to the state array before calling the `processState()` function.
 Exceptions thrown by the processing filters will be delivered directly to the caller of `processState()` if possible.
@@ -195,9 +195,9 @@ The result will be delivered directly if it is possible, but if not, it will be
 
 The code for handling this becomes something like:
 
-    if (array_key_exists(SimpleSAML_Auth_State::EXCEPTION_PARAM, $_REQUEST)) {
-        $state = SimpleSAML_Auth_State::loadExceptionState();
-        $exception = $state[SimpleSAML_Auth_State::EXCEPTION_DATA];
+    if (array_key_exists(\SimpleSAML\Auth\State::EXCEPTION_PARAM, $_REQUEST)) {
+        $state = \SimpleSAML\Auth\State::loadExceptionState();
+        $exception = $state[\SimpleSAML\Auth\State::EXCEPTION_DATA];
 
         /* Handle exception... */
         [...]
@@ -206,14 +206,14 @@ The code for handling this becomes something like:
     $procChain = [...];
 
     $state = array(
-        'ReturnURL' => SimpleSAML_Utilities::selfURLNoQuery(),
-        SimpleSAML_Auth_State::EXCEPTION_HANDLER_URL => SimpleSAML_Utilities::selfURLNoQuery(),
+        'ReturnURL' => \SimpleSAML\Utils\HTTP::getSelfURLNoQuery(),
+        \SimpleSAML\Auth\State::EXCEPTION_HANDLER_URL => \SimpleSAML\Utils\HTTP::getSelfURLNoQuery(),
         [...],
     )
 
     try {
         $procChain->processState($state);
-    } catch (SimpleSAML_Error_Exception $e) {
+    } catch (\SimpleSAML\Error\Exception $e) {
         /* Handle exception. */
         [...];
     }
@@ -221,7 +221,7 @@ The code for handling this becomes something like:
 
 #### Note
 
-An exception which isn't a subclass of `SimpleSAML_Error_Exception` will be converted to the `SimpleSAML_Error_UnserializedException` class.
+An exception which isn't a subclass of `\SimpleSAML\Error\Exception` will be converted to the `\SimpleSAML\Error\UnserializedException` class.
 This happens regardless of whether the exception is delivered directly or through the error handler.
 This is done to be consistent in what the application receives - now it will always receive the same exception, regardless of whether it is delivered directly or through a redirect.
 
@@ -229,12 +229,12 @@ This is done to be consistent in what the application receives - now it will alw
 Custom error show function
 --------------------------
 
-Optional custom error show function, called from SimpleSAML_Error_Error::show, is defined with 'errors.show_function' in config.php.
+Optional custom error show function, called from \SimpleSAML\Error\Error::show, is defined with 'errors.show_function' in config.php.
 
-Example code for this function, which implements the same functionality as SimpleSAML_Error_Error::show, looks something like:
+Example code for this function, which implements the same functionality as \SimpleSAML\Error\Error::show, looks something like:
 
-    public static function show(SimpleSAML_Configuration $config, array $data) {
-        $t = new SimpleSAML_XHTML_Template($config, 'error.php', 'errors');
+    public static function show(\SimpleSAML\Configuration $config, array $data) {
+        $t = new \SimpleSAML\XHTML\Template($config, 'error.php', 'errors');
         $t->data = array_merge($t->data, $data);
         $t->show();
         exit;
diff --git a/docs/simplesamlphp-googleapps.md b/docs/simplesamlphp-googleapps.md
index 775e71ee1c31c3d7c4348652961a045b0dbafcb7..3eba11a6a634d221c2fcbcbe29ded49a87c9685b 100644
--- a/docs/simplesamlphp-googleapps.md
+++ b/docs/simplesamlphp-googleapps.md
@@ -152,7 +152,7 @@ In the `saml20-sp-remote.php` file we will configure an entry for G Suite (Googl
        * at G Suite. E.g. if your google account is foo.com, and you have a user with email john@foo.com, then you
        * must set the simplesaml.nameidattribute to be the name of an attribute that for this user has the value of 'john'.
        */
-      $metadata['google.com'] => array(
+      $metadata['https://www.google.com/a/g.feide.no'] => array(
         'AssertionConsumerService'   => 'https://www.google.com/a/g.feide.no/acs', 
         'NameIDFormat'               => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
         'simplesaml.nameidattribute' => 'uid',
diff --git a/docs/simplesamlphp-install.md b/docs/simplesamlphp-install.md
index 1f127a549fced03ee53f494b1033753f669c07a8..14d8550c63f57515886c15db78366b9ff673713c 100644
--- a/docs/simplesamlphp-install.md
+++ b/docs/simplesamlphp-install.md
@@ -24,7 +24,7 @@ Development version
 --------------------
 
 This document is about the latest stable version of SimpleSAMLphp.
-If you want to install the development version, look at the instructions for [installing SimpleSAMLphp from the repository](simplesamlphp-install-repo).
+If you want to install the development version, look at the instructions for [installing SimpleSAMLphp from the repository](simplesamlphp-install-repo.md).
 
 
 Prerequisites
@@ -33,7 +33,7 @@ Prerequisites
  * Some webserver capable of executing PHP scripts.
  * PHP version >= 5.4.0.
  * Support for the following PHP extensions:
-   * Always required: `date`, `dom`, `hash`, `libxml`, `openssl`, `pcre`, `SPL`, `zlib`, `json`
+   * Always required: `date`, `dom`, `hash`, `libxml`, `openssl`, `pcre`, `SPL`, `zlib`, `json`, `mbstring`
    * When automatically checking for latest versions, and used by some modules: `cURL`
    * When authenticating against LDAP server: `ldap`
    * When authenticating against RADIUS server: `radius`
@@ -151,9 +151,43 @@ This works only for the `config` directory. If you need your metadata to be in a
 
 This is just the basic configuration to get things working. For a checklist
 further completing your documentation, please see
-[Maintenance and configuration: Apache](simplesamlphp-maintenance#section_4).
+[Maintenance and configuration: Apache](simplesamlphp-maintenance.md#apache-configuration).
 
 
+Configuring Nginx
+------------------
+
+Examples below assume that SimpleSAMLphp is installed in the default location, `/var/simplesamlphp`. You may choose another location, but this requires a path update in a few files. See Appendix for details ‹Installing SimpleSAMLphp in alternative locations›.
+
+The only subdirectory of `SimpleSAMLphp` that needs to be accessible from the web is `www`. There are several ways of exposing SimpleSAMLphp depending on the way web sites are structured on your Nginx web server. The following is just one possible configuration.
+
+Find the Nginx configuration file for the virtual hosts where you want to run SimpleSAMLphp. The configuration may look like this:
+
+    server {
+        listen 443 ssl;
+        server_name idp.example.com;
+
+        ssl_certificate        /etc/pki/tls/certs/idp.example.com.crt;
+        ssl_certificate_key    /etc/pki/tls/private/idp.example.com.key;
+        ssl_protocols          TLSv1.1 TLSv1.2;
+        ssl_ciphers            HIGH:!aNULL:!MD5;
+
+        location / {
+            root     /var/simplesamlphp/www;
+            index    index.php;
+        }
+
+        location ~ \.php$ {
+            root             /var/simplesamlphp/www;
+            fastcgi_pass     127.0.0.1:9000;
+            fastcgi_index    index.php;
+            fastcgi_param    SCRIPT_FILENAME  $document_root$fastcgi_script_name;
+            fastcgi_split_path_info ^(.+?\.php)(/.*)$;
+            fastcgi_param    PATH_INFO $fastcgi_path_info;
+            include          fastcgi_params;
+        }
+    }
+
 SimpleSAMLphp configuration: config.php
 ---------------------------------------
 
@@ -164,7 +198,7 @@ file, `config.php`, right away:
 
 		'auth.adminpassword'        => 'setnewpasswordhere',
 
-   Hashed passwords can also be used here. See the [`authcrypt`](./authcrypt:authcrypt) documentation for more information.
+   Hashed passwords can also be used here. See the [`authcrypt`](../modules/authcrypt/docs/authcrypt.md) documentation for more information.
 
 -  Set a secret salt. This should be a random string. Some parts of the SimpleSAMLphp needs this salt to generate cryptographically secure hashes. SimpleSAMLphp will give an error if the salt is not changed from the default value. The command below can help you to generated a random string on (some) unix systems:
 
@@ -254,7 +288,6 @@ At the bottom of the installation page are some green lights. simpleSAML runs so
 You have now successfully installed SimpleSAMLphp, and the next steps depends on whether you want to setup a service provider, to protect a website by authentication or if you want to setup an identity provider and connect it to a user catalog. Documentation on bridging between federation protocols is found in a separate document.
 
  * [Using SimpleSAMLphp as a SAML Service Provider](simplesamlphp-sp)
-  * [Hosted SP Configuration Reference](./saml:sp)
   * [IdP remote reference](simplesamlphp-reference-idp-remote)
   * [Connecting SimpleSAMLphp as a SP to UK Access Federation or InCommon](simplesamlphp-ukaccess)
   * [Upgrading - migration to use the SAML authentication source](simplesamlphp-sp-migration)
diff --git a/docs/simplesamlphp-maintenance.md b/docs/simplesamlphp-maintenance.md
index ab38566e94330c607808a0b5218889247e3b5b2b..cfd2d7e3766a20921ea6e9b0b1fc89e0c106d534 100644
--- a/docs/simplesamlphp-maintenance.md
+++ b/docs/simplesamlphp-maintenance.md
@@ -52,7 +52,7 @@ SimpleSAMLphp as an Identity Provider, or any other applications using it are no
 settings by leaving these options unset or setting them to `null`.
 
 If you need to restore your session's application after calling SimpleSAMLphp, you can do it by calling the `cleanup()` method of the
-`SimpleSAML_Session` class, like described [here](simplesamlphp-sp#section_6).
+`\SimpleSAML\Session` class, like described [here](simplesamlphp-sp#section_6).
 
 ### Configuring memcache
 
@@ -178,7 +178,7 @@ example configuration of different metadata sources in use at the same time:
 ```
 
 You may also implement your own metadata storage handler, in a very similar way to how you would implement
-your own session handler. Your class **must** extend the `SimpleSAML_Metadata_MetaDataStorageSource` class
+your own session handler. Your class **must** extend the `\SimpleSAML\Metadata\MetaDataStorageSource` class
 and override the methods needed to change the backend used. This class **must** also be located in the
 `lib/MetadataStore/` directory of your custom module.
 
@@ -190,7 +190,7 @@ module is named _mymodule_ and your class is named _MyMetadataHandler_, you shou
 <?php
 namespace SimpleSAML\Module\mymodule\MetadataStore;
 
-class MyMetadataHandler extends SimpleSAML_Metadata_MetaDataStorageSource
+class MyMetadataHandler extends \SimpleSAML\Metadata\MetaDataStorageSource
 {
     ...
 ```
diff --git a/docs/simplesamlphp-metadata-extensions-ui.md b/docs/simplesamlphp-metadata-extensions-ui.md
index 94a855d8451f8149db0e5e986a88b415b5895ffd..f9627b93e6206bc0c53e26c5e091058335c640ef 100644
--- a/docs/simplesamlphp-metadata-extensions-ui.md
+++ b/docs/simplesamlphp-metadata-extensions-ui.md
@@ -83,7 +83,7 @@ And for an SP it could look like this:
                 ),
                 'Description' => array(
                     'en' => 'English description',
-                    'es' => 'Descripción en Español
+                    'es' => 'Descripción en Español'
                 ),
             ),
             /* ... */
diff --git a/docs/simplesamlphp-modules.md b/docs/simplesamlphp-modules.md
index ccbb851c81223793ed5dc742b2e26efe3014c460..300cfb8022fa41456b89c4613d5913ffca713717 100644
--- a/docs/simplesamlphp-modules.md
+++ b/docs/simplesamlphp-modules.md
@@ -66,7 +66,7 @@ dictionaries
 
 :   It is also possible to specify
     `<module name>:<dictionary name>` as the default
-    dictionary when instantiating the `SimpleSAML_XHTML_Template`
+    dictionary when instantiating the `\SimpleSAML\XHTML\Template`
     class.
 
 hooks
@@ -77,20 +77,20 @@ hooks
 lib
 :   This directory contains classes which belong to this module.
     All classes must be named in the following pattern:
-    `sspmod_<module name>_<class name>` When looking up the filename of
+    `\SimpleSAML\Module\<module name>\<class name>` When looking up the filename of
     a class, SimpleSAMLphp will search for `<class name>` in the `lib`
     directory. Underscores in the class name will be translated into
     slashes.
 
 :   Thus, if SimpleSAMLphp needs to load a class named
-    `sspmod_example_Auth_Source_Example`, it will load the file named
+    `\SimpleSAML\Module\example\Auth\Source\Example`, it will load the file named
     `modules/example/lib/Auth/Source/Example.php`.
 
 templates
 :   These are module-specific templates. To use one of these
     templates, specify `<module name>:<template file>.php`
     as the template file in the constructor of
-    `SimpleSAML_XHTML_Template`. For example, `example:login-form.php`
+    `\SimpleSAML\XHTML\Template`. For example, `example:login-form.php`
     is translated to the file
     `modules/example/templates/default/login-form.php`. Note that
     `default` in the previous example is defined by the `theme.use`
diff --git a/docs/simplesamlphp-nostate.md b/docs/simplesamlphp-nostate.md
index 6d0535fb18eb8b6489cb8d7248b73ce62084b46e..208d9d5773c9ee89449585758d8c6370087fedf3 100644
--- a/docs/simplesamlphp-nostate.md
+++ b/docs/simplesamlphp-nostate.md
@@ -1,7 +1,7 @@
 Debugging "State Information Lost" errors
 =========================================
 
-**"State Information Lost"** (`SimpleSAML_Error_NoState: NOSTATE`)
+**"State Information Lost"** (`\SimpleSAML\Error\NoState: NOSTATE`)
 
 This is one of the most common errors that you can encounter when configuring
 SimpleSAMLphp. Unfortunately, it is also a generic error that can have many
diff --git a/docs/simplesamlphp-reference-idp-hosted.md b/docs/simplesamlphp-reference-idp-hosted.md
index 0e5cb6298e92a0ba1f393c4d9961955345b81335..ba558066e3e5ca226eed9ae9d80e1c1d75cbd406 100644
--- a/docs/simplesamlphp-reference-idp-hosted.md
+++ b/docs/simplesamlphp-reference-idp-hosted.md
@@ -255,6 +255,10 @@ The following SAML 2.0 options are available:
 
 :   Note that this requires a configured memcache server.
 
+`saml20.ecp`
+:   Set to `true` to enable the IdP to recieve authnrequests and send responses according the Enhanced Client or Proxy (ECP) Profile. Note: authentication filters that require interaction with the user will not work with ECP.
+    Defaults to `false`.
+
 `saml20.hok.assertion`
 :   Set to `TRUE` to enable the IdP to send responses according the [Holder-of-Key Web Browser SSO Profile](./simplesamlphp-hok-idp).
     Defaults to `FALSE`.
@@ -325,12 +329,13 @@ The following SAML 2.0 options are available:
 	the default one.
 
 `signature.algorithm`
-:   The algorithm to use when signing any message generated by this identity provider. Defaults to RSA-SHA1.
+:   The algorithm to use when signing any message generated by this identity provider. Defaults to RSA-SHA256.
 :   Possible values:
 
     * `http://www.w3.org/2000/09/xmldsig#rsa-sha1`
        *Note*: the use of SHA1 is **deprecated** and will be disallowed in the future.
     * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha256`
+       The default.
     * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha384`
     * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha512`
 
diff --git a/docs/simplesamlphp-reference-idp-remote.md b/docs/simplesamlphp-reference-idp-remote.md
index 89526fdfdea27bad7f6f260bd733681ce05139b6..7908ebc3966748e4cce3b5bb1fe91ab56b610391 100644
--- a/docs/simplesamlphp-reference-idp-remote.md
+++ b/docs/simplesamlphp-reference-idp-remote.md
@@ -120,6 +120,9 @@ The following SAML 2.0 options are available:
 `hide.from.discovery`
 :   Whether to hide hide this IdP from the local discovery or not. Set to true to hide it. Defaults to false.
 
+`IDPList`
+:   The IdP is allowed to respond to an `AuthNRequest` originally sent to entityIDs in this list.
+
 `nameid.encryption`
 :   Whether NameIDs sent to this IdP should be encrypted. The default
     value is `FALSE`.
@@ -149,7 +152,7 @@ The following SAML 2.0 options are available:
 :   Endpoint URL for logout responses. Overrides the `SingleLogoutService`-option for responses.
 
 `signature.algorithm`
-:   The algorithm to use when signing any message sent to this specific identity provider. Defaults to RSA-SHA1.
+:   The algorithm to use when signing any message sent to this specific identity provider. Defaults to RSA-SHA256.
 :   Note that this option also exists in the SP configuration.
     This value in the IdP remote metadata overrides the value in the SP configuration.
 :   Possible values:
@@ -157,6 +160,7 @@ The following SAML 2.0 options are available:
     * `http://www.w3.org/2000/09/xmldsig#rsa-sha1`
        *Note*: the use of SHA1 is **deprecated** and will be disallowed in the future.
     * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha256`
+      The default.
     * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha384`
     * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha512`
 
diff --git a/docs/simplesamlphp-reference-sp-remote.md b/docs/simplesamlphp-reference-sp-remote.md
index 943c862626dd4cce16b6c3d31449c399569c610d..2eb7efd320ad19b3eff355fe6e75b078ccee9882 100644
--- a/docs/simplesamlphp-reference-sp-remote.md
+++ b/docs/simplesamlphp-reference-sp-remote.md
@@ -238,7 +238,7 @@ The following SAML 2.0 options are available:
     The value in the SP-remote metadata overrides the value in the IdP-hosted metadata.
 
 `signature.algorithm`
-:   The algorithm to use when signing any message sent to this specific service provider. Defaults to RSA-SHA1.
+:   The algorithm to use when signing any message sent to this specific service provider. Defaults to RSA-SHA256.
 :   Note that this option also exists in the IdP-hosted metadata.
     The value in the SP-remote metadata overrides the value in the IdP-hosted metadata.
 :   Possible values:
@@ -246,6 +246,7 @@ The following SAML 2.0 options are available:
     * `http://www.w3.org/2000/09/xmldsig#rsa-sha1`
        *Note*: the use of SHA1 is **deprecated** and will be disallowed in the future.
     * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha256`
+      The default.
     * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha384`
     * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha512`
 
diff --git a/docs/simplesamlphp-sp-api.md b/docs/simplesamlphp-sp-api.md
index 2de1b509a698b342312ea41386657980d6efc3f9..cc43e4bcd8d18f70c562e263f7f5a8cf5e4c11f3 100644
--- a/docs/simplesamlphp-sp-api.md
+++ b/docs/simplesamlphp-sp-api.md
@@ -157,7 +157,7 @@ Same as the previous, but check the result of the logout operation afterwards.
 
 And in logged_out.php:
 
-    $state = SimpleSAML_Auth_State::loadState((string)$_REQUEST['LogoutState'], 'MyLogoutState');
+    $state = \SimpleSAML\Auth\State::loadState((string)$_REQUEST['LogoutState'], 'MyLogoutState');
     $ls = $state['saml:sp:LogoutStatus']; /* Only works for SAML SP */
     if ($ls['Code'] === 'urn:oasis:names:tc:SAML:2.0:status:Success' && !isset($ls['SubCode'])) {
         /* Successful logout. */
diff --git a/docs/simplesamlphp-sp-migration.md b/docs/simplesamlphp-sp-migration.md
index ae3303cf8121dea9b631be21383994e1011bd0f8..92187b802ebccd51be22412e4aa67db448953618 100644
--- a/docs/simplesamlphp-sp-migration.md
+++ b/docs/simplesamlphp-sp-migration.md
@@ -154,8 +154,8 @@ This is a quick overview of the API:
 
 Generally, if you have:
 
-    $config = SimpleSAML_Configuration::getInstance();
-    $session = SimpleSAML_Session::getSessionFromRequest();
+    $config = \SimpleSAML\Configuration::getInstance();
+    $session = \SimpleSAML\Session::getSessionFromRequest();
 
 you should replace it with this single line:
 
@@ -168,10 +168,10 @@ Blocks of code like the following:
 
     /* Check if valid local session exists.. */
     if (!isset($session) || !$session->isValid('saml2') ) {
-      SimpleSAML_Utilities::redirect(
+      \SimpleSAML\Utilities::redirect(
         '/' . $config->getBaseURL() .
         'saml2/sp/initSSO.php',
-        array('RelayState' => SimpleSAML_Utilities::selfURL())
+        array('RelayState' => \SimpleSAML\Utilities::selfURL())
         );
     }
 
@@ -195,10 +195,10 @@ you should now call:
 
 Redirecting to the initSLO-script:
 
-    SimpleSAML_Utilities::redirect(
+    \SimpleSAML\Utilities::redirect(
         '/' . $config->getBaseURL() .
         'saml2/sp/initSLO.php',
-        array('RelayState' => SimpleSAML_Utilities::selfURL())
+        array('RelayState' => \SimpleSAML\Utilities::selfURL())
         );
 
 should be replaced with a call to `logout()`:
@@ -210,7 +210,7 @@ If you want to return to a specific URL after logging out, you should include th
     $as->logout('https://example.org/');
 
 Please make sure the URL is trusted. If you obtain the URL from the user input, make sure it is trusted before
-calling $as->logout(), by using the SimpleSAML_Utilities::checkURLAllowed() method.
+calling $as->logout(), by using the \SimpleSAML\Utilities::checkURLAllowed() method.
 
 
 #### Login link
diff --git a/docs/simplesamlphp-sp.md b/docs/simplesamlphp-sp.md
index dd50adab9a7c5435d95b5b24e5a6e079c70287b1..453b9b525101a2b2b10c3008c8de62df75a82b4e 100644
--- a/docs/simplesamlphp-sp.md
+++ b/docs/simplesamlphp-sp.md
@@ -191,7 +191,7 @@ If we are using PHP sessions in SimpleSAMLphp and in the application we are prot
 existing session when invoked for the first time, and its own session will prevail afterwards. If you want to restore
 your own session after calling SimpleSAMLphp, you can do so by cleaning up the session like this:
 
-    $session = SimpleSAML_Session::getSessionFromRequest();
+    $session = \SimpleSAML\Session::getSessionFromRequest();
     $session->cleanup();
 
 If you don't cleanup SimpleSAMLphp's session and try to use $_SESSION afterwards, you won't be using your own session
diff --git a/docs/simplesamlphp-theming.md b/docs/simplesamlphp-theming.md
index 0c66fbde91ea3f948e96767901fa788113294a3d..51cbe65b5bdfd7d3bdea78d37b78c888e3c7fdc0 100644
--- a/docs/simplesamlphp-theming.md
+++ b/docs/simplesamlphp-theming.md
@@ -107,10 +107,29 @@ modules
 
 Reference these resources in your custom PHP templates under `themes/fancytheme` by using a generator for the URL:
 ```php
-<?php echo SimpleSAML_Module::getModuleURL('mymodule/logo.png'); ?>
+<?php echo SimpleSAML\Module::getModuleURL('mymodule/logo.png'); ?>
 ```
 
 Example for a custom CSS stylesheet file:
 ```html
-<link rel="stylesheet" type="text/css" href="<?php echo SimpleSAML_Module::getModuleURL('mymodule/style.css'); ?>" />
+<link rel="stylesheet" type="text/css" href="<?php echo SimpleSAML\Module::getModuleURL('mymodule/style.css'); ?>" />
 ```
+
+Migrating to Twig templates
+---------------------------
+
+In version 1.15, a new templating system based on [Twig](https://twig.symfony.com/) was introduced. As modules migrate, it will become necessary for themes to include both the old templating style described above and new Twig-based templates.
+
+Twig works by extending a base template, which can itself include other partial templates. Some of the content of the old `includes/header.php` template is now located in a separate `_header.twig` file. This can be customized by copying it from the base template:
+
+	cp templates/_header.twig modules/mymodule/themes/fancytheme/default/
+
+If you need to make more extensive customizations to the base template, you should copy it from the base theme:
+
+	cp templates/base.twig modules/mymodule/themes/fancytheme/default/
+
+Any references to `$this->data['baseurlpath']` in old-style templates can be replaced with `{{baseurlpath}}` in Twig templates. Likewise, references to `\SimpleSAML\Module::getModuleURL()` can be replaced with `{{baseurlpath}}module.php/mymodule/...`
+
+See the [Twig documentation](https://twig.symfony.com/doc/1.x/templates.html) for more information on using variables and expressions in Twig templates, and the SimpleSAMLphp wiki for [our conventions](https://github.com/simplesamlphp/simplesamlphp/wiki/Twig-conventions).
+
+The wiki also includes some information on [migrating translations](https://github.com/simplesamlphp/simplesamlphp/wiki/Migrating-translation-in-Twig) and [migrating templates](https://github.com/simplesamlphp/simplesamlphp/wiki/Twig:-Migrating-templates).
diff --git a/docs/simplesamlphp-upgrade-notes-1.15.md b/docs/simplesamlphp-upgrade-notes-1.15.md
index 19523af595a2397051f980bc29990f2fdcecba0d..a4ffd2483d3c320b80ac1e00607b8c154b033cda 100644
--- a/docs/simplesamlphp-upgrade-notes-1.15.md
+++ b/docs/simplesamlphp-upgrade-notes-1.15.md
@@ -5,7 +5,9 @@ The minimum required PHP version is now 5.4. The dependency on mcrypt has been
 dropped.
 
 A new templating system based on Twig has been introduced. The old templating
-system is still available but should be considered deprecated.
+system is still available but should be considered deprecated. Custom themes
+may need to be updated to include Twig-style templates as well. See the
+[theming documentation](simplesamlphp-theming).
 
 A new internationalization system based on Gettext has been introduced. While
 old templates can use either the old or the new system (refer to the
diff --git a/docs/simplesamlphp-upgrade-notes-1.16.md b/docs/simplesamlphp-upgrade-notes-1.16.md
new file mode 100644
index 0000000000000000000000000000000000000000..6a809cc5da66f71584a9600ea13d78005c1ec080
--- /dev/null
+++ b/docs/simplesamlphp-upgrade-notes-1.16.md
@@ -0,0 +1,17 @@
+Upgrade notes for SimpleSAMLphp 1.16
+====================================
+
+The default signature algoritm is now SHA-256 (SHA-1 has been considered
+obsolete since 2014). For entities that need it, you can switch back to
+SHA-1 by setting the `signature.algorithm` option in the remote entity
+metadata.
+
+In the Consent module, the `noconsentattributes` has been renamed to
+`attributes.exclude`. The old name continues to work but is considered
+deprecated.
+
+The class `SimpleSAML_Error_BadUserInnput` has been renamed to
+`SimpleSAML_Error_BadUserInput`.
+
+The `authmyspace` module has been removed since the service is no longer
+available. 
diff --git a/lib/SimpleSAML/Auth/Default.php b/lib/SimpleSAML/Auth/Default.php
index 17ad9c38e575ebf497d7eb6d175418225d367fb4..486d3eaa166365d8631228423121b9e80533e8e3 100644
--- a/lib/SimpleSAML/Auth/Default.php
+++ b/lib/SimpleSAML/Auth/Default.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Auth;
+
 /**
  * Implements the default behaviour for authentication.
  *
@@ -11,12 +13,11 @@
  *
  * @deprecated This class will be removed in SSP 2.0.
  */
-class SimpleSAML_Auth_Default
-{
-
 
+class DefaultAuth
+{
     /**
-     * @deprecated This method will be removed in SSP 2.0. Use SimpleSAML_Auth_Source::initLogin() instead.
+     * @deprecated This method will be removed in SSP 2.0. Use Source::initLogin() instead.
      */
     public static function initLogin(
         $authId,
@@ -32,21 +33,20 @@ class SimpleSAML_Auth_Default
 
     /**
      * @deprecated This method will be removed in SSP 2.0. Please use
-     * SimpleSAML_Auth_State::getPersistentAuthData() instead.
+     * State::getPersistentAuthData() instead.
      */
     public static function extractPersistentAuthState(array &$state)
     {
-
-        return SimpleSAML_Auth_State::getPersistentAuthData($state);
+        return State::getPersistentAuthData($state);
     }
 
 
     /**
-     * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML_Auth_Source::loginCompleted() instead.
+     * @deprecated This method will be removed in SSP 2.0. Please use Source::loginCompleted() instead.
      */
     public static function loginCompleted($state)
     {
-        SimpleSAML_Auth_Source::loginCompleted($state);
+        Source::loginCompleted($state);
     }
 
 
@@ -58,15 +58,15 @@ class SimpleSAML_Auth_Default
         assert(is_string($returnURL));
         assert(is_string($authority));
 
-        $session = SimpleSAML_Session::getSessionFromRequest();
+        $session = \SimpleSAML\Session::getSessionFromRequest();
 
         $state = $session->getAuthData($authority, 'LogoutState');
         $session->doLogout($authority);
 
-        $state['SimpleSAML_Auth_Default.ReturnURL'] = $returnURL;
+        $state['\SimpleSAML\Auth\DefaultAuth.ReturnURL'] = $returnURL;
         $state['LogoutCompletedHandler'] = array(get_class(), 'logoutCompleted');
 
-        $as = SimpleSAML_Auth_Source::getById($authority);
+        $as = Source::getById($authority);
         if ($as === null) {
             // The authority wasn't an authentication source...
             self::logoutCompleted($state);
@@ -96,28 +96,28 @@ class SimpleSAML_Auth_Default
     public static function logoutCompleted($state)
     {
         assert(is_array($state));
-        assert(array_key_exists('SimpleSAML_Auth_Default.ReturnURL', $state));
+        assert(array_key_exists('\SimpleSAML\Auth\DefaultAuth.ReturnURL', $state));
 
-        \SimpleSAML\Utils\HTTP::redirectTrustedURL($state['SimpleSAML_Auth_Default.ReturnURL']);
+        \SimpleSAML\Utils\HTTP::redirectTrustedURL($state['\SimpleSAML\Auth\DefaultAuth.ReturnURL']);
     }
 
 
     /**
-     * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML_Auth_Source::logoutCallback() instead.
+     * @deprecated This method will be removed in SSP 2.0. Please use Source::logoutCallback() instead.
      */
     public static function logoutCallback($state)
     {
-        SimpleSAML_Auth_Source::logoutCallback($state);
+        Source::logoutCallback($state);
     }
 
 
     /**
      * @deprecated This method will be removed in SSP 2.0. Please use
-     * sspmod_saml_Auth_Source_SP::handleUnsolicitedAuth() instead.
+     * \SimpleSAML\Module\saml\Auth\Source\SP::handleUnsolicitedAuth() instead.
      */
     public static function handleUnsolicitedAuth($authId, array $state, $redirectTo)
     {
-        sspmod_saml_Auth_Source_SP::handleUnsolicitedAuth($authId, $state, $redirectTo);
+        \SimpleSAML\Module\saml\Auth\Source\SP::handleUnsolicitedAuth($authId, $state, $redirectTo);
     }
 
 
@@ -125,14 +125,14 @@ class SimpleSAML_Auth_Default
      * Return an authentication source by ID.
      *
      * @param string $id The id of the authentication source.
-     * @return SimpleSAML_Auth_Source The authentication source.
-     * @throws Exception If the $id does not correspond with an authentication source.
+     * @return Source The authentication source.
+     * @throws \Exception If the $id does not correspond with an authentication source.
      */
     private static function getAuthSource($id)
     {
-        $as = SimpleSAML_Auth_Source::getById($id);
+        $as = Source::getById($id);
         if ($as === null) {
-            throw new Exception('Invalid authentication source: ' . $id);
+            throw new \Exception('Invalid authentication source: ' . $id);
         }
         return $as;
     }
diff --git a/lib/SimpleSAML/Auth/LDAP.php b/lib/SimpleSAML/Auth/LDAP.php
index 08ca44ad55574ab96e65bad05bbcc8ec2c37eaa3..437ff7bf3e539db801c98b86bce5b58158a929d8 100644
--- a/lib/SimpleSAML/Auth/LDAP.php
+++ b/lib/SimpleSAML/Auth/LDAP.php
@@ -1,8 +1,14 @@
 <?php
 
+namespace SimpleSAML\Auth;
+
+use SimpleSAmL\Error;
+use SimpleSAMl\Logger;
+
 /**
  * Constants defining possible errors
  */
+
 define('ERR_INTERNAL', 1);
 define('ERR_NO_USER', 2);
 define('ERR_WRONG_PW', 3);
@@ -22,7 +28,8 @@ if (!defined('LDAP_OPT_DIAGNOSTIC_MESSAGE')) {
  * @author Anders Lund, UNINETT AS. <anders.lund@uninett.no>
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Auth_LDAP
+
+class LDAP
 {
     /**
      * LDAP link identifier.
@@ -53,17 +60,15 @@ class SimpleSAML_Auth_LDAP
      * @param int $port
      * @param bool $referrals
      */
-    // TODO: Flesh out documentation
     public function __construct($hostname, $enable_tls = true, $debug = false, $timeout = 0, $port = 389, $referrals = true)
     {
-
         // Debug
-        SimpleSAML\Logger::debug('Library - LDAP __construct(): Setup LDAP with ' .
-                        'host=\'' . $hostname .
-                        '\', tls=' . var_export($enable_tls, true) .
-                        ', debug=' . var_export($debug, true) .
-                        ', timeout=' . var_export($timeout, true) .
-                        ', referrals=' . var_export($referrals, true));
+        Logger::debug('Library - LDAP __construct(): Setup LDAP with '.
+                        'host=\''.$hostname.
+                        '\', tls='.var_export($enable_tls, true).
+                        ', debug='.var_export($debug, true).
+                        ', timeout='.var_export($timeout, true).
+                        ', referrals='.var_export($referrals, true));
 
         /*
          * Set debug level before calling connect. Note that this passes
@@ -72,7 +77,7 @@ class SimpleSAML_Auth_LDAP
          * OpenLDAP 2.x.x or Netscape Directory SDK x.x needed for this option.
          */
         if ($debug && !ldap_set_option(null, LDAP_OPT_DEBUG_LEVEL, 7)) {
-                SimpleSAML\Logger::warning('Library - LDAP __construct(): Unable to set debug level (LDAP_OPT_DEBUG_LEVEL) to 7');
+                Logger::warning('Library - LDAP __construct(): Unable to set debug level (LDAP_OPT_DEBUG_LEVEL) to 7');
         }
 
         /*
@@ -81,7 +86,7 @@ class SimpleSAML_Auth_LDAP
          */
         $this->ldap = @ldap_connect($hostname, $port);
         if ($this->ldap === false) {
-            throw $this->makeException('Library - LDAP __construct(): Unable to connect to \'' . $hostname . '\'', ERR_INTERNAL);
+            throw $this->makeException('Library - LDAP __construct(): Unable to connect to \''.$hostname.'\'', ERR_INTERNAL);
         }
 
         // Enable LDAP protocol version 3
@@ -99,15 +104,15 @@ class SimpleSAML_Auth_LDAP
         $this->timeout = $timeout;
         if ($timeout > 0) {
             if (!@ldap_set_option($this->ldap, LDAP_OPT_NETWORK_TIMEOUT, $timeout)) {
-                SimpleSAML\Logger::warning('Library - LDAP __construct(): Unable to set timeouts (LDAP_OPT_NETWORK_TIMEOUT) to ' . $timeout);
+                Logger::warning('Library - LDAP __construct(): Unable to set timeouts (LDAP_OPT_NETWORK_TIMEOUT) to '.$timeout);
             }
             if (!@ldap_set_option($this->ldap, LDAP_OPT_TIMELIMIT, $timeout)) {
-                SimpleSAML\Logger::warning('Library - LDAP __construct(): Unable to set timeouts (LDAP_OPT_TIMELIMIT) to ' . $timeout);
+                Logger::warning('Library - LDAP __construct(): Unable to set timeouts (LDAP_OPT_TIMELIMIT) to '.$timeout);
             }
         }
 
         // Enable TLS, if needed
-        if (stripos($hostname, "ldaps:") === false and $enable_tls) {
+        if (stripos($hostname, "ldaps:") === false && $enable_tls) {
             if (!@ldap_start_tls($this->ldap)) {
                 throw $this->makeException('Library - LDAP __construct(): Unable to force TLS', ERR_INTERNAL);
             }
@@ -121,7 +126,7 @@ class SimpleSAML_Auth_LDAP
      *
      * @param string $description
      * The exception's description
-     * @return Exception
+     * @return \Exception
      */
     private function makeException($description, $type = null)
     {
@@ -129,7 +134,7 @@ class SimpleSAML_Auth_LDAP
 
         // Log LDAP code and description, if possible
         if (empty($this->ldap)) {
-            SimpleSAML\Logger::error($description);
+            Logger::error($description);
         } else {
             $errNo = @ldap_errno($this->ldap);
         }
@@ -138,43 +143,43 @@ class SimpleSAML_Auth_LDAP
         if ($type) {
             if ($errNo !== 0) {
                 // Only log real LDAP errors; not success
-                SimpleSAML\Logger::error($description . '; cause: \'' . ldap_error($this->ldap) . '\' (0x' . dechex($errNo) . ')');
+                Logger::error($description.'; cause: \''.ldap_error($this->ldap).'\' (0x'.dechex($errNo).')');
             } else {
-                SimpleSAML\Logger::error($description);
+                Logger::error($description);
             }
 
             switch ($type) {
                 case ERR_INTERNAL:// 1 - ExInternal
-                    return new SimpleSAML_Error_Exception($description, $errNo);
+                    return new Error\Exception($description, $errNo);
                 case ERR_NO_USER:// 2 - ExUserNotFound
-                    return new SimpleSAML_Error_UserNotFound($description, $errNo);
+                    return new Error\UserNotFound($description, $errNo);
                 case ERR_WRONG_PW:// 3 - ExInvalidCredential
-                    return new SimpleSAML_Error_InvalidCredential($description, $errNo);
+                    return new Error\InvalidCredential($description, $errNo);
                 case ERR_AS_DATA_INCONSIST:// 4 - ExAsDataInconsist
-                    return new SimpleSAML_Error_AuthSource('ldap', $description);
+                    return new Error\AuthSource('ldap', $description);
                 case ERR_AS_INTERNAL:// 5 - ExAsInternal
-                    return new SimpleSAML_Error_AuthSource('ldap', $description);
+                    return new Error\AuthSource('ldap', $description);
             }
         } else {
             if ($errNo !== 0) {
-                $description .= '; cause: \'' . ldap_error($this->ldap) . '\' (0x' . dechex($errNo) . ')';
+                $description .= '; cause: \''.ldap_error($this->ldap).'\' (0x'.dechex($errNo).')';
                 if (@ldap_get_option($this->ldap, LDAP_OPT_DIAGNOSTIC_MESSAGE, $extendedError) && !empty($extendedError)) {
-                    $description .= '; additional: \'' . $extendedError . '\'';
+                    $description .= '; additional: \''.$extendedError.'\'';
                 }
             }
             switch ($errNo) {
                 case 0x20://LDAP_NO_SUCH_OBJECT
-                    SimpleSAML\Logger::warning($description);
-                    return new SimpleSAML_Error_UserNotFound($description, $errNo);
+                    Logger::warning($description);
+                    return new Error\UserNotFound($description, $errNo);
                 case 0x31://LDAP_INVALID_CREDENTIALS
-                    SimpleSAML\Logger::info($description);
-                    return new SimpleSAML_Error_InvalidCredential($description, $errNo);
+                    Logger::info($description);
+                    return new Error\InvalidCredential($description, $errNo);
                 case -1://NO_SERVER_CONNECTION
-                    SimpleSAML\Logger::error($description);
-                    return new SimpleSAML_Error_AuthSource('ldap', $description);
+                    Logger::error($description);
+                    return new Error\AuthSource('ldap', $description);
                 default:
-                    SimpleSAML\Logger::error($description);
-                    return new SimpleSAML_Error_AuthSource('ldap', $description);
+                    Logger::error($description);
+                    return new Error\AuthSource('ldap', $description);
             }
         }
     }
@@ -189,30 +194,34 @@ class SimpleSAML_Auth_LDAP
      * The attribute name(s) to search for.
      * @param string $value
      * The attribute value to search for.
+     * Additional search filter
+     * @param string|null $searchFilter
+     * The scope of the search
+     * @param string $scope
      * @return string
      * The DN of the resulting found element.
-     * @throws SimpleSAML_Error_Exception if:
+     * @throws Error\Exception if:
      * - Attribute parameter is wrong type
-     * @throws SimpleSAML_Error_AuthSource if:
+     * @throws Error\AuthSource if:
      * - Not able to connect to LDAP server
      * - False search result
      * - Count return false
      * - Searche found more than one result
      * - Failed to get first entry from result
      * - Failed to get DN for entry
-     * @throws SimpleSAML_Error_UserNotFound if:
+     * @throws Error\UserNotFound if:
      * - Zero entries were found
      */
-    private function search($base, $attribute, $value, $searchFilter = null)
+    private function search($base, $attribute, $value, $searchFilter = null, $scope = "subtree")
     {
         // Create the search filter
         $attribute = self::escape_filter_value($attribute, false);
-        $value = self::escape_filter_value($value);
+        $value = self::escape_filter_value($value, true);
         $filter = '';
         foreach ($attribute as $attr) {
-            $filter .= '(' . $attr . '=' . $value. ')';
+            $filter .= '('.$attr.'='.$value.')';
         }
-        $filter = '(|' . $filter . ')';
+        $filter = '(|'.$filter.')';
 
         // Append LDAP filters if defined
         if ($searchFilter != null) {
@@ -220,11 +229,17 @@ class SimpleSAML_Auth_LDAP
         }
 
         // Search using generated filter
-        SimpleSAML\Logger::debug('Library - LDAP search(): Searching base \'' . $base . '\' for \'' . $filter . '\'');
-        // TODO: Should aliases be dereferenced?
-        $result = @ldap_search($this->ldap, $base, $filter, array(), 0, 0, $this->timeout);
+        Logger::debug('Library - LDAP search(): Searching base ('.$scope.') \''.$base.'\' for \''.$filter.'\'');
+        if ($scope === 'base') {
+            $result = @ldap_read($this->ldap, $base, $filter, array(), 0, 0, $this->timeout, LDAP_DEREF_NEVER);
+        } else if ($scope === 'onelevel') {
+            $result = @ldap_list($this->ldap, $base, $filter, array(), 0, 0, $this->timeout, LDAP_DEREF_NEVER);
+        } else {
+            $result = @ldap_search($this->ldap, $base, $filter, array(), 0, 0, $this->timeout, LDAP_DEREF_NEVER);
+        }
+
         if ($result === false) {
-            throw $this->makeException('Library - LDAP search(): Failed search on base \'' . $base . '\' for \'' . $filter . '\'');
+            throw $this->makeException('Library - LDAP search(): Failed search on base \''.$base.'\' for \''.$filter.'\'');
         }
 
         // Sanity checks on search results
@@ -233,23 +248,22 @@ class SimpleSAML_Auth_LDAP
             throw $this->makeException('Library - LDAP search(): Failed to get number of entries returned');
         } elseif ($count > 1) {
             // More than one entry is found. External error
-            throw $this->makeException('Library - LDAP search(): Found ' . $count . ' entries searching base \'' . $base . '\' for \'' . $filter . '\'', ERR_AS_DATA_INCONSIST);
+            throw $this->makeException('Library - LDAP search(): Found '.$count.' entries searching base \''.$base.'\' for \''.$filter.'\'', ERR_AS_DATA_INCONSIST);
         } elseif ($count === 0) {
             // No entry is fond => wrong username is given (or not registered in the catalogue). User error
-            throw $this->makeException('Library - LDAP search(): Found no entries searching base \'' . $base . '\' for \'' . $filter . '\'', ERR_NO_USER);
+            throw $this->makeException('Library - LDAP search(): Found no entries searching base \''.$base.'\' for \''.$filter.'\'', ERR_NO_USER);
         }
 
 
         // Resolve the DN from the search result
         $entry = @ldap_first_entry($this->ldap, $result);
         if ($entry === false) {
-            throw $this->makeException('Library - LDAP search(): Unable to retrieve result after searching base \'' . $base . '\' for \'' . $filter . '\'');
+            throw $this->makeException('Library - LDAP search(): Unable to retrieve result after searching base \''.$base.'\' for \''.$filter.'\'');
         }
         $dn = @ldap_get_dn($this->ldap, $entry);
         if ($dn === false) {
-            throw $this->makeException('Library - LDAP search(): Unable to get DN after searching base \'' . $base . '\' for \'' . $filter . '\'');
+            throw $this->makeException('Library - LDAP search(): Unable to get DN after searching base \''.$base.'\' for \''.$filter.'\'');
         }
-        // FIXME: Are we now sure, if no excepton has been thrown, that we are returning a DN?
         return $dn;
     }
 
@@ -266,45 +280,48 @@ class SimpleSAML_Auth_LDAP
      * @param bool $allowZeroHits
      * Determines if the method will throw an exception if no hits are found.
      * Defaults to FALSE.
+     * @param string|null $searchFilter
+     * Additional searchFilter to be added to the (attribute=value) filter
+     * @param string $scope
+     * The scope of the search
      * @return string
      * The DN of the matching element, if found. If no element was found and
      * $allowZeroHits is set to FALSE, an exception will be thrown; otherwise
      * NULL will be returned.
-     * @throws SimpleSAML_Error_AuthSource if:
+     * @throws Error\AuthSource if:
      * - LDAP search encounter some problems when searching cataloge
      * - Not able to connect to LDAP server
-     * @throws SimpleSAML_Error_UserNotFound if:
+     * @throws Error\UserNotFound if:
      * - $allowZeroHits is FALSE and no result is found
      *
      */
-    public function searchfordn($base, $attribute, $value, $allowZeroHits = false, $searchFilter = null)
+    public function searchfordn($base, $attribute, $value, $allowZeroHits = false, $searchFilter = null, $scope = 'subtree')
     {
         // Traverse all search bases, returning DN if found
-        $bases = SimpleSAML\Utils\Arrays::arrayize($base);
-        $result = null;
+        $bases = \SimpleSAML\Utils\Arrays::arrayize($base);
         foreach ($bases as $current) {
             try {
                 // Single base search
-                $result = $this->search($current, $attribute, $value, $searchFilter);
+                $result = $this->search($current, $attribute, $value, $searchFilter, $scope);
 
                 // We don't hawe to look any futher if user is found
                 if (!empty($result)) {
                     return $result;
                 }
                 // If search failed, attempt the other base DNs
-            } catch (SimpleSAML_Error_UserNotFound $e) {
+            } catch (Error\UserNotFound $e) {
                 // Just continue searching
             }
         }
         // Decide what to do for zero entries
-        SimpleSAML\Logger::debug('Library - LDAP searchfordn(): No entries found');
+        Logger::debug('Library - LDAP searchfordn(): No entries found');
         if ($allowZeroHits) {
             // Zero hits allowed
             return null;
         } else {
             // Zero hits not allowed
-            throw $this->makeException('Library - LDAP searchfordn(): LDAP search returned zero entries for filter \'(' .
-                $attribute . ' = ' . $value . ')\' on base(s) \'(' . join(' & ', $bases) . ')\'', 2);
+            throw $this->makeException('Library - LDAP searchfordn(): LDAP search returned zero entries for filter \'('.
+                join(' | ', $attribute).' = '.$value.')\' on base(s) \'('.join(' & ', $bases).')\'', 2);
         }
     }
 
@@ -313,15 +330,16 @@ class SimpleSAML_Auth_LDAP
      * This method was created specifically for the ldap:AttributeAddUsersGroups->searchActiveDirectory()
      * method, but could be used for other LDAP search needs. It will search LDAP and return all the entries.
      *
-     * @throws Exception
+     * @throws \Exception
      * @param string|array $bases
      * @param string|array $filters Array of 'attribute' => 'values' to be combined into the filter, or a raw filter string
      * @param string|array $attributes Array of attributes requested from LDAP
      * @param bool $and If multiple filters defined, then either bind them with & or |
      * @param bool $escape Weather to escape the filter values or not
+     * @param string $scope The scope of the search
      * @return array
      */
-    public function searchformultiple($bases, $filters, $attributes = array(), $and = true, $escape = true)
+    public function searchformultiple($bases, $filters, $attributes = array(), $and = true, $escape = true, $scope = 'subtree')
     {
         // Escape the filter values, if requested
         if ($escape) {
@@ -335,7 +353,7 @@ class SimpleSAML_Auth_LDAP
                 $filter .= "($attribute=$value)";
             }
             if (count($filters) > 1) {
-                $filter = ($and ? '(&' : '(|') . $filter . ')';
+                $filter = ($and ? '(&' : '(|').$filter.')';
             }
         } elseif (is_string($filters)) {
             $filter = $filters;
@@ -355,7 +373,14 @@ class SimpleSAML_Auth_LDAP
         // Search each base until result is found
         $result = false;
         foreach ($bases as $base) {
-            $result = @ldap_search($this->ldap, $base, $filter, $attributes, 0, 0, $this->timeout);
+            if ($scope === 'base') {
+                $result = @ldap_read($this->ldap, $base, $filter, $attributes, 0, 0, $this->timeout);
+            } else if ($scope === 'onelevel') {
+                $result = @ldap_list($this->ldap, $base, $filter, $attributes, 0, 0, $this->timeout);
+            } else {
+                $result = @ldap_search($this->ldap, $base, $filter, $attributes, 0, 0, $this->timeout);
+            }
+
             if ($result !== false && @ldap_count_entries($this->ldap, $result) > 0) {
                 break;
             }
@@ -364,14 +389,14 @@ class SimpleSAML_Auth_LDAP
         // Verify that a result was found in one of the bases
         if ($result === false) {
             throw $this->makeException(
-                'ldap:LdapConnection->search_manual : Failed to search LDAP using base(s) [' .
-                implode('; ', $bases) . '] with filter [' . $filter . ']. LDAP error [' .
-                ldap_error($this->ldap) . ']'
+                'ldap:LdapConnection->search_manual : Failed to search LDAP using base(s) ['.
+                implode('; ', $bases).'] with filter ['.$filter.']. LDAP error ['.
+                ldap_error($this->ldap).']'
             );
         } elseif (@ldap_count_entries($this->ldap, $result) < 1) {
             throw $this->makeException(
-                'ldap:LdapConnection->search_manual : No entries found in LDAP using base(s) [' .
-                implode('; ', $bases) . '] with filter [' . $filter . ']',
+                'ldap:LdapConnection->search_manual : No entries found in LDAP using base(s) ['.
+                implode('; ', $bases).'] with filter ['.$filter.']',
                 ERR_NO_USER
             );
         }
@@ -423,12 +448,10 @@ class SimpleSAML_Auth_LDAP
      * Returns TRUE if successful, FALSE if
      * LDAP_INVALID_CREDENTIALS, LDAP_X_PROXY_AUTHZ_FAILURE,
      * LDAP_INAPPROPRIATE_AUTH, LDAP_INSUFFICIENT_ACCESS
-     * @throws SimpleSAML_Error_Exception on other errors
+     * @throws Error\Exception on other errors
      */
     public function bind($dn, $password, array $sasl_args = null)
     {
-        $authz_id = null;
-
         if ($sasl_args != null) {
             if (!function_exists('ldap_sasl_bind')) {
                 $ex_msg = 'Library - missing SASL support';
@@ -456,7 +479,7 @@ class SimpleSAML_Auth_LDAP
         if ($error === true) {
             // Good
             $this->authz_id = $authz_id;
-            SimpleSAML\Logger::debug('Library - LDAP bind(): Bind successful with DN \'' . $dn . '\'');
+            Logger::debug('Library - LDAP bind(): Bind successful with DN \''.$dn.'\'');
             return true;
         }
 
@@ -479,7 +502,7 @@ class SimpleSAML_Auth_LDAP
         }
 
         // Bad
-        throw $this->makeException('Library - LDAP bind(): Bind failed with DN \'' . $dn . '\'');
+        throw $this->makeException('Library - LDAP bind(): Bind failed with DN \''.$dn.'\'');
     }
 
 
@@ -496,16 +519,16 @@ class SimpleSAML_Auth_LDAP
         // Attempt to set the LDAP option
         if (!@ldap_set_option($this->ldap, $option, $value)) {
             throw $this->makeException(
-                'ldap:LdapConnection->setOption : Failed to set LDAP option [' .
-                $option . '] with the value [' . $value . '] error: ' . ldap_error($this->ldap),
+                'ldap:LdapConnection->setOption : Failed to set LDAP option ['.
+                $option.'] with the value ['.$value.'] error: '.ldap_error($this->ldap),
                 ERR_INTERNAL
             );
         }
 
         // Log debug message
-        SimpleSAML\Logger::debug(
-            'ldap:LdapConnection->setOption : Set the LDAP option [' .
-            $option . '] with the value [' . $value . ']'
+        Logger::debug(
+            'ldap:LdapConnection->setOption : Set the LDAP option ['.
+            $option.'] with the value ['.$value.']'
         );
     }
 
@@ -531,31 +554,31 @@ class SimpleSAML_Auth_LDAP
         // Preparations, including a pretty debug message...
         $description = 'all attributes';
         if (is_array($attributes)) {
-            $description = '\'' . join(',', $attributes) . '\'';
+            $description = '\''.join(',', $attributes).'\'';
         } else {
             // Get all attributes...
             // TODO: Verify that this originally was the intended behaviour. Could $attributes be a string?
             $attributes = array();
         }
-        SimpleSAML\Logger::debug('Library - LDAP getAttributes(): Getting ' . $description . ' from DN \'' . $dn . '\'');
+        Logger::debug('Library - LDAP getAttributes(): Getting '.$description.' from DN \''.$dn.'\'');
 
         // Attempt to get attributes
         // TODO: Should aliases be dereferenced?
         $result = @ldap_read($this->ldap, $dn, 'objectClass=*', $attributes, 0, 0, $this->timeout);
         if ($result === false) {
-            throw $this->makeException('Library - LDAP getAttributes(): Failed to get attributes from DN \'' . $dn . '\'');
+            throw $this->makeException('Library - LDAP getAttributes(): Failed to get attributes from DN \''.$dn.'\'');
         }
         $entry = @ldap_first_entry($this->ldap, $result);
         if ($entry === false) {
-            throw $this->makeException('Library - LDAP getAttributes(): Could not get first entry from DN \'' . $dn . '\'');
+            throw $this->makeException('Library - LDAP getAttributes(): Could not get first entry from DN \''.$dn.'\'');
         }
-        $attributes = @ldap_get_attributes($this->ldap, $entry);  // Recycling $attributes... Possibly bad practice.
+        $attributes = @ldap_get_attributes($this->ldap, $entry); // Recycling $attributes... Possibly bad practice.
         if ($attributes === false) {
-            throw $this->makeException('Library - LDAP getAttributes(): Could not get attributes of first entry from DN \'' . $dn . '\'');
+            throw $this->makeException('Library - LDAP getAttributes(): Could not get attributes of first entry from DN \''.$dn.'\'');
         }
 
         // Parsing each found attribute into our result set
-        $result = array();  // Recycling $result... Possibly bad practice.
+        $result = array(); // Recycling $result... Possibly bad practice.
         for ($i = 0; $i < $attributes['count']; $i++) {
             // Ignore attributes that exceed the maximum allowed size
             $name = $attributes[$i];
@@ -566,15 +589,15 @@ class SimpleSAML_Auth_LDAP
             for ($j = 0; $j < $attribute['count']; $j++) {
                 $value = $attribute[$j];
 
-                if (!empty($maxsize) && strlen($value) >= $maxsize) {
+                if (!empty($maxsize) && strlen($value) > $maxsize) {
                     // Ignoring and warning
-                    SimpleSAML\Logger::warning('Library - LDAP getAttributes(): Attribute \'' .
-                        $name . '\' exceeded maximum allowed size by ' + ($maxsize - strlen($value)));
+                    Logger::warning('Library - LDAP getAttributes(): Attribute \''.
+                        $name.'\' exceeded maximum allowed size by '.(strlen($value) - $maxsize));
                     continue;
                 }
 
                 // Base64 encode binary attributes
-                if (strtolower($name) === 'jpegphoto' || strtolower($name) === 'objectguid') {
+                if (strtolower($name) === 'jpegphoto' || strtolower($name) === 'objectguid' || strtolower($name) === 'ms-ds-consistencyguid') {
                     $values[] = base64_encode($value);
                 } else {
                     $values[] = $value;
@@ -586,7 +609,7 @@ class SimpleSAML_Auth_LDAP
         }
 
         // We're done
-        SimpleSAML\Logger::debug('Library - LDAP getAttributes(): Found attributes \'(' . join(',', array_keys($result)) . ')\'');
+        Logger::debug('Library - LDAP getAttributes(): Found attributes \'('.join(',', array_keys($result)).')\'');
         return $result;
     }
 
@@ -594,12 +617,11 @@ class SimpleSAML_Auth_LDAP
     /**
      * Enter description here...
      *
-     * @param string $config
+     * @param array $config
      * @param string $username
      * @param string $password
      * @return array|bool
      */
-    // TODO: Documentation; only cleared up exception/log messages
     public function validate($config, $username, $password = null)
     {
         /* Escape any characters with a special meaning in LDAP. The following
@@ -622,7 +644,7 @@ class SimpleSAML_Auth_LDAP
             // escape characters with a special meaning, also in the password
             $password = addcslashes($password, ',+"\\<>;*');
             if (!$this->bind($dn, $password)) {
-                SimpleSAML\Logger::info('Library - LDAP validate(): Failed to authenticate \''. $username . '\' using DN \'' . $dn . '\'');
+                Logger::info('Library - LDAP validate(): Failed to authenticate \''.$username.'\' using DN \''.$dn.'\'');
                 return false;
             }
         }
@@ -645,15 +667,13 @@ class SimpleSAML_Auth_LDAP
      * backslash followed by two hex digits representing the hexadecimal value of the character.
      *
      * @static
-     * @param array $values Array of values to escape
+     * @param string|array $values Array of values to escape
      * @return array Array $values, but escaped
      */
     public static function escape_filter_value($values = array(), $singleValue = true)
     {
         // Parameter validation
-        if (!is_array($values)) {
-            $values = array($values);
-        }
+        $values = \SimpleSAML\Utils\Arrays::arrayize($values);
 
         foreach ($values as $key => $val) {
             // Escaping of filter meta characters
@@ -666,7 +686,7 @@ class SimpleSAML_Auth_LDAP
             $val = self::asc2hex32($val);
 
             if (null === $val) {
-                $val = '\0';  // apply escaped "null" if string is empty
+                $val = '\0'; // apply escaped "null" if string is empty
             }
 
             $values[$key] = $val;
@@ -737,7 +757,6 @@ class SimpleSAML_Auth_LDAP
     public function whoami($searchBase, $searchAttributes)
     {
         $authz_id = '';
-
         if (function_exists('ldap_exop_whoami')) {
             if (version_compare(phpversion(), '7', '<')) {
                 if (ldap_exop_whoami($this->ldap, $authz_id) !== true) {
diff --git a/lib/SimpleSAML/Auth/ProcessingChain.php b/lib/SimpleSAML/Auth/ProcessingChain.php
index 1477203f73d366b8e0aa9463e3f6b6bb92f933cc..620c5c5ce46a53fa00f966f601c3059b2f73a213 100644
--- a/lib/SimpleSAML/Auth/ProcessingChain.php
+++ b/lib/SimpleSAML/Auth/ProcessingChain.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Auth;
+
 /**
  * Class for implementing authentication processing chains for IdPs.
  *
@@ -10,20 +12,19 @@
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Auth_ProcessingChain
-{
-
 
+class ProcessingChain
+{
     /**
      * The list of remaining filters which should be applied to the state.
      */
-    const FILTERS_INDEX = 'SimpleSAML_Auth_ProcessingChain.filters';
+    const FILTERS_INDEX = '\SimpleSAML\Auth\ProcessingChain.filters';
 
 
     /**
      * The stage we use for completed requests.
      */
-    const COMPLETED_STAGE = 'SimpleSAML_Auth_ProcessingChain.completed';
+    const COMPLETED_STAGE = '\SimpleSAML\Auth\ProcessingChain.completed';
 
 
     /**
@@ -53,7 +54,7 @@ class SimpleSAML_Auth_ProcessingChain
 
         $this->filters = array();
 
-        $config = SimpleSAML_Configuration::getInstance();
+        $config = \SimpleSAML\Configuration::getInstance();
         $configauthproc = $config->getArray('authproc.' . $mode, null);
 
         if (!empty($configauthproc)) {
@@ -71,8 +72,7 @@ class SimpleSAML_Auth_ProcessingChain
             self::addFilters($this->filters, $spFilters);
         }
 
-
-        SimpleSAML\Logger::debug('Filter config for ' . $idpMetadata['entityid'] . '->' .
+        \SimpleSAML\Logger::debug('Filter config for ' . $idpMetadata['entityid'] . '->' .
             $spMetadata['entityid'] . ': ' . str_replace("\n", '', var_export($this->filters, true)));
     }
 
@@ -110,7 +110,7 @@ class SimpleSAML_Auth_ProcessingChain
      * Parse an array of authentication processing filters.
      *
      * @param array $filterSrc  Array with filter configuration.
-     * @return array  Array of SimpleSAML_Auth_ProcessingFilter objects.
+     * @return array  Array of ProcessingFilter objects.
      */
     private static function parseFilterList($filterSrc)
     {
@@ -124,7 +124,7 @@ class SimpleSAML_Auth_ProcessingChain
             }
 
             if (!is_array($filter)) {
-                throw new Exception('Invalid authentication processing filter configuration: ' .
+                throw new \Exception('Invalid authentication processing filter configuration: ' .
                     'One of the filters wasn\'t a string or an array.');
             }
 
@@ -138,20 +138,20 @@ class SimpleSAML_Auth_ProcessingChain
     /**
      * Parse an authentication processing filter.
      *
-     * @param array $config     Array with the authentication processing filter configuration.
-     * @param int $priority     The priority of the current filter, (not included in the filter
-     *                          definition.)
-     * @return SimpleSAML_Auth_ProcessingFilter  The parsed filter.
+     * @param array $config      Array with the authentication processing filter configuration.
+     * @param int $priority      The priority of the current filter, (not included in the filter
+     *                           definition.)
+     * @return ProcessingFilter  The parsed filter.
      */
     private static function parseFilter($config, $priority)
     {
         assert(is_array($config));
 
         if (!array_key_exists('class', $config)) {
-            throw new Exception('Authentication processing filter without name given.');
+            throw new \Exception('Authentication processing filter without name given.');
         }
 
-        $className = SimpleSAML\Module::resolveClass($config['class'], 'Auth_Process', 'SimpleSAML_Auth_ProcessingFilter');
+        $className = \SimpleSAML\Module::resolveClass($config['class'], 'Auth_Process', '\SimpleSAML\Auth\ProcessingFilter');
         $config['%priority'] = $priority;
         unset($config['class']);
         return new $className($config, null);
@@ -170,11 +170,11 @@ class SimpleSAML_Auth_ProcessingChain
      * If an exception is thrown during processing, it should be handled by the caller of
      * this function. If the user has redirected to a different page, the exception will be
      * returned through the exception handler defined on the state array. See
-     * SimpleSAML_Auth_State for more information.
+     * State for more information.
      *
-     * @see SimpleSAML_Auth_State
-     * @see SimpleSAML_Auth_State::EXCEPTION_HANDLER_URL
-     * @see SimpleSAML_Auth_State::EXCEPTION_HANDLER_FUNC
+     * @see State
+     * @see State::EXCEPTION_HANDLER_URL
+     * @see State::EXCEPTION_HANDLER_FUNC
      *
      * @param array &$state  The state we are processing.
      */
@@ -197,15 +197,15 @@ class SimpleSAML_Auth_ProcessingChain
                 $filter = array_shift($state[self::FILTERS_INDEX]);
                 $filter->process($state);
             }
-        } catch (SimpleSAML_Error_Exception $e) {
+        } catch (\SimpleSAML\Error\Exception $e) {
             // No need to convert the exception
             throw $e;
-        } catch (Exception $e) {
+        } catch (\Exception $e) {
             /*
 			 * To be consistent with the exception we return after an redirect,
 			 * we convert this exception before returning it.
 			 */
-            throw new SimpleSAML_Error_UnserializableException($e);
+            throw new \SimpleSAML\Error\UnserializableException($e);
         }
 
         // Completed
@@ -231,11 +231,11 @@ class SimpleSAML_Auth_ProcessingChain
             $filter = array_shift($state[self::FILTERS_INDEX]);
             try {
                 $filter->process($state);
-            } catch (SimpleSAML_Error_Exception $e) {
-                SimpleSAML_Auth_State::throwException($state, $e);
-            } catch (Exception $e) {
-                $e = new SimpleSAML_Error_UnserializableException($e);
-                SimpleSAML_Auth_State::throwException($state, $e);
+            } catch (\SimpleSAML\Error\Exception $e) {
+                State::throwException($state, $e);
+            } catch (\Exception $e) {
+                $e = new \SimpleSAML\Error\UnserializableException($e);
+                State::throwException($state, $e);
             }
         }
 
@@ -250,13 +250,13 @@ class SimpleSAML_Auth_ProcessingChain
 			 * Save state information, and redirect to the URL specified
 			 * in $state['ReturnURL'].
 			 */
-            $id = SimpleSAML_Auth_State::saveState($state, self::COMPLETED_STAGE);
+            $id = State::saveState($state, self::COMPLETED_STAGE);
             \SimpleSAML\Utils\HTTP::redirectTrustedURL($state['ReturnURL'], array(self::AUTHPARAM => $id));
         } else {
             /* Pass the state to the function defined in $state['ReturnCall']. */
 
             // We are done with the state array in the session. Delete it.
-            SimpleSAML_Auth_State::deleteState($state);
+            State::deleteState($state);
 
             $func = $state['ReturnCall'];
             assert(is_callable($func));
@@ -270,7 +270,7 @@ class SimpleSAML_Auth_ProcessingChain
     /**
      * Process the given state passivly.
      *
-     * Modules with user interaction are expected to throw an SimpleSAML_Error_NoPassive exception
+     * Modules with user interaction are expected to throw an \SimpleSAML\Error\NoPassive exception
      * which are silently ignored. Exceptions of other types are passed further up the call stack.
      *
      * This function will only return if processing completes.
@@ -299,8 +299,8 @@ class SimpleSAML_Auth_ProcessingChain
             try {
                 $filter->process($state);
 
-            // Ignore SimpleSAML_Error_NoPassive exceptions
-            } catch (SimpleSAML_Error_NoPassive $e) {
+            // Ignore \SimpleSAML\Error\NoPassive exceptions
+            } catch (\SimpleSAML\Error\NoPassive $e) {
             }
         }
     }
@@ -309,14 +309,14 @@ class SimpleSAML_Auth_ProcessingChain
      * Retrieve a state which has finished processing.
      *
      * @param string $id The state identifier.
-     * @see SimpleSAML_Auth_State::parseStateID()
+     * @see State::parseStateID()
      * @return Array The state referenced by the $id parameter.
      */
     public static function fetchProcessedState($id)
     {
         assert(is_string($id));
 
-        return SimpleSAML_Auth_State::loadState($id, self::COMPLETED_STAGE);
+        return State::loadState($id, self::COMPLETED_STAGE);
     }
 
 
@@ -330,10 +330,10 @@ class SimpleSAML_Auth_ProcessingChain
 
         if (isset($state['Destination']['userid.attribute'])) {
             $attributeName = $state['Destination']['userid.attribute'];
-            SimpleSAML\Logger::warning("The 'userid.attribute' option has been deprecated.");
+            \SimpleSAML\Logger::warning("The 'userid.attribute' option has been deprecated.");
         } elseif (isset($state['Source']['userid.attribute'])) {
             $attributeName = $state['Source']['userid.attribute'];
-            SimpleSAML\Logger::warning("The 'userid.attribute' option has been deprecated.");
+            \SimpleSAML\Logger::warning("The 'userid.attribute' option has been deprecated.");
         } else {
             // Default attribute
             $attributeName = 'eduPersonPrincipalName';
@@ -345,12 +345,12 @@ class SimpleSAML_Auth_ProcessingChain
 
         $uid = $state['Attributes'][$attributeName];
         if (count($uid) === 0) {
-            SimpleSAML\Logger::warning('Empty user id attribute [' . $attributeName . '].');
+            \SimpleSAML\Logger::warning('Empty user id attribute [' . $attributeName . '].');
             return;
         }
 
         if (count($uid) > 1) {
-            SimpleSAML\Logger::warning('Multiple attribute values for user id attribute [' . $attributeName . '].');
+            \SimpleSAML\Logger::warning('Multiple attribute values for user id attribute [' . $attributeName . '].');
             return;
         }
 
@@ -358,7 +358,7 @@ class SimpleSAML_Auth_ProcessingChain
         $uid = $uid[0];
 
         if (empty($uid)) {
-            SimpleSAML\Logger::warning('Empty value in attribute '.$attributeName.". on user. Cannot set UserID.");
+            \SimpleSAML\Logger::warning('Empty value in attribute '.$attributeName.". on user. Cannot set UserID.");
             return;
         }
         $state['UserID'] = $uid;
diff --git a/lib/SimpleSAML/Auth/ProcessingFilter.php b/lib/SimpleSAML/Auth/ProcessingFilter.php
index e6126da1de01bd040d39c5a8feff6f813761b290..baeb5834b68dc81dd8c2f3e1f35cbde829a40663 100644
--- a/lib/SimpleSAML/Auth/ProcessingFilter.php
+++ b/lib/SimpleSAML/Auth/ProcessingFilter.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML\Auth;
 
 /**
  * Base class for authentication processing filters.
@@ -18,9 +19,9 @@
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-abstract class SimpleSAML_Auth_ProcessingFilter
-{
 
+abstract class ProcessingFilter
+{
     /**
      * Priority of this filter.
      *
@@ -49,7 +50,7 @@ abstract class SimpleSAML_Auth_ProcessingFilter
         if (array_key_exists('%priority', $config)) {
             $this->priority = $config['%priority'];
             if (!is_int($this->priority)) {
-                throw new Exception('Invalid priority: ' . var_export($this->priority, true));
+                throw new \Exception('Invalid priority: ' . var_export($this->priority, true));
             }
             unset($config['%priority']);
         }
diff --git a/lib/SimpleSAML/Auth/Simple.php b/lib/SimpleSAML/Auth/Simple.php
index 9ad8e86a2d575cc8ab3a5edd289c4b4266ae8fc9..a7efadca9b8354496623aa5c858e2d14b39e9410 100644
--- a/lib/SimpleSAML/Auth/Simple.php
+++ b/lib/SimpleSAML/Auth/Simple.php
@@ -2,12 +2,10 @@
 
 namespace SimpleSAML\Auth;
 
-use \SimpleSAML_Auth_Source as Source;
-use \SimpleSAML_Auth_State as State;
-use \SimpleSAML_Configuration as Configuration;
-use \SimpleSAML_Error_AuthSource as AuthSourceError;
+use \SimpleSAML\Configuration;
+use \SimpleSAML\Error\AuthSource as AuthSourceError;
 use \SimpleSAML\Module;
-use \SimpleSAML_Session as Session;
+use \SimpleSAML\Session;
 use \SimpleSAML\Utils\HTTP;
 
 /**
@@ -15,9 +13,9 @@ use \SimpleSAML\Utils\HTTP;
  *
  * @package SimpleSAMLphp
  */
+
 class Simple
 {
-
     /**
      * The id of the authentication source we are accessing.
      *
@@ -26,7 +24,7 @@ class Simple
     protected $authSource;
 
     /**
-     * @var \SimpleSAML_Configuration|null
+     * @var Configuration|null
      */
     protected $app_config;
 
@@ -47,9 +45,9 @@ class Simple
     /**
      * Retrieve the implementing authentication source.
      *
-     * @return \SimpleSAML_Auth_Source The authentication source.
+     * @return Source The authentication source.
      *
-     * @throws \SimpleSAML_Error_AuthSource If the requested auth source is unknown.
+     * @throws AuthSourceError If the requested auth source is unknown.
      */
     public function getAuthSource()
     {
@@ -92,7 +90,6 @@ class Simple
      */
     public function requireAuth(array $params = array())
     {
-
         $session = Session::getSessionFromRequest();
 
         if ($session->isValid($this->authSource)) {
@@ -120,7 +117,6 @@ class Simple
      */
     public function login(array $params = array())
     {
-
         if (array_key_exists('KeepPost', $params)) {
             $keepPost = (bool) $params['KeepPost'];
         } else {
@@ -242,7 +238,7 @@ class Simple
                 $stateID = State::saveState($state, $state['ReturnStateStage']);
                 $params[$state['ReturnStateParam']] = $stateID;
             }
-            \SimpleSAML\Utils\HTTP::redirectTrustedURL($state['ReturnTo'], $params);
+            HTTP::redirectTrustedURL($state['ReturnTo'], $params);
         }
     }
 
@@ -257,7 +253,6 @@ class Simple
      */
     public function getAttributes()
     {
-
         if (!$this->isAuthenticated()) {
             // Not authenticated
             return array();
@@ -296,7 +291,6 @@ class Simple
      */
     public function getAuthDataArray()
     {
-
         if (!$this->isAuthenticated()) {
             return null;
         }
diff --git a/lib/SimpleSAML/Auth/Source.php b/lib/SimpleSAML/Auth/Source.php
index 349d097df7810f252812418a5523768f45984c0d..9f18a0af3124a137d56f703f2ed5753afbae8769 100644
--- a/lib/SimpleSAML/Auth/Source.php
+++ b/lib/SimpleSAML/Auth/Source.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML\Auth;
 
 /**
  * This class defines a base class for authentication source.
@@ -9,10 +10,9 @@
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-abstract class SimpleSAML_Auth_Source
-{
-
 
+abstract class Source
+{
     /**
      * The authentication source identifier. This identifier can be used to look up this object, for example when
      * returning from a login form.
@@ -46,14 +46,14 @@ abstract class SimpleSAML_Auth_Source
      *
      * @param string $type The type of the authentication source.
      *
-     * @return SimpleSAML_Auth_Source[]  Array of SimpleSAML_Auth_Source objects of the specified type.
+     * @return Source[]  Array of \SimpleSAML\Auth\Source objects of the specified type.
      * @throws Exception If the authentication source is invalid.
      */
     public static function getSourcesOfType($type)
     {
         assert(is_string($type));
 
-        $config = SimpleSAML_Configuration::getConfig('authsources.php');
+        $config = \SimpleSAML\Configuration::getConfig('authsources.php');
 
         $ret = array();
 
@@ -115,7 +115,7 @@ abstract class SimpleSAML_Auth_Source
         assert(isset($state['ReturnCallback']));
 
         // the default implementation just copies over the previous authentication data
-        $session = SimpleSAML_Session::getSessionFromRequest();
+        $session = \SimpleSAML\Session::getSessionFromRequest();
         $data = $session->getAuthState($this->authId);
         foreach ($data as $k => $v) {
             $state[$k] = $v;
@@ -137,7 +137,7 @@ abstract class SimpleSAML_Auth_Source
         assert(is_array($state));
         assert(array_key_exists('LoginCompletedHandler', $state));
 
-        SimpleSAML_Auth_State::deleteState($state);
+        State::deleteState($state);
 
         $func = $state['LoginCompletedHandler'];
         assert(is_callable($func));
@@ -166,36 +166,36 @@ abstract class SimpleSAML_Auth_Source
         assert(is_string($errorURL) || $errorURL === null);
 
         $state = array_merge($params, array(
-            'SimpleSAML_Auth_Default.id' => $this->authId, // TODO: remove in 2.0
-            'SimpleSAML_Auth_Source.id' => $this->authId,
-            'SimpleSAML_Auth_Default.Return' => $return, // TODO: remove in 2.0
-            'SimpleSAML_Auth_Source.Return' => $return,
-            'SimpleSAML_Auth_Default.ErrorURL' => $errorURL, // TODO: remove in 2.0
-            'SimpleSAML_Auth_Source.ErrorURL' => $errorURL,
+            '\SimpleSAML\Auth\DefaultAuth.id' => $this->authId, // TODO: remove in 2.0
+            '\SimpleSAML\Auth\Source.id' => $this->authId,
+            '\SimpleSAML\Auth\DefaultAuth.Return' => $return, // TODO: remove in 2.0
+            '\SimpleSAML\Auth\Source.Return' => $return,
+            '\SimpleSAML\Auth\DefaultAuth.ErrorURL' => $errorURL, // TODO: remove in 2.0
+            '\SimpleSAML\Auth\Source.ErrorURL' => $errorURL,
             'LoginCompletedHandler' => array(get_class(), 'loginCompleted'),
             'LogoutCallback' => array(get_class(), 'logoutCallback'),
             'LogoutCallbackState' => array(
-                'SimpleSAML_Auth_Default.logoutSource' => $this->authId, // TODO: remove in 2.0
-                'SimpleSAML_Auth_Source.logoutSource' => $this->authId,
+                '\SimpleSAML\Auth\DefaultAuth.logoutSource' => $this->authId, // TODO: remove in 2.0
+                '\SimpleSAML\Auth\Source.logoutSource' => $this->authId,
             ),
         ));
 
         if (is_string($return)) {
-            $state['SimpleSAML_Auth_Default.ReturnURL'] = $return; // TODO: remove in 2.0
-            $state['SimpleSAML_Auth_Source.ReturnURL'] = $return;
+            $state['\SimpleSAML\Auth\DefaultAuth.ReturnURL'] = $return; // TODO: remove in 2.0
+            $state['\SimpleSAML\Auth\Source.ReturnURL'] = $return;
         }
 
         if ($errorURL !== null) {
-            $state[SimpleSAML_Auth_State::EXCEPTION_HANDLER_URL] = $errorURL;
+            $state[State::EXCEPTION_HANDLER_URL] = $errorURL;
         }
 
         try {
             $this->authenticate($state);
-        } catch (SimpleSAML_Error_Exception $e) {
-            SimpleSAML_Auth_State::throwException($state, $e);
-        } catch (Exception $e) {
-            $e = new SimpleSAML_Error_UnserializableException($e);
-            SimpleSAML_Auth_State::throwException($state, $e);
+        } catch (\SimpleSAML\Error\Exception $e) {
+            State::throwException($state, $e);
+        } catch (\Exception $e) {
+            $e = new \SimpleSAML\Error\UnserializableException($e);
+            State::throwException($state, $e);
         }
         self::loginCompleted($state);
     }
@@ -211,17 +211,17 @@ abstract class SimpleSAML_Auth_Source
     public static function loginCompleted($state)
     {
         assert(is_array($state));
-        assert(array_key_exists('SimpleSAML_Auth_Source.Return', $state));
-        assert(array_key_exists('SimpleSAML_Auth_Source.id', $state));
+        assert(array_key_exists('\SimpleSAML\Auth\Source.Return', $state));
+        assert(array_key_exists('\SimpleSAML\Auth\Source.id', $state));
         assert(array_key_exists('Attributes', $state));
         assert(!array_key_exists('LogoutState', $state) || is_array($state['LogoutState']));
 
-        $return = $state['SimpleSAML_Auth_Source.Return'];
+        $return = $state['\SimpleSAML\Auth\Source.Return'];
 
         // save session state
-        $session = SimpleSAML_Session::getSessionFromRequest();
-        $authId = $state['SimpleSAML_Auth_Source.id'];
-        $session->doLogin($authId, SimpleSAML_Auth_State::getPersistentAuthData($state));
+        $session = \SimpleSAML\Session::getSessionFromRequest();
+        $authId = $state['\SimpleSAML\Auth\Source.id'];
+        $session->doLogin($authId, State::getPersistentAuthData($state));
 
         if (is_string($return)) { // redirect...
             \SimpleSAML\Utils\HTTP::redirectTrustedURL($return);
@@ -266,7 +266,7 @@ abstract class SimpleSAML_Auth_Source
         assert(is_array($state));
         assert(array_key_exists('LogoutCompletedHandler', $state));
 
-        SimpleSAML_Auth_State::deleteState($state);
+        State::deleteState($state);
 
         $func = $state['LogoutCompletedHandler'];
         assert(is_callable($func));
@@ -285,8 +285,8 @@ abstract class SimpleSAML_Auth_Source
      * @param string $authId The authentication source identifier.
      * @param array  $config The configuration.
      *
-     * @return SimpleSAML_Auth_Source The parsed authentication source.
-     * @throws Exception If the authentication source is invalid.
+     * @return Source The parsed authentication source.
+     * @throws \Exception If the authentication source is invalid.
      */
     private static function parseAuthSource($authId, $config)
     {
@@ -295,11 +295,26 @@ abstract class SimpleSAML_Auth_Source
 
         self::validateSource($config, $authId);
 
-        $className = SimpleSAML\Module::resolveClass($config[0], 'Auth_Source', 'SimpleSAML_Auth_Source');
-
+        $id = $config[0];
         $info = array('AuthId' => $authId);
+        $authSource = null;
+
         unset($config[0]);
-        return new $className($info, $config);
+
+        try {
+            // Check whether or not there's a factory responsible for instantiating our Auth Source instance
+            $factoryClass = \SimpleSAML\Module::resolveClass($id, 'Auth_Source_Factory', '\SimpleSAML\Auth\SourceFactory');
+
+            /** @var SourceFactory $factory */
+            $factory = new $factoryClass;
+            $authSource = $factory->create($info, $config);
+        } catch (\Exception $e) {
+            // If not, instantiate the Auth Source here
+            $className = \SimpleSAML\Module::resolveClass($id, 'Auth_Source', '\SimpleSAML\Auth\Source');
+            $authSource = new $className($info, $config);
+        }
+
+        return $authSource;
     }
 
 
@@ -317,9 +332,9 @@ abstract class SimpleSAML_Auth_Source
      * @param string      $authId The authentication source identifier.
      * @param string|NULL $type The type of authentication source. If NULL, any type will be accepted.
      *
-     * @return SimpleSAML_Auth_Source|NULL The AuthSource object, or NULL if no authentication
+     * @return Source|NULL The AuthSource object, or NULL if no authentication
      *     source with the given identifier is found.
-     * @throws SimpleSAML_Error_Exception If no such authentication source is found or it is invalid.
+     * @throws \SimpleSAML\Error\Exception If no such authentication source is found or it is invalid.
      */
     public static function getById($authId, $type = null)
     {
@@ -327,12 +342,12 @@ abstract class SimpleSAML_Auth_Source
         assert($type === null || is_string($type));
 
         // for now - load and parse config file
-        $config = SimpleSAML_Configuration::getConfig('authsources.php');
+        $config = \SimpleSAML\Configuration::getConfig('authsources.php');
 
         $authConfig = $config->getArray($authId, null);
         if ($authConfig === null) {
             if ($type !== null) {
-                throw new SimpleSAML_Error_Exception(
+                throw new \SimpleSAML\Error\Exception(
                     'No authentication source with id '.
                     var_export($authId, true).' found.'
                 );
@@ -347,7 +362,7 @@ abstract class SimpleSAML_Auth_Source
         }
 
         // the authentication source doesn't have the correct type
-        throw new SimpleSAML_Error_Exception(
+        throw new \SimpleSAML\Error\Exception(
             'Invalid type of authentication source '.
             var_export($authId, true).'. Was '.var_export(get_class($ret), true).
             ', should be '.var_export($type, true).'.'
@@ -363,13 +378,13 @@ abstract class SimpleSAML_Auth_Source
     public static function logoutCallback($state)
     {
         assert(is_array($state));
-        assert(array_key_exists('SimpleSAML_Auth_Source.logoutSource', $state));
+        assert(array_key_exists('\SimpleSAML\Auth\Source.logoutSource', $state));
 
-        $source = $state['SimpleSAML_Auth_Source.logoutSource'];
+        $source = $state['\SimpleSAML\Auth\Source.logoutSource'];
 
-        $session = SimpleSAML_Session::getSessionFromRequest();
+        $session = \SimpleSAML\Session::getSessionFromRequest();
         if (!$session->isValid($source)) {
-            SimpleSAML\Logger::warning(
+            \SimpleSAML\Logger::warning(
                 'Received logout from an invalid authentication source '.
                 var_export($source, true)
             );
@@ -416,12 +431,12 @@ abstract class SimpleSAML_Auth_Source
             'state'    => $callbackState,
         );
 
-        $session = SimpleSAML_Session::getSessionFromRequest();
+        $session = \SimpleSAML\Session::getSessionFromRequest();
         $session->setData(
-            'SimpleSAML_Auth_Source.LogoutCallbacks',
+            '\SimpleSAML\Auth\Source.LogoutCallbacks',
             $id,
             $data,
-            SimpleSAML_Session::DATA_TIMEOUT_SESSION_END
+            \SimpleSAML\Session::DATA_TIMEOUT_SESSION_END
         );
     }
 
@@ -442,9 +457,9 @@ abstract class SimpleSAML_Auth_Source
 
         $id = strlen($this->authId).':'.$this->authId.$assoc;
 
-        $session = SimpleSAML_Session::getSessionFromRequest();
+        $session = \SimpleSAML\Session::getSessionFromRequest();
 
-        $data = $session->getData('SimpleSAML_Auth_Source.LogoutCallbacks', $id);
+        $data = $session->getData('\SimpleSAML\Auth\Source.LogoutCallbacks', $id);
         if ($data === null) {
             // FIXME: fix for IdP-first flow (issue 397) -> reevaluate logout callback infrastructure
             $session->doLogout($this->authId);
@@ -459,7 +474,7 @@ abstract class SimpleSAML_Auth_Source
         $callback = $data['callback'];
         $callbackState = $data['state'];
 
-        $session->deleteData('SimpleSAML_Auth_Source.LogoutCallbacks', $id);
+        $session->deleteData('\SimpleSAML\Auth\Source.LogoutCallbacks', $id);
         call_user_func($callback, $callbackState);
     }
 
@@ -471,7 +486,7 @@ abstract class SimpleSAML_Auth_Source
      */
     public static function getSources()
     {
-        $config = SimpleSAML_Configuration::getOptionalConfig('authsources.php');
+        $config = \SimpleSAML\Configuration::getOptionalConfig('authsources.php');
 
         return $config->getOptions();
     }
@@ -483,12 +498,12 @@ abstract class SimpleSAML_Auth_Source
      * @param array $source An array with the auth source configuration.
      * @param string $id The auth source identifier.
      *
-     * @throws Exception If the first element of $source is not an identifier for the auth source.
+     * @throws \Exception If the first element of $source is not an identifier for the auth source.
      */
     protected static function validateSource($source, $id)
     {
         if (!array_key_exists(0, $source) || !is_string($source[0])) {
-            throw new Exception(
+            throw new \Exception(
                 'Invalid authentication source \''.$id.
                 '\': First element must be a string which identifies the authentication source.'
             );
diff --git a/lib/SimpleSAML/Auth/SourceFactory.php b/lib/SimpleSAML/Auth/SourceFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..9f5fdfafbeccf28ad2c37c1e18cb30844fea8055
--- /dev/null
+++ b/lib/SimpleSAML/Auth/SourceFactory.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace SimpleSAML\Auth;
+
+interface SourceFactory
+{
+    /**
+     * @param array $info
+     * @param array $config
+     * @return Source
+     */
+    public function create(array $info, array $config);
+}
diff --git a/lib/SimpleSAML/Auth/State.php b/lib/SimpleSAML/Auth/State.php
index 06bee7ae8e48058d0e5f9cffd29d0fc2f857373f..44454b41ff6f379eea5f2eb782dbf6143b548f89 100644
--- a/lib/SimpleSAML/Auth/State.php
+++ b/lib/SimpleSAML/Auth/State.php
@@ -1,15 +1,16 @@
 <?php
 
+namespace SimpleSAML\Auth;
 
 /**
  * This is a helper class for saving and loading state information.
  *
  * The state must be an associative array. This class will add additional keys to this
- * array. These keys will always start with 'SimpleSAML_Auth_State.'.
+ * array. These keys will always start with '\SimpleSAML\Auth\State.'.
  *
  * It is also possible to add a restart URL to the state. If state information is lost, for
  * example because it timed out, or the user loaded a bookmarked page, the loadState function
- * will redirect to this URL. To use this, set $state[SimpleSAML_Auth_State::RESTART] to this
+ * will redirect to this URL. To use this, set $state[\SimpleSAML\Auth\State::RESTART] to this
  * URL.
  *
  * Both the saveState and the loadState function takes in a $stage parameter. This parameter is
@@ -28,63 +29,62 @@
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Auth_State
-{
-
 
+class State
+{
     /**
      * The index in the state array which contains the identifier.
      */
-    const ID = 'SimpleSAML_Auth_State.id';
+    const ID = '\SimpleSAML\Auth\State.id';
 
 
     /**
      * The index in the cloned state array which contains the identifier of the
      * original state.
      */
-    const CLONE_ORIGINAL_ID = 'SimpleSAML_Auth_State.cloneOriginalId';
+    const CLONE_ORIGINAL_ID = '\SimpleSAML\Auth\State.cloneOriginalId';
 
 
     /**
      * The index in the state array which contains the current stage.
      */
-    const STAGE = 'SimpleSAML_Auth_State.stage';
+    const STAGE = '\SimpleSAML\Auth\State.stage';
 
 
     /**
      * The index in the state array which contains the restart URL.
      */
-    const RESTART = 'SimpleSAML_Auth_State.restartURL';
+    const RESTART = '\SimpleSAML\Auth\State.restartURL';
 
 
     /**
      * The index in the state array which contains the exception handler URL.
      */
-    const EXCEPTION_HANDLER_URL = 'SimpleSAML_Auth_State.exceptionURL';
+    const EXCEPTION_HANDLER_URL = '\SimpleSAML\Auth\State.exceptionURL';
 
 
     /**
      * The index in the state array which contains the exception handler function.
      */
-    const EXCEPTION_HANDLER_FUNC = 'SimpleSAML_Auth_State.exceptionFunc';
+    const EXCEPTION_HANDLER_FUNC = '\SimpleSAML\Auth\State.exceptionFunc';
 
 
     /**
      * The index in the state array which contains the exception data.
      */
-    const EXCEPTION_DATA = 'SimpleSAML_Auth_State.exceptionData';
+    const EXCEPTION_DATA = '\SimpleSAML\Auth\State.exceptionData';
 
 
     /**
      * The stage of a state with an exception.
      */
-    const EXCEPTION_STAGE = 'SimpleSAML_Auth_State.exceptionStage';
+    const EXCEPTION_STAGE = '\SimpleSAML\Auth\State.exceptionStage';
 
 
     /**
      * The URL parameter which contains the exception state id.
      */
-    const EXCEPTION_PARAM = 'SimpleSAML_Auth_State_exceptionId';
+    const EXCEPTION_PARAM = '\SimpleSAML\Auth\State.exceptionId';
 
 
     /**
@@ -148,7 +148,7 @@ class SimpleSAML_Auth_State
         assert(is_bool($rawId));
 
         if (!array_key_exists(self::ID, $state)) {
-            $state[self::ID] = SimpleSAML\Utils\Random::generateID();
+            $state[self::ID] = \SimpleSAML\Utils\Random::generateID();
         }
 
         $id = $state[self::ID];
@@ -171,7 +171,7 @@ class SimpleSAML_Auth_State
     private static function getStateTimeout()
     {
         if (self::$stateTimeout === null) {
-            $globalConfig = SimpleSAML_Configuration::getInstance();
+            $globalConfig = \SimpleSAML\Configuration::getInstance();
             self::$stateTimeout = $globalConfig->getInteger('session.state.timeout', 60 * 60);
         }
 
@@ -205,10 +205,10 @@ class SimpleSAML_Auth_State
 
         // Save state
         $serializedState = serialize($state);
-        $session = SimpleSAML_Session::getSessionFromRequest();
-        $session->setData('SimpleSAML_Auth_State', $id, $serializedState, self::getStateTimeout());
+        $session = \SimpleSAML\Session::getSessionFromRequest();
+        $session->setData('\SimpleSAML\Auth\State', $id, $serializedState, self::getStateTimeout());
 
-        SimpleSAML\Logger::debug('Saved state: '.var_export($return, true));
+        \SimpleSAML\Logger::debug('Saved state: '.var_export($return, true));
 
         return $return;
     }
@@ -231,9 +231,9 @@ class SimpleSAML_Auth_State
             $clonedState[self::CLONE_ORIGINAL_ID] = $state[self::ID];
             unset($clonedState[self::ID]);
 
-            SimpleSAML\Logger::debug('Cloned state: '.var_export($state[self::ID], true));
+            \SimpleSAML\Logger::debug('Cloned state: '.var_export($state[self::ID], true));
         } else {
-            SimpleSAML\Logger::debug('Cloned state with undefined id.');
+            \SimpleSAML\Logger::debug('Cloned state with undefined id.');
         }
 
         return $clonedState;
@@ -251,8 +251,8 @@ class SimpleSAML_Auth_State
      * @param string $stage The stage the state should have been saved in.
      * @param bool   $allowMissing Whether to allow the state to be missing.
      *
-     * @throws SimpleSAML_Error_NoState If we couldn't find the state and there's no URL defined to redirect to.
-     * @throws Exception If the stage of the state is invalid and there's no URL defined to redirect to.
+     * @throws \SimpleSAML\Error\NoState If we couldn't find the state and there's no URL defined to redirect to.
+     * @throws \Exception If the stage of the state is invalid and there's no URL defined to redirect to.
      *
      * @return array|NULL  State information, or null if the state is missing and $allowMissing is true.
      */
@@ -261,12 +261,12 @@ class SimpleSAML_Auth_State
         assert(is_string($id));
         assert(is_string($stage));
         assert(is_bool($allowMissing));
-        SimpleSAML\Logger::debug('Loading state: '.var_export($id, true));
+        \SimpleSAML\Logger::debug('Loading state: '.var_export($id, true));
 
         $sid = self::parseStateID($id);
 
-        $session = SimpleSAML_Session::getSessionFromRequest();
-        $state = $session->getData('SimpleSAML_Auth_State', $sid['id']);
+        $session = \SimpleSAML\Session::getSessionFromRequest();
+        $state = $session->getData('\SimpleSAML\Auth\State', $sid['id']);
 
         if ($state === null) {
             // Could not find saved data
@@ -275,7 +275,7 @@ class SimpleSAML_Auth_State
             }
 
             if ($sid['url'] === null) {
-                throw new SimpleSAML_Error_NoState();
+                throw new \SimpleSAML\Error\NoState();
             }
 
             \SimpleSAML\Utils\HTTP::redirectUntrustedURL($sid['url']);
@@ -296,10 +296,10 @@ class SimpleSAML_Auth_State
             $msg = 'Wrong stage in state. Was \''.$state[self::STAGE].
                 '\', should be \''.$stage.'\'.';
 
-            SimpleSAML\Logger::warning($msg);
+            \SimpleSAML\Logger::warning($msg);
 
             if ($sid['url'] === null) {
-                throw new Exception($msg);
+                throw new \Exception($msg);
             }
 
             \SimpleSAML\Utils\HTTP::redirectUntrustedURL($sid['url']);
@@ -325,10 +325,10 @@ class SimpleSAML_Auth_State
             return;
         }
 
-        SimpleSAML\Logger::debug('Deleting state: '.var_export($state[self::ID], true));
+        \SimpleSAML\Logger::debug('Deleting state: '.var_export($state[self::ID], true));
 
-        $session = SimpleSAML_Session::getSessionFromRequest();
-        $session->deleteData('SimpleSAML_Auth_State', $state[self::ID]);
+        $session = \SimpleSAML\Session::getSessionFromRequest();
+        $session->deleteData('\SimpleSAML\Auth\State', $state[self::ID]);
     }
 
 
@@ -336,11 +336,11 @@ class SimpleSAML_Auth_State
      * Throw exception to the state exception handler.
      *
      * @param array                      $state The state array.
-     * @param SimpleSAML_Error_Exception $exception The exception.
+     * @param \SimpleSAML\Error\Exception $exception The exception.
      *
-     * @throws SimpleSAML_Error_Exception If there is no exception handler defined, it will just throw the $exception.
+     * @throws \SimpleSAML\Error\Exception If there is no exception handler defined, it will just throw the $exception.
      */
-    public static function throwException($state, SimpleSAML_Error_Exception $exception)
+    public static function throwException($state, \SimpleSAML\Error\Exception $exception)
     {
         assert(is_array($state));
 
diff --git a/lib/SimpleSAML/Auth/TimeLimitedToken.php b/lib/SimpleSAML/Auth/TimeLimitedToken.php
index 0fd02dd4f05ffe6ccf686490c9ae1e18edb487df..eb6620d5ec039213f25ba8acee90b7a8b9350a48 100644
--- a/lib/SimpleSAML/Auth/TimeLimitedToken.php
+++ b/lib/SimpleSAML/Auth/TimeLimitedToken.php
@@ -5,9 +5,9 @@ namespace SimpleSAML\Auth;
 /**
  * A class that generates and verifies time-limited tokens.
  */
+
 class TimeLimitedToken
 {
-
     /**
      * @var string
      */
@@ -130,7 +130,7 @@ class TimeLimitedToken
         if (count($splittoken) !== 2) {
             return false;
         }
-        $offset = hexdec($splittoken[0]);
+        $offset = intval(hexdec($splittoken[0]));
         $value = $splittoken[1];
         return ($this->calculateTokenValue($offset) === $value);
     }
diff --git a/lib/SimpleSAML/AuthMemCookie.php b/lib/SimpleSAML/AuthMemCookie.php
index 33944677e48399d63c2bbc9863e5dd9e42fea77a..1c5fb7c967a09684789ee93fd52a59501f4fb564 100644
--- a/lib/SimpleSAML/AuthMemCookie.php
+++ b/lib/SimpleSAML/AuthMemCookie.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML;
 
 /**
  * This is a helper class for the Auth MemCookie module.
@@ -10,17 +11,17 @@
  *
  * @deprecated This class has been deprecated and will be removed in SSP 2.0. Use the memcookie module instead.
  */
-class SimpleSAML_AuthMemCookie
-{
 
+class AuthMemCookie
+{
     /**
-     * @var SimpleSAML_AuthMemCookie This is the singleton instance of this class.
+     * @var AuthMemCookie This is the singleton instance of this class.
      */
     private static $instance = null;
 
 
     /**
-     * @var SimpleSAML_Configuration The configuration for Auth MemCookie.
+     * @var Configuration The configuration for Auth MemCookie.
      */
     private $amcConfig;
 
@@ -28,12 +29,12 @@ class SimpleSAML_AuthMemCookie
     /**
      * This function is used to retrieve the singleton instance of this class.
      *
-     * @return SimpleSAML_AuthMemCookie The singleton instance of this class.
+     * @return AuthMemCookie The singleton instance of this class.
      */
     public static function getInstance()
     {
         if (self::$instance === null) {
-            self::$instance = new SimpleSAML_AuthMemCookie();
+            self::$instance = new AuthMemCookie();
         }
 
         return self::$instance;
@@ -46,7 +47,7 @@ class SimpleSAML_AuthMemCookie
     private function __construct()
     {
         // load AuthMemCookie configuration
-        $this->amcConfig = SimpleSAML_Configuration::getConfig('authmemcookie.php');
+        $this->amcConfig = Configuration::getConfig('authmemcookie.php');
     }
 
 
@@ -71,7 +72,7 @@ class SimpleSAML_AuthMemCookie
     {
         $cookieName = $this->amcConfig->getString('cookiename', 'AuthMemCookie');
         if (!is_string($cookieName) || strlen($cookieName) === 0) {
-            throw new Exception(
+            throw new \Exception(
                 "Configuration option 'cookiename' contains an invalid value. This option should be a string."
             );
         }
@@ -109,17 +110,17 @@ class SimpleSAML_AuthMemCookie
     /**
      * This function creates and initializes a Memcache object from our configuration.
      *
-     * @return Memcache A Memcache object initialized from our configuration.
-     * @throws Exception If the servers configuration is invalid.
+     * @return \Memcache A Memcache object initialized from our configuration.
+     * @throws \Exception If the servers configuration is invalid.
      */
     public function getMemcache()
     {
         $memcacheHost = $this->amcConfig->getString('memcache.host', '127.0.0.1');
         $memcachePort = $this->amcConfig->getInteger('memcache.port', 11211);
 
-        $class = class_exists('Memcache') ? 'Memcache' : (class_exists('Memcached') ? 'Memcached' : FALSE);
+        $class = class_exists('Memcache') ? '\Memcache' : (class_exists('Memcached') ? '\Memcached' : false);
         if (!$class) {
-            throw new Exception('Missing Memcached implementation. You must install either the Memcache or Memcached extension.');
+            throw new \Exception('Missing Memcached implementation. You must install either the Memcache or Memcached extension.');
         }
 
         // Create the Memcache(d) object.
diff --git a/lib/SimpleSAML/Bindings/Shib13/Artifact.php b/lib/SimpleSAML/Bindings/Shib13/Artifact.php
index 726461aaff844d3d79dd6eb55d0b47d63fd7d300..844f0818181cdf00f586e3c23d4578d822714696 100644
--- a/lib/SimpleSAML/Bindings/Shib13/Artifact.php
+++ b/lib/SimpleSAML/Bindings/Shib13/Artifact.php
@@ -9,6 +9,7 @@
 namespace SimpleSAML\Bindings\Shib13;
 
 use SAML2\DOMDocumentFactory;
+use SimpleSAML\Error;
 use SimpleSAML\Utils\Config;
 use SimpleSAML\Utils\HTTP;
 use SimpleSAML\Utils\Random;
@@ -18,7 +19,6 @@ use SimpleSAML\Utils\XML;
 
 class Artifact
 {
-
     /**
      * Parse the query string, and extract the SAMLart parameters.
      *
@@ -83,7 +83,7 @@ class Artifact
      *
      * @param string $soapResponse The SOAP response.
      * @return string The <saml1p:Response> element, as a string.
-     * @throws \SimpleSAML_Error_Exception
+     * @throws Error\Exception
      */
     private static function extractResponse($soapResponse)
     {
@@ -92,24 +92,24 @@ class Artifact
         try {
             $doc = DOMDocumentFactory::fromString($soapResponse);
         } catch (\Exception $e) {
-            throw new \SimpleSAML_Error_Exception('Error parsing SAML 1 artifact response.');
+            throw new Error\Exception('Error parsing SAML 1 artifact response.');
         }
 
         $soapEnvelope = $doc->firstChild;
         if (!XML::isDOMNodeOfType($soapEnvelope, 'Envelope', 'http://schemas.xmlsoap.org/soap/envelope/')) {
-            throw new \SimpleSAML_Error_Exception('Expected artifact response to contain a <soap:Envelope> element.');
+            throw new Error\Exception('Expected artifact response to contain a <soap:Envelope> element.');
         }
 
         $soapBody = XML::getDOMChildren($soapEnvelope, 'Body', 'http://schemas.xmlsoap.org/soap/envelope/');
         if (count($soapBody) === 0) {
-            throw new \SimpleSAML_Error_Exception('Couldn\'t find <soap:Body> in <soap:Envelope>.');
+            throw new Error\Exception('Couldn\'t find <soap:Body> in <soap:Envelope>.');
         }
         $soapBody = $soapBody[0];
 
 
         $responseElement = XML::getDOMChildren($soapBody, 'Response', 'urn:oasis:names:tc:SAML:1.0:protocol');
         if (count($responseElement) === 0) {
-            throw new \SimpleSAML_Error_Exception('Couldn\'t find <saml1p:Response> in <soap:Body>.');
+            throw new Error\Exception('Couldn\'t find <saml1p:Response> in <soap:Body>.');
         }
         $responseElement = $responseElement[0];
 
@@ -128,12 +128,12 @@ class Artifact
     /**
      * This function receives a SAML 1.1 artifact.
      *
-     * @param \SimpleSAML_Configuration $spMetadata The metadata of the SP.
-     * @param \SimpleSAML_Configuration $idpMetadata The metadata of the IdP.
+     * @param \SimpleSAML\Configuration $spMetadata The metadata of the SP.
+     * @param \SimpleSAML\Configuration $idpMetadata The metadata of the IdP.
      * @return string The <saml1p:Response> element, as an XML string.
-     * @throws \SimpleSAML_Error_Exception
+     * @throws Error\Exception
      */
-    public static function receive(\SimpleSAML_Configuration $spMetadata, \SimpleSAML_Configuration $idpMetadata)
+    public static function receive(\SimpleSAML\Configuration $spMetadata, \SimpleSAML\Configuration $idpMetadata)
     {
         $artifacts = self::getArtifacts();
         $request = self::buildRequest($artifacts);
diff --git a/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php b/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php
index 5359c8ff30aef0ffdc8747ca7c0eeda1f0385ed7..97d004c7179475dd155cf850f56589891edecf14 100644
--- a/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php
+++ b/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php
@@ -19,14 +19,13 @@ use SimpleSAML\XML\Signer;
 
 class HTTPPost
 {
-
     /**
-     * @var \SimpleSAML_Configuration
+     * @var \SimpleSAML\Configuration
      */
     private $configuration = null;
 
     /**
-     * @var \SimpleSAML_Metadata_MetaDataStorageHandler
+     * @var \SimpleSAML\Metadata\MetaDataStorageHandler
      */
     private $metadata = null;
 
@@ -34,12 +33,12 @@ class HTTPPost
     /**
      * Constructor for the \SimpleSAML\Bindings\Shib13\HTTPPost class.
      *
-     * @param \SimpleSAML_Configuration                   $configuration The configuration to use.
-     * @param \SimpleSAML_Metadata_MetaDataStorageHandler $metadatastore A store where to find metadata.
+     * @param \SimpleSAML\Configuration                   $configuration The configuration to use.
+     * @param \SimpleSAML\Metadata\MetaDataStorageHandler $metadatastore A store where to find metadata.
      */
     public function __construct(
-        \SimpleSAML_Configuration $configuration,
-        \SimpleSAML_Metadata_MetaDataStorageHandler $metadatastore
+        \SimpleSAML\Configuration $configuration,
+        \SimpleSAML\Metadata\MetaDataStorageHandler $metadatastore
     ) {
         $this->configuration = $configuration;
         $this->metadata = $metadatastore;
@@ -50,15 +49,15 @@ class HTTPPost
      * Send an authenticationResponse using HTTP-POST.
      *
      * @param string                    $response The response which should be sent.
-     * @param \SimpleSAML_Configuration $idpmd The metadata of the IdP which is sending the response.
-     * @param \SimpleSAML_Configuration $spmd The metadata of the SP which is receiving the response.
+     * @param \SimpleSAML\Configuration $idpmd The metadata of the IdP which is sending the response.
+     * @param \SimpleSAML\Configuration $spmd The metadata of the SP which is receiving the response.
      * @param string|null               $relayState The relaystate for the SP.
      * @param string                    $shire The shire which should receive the response.
      */
     public function sendResponse(
         $response,
-        \SimpleSAML_Configuration $idpmd,
-        \SimpleSAML_Configuration $spmd,
+        \SimpleSAML\Configuration $idpmd,
+        \SimpleSAML\Configuration $spmd,
         $relayState,
         $shire
     ) {
diff --git a/lib/SimpleSAML/Configuration.php b/lib/SimpleSAML/Configuration.php
index 7ef65661a4f6c105446248348460aa336ba0610e..9b6fb9710e05897f24d02bed5507f91c74bbc8e5 100644
--- a/lib/SimpleSAML/Configuration.php
+++ b/lib/SimpleSAML/Configuration.php
@@ -1,5 +1,8 @@
 <?php
 
+namespace SimpleSAML;
+
+use SimpleSAML\Utils\System;
 
 /**
  * Configuration of SimpleSAMLphp
@@ -7,9 +10,8 @@
  * @author Andreas Aakre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
+class Configuration implements Utils\ClearableState
 {
-
     /**
      * A default value which means that the given option is required.
      *
@@ -94,17 +96,16 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
         $this->location = $location;
     }
 
-
     /**
      * Load the given configuration file.
      *
      * @param string $filename The full path of the configuration file.
      * @param bool $required Whether the file is required.
      *
-     * @return SimpleSAML_Configuration The configuration file. An exception will be thrown if the
+     * @return \SimpleSAML\Configuration The configuration file. An exception will be thrown if the
      *                                   configuration file is missing.
      *
-     * @throws Exception If the configuration file is invalid or missing.
+     * @throws \Exception If the configuration file is invalid or missing.
      */
     private static function loadFromFile($filename, $required)
     {
@@ -120,12 +121,12 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
 
             // the file initializes a variable named '$config'
             ob_start();
-            if (interface_exists('Throwable')) {
+            if (interface_exists('Throwable', false)) {
                 try {
                     require($filename);
-                } catch (ParseError $e) {
+                } catch (\ParseError $e) {
                     self::$loadedConfigs[$filename] = self::loadFromArray(array(), '[ARRAY]', 'simplesaml');
-                    throw new SimpleSAML\Error\ConfigurationError($e->getMessage(), $filename, array());
+                    throw new Error\ConfigurationError($e->getMessage(), $filename, array());
                 }
             } else {
                 require($filename);
@@ -136,7 +137,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
 
             // check that $config exists
             if (!isset($config)) {
-                throw new \SimpleSAML\Error\ConfigurationError(
+                throw new Error\ConfigurationError(
                     '$config is not defined in the configuration file.',
                     $filename
                 );
@@ -144,7 +145,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
 
             // check that $config is initialized to an array
             if (!is_array($config)) {
-                throw new \SimpleSAML\Error\ConfigurationError(
+                throw new Error\ConfigurationError(
                     '$config is not an array.',
                     $filename
                 );
@@ -152,28 +153,28 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
 
             // check that $config is not empty
             if (empty($config)) {
-                throw new \SimpleSAML\Error\ConfigurationError(
+                throw new Error\ConfigurationError(
                     '$config is empty.',
                     $filename
                 );
             }
         } elseif ($required) {
             // file does not exist, but is required
-            throw new \SimpleSAML\Error\ConfigurationError('Missing configuration file', $filename);
+            throw new Error\ConfigurationError('Missing configuration file', $filename);
         } else {
             // file does not exist, but is optional, so return an empty configuration object without saving it
-            $cfg = new SimpleSAML_Configuration(array(), $filename);
+            $cfg = new Configuration(array(), $filename);
             $cfg->filename = $filename;
             return $cfg;
         }
 
-        $cfg = new SimpleSAML_Configuration($config, $filename);
+        $cfg = new Configuration($config, $filename);
         $cfg->filename = $filename;
 
         self::$loadedConfigs[$filename] = $cfg;
 
         if ($spurious_output) {
-            SimpleSAML\Logger::warning(
+            Logger::warning(
                 "The configuration file '$filename' generates output. Please review your configuration."
             );
         }
@@ -196,6 +197,35 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
         self::$configDirs[$configSet] = $path;
     }
 
+    /**
+     * Store a pre-initialized configuration.
+     *
+     * Allows consumers to create configuration objects without having them
+     * loaded from a file.
+     *
+     * @param \SimpleSAML\Configuration $config  The configuration object to store
+     * @param string $filename  The name of the configuration file.
+     * @param string $configSet  The configuration set. Optional, defaults to 'simplesaml'.
+     */
+    public static function setPreLoadedConfig(Configuration $config, $filename = 'config.php', $configSet = 'simplesaml')
+    {
+        assert(is_string($filename));
+        assert(is_string($configSet));
+
+        if (!array_key_exists($configSet, self::$configDirs)) {
+            if ($configSet !== 'simplesaml') {
+                throw new \Exception('Configuration set \'' . $configSet . '\' not initialized.');
+            } else {
+                self::$configDirs['simplesaml'] = dirname(dirname(dirname(__FILE__))) . '/config';
+            }
+        }
+
+        $dir = self::$configDirs[$configSet];
+        $filePath = $dir . '/' . $filename;
+
+        self::$loadedConfigs[$filePath] = $config;
+    }
+
 
     /**
      * Load a configuration file from a configuration set.
@@ -203,8 +233,8 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      * @param string $filename The name of the configuration file.
      * @param string $configSet The configuration set. Optional, defaults to 'simplesaml'.
      *
-     * @return SimpleSAML_Configuration The SimpleSAML_Configuration object.
-     * @throws Exception If the configuration set is not initialized.
+     * @return \SimpleSAML\Configuration The Configuration object.
+     * @throws \Exception If the configuration set is not initialized.
      */
     public static function getConfig($filename = 'config.php', $configSet = 'simplesaml')
     {
@@ -213,9 +243,9 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
 
         if (!array_key_exists($configSet, self::$configDirs)) {
             if ($configSet !== 'simplesaml') {
-                throw new Exception('Configuration set \''.$configSet.'\' not initialized.');
+                throw new \Exception('Configuration set \''.$configSet.'\' not initialized.');
             } else {
-                self::$configDirs['simplesaml'] = SimpleSAML\Utils\Config::getConfigDir();
+                self::$configDirs['simplesaml'] = Utils\Config::getConfigDir();
             }
         }
 
@@ -233,8 +263,8 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      * @param string $filename The name of the configuration file.
      * @param string $configSet The configuration set. Optional, defaults to 'simplesaml'.
      *
-     * @return SimpleSAML_Configuration A configuration object.
-     * @throws Exception If the configuration set is not initialized.
+     * @return \SimpleSAML\Configuration A configuration object.
+     * @throws \Exception If the configuration set is not initialized.
      */
     public static function getOptionalConfig($filename = 'config.php', $configSet = 'simplesaml')
     {
@@ -243,9 +273,9 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
 
         if (!array_key_exists($configSet, self::$configDirs)) {
             if ($configSet !== 'simplesaml') {
-                throw new Exception('Configuration set \''.$configSet.'\' not initialized.');
+                throw new \Exception('Configuration set \''.$configSet.'\' not initialized.');
             } else {
-                self::$configDirs['simplesaml'] = SimpleSAML\Utils\Config::getConfigDir();
+                self::$configDirs['simplesaml'] = Utils\Config::getConfigDir();
             }
         }
 
@@ -264,14 +294,14 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      * instance with that name will be kept for it to be retrieved later with getInstance($instance). If null, the
      * configuration will not be kept for later use. Defaults to null.
      *
-     * @return SimpleSAML_Configuration The configuration object.
+     * @return \SimpleSAML\Configuration The configuration object.
      */
     public static function loadFromArray($config, $location = '[ARRAY]', $instance = null)
     {
         assert(is_array($config));
         assert(is_string($location));
 
-        $c = new SimpleSAML_Configuration($config, $location);
+        $c = new Configuration($config, $location);
         if ($instance !== null) {
             self::$instance[$instance] = $c;
         }
@@ -290,9 +320,9 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      *
      * @param string $instancename The instance name of the configuration file. Deprecated.
      *
-     * @return SimpleSAML_Configuration The configuration object.
+     * @return \SimpleSAML\Configuration The configuration object.
      *
-     * @throws Exception If the configuration with $instancename name is not initialized.
+     * @throws \Exception If the configuration with $instancename name is not initialized.
      */
     public static function getInstance($instancename = 'simplesaml')
     {
@@ -306,12 +336,12 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
         if ($instancename === 'simplesaml') {
             try {
                 return self::getConfig();
-            } catch (SimpleSAML\Error\ConfigurationError $e) {
-                throw \SimpleSAML\Error\CriticalConfigurationError::fromException($e);
+            } catch (Error\ConfigurationError $e) {
+                throw Error\CriticalConfigurationError::fromException($e);
             }
         }
 
-        throw new \SimpleSAML\Error\CriticalConfigurationError(
+        throw new Error\CriticalConfigurationError(
             'Configuration with name '.$instancename.' is not initialized.'
         );
     }
@@ -395,19 +425,19 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      *
      * @param string $name Name of the configuration option.
      * @param mixed  $default Default value of the configuration option. This parameter will default to null if not
-     *                        specified. This can be set to SimpleSAML_Configuration::REQUIRED_OPTION, which will
+     *                        specified. This can be set to \SimpleSAML\Configuration::REQUIRED_OPTION, which will
      *                        cause an exception to be thrown if the option isn't found.
      *
      * @return mixed The configuration option with name $name, or $default if the option was not found.
      *
-     * @throws Exception If the required option cannot be retrieved.
+     * @throws \Exception If the required option cannot be retrieved.
      */
     public function getValue($name, $default = null)
     {
         // return the default value if the option is unset
         if (!array_key_exists($name, $this->configuration)) {
             if ($default === self::REQUIRED_OPTION) {
-                throw new Exception(
+                throw new \Exception(
                     $this->location.': Could not retrieve the required option '.
                     var_export($name, true)
                 );
@@ -459,7 +489,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      *
      * @return string The absolute path relative to the root of the website.
      *
-     * @throws SimpleSAML\Error\CriticalConfigurationError If the format of 'baseurlpath' is incorrect.
+     * @throws \SimpleSAML\Error\CriticalConfigurationError If the format of 'baseurlpath' is incorrect.
      *
      * @deprecated This method will be removed in SimpleSAMLphp 2.0. Please use getBasePath() instead.
      */
@@ -467,13 +497,13 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
     {
         if (!$this->deprecated_base_url_used) {
             $this->deprecated_base_url_used = true;
-            SimpleSAML\Logger::warning(
-                "SimpleSAML_Configuration::getBaseURL() is deprecated, please use getBasePath() instead."
+            Logger::warning(
+                "\SimpleSAML\Configuration::getBaseURL() is deprecated, please use getBasePath() instead."
             );
         }
         if (preg_match('/^\*(.*)$/D', $this->getString('baseurlpath', 'simplesaml/'), $matches)) {
             // deprecated behaviour, will be removed in the future
-            return \SimpleSAML\Utils\HTTP::getFirstPathElement(false).$matches[1];
+            return Utils\HTTP::getFirstPathElement(false).$matches[1];
         }
         return ltrim($this->getBasePath(), '/');
     }
@@ -486,7 +516,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      *
      * @return string The absolute path where SimpleSAMLphp can be reached in the web server.
      *
-     * @throws SimpleSAML\Error\CriticalConfigurationError If the format of 'baseurlpath' is incorrect.
+     * @throws \SimpleSAML\Error\CriticalConfigurationError If the format of 'baseurlpath' is incorrect.
      */
     public function getBasePath()
     {
@@ -511,8 +541,8 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
              * with the configuration. Use a guessed base path instead of the one provided.
              */
             $c = $this->toArray();
-            $c['baseurlpath'] = SimpleSAML\Utils\HTTP::guessBasePath();
-            throw new SimpleSAML\Error\CriticalConfigurationError(
+            $c['baseurlpath'] = Utils\HTTP::guessBasePath();
+            throw new Error\CriticalConfigurationError(
                 'Incorrect format for option \'baseurlpath\'. Value is: "'.
                 $this->getString('baseurlpath', 'simplesaml/').'". Valid format is in the form'.
                 ' [(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/].',
@@ -541,19 +571,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
 
         assert(is_string($path));
 
-        /* Prepend path with basedir if it doesn't start with a slash or a Windows drive letter (e.g. "C:\"). We assume
-         * getBaseDir ends with a slash.
-         */
-        if ($path[0] !== '/' &&
-            !(preg_match('@^[a-z]:[\\\\/]@i', $path, $matches) && is_dir($matches[0]))
-        ) {
-            $path = $this->getBaseDir().$path;
-        }
-
-        // remove trailing slashes
-        $path = rtrim($path, '/');
-
-        return $path;
+        return System::resolvePath($path, $this->getBaseDir());
     }
 
 
@@ -643,7 +661,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      * @return boolean|mixed The option with the given name, or $default if the option isn't found and $default is
      *     specified.
      *
-     * @throws Exception If the option is not boolean.
+     * @throws \Exception If the option is not boolean.
      */
     public function getBoolean($name, $default = self::REQUIRED_OPTION)
     {
@@ -657,7 +675,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
         }
 
         if (!is_bool($ret)) {
-            throw new Exception(
+            throw new \Exception(
                 $this->location.': The option '.var_export($name, true).
                 ' is not a valid boolean value.'
             );
@@ -681,7 +699,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      * @return string|mixed The option with the given name, or $default if the option isn't found and $default is
      *     specified.
      *
-     * @throws Exception If the option is not a string.
+     * @throws \Exception If the option is not a string.
      */
     public function getString($name, $default = self::REQUIRED_OPTION)
     {
@@ -695,7 +713,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
         }
 
         if (!is_string($ret)) {
-            throw new Exception(
+            throw new \Exception(
                 $this->location.': The option '.var_export($name, true).
                 ' is not a valid string value.'
             );
@@ -719,7 +737,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      * @return int|mixed The option with the given name, or $default if the option isn't found and $default is
      * specified.
      *
-     * @throws Exception If the option is not an integer.
+     * @throws \Exception If the option is not an integer.
      */
     public function getInteger($name, $default = self::REQUIRED_OPTION)
     {
@@ -733,7 +751,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
         }
 
         if (!is_int($ret)) {
-            throw new Exception(
+            throw new \Exception(
                 $this->location.': The option '.var_export($name, true).
                 ' is not a valid integer value.'
             );
@@ -761,7 +779,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      * @return int|mixed The option with the given name, or $default if the option isn't found and $default is
      *     specified.
      *
-     * @throws Exception If the option is not in the range specified.
+     * @throws \Exception If the option is not in the range specified.
      */
     public function getIntegerRange($name, $minimum, $maximum, $default = self::REQUIRED_OPTION)
     {
@@ -777,7 +795,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
         }
 
         if ($ret < $minimum || $ret > $maximum) {
-            throw new Exception(
+            throw new \Exception(
                 $this->location.': Value of option '.var_export($name, true).
                 ' is out of range. Value is '.$ret.', allowed range is ['
                 .$minimum.' - '.$maximum.']'
@@ -807,7 +825,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      *
      * @return mixed The option with the given name, or $default if the option isn't found and $default is given.
      *
-     * @throws Exception If the option does not have any of the allowed values.
+     * @throws \Exception If the option does not have any of the allowed values.
      */
     public function getValueValidate($name, $allowedValues, $default = self::REQUIRED_OPTION)
     {
@@ -827,7 +845,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
             }
             $strValues = implode(', ', $strValues);
 
-            throw new Exception(
+            throw new \Exception(
                 $this->location.': Invalid value given for the option '.
                 var_export($name, true).'. It should have one of the following values: '.
                 $strValues.'; but it had the following value: '.var_export($ret, true)
@@ -852,7 +870,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      * @return array|mixed The option with the given name, or $default if the option isn't found and $default is
      * specified.
      *
-     * @throws Exception If the option is not an array.
+     * @throws \Exception If the option is not an array.
      */
     public function getArray($name, $default = self::REQUIRED_OPTION)
     {
@@ -866,7 +884,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
         }
 
         if (!is_array($ret)) {
-            throw new Exception($this->location.': The option '.var_export($name, true).' is not an array.');
+            throw new \Exception($this->location.': The option '.var_export($name, true).' is not an array.');
         }
 
         return $ret;
@@ -916,7 +934,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      *
      * @return array The option with the given name, or $default if the option isn't found and $default is specified.
      *
-     * @throws Exception If the option is not a string or an array of strings.
+     * @throws \Exception If the option is not a string or an array of strings.
      */
     public function getArrayizeString($name, $default = self::REQUIRED_OPTION)
     {
@@ -931,7 +949,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
 
         foreach ($ret as $value) {
             if (!is_string($value)) {
-                throw new Exception(
+                throw new \Exception(
                     $this->location.': The option '.var_export($name, true).
                     ' must be a string or an array of strings.'
                 );
@@ -943,9 +961,9 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
 
 
     /**
-     * Retrieve an array as a SimpleSAML_Configuration object.
+     * Retrieve an array as a \SimpleSAML\Configuration object.
      *
-     * This function will load the value of an option into a SimpleSAML_Configuration object. The option must contain
+     * This function will load the value of an option into a \SimpleSAML\Configuration object. The option must contain
      * an array.
      *
      * An exception will be thrown if this option isn't an array, or if this option isn't found, and no default value
@@ -958,7 +976,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      *
      * @return mixed The option with the given name, or $default if the option isn't found and $default is specified.
      *
-     * @throws Exception If the option is not an array.
+     * @throws \Exception If the option is not an array.
      */
     public function getConfigItem($name, $default = self::REQUIRED_OPTION)
     {
@@ -972,7 +990,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
         }
 
         if (!is_array($ret)) {
-            throw new Exception(
+            throw new \Exception(
                 $this->location.': The option '.var_export($name, true).
                 ' is not an array.'
             );
@@ -983,11 +1001,11 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
 
 
     /**
-     * Retrieve an array of arrays as an array of SimpleSAML_Configuration objects.
+     * Retrieve an array of arrays as an array of \SimpleSAML\Configuration objects.
      *
      * This function will retrieve an option containing an array of arrays, and create an array of
-     * SimpleSAML_Configuration objects from that array. The indexes in the new array will be the same as the original
-     * indexes, but the values will be SimpleSAML_Configuration objects.
+     * \SimpleSAML\Configuration objects from that array. The indexes in the new array will be the same as the original
+     * indexes, but the values will be \SimpleSAML\Configuration objects.
      *
      * An exception will be thrown if this option isn't an array of arrays, or if this option isn't found, and no
      * default value is given.
@@ -999,7 +1017,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      *
      * @return mixed The option with the given name, or $default if the option isn't found and $default is specified.
      *
-     * @throws Exception If the value of this element is not an array.
+     * @throws \Exception If the value of this element is not an array.
      */
     public function getConfigList($name, $default = self::REQUIRED_OPTION)
     {
@@ -1013,7 +1031,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
         }
 
         if (!is_array($ret)) {
-            throw new Exception(
+            throw new \Exception(
                 $this->location.': The option '.var_export($name, true).
                 ' is not an array.'
             );
@@ -1024,7 +1042,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
             $newLoc = $this->location.'['.var_export($name, true).']['.
                 var_export($index, true).']';
             if (!is_array($config)) {
-                throw new Exception($newLoc.': The value of this element was expected to be an array.');
+                throw new \Exception($newLoc.': The value of this element was expected to be an array.');
             }
             $out[$index] = self::loadFromArray($config, $newLoc);
         }
@@ -1068,7 +1086,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      *
      * @return string The default binding.
      *
-     * @throws Exception If the default binding is missing for this endpoint type.
+     * @throws \Exception If the default binding is missing for this endpoint type.
      */
     private function getDefaultBinding($endpointType)
     {
@@ -1089,7 +1107,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
             case 'shib13-sp-remote:AssertionConsumerService':
                 return 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post';
             default:
-                throw new Exception('Missing default binding for '.$endpointType.' in '.$set);
+                throw new \Exception('Missing default binding for '.$endpointType.' in '.$set);
         }
     }
 
@@ -1101,7 +1119,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      *
      * @return array Array of endpoints of the given type.
      *
-     * @throws Exception If any element of the configuration options for this endpoint type is incorrect.
+     * @throws \Exception If any element of the configuration options for this endpoint type is incorrect.
      */
     public function getEndpoints($endpointType)
     {
@@ -1120,7 +1138,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
             // for backwards-compatibility
             $eps = array($eps);
         } elseif (!is_array($eps)) {
-            throw new Exception($loc.': Expected array or string.');
+            throw new \Exception($loc.': Expected array or string.');
         }
 
 
@@ -1138,32 +1156,32 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
                     $ep['ResponseLocation'] = $responseLocation;
                 }
             } elseif (!is_array($ep)) {
-                throw new Exception($iloc.': Expected a string or an array.');
+                throw new \Exception($iloc.': Expected a string or an array.');
             }
 
             if (!array_key_exists('Location', $ep)) {
-                throw new Exception($iloc.': Missing Location.');
+                throw new \Exception($iloc.': Missing Location.');
             }
             if (!is_string($ep['Location'])) {
-                throw new Exception($iloc.': Location must be a string.');
+                throw new \Exception($iloc.': Location must be a string.');
             }
 
             if (!array_key_exists('Binding', $ep)) {
-                throw new Exception($iloc.': Missing Binding.');
+                throw new \Exception($iloc.': Missing Binding.');
             }
             if (!is_string($ep['Binding'])) {
-                throw new Exception($iloc.': Binding must be a string.');
+                throw new \Exception($iloc.': Binding must be a string.');
             }
 
             if (array_key_exists('ResponseLocation', $ep)) {
                 if (!is_string($ep['ResponseLocation'])) {
-                    throw new Exception($iloc.': ResponseLocation must be a string.');
+                    throw new \Exception($iloc.': ResponseLocation must be a string.');
                 }
             }
 
             if (array_key_exists('index', $ep)) {
                 if (!is_int($ep['index'])) {
-                    throw new Exception($iloc.': index must be an integer.');
+                    throw new \Exception($iloc.': index must be an integer.');
                 }
             }
         }
@@ -1182,7 +1200,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      *
      * @return array|null The default endpoint, or null if no acceptable endpoints are used.
      *
-     * @throws Exception If no supported endpoint is found.
+     * @throws \Exception If no supported endpoint is found.
      */
     public function getEndpointPrioritizedByBinding($endpointType, array $bindings, $default = self::REQUIRED_OPTION)
     {
@@ -1200,7 +1218,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
 
         if ($default === self::REQUIRED_OPTION) {
             $loc = $this->location.'['.var_export($endpointType, true).']:';
-            throw new Exception($loc.'Could not find a supported '.$endpointType.' endpoint.');
+            throw new \Exception($loc.'Could not find a supported '.$endpointType.' endpoint.');
         }
 
         return $default;
@@ -1217,7 +1235,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      *
      * @return array|null The default endpoint, or null if no acceptable endpoints are used.
      *
-     * @throws Exception If no supported endpoint is found.
+     * @throws \Exception If no supported endpoint is found.
      */
     public function getDefaultEndpoint($endpointType, array $bindings = null, $default = self::REQUIRED_OPTION)
     {
@@ -1225,14 +1243,14 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
 
         $endpoints = $this->getEndpoints($endpointType);
 
-        $defaultEndpoint = \SimpleSAML\Utils\Config\Metadata::getDefaultEndpoint($endpoints, $bindings);
+        $defaultEndpoint = Utils\Config\Metadata::getDefaultEndpoint($endpoints, $bindings);
         if ($defaultEndpoint !== null) {
             return $defaultEndpoint;
         }
 
         if ($default === self::REQUIRED_OPTION) {
             $loc = $this->location.'['.var_export($endpointType, true).']:';
-            throw new Exception($loc.'Could not find a supported '.$endpointType.' endpoint.');
+            throw new \Exception($loc.'Could not find a supported '.$endpointType.' endpoint.');
         }
 
         return $default;
@@ -1250,7 +1268,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      *
      * @return array Associative array with language => string pairs.
      *
-     * @throws Exception If the translation is not an array or a string, or its index or value are not strings.
+     * @throws \Exception If the translation is not an array or a string, or its index or value are not strings.
      */
     public function getLocalizedString($name, $default = self::REQUIRED_OPTION)
     {
@@ -1269,15 +1287,15 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
         }
 
         if (!is_array($ret)) {
-            throw new Exception($loc.': Must be an array or a string.');
+            throw new \Exception($loc.': Must be an array or a string.');
         }
 
         foreach ($ret as $k => $v) {
             if (!is_string($k)) {
-                throw new Exception($loc.': Invalid language code: '.var_export($k, true));
+                throw new \Exception($loc.': Invalid language code: '.var_export($k, true));
             }
             if (!is_string($v)) {
-                throw new Exception($loc.'['.var_export($v, true).']: Must be a string.');
+                throw new \Exception($loc.'['.var_export($v, true).']: Must be a string.');
             }
         }
 
@@ -1294,10 +1312,10 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
      * @param string $prefix The prefix which should be used when reading from the metadata
      *                       array. Defaults to ''.
      *
-     * @return array|null Public key data, or null if no public key or was found.
+     * @return array Public key data, or empty array if no public key or was found.
      *
-     * @throws Exception If the certificate or public key cannot be loaded from a file.
-     * @throws SimpleSAML_Error_Exception If the file does not contain a valid PEM-encoded certificate, or there is no
+     * @throws \Exception If the certificate or public key cannot be loaded from a file.
+     * @throws \SimpleSAML\Error\Exception If the file does not contain a valid PEM-encoded certificate, or there is no
      * certificate in the metadata.
      */
     public function getPublicKeys($use = null, $required = false, $prefix = '')
@@ -1317,9 +1335,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
                 }
                 $ret[] = $key;
             }
-            if (!empty($ret)) {
-                return $ret;
-            }
+            return $ret;
         } elseif ($this->hasValue($prefix.'certData')) {
             $certData = $this->getString($prefix.'certData');
             $certData = preg_replace('/\s+/', '', $certData);
@@ -1333,17 +1349,17 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
             );
         } elseif ($this->hasValue($prefix.'certificate')) {
             $file = $this->getString($prefix.'certificate');
-            $file = \SimpleSAML\Utils\Config::getCertPath($file);
+            $file = Utils\Config::getCertPath($file);
             $data = @file_get_contents($file);
 
             if ($data === false) {
-                throw new Exception($this->location.': Unable to load certificate/public key from file "'.$file.'".');
+                throw new \Exception($this->location.': Unable to load certificate/public key from file "'.$file.'".');
             }
 
             // extract certificate data (if this is a certificate)
             $pattern = '/^-----BEGIN CERTIFICATE-----([^-]*)^-----END CERTIFICATE-----/m';
             if (!preg_match($pattern, $data, $matches)) {
-                throw new SimpleSAML_Error_Exception(
+                throw new \SimpleSAML\Error\Exception(
                     $this->location.': Could not find PEM encoded certificate in "'.$file.'".'
                 );
             }
@@ -1357,12 +1373,10 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
                     'X509Certificate' => $certData,
                 ),
             );
-        }
-
-        if ($required) {
-            throw new SimpleSAML_Error_Exception($this->location.': Missing certificate in metadata.');
+        } elseif ($required === true) {
+            throw new \SimpleSAML\Error\Exception($this->location.': Missing certificate in metadata.');
         } else {
-            return null;
+            return array();
         }
     }
 
diff --git a/lib/SimpleSAML/Database.php b/lib/SimpleSAML/Database.php
index 85e19134ebbdc505adecf1f84c990fe5a2a213a3..636e6abbdf6d3d3004e5aa5e102451f75f58b3e8 100644
--- a/lib/SimpleSAML/Database.php
+++ b/lib/SimpleSAML/Database.php
@@ -1,4 +1,5 @@
 <?php
+
 namespace SimpleSAML;
 
 /**
@@ -18,7 +19,6 @@ namespace SimpleSAML;
 
 class Database
 {
-
     /**
      * This variable holds the instance of the session - Singleton approach.
      */
@@ -48,13 +48,13 @@ class Database
     /**
      * Retrieves the current database instance. Will create a new one if there isn't an existing connection.
      *
-     * @param \SimpleSAML_Configuration $altConfig Optional: Instance of a SimpleSAML_Configuration class
+     * @param \SimpleSAML\Configuration $altConfig Optional: Instance of a \SimpleSAML\Configuration class
      *
      * @return \SimpleSAML\Database The shared database connection.
      */
     public static function getInstance($altConfig = null)
     {
-        $config = ($altConfig) ? $altConfig : \SimpleSAML_Configuration::getInstance();
+        $config = ($altConfig) ? $altConfig : Configuration::getInstance();
         $instanceId = self::generateInstanceId($config);
 
         // check if we already have initialized the session
@@ -71,7 +71,7 @@ class Database
     /**
      * Private constructor that restricts instantiation to getInstance().
      *
-     * @param \SimpleSAML_Configuration $config Instance of the SimpleSAML_Configuration class
+     * @param \SimpleSAML\Configuration $config Instance of the \SimpleSAML\Configuration class
      */
     private function __construct($config)
     {
@@ -90,18 +90,16 @@ class Database
 
         // connect to any configured slaves
         $slaves = $config->getArray('database.slaves', array());
-        if (count($slaves >= 1)) {
-            foreach ($slaves as $slave) {
-                array_push(
-                    $this->dbSlaves,
-                    $this->connect(
-                        $slave['dsn'],
-                        $slave['username'],
-                        $slave['password'],
-                        $driverOptions
-                    )
-                );
-            }
+        foreach ($slaves as $slave) {
+            array_push(
+                $this->dbSlaves,
+                $this->connect(
+                    $slave['dsn'],
+                    $slave['username'],
+                    $slave['password'],
+                    $driverOptions
+                )
+            );
         }
 
         $this->tablePrefix = $config->getString('database.prefix', '');
@@ -111,7 +109,7 @@ class Database
     /**
      * Generate an Instance ID based on the database configuration.
      *
-     * @param \SimpleSAML_Configuration $config Configuration class
+     * @param \SimpleSAML\Configuration $config Configuration class
      *
      * @return string $instanceId
      */
diff --git a/lib/SimpleSAML/Error/Assertion.php b/lib/SimpleSAML/Error/Assertion.php
index 3497d32b2f4adce9331e1c71f4971e7760abee79..e70281385bf0c8e2ec04bcde82d97401f1fe2f72 100644
--- a/lib/SimpleSAML/Error/Assertion.php
+++ b/lib/SimpleSAML/Error/Assertion.php
@@ -1,81 +1,86 @@
 <?php
 
+namespace SimpleSAML\Error;
+
 /**
  * Class for creating exceptions from assertion failures.
  *
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Error_Assertion extends SimpleSAML_Error_Exception {
-
-
-	/**
-	 * The assertion which failed, or NULL if only an expression was passed to the
-	 * assert-function.
-	 */
-	private $assertion;
-
-
-	/**
-	 * Constructor for the assertion exception.
-	 *
-	 * Should only be called from the onAssertion handler.
-	 *
-	 * @param string|NULL $assertion  The assertion which failed, or NULL if the assert-function was
-	 *                                given an expression.
-	 */
-	public function __construct($assertion = NULL) {
-		assert($assertion === null || is_string($assertion));
-
-		$msg = 'Assertion failed: ' . var_export($assertion, TRUE);
-		parent::__construct($msg);
-
-		$this->assertion = $assertion;
-	}
-
-
-	/**
-	 * Retrieve the assertion which failed.
-	 *
-	 * @return string|NULL  The assertion which failed, or NULL if the assert-function was called with an expression.
-	 */
-	public function getAssertion() {
-		return $this->assertion;
-	}
-
-
-	/**
-	 * Install this assertion handler.
-	 *
-	 * This function will register this assertion handler. If will not enable assertions if they are
-	 * disabled.
-	 */
-	public static function installHandler() {
-
-		assert_options(ASSERT_WARNING,    0);
-		assert_options(ASSERT_QUIET_EVAL, 0);
-		assert_options(ASSERT_CALLBACK,   array('SimpleSAML_Error_Assertion', 'onAssertion'));
-	}
-
-
-	/**
-	 * Handle assertion.
-	 *
-	 * This function handles an assertion.
-	 *
-	 * @param string $file  The file assert was called from.
-	 * @param int $line  The line assert was called from.
-	 * @param mixed $message  The expression which was passed to the assert-function.
-	 */
-	public static function onAssertion($file, $line, $message) {
-
-		if(!empty($message)) {
-			$exception = new self($message);
-		} else {
-			$exception = new self();
-		}
-
-		$exception->logError();
-	}
 
+class Assertion extends Exception
+{
+    /**
+     * The assertion which failed, or null if only an expression was passed to the
+     * assert-function.
+     */
+    private $assertion;
+
+
+    /**
+     * Constructor for the assertion exception.
+     *
+     * Should only be called from the onAssertion handler.
+     *
+     * @param string|null $assertion  The assertion which failed, or null if the assert-function was
+     *                                given an expression.
+     */
+    public function __construct($assertion = null)
+    {
+        assert($assertion === null || is_string($assertion));
+
+        $msg = 'Assertion failed: ' . var_export($assertion, true);
+        parent::__construct($msg);
+
+        $this->assertion = $assertion;
+    }
+
+
+    /**
+     * Retrieve the assertion which failed.
+     *
+     * @return string|null  The assertion which failed, or null if the assert-function was called with an expression.
+     */
+    public function getAssertion()
+    {
+        return $this->assertion;
+    }
+
+
+    /**
+     * Install this assertion handler.
+     *
+     * This function will register this assertion handler. If will not enable assertions if they are
+     * disabled.
+     */
+    public static function installHandler()
+    {
+
+        assert_options(ASSERT_WARNING, 0);
+        assert_options(ASSERT_QUIET_EVAL, 0);
+        assert_options(ASSERT_CALLBACK, array('\SimpleSAML\Error\Assertion', 'onAssertion'));
+    }
+
+
+    /**
+     * Handle assertion.
+     *
+     * This function handles an assertion.
+     *
+     * @param string $file  The file assert was called from.
+     * @param int $line  The line assert was called from.
+     * @param mixed $message  The expression which was passed to the assert-function.
+     */
+    public static function onAssertion($file, $line, $message)
+    {
+
+        if (!empty($message)) {
+            $exception = new self($message);
+        } else {
+            $exception = new self();
+        }
+
+        $exception->logError();
+    }
 }
diff --git a/lib/SimpleSAML/Error/AuthSource.php b/lib/SimpleSAML/Error/AuthSource.php
index 119ffc4b38740d61c86f5f1be96f015dad42fd62..6db18812164ec06b994d7860c1324bc131daec9c 100644
--- a/lib/SimpleSAML/Error/AuthSource.php
+++ b/lib/SimpleSAML/Error/AuthSource.php
@@ -1,68 +1,72 @@
 <?php
+
+namespace SimpleSAML\Error;
+
 /**
  * Baseclass for auth source exceptions.
- * 
+ *
  * @package SimpleSAMLphp_base
  *
  */
-class SimpleSAML_Error_AuthSource extends SimpleSAML_Error_Error {
-
-
-	/**
-	 * Authsource module name.
-	 */
-	private $authsource;
 
+class AuthSource extends Error
+{
+    /**
+     * Authsource module name.
+     */
+    private $authsource;
 
-	/**
-	 * Reason why this request was invalid.
-	 */
-	private $reason;
 
+    /**
+     * Reason why this request was invalid.
+     */
+    private $reason;
 
-	/**
-	 * Create a new AuthSource error.
-	 *
-	 * @param string $authsource  Authsource module name from where this error was thrown.
-	 * @param string $reason  Description of the error.
-	 */
-	public function __construct($authsource, $reason, $cause = NULL) {
-		assert(is_string($authsource));
-		assert(is_string($reason));
 
-		$this->authsource = $authsource;
-		$this->reason = $reason;
-		parent::__construct(
-			array(
-				'AUTHSOURCEERROR',
-				'%AUTHSOURCE%' => htmlspecialchars(var_export($this->authsource, TRUE)),
-				'%REASON%' => htmlspecialchars(var_export($this->reason, TRUE))
-			),
-			$cause
-		);
+    /**
+     * Create a new AuthSource error.
+     *
+     * @param string $authsource  Authsource module name from where this error was thrown.
+     * @param string $reason  Description of the error.
+     */
+    public function __construct($authsource, $reason, $cause = null)
+    {
+        assert(is_string($authsource));
+        assert(is_string($reason));
 
-		$this->message = "Error with authentication source '$authsource': $reason";
-	}
+        $this->authsource = $authsource;
+        $this->reason = $reason;
+        parent::__construct(
+            array(
+                'AUTHSOURCEERROR',
+                '%AUTHSOURCE%' => htmlspecialchars(var_export($this->authsource, true)),
+                '%REASON%' => htmlspecialchars(var_export($this->reason, true))
+            ),
+            $cause
+        );
 
+        $this->message = "Error with authentication source '$authsource': $reason";
+    }
 
-	/**
-	 * Retrieve the authsource module name from where this error was thrown.
-	 *
-	 * @return string  Authsource module name.
-	 */
-	public function getAuthSource() {
-		return $this->authsource;
-	}
 
+    /**
+     * Retrieve the authsource module name from where this error was thrown.
+     *
+     * @return string  Authsource module name.
+     */
+    public function getAuthSource()
+    {
+        return $this->authsource;
+    }
 
-	/**
-	 * Retrieve the reason why the request was invalid.
-	 *
-	 * @return string  The reason why the request was invalid.
-	 */
-	public function getReason() {
-		return $this->reason;
-	}
 
-	
+    /**
+     * Retrieve the reason why the request was invalid.
+     *
+     * @return string  The reason why the request was invalid.
+     */
+    public function getReason()
+    {
+        return $this->reason;
+    }
 }
diff --git a/lib/SimpleSAML/Error/BadRequest.php b/lib/SimpleSAML/Error/BadRequest.php
index 21b57296b53ca363d58d59f2f0f690ab8e0082a5..41bf65c1f98c0653960b9fb124c92591bd80f18e 100644
--- a/lib/SimpleSAML/Error/BadRequest.php
+++ b/lib/SimpleSAML/Error/BadRequest.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Error;
+
 /**
  * Exception which will show a 400 Bad Request error page.
  *
@@ -9,36 +11,37 @@
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Error_BadRequest extends SimpleSAML_Error_Error {
-
-
-	/**
-	 * Reason why this request was invalid.
-	 */
-	private $reason;
-
-
-	/**
-	 * Create a new BadRequest error.
-	 *
-	 * @param string $reason  Description of why the request was unacceptable.
-	 */
-	public function __construct($reason) {
-		assert(is_string($reason));
-
-		$this->reason = $reason;
-		parent::__construct(array('BADREQUEST', '%REASON%' => $this->reason));
-		$this->httpCode = 400;
-	}
-
-
-	/**
-	 * Retrieve the reason why the request was invalid.
-	 *
-	 * @return string  The reason why the request was invalid.
-	 */
-	public function getReason() {
-		return $this->reason;
-	}
 
+class BadRequest extends Error
+{
+    /**
+     * Reason why this request was invalid.
+     */
+    private $reason;
+
+
+    /**
+     * Create a new BadRequest error.
+     *
+     * @param string $reason  Description of why the request was unacceptable.
+     */
+    public function __construct($reason)
+    {
+        assert(is_string($reason));
+
+        $this->reason = $reason;
+        parent::__construct(array('BADREQUEST', '%REASON%' => $this->reason));
+        $this->httpCode = 400;
+    }
+
+
+    /**
+     * Retrieve the reason why the request was invalid.
+     *
+     * @return string  The reason why the request was invalid.
+     */
+    public function getReason()
+    {
+        return $this->reason;
+    }
 }
diff --git a/lib/SimpleSAML/Error/BadUserInnput.php b/lib/SimpleSAML/Error/BadUserInput.php
similarity index 66%
rename from lib/SimpleSAML/Error/BadUserInnput.php
rename to lib/SimpleSAML/Error/BadUserInput.php
index 48386c16ecea80a3275363f7058f8006aafaf122..5f94dcc0493fc0a17a88cb4a17d9aabed17921f8 100644
--- a/lib/SimpleSAML/Error/BadUserInnput.php
+++ b/lib/SimpleSAML/Error/BadUserInput.php
@@ -1,11 +1,15 @@
 <?php
+
+namespace SimpleSAML\Error;
+
 /**
  * Exception indicating illegal innput from user.
- * 
+ *
  * @author Thomas Graff <thomas.graff@uninett.no>
  * @package SimpleSAMLphp_base
  *
  */
-class SimpleSAML_Error_BadUserInnput extends SimpleSAML_Error_User{
-	
+
+class BadUserInput extends User
+{
 }
diff --git a/lib/SimpleSAML/Error/CannotSetCookie.php b/lib/SimpleSAML/Error/CannotSetCookie.php
index 31a25b0c535bb1006856f8e6f6741f25aac16556..70287404f9f7d9fb48a2d2e0e7718020b09f910a 100644
--- a/lib/SimpleSAML/Error/CannotSetCookie.php
+++ b/lib/SimpleSAML/Error/CannotSetCookie.php
@@ -1,4 +1,7 @@
 <?php
+
+namespace SimpleSAML\Error;
+
 /**
  * Exception to indicate that we cannot set a cookie.
  *
@@ -6,12 +9,8 @@
  * @package SimpleSAMLphp
  */
 
-namespace SimpleSAML\Error;
-
-
-class CannotSetCookie extends \SimpleSAML_Error_Exception
+class CannotSetCookie extends Exception
 {
-
     /**
      * The exception was thrown for unknown reasons.
      *
diff --git a/lib/SimpleSAML/Error/ConfigurationError.php b/lib/SimpleSAML/Error/ConfigurationError.php
index 15eb30f366ee918b0226f1345587598c52cb4b2d..47dd0ccc9859d9c7e9b558a6e2472403980438b0 100644
--- a/lib/SimpleSAML/Error/ConfigurationError.php
+++ b/lib/SimpleSAML/Error/ConfigurationError.php
@@ -1,4 +1,7 @@
 <?php
+
+namespace SimpleSAML\Error;
+
 /**
  * This exception represents a configuration error.
  *
@@ -6,12 +9,8 @@
  * @package SimpleSAMLphp
  */
 
-namespace SimpleSAML\Error;
-
-
-class ConfigurationError extends \SimpleSAML_Error_Error
+class ConfigurationError extends Error
 {
-
     /**
      * The reason for this exception.
      *
diff --git a/lib/SimpleSAML/Error/CriticalConfigurationError.php b/lib/SimpleSAML/Error/CriticalConfigurationError.php
index 76af87ff8acbcb33fd404e6ff96aabbdc1c50c2a..1e67a1e80d9dd7f6caee13706da426b66100bf71 100644
--- a/lib/SimpleSAML/Error/CriticalConfigurationError.php
+++ b/lib/SimpleSAML/Error/CriticalConfigurationError.php
@@ -1,4 +1,7 @@
 <?php
+
+namespace SimpleSAML\Error;
+
 /**
  * This exception represents a configuration error that we cannot recover from.
  *
@@ -18,12 +21,8 @@
  * @package SimpleSAMLphp
  */
 
-namespace SimpleSAML\Error;
-
-
 class CriticalConfigurationError extends ConfigurationError
 {
-
     /**
      * This is the bare minimum configuration that we can use.
      *
@@ -42,7 +41,7 @@ class CriticalConfigurationError extends ConfigurationError
      *
      * @param string|null $reason The reason for this critical error.
      * @param string|null $file The configuration file that originated this error.
-     * @param array|null The configuration array that led to this problem.
+     * @param array|null $config The configuration array that led to this problem.
      */
     public function __construct($reason = null, $file = null, $config = null)
     {
@@ -51,7 +50,7 @@ class CriticalConfigurationError extends ConfigurationError
             $config['baseurlpath'] = \SimpleSAML\Utils\HTTP::guessBasePath();
         }
 
-        \SimpleSAML_Configuration::loadFromArray(
+        \SimpleSAML\Configuration::loadFromArray(
             $config,
             '',
             'simplesaml'
@@ -61,7 +60,7 @@ class CriticalConfigurationError extends ConfigurationError
 
 
     /**
-     * @param \Exception $exception
+     * @param ConfigurationError $exception
      *
      * @return CriticalConfigurationError
      */
diff --git a/lib/SimpleSAML/Error/Error.php b/lib/SimpleSAML/Error/Error.php
index 483b4c8f06696a60e93e1e8b1b340be785af3ebf..9632df87de26b5b874bd03b5050aa72dae4ad633 100644
--- a/lib/SimpleSAML/Error/Error.php
+++ b/lib/SimpleSAML/Error/Error.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML\Error;
 
 /**
  * Class that wraps SimpleSAMLphp errors in exceptions.
@@ -7,10 +8,9 @@
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Error_Error extends SimpleSAML_Error_Exception
-{
-
 
+class Error extends Exception
+{
     /**
      * The error code.
      *
@@ -18,7 +18,6 @@ class SimpleSAML_Error_Error extends SimpleSAML_Error_Exception
      */
     private $errorCode;
 
-
     /**
      * The http code.
      *
@@ -26,7 +25,6 @@ class SimpleSAML_Error_Error extends SimpleSAML_Error_Exception
      */
     protected $httpCode = 500;
 
-
     /**
      * The error title tag in dictionary.
      *
@@ -34,7 +32,6 @@ class SimpleSAML_Error_Error extends SimpleSAML_Error_Exception
      */
     private $dictTitle;
 
-
     /**
      * The error description tag in dictionary.
      *
@@ -42,7 +39,6 @@ class SimpleSAML_Error_Error extends SimpleSAML_Error_Exception
      */
     private $dictDescr;
 
-
     /**
      * The name of module that threw the error.
      *
@@ -50,7 +46,6 @@ class SimpleSAML_Error_Error extends SimpleSAML_Error_Exception
      */
     private $module = null;
 
-
     /**
      * The parameters for the error.
      *
@@ -58,7 +53,6 @@ class SimpleSAML_Error_Error extends SimpleSAML_Error_Exception
      */
     private $parameters;
 
-
     /**
      * Name of custom include template for the error.
      *
@@ -66,7 +60,6 @@ class SimpleSAML_Error_Error extends SimpleSAML_Error_Exception
      */
     protected $includeTemplate = null;
 
-
     /**
      * Constructor for this error.
      *
@@ -74,10 +67,10 @@ class SimpleSAML_Error_Error extends SimpleSAML_Error_Exception
      * (with index 0), is the error code, while the other elements are replacements for the error text.
      *
      * @param mixed     $errorCode One of the error codes defined in the errors dictionary.
-     * @param Exception $cause The exception which caused this fatal error (if any). Optional.
+     * @param \Exception $cause The exception which caused this fatal error (if any). Optional.
      * @param int|null  $httpCode The HTTP response code to use. Optional.
      */
-    public function __construct($errorCode, Exception $cause = null, $httpCode = null)
+    public function __construct($errorCode, \Exception $cause = null, $httpCode = null)
     {
         assert(is_string($errorCode) || is_array($errorCode));
 
@@ -100,8 +93,8 @@ class SimpleSAML_Error_Error extends SimpleSAML_Error_Exception
             $this->dictTitle = '{'.$this->module.':errors:title_'.$moduleCode[1].'}';
             $this->dictDescr = '{'.$this->module.':errors:descr_'.$moduleCode[1].'}';
         } else {
-            $this->dictTitle = SimpleSAML\Error\ErrorCodes::getErrorCodeTitle($this->errorCode);
-            $this->dictDescr = SimpleSAML\Error\ErrorCodes::getErrorCodeDescription($this->errorCode);
+            $this->dictTitle = ErrorCodes::getErrorCodeTitle($this->errorCode);
+            $this->dictDescr = ErrorCodes::getErrorCodeDescription($this->errorCode);
         }
 
         if (!empty($this->parameters)) {
@@ -192,7 +185,7 @@ class SimpleSAML_Error_Error extends SimpleSAML_Error_Exception
 
         if (!array_key_exists($this->httpCode, $httpCodesMap)) {
             $httpCode = 500;
-            SimpleSAML\Logger::warning('HTTP response code not defined: '.var_export($this->httpCode, true));
+            \SimpleSAML\Logger::warning('HTTP response code not defined: '.var_export($this->httpCode, true));
         }
 
         header($httpCodesMap[$httpCode]);
@@ -211,10 +204,10 @@ class SimpleSAML_Error_Error extends SimpleSAML_Error_Exception
         $etrace = implode("\n", $data);
 
         $reportId = bin2hex(openssl_random_pseudo_bytes(4));
-        SimpleSAML\Logger::error('Error report with id '.$reportId.' generated.');
+        \SimpleSAML\Logger::error('Error report with id '.$reportId.' generated.');
 
-        $config = SimpleSAML_Configuration::getInstance();
-        $session = SimpleSAML_Session::getSessionFromRequest();
+        $config = \SimpleSAML\Configuration::getInstance();
+        $session = \SimpleSAML\Session::getSessionFromRequest();
 
         if (isset($_SERVER['HTTP_REFERER'])) {
             $referer = $_SERVER['HTTP_REFERER'];
@@ -254,9 +247,9 @@ class SimpleSAML_Error_Error extends SimpleSAML_Error_Exception
         $this->logError();
 
         $errorData = $this->saveError();
+        $config = \SimpleSAML\Configuration::getInstance();
 
-        $config = SimpleSAML_Configuration::getInstance();
-
+        $data = array();
         $data['showerrors'] = $config->getBoolean('showerrors', true);
         $data['error'] = $errorData;
         $data['errorCode'] = $this->errorCode;
@@ -277,7 +270,7 @@ class SimpleSAML_Error_Error extends SimpleSAML_Error_Exception
         }
 
         $data['email'] = '';
-        $session = SimpleSAML_Session::getSessionFromRequest();
+        $session = \SimpleSAML\Session::getSessionFromRequest();
         $authorities = $session->getAuthorities();
         foreach ($authorities as $authority) {
             $attributes = $session->getAuthData($authority, 'Attributes');
@@ -293,7 +286,7 @@ class SimpleSAML_Error_Error extends SimpleSAML_Error_Exception
             call_user_func($show_function, $config, $data);
             assert(false);
         } else {
-            $t = new SimpleSAML_XHTML_Template($config, 'error.php', 'errors');
+            $t = new \SimpleSAML\XHTML\Template($config, 'error.php', 'errors');
             $t->data = array_merge($t->data, $data);
             $t->data['dictTitleTranslated'] = $t->getTranslator()->t($t->data['dictTitle']);
             $t->data['dictDescrTranslated'] = $t->getTranslator()->t($t->data['dictDescr'], $t->data['parameters']);
diff --git a/lib/SimpleSAML/Error/ErrorCodes.php b/lib/SimpleSAML/Error/ErrorCodes.php
index 3563a2d3d8f0c8eeb60a69f5246264174c86d38d..803f1acea0a7dad7c5551fef157de569c69cd485 100644
--- a/lib/SimpleSAML/Error/ErrorCodes.php
+++ b/lib/SimpleSAML/Error/ErrorCodes.php
@@ -1,4 +1,7 @@
 <?php
+
+namespace SimpleSAML\Error;
+
 /**
  * Class that maps SimpleSAMLphp error codes to translateable strings.
  *
@@ -6,8 +9,6 @@
  * @package SimpleSAMLphp
  */
 
-namespace SimpleSAML\Error;
-
 class ErrorCodes
 {
     /**
diff --git a/lib/SimpleSAML/Error/Exception.php b/lib/SimpleSAML/Error/Exception.php
index 48d74cd2f6ef3159cbc3d8395e4611d5570b3586..4131c993d21df8b046ca967c958c8b27d5a7d2b3 100644
--- a/lib/SimpleSAML/Error/Exception.php
+++ b/lib/SimpleSAML/Error/Exception.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML\Error;
 
 /**
  * Base class for SimpleSAMLphp Exceptions
@@ -9,9 +10,9 @@
  * @author Thomas Graff <thomas.graff@uninett.no>
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Error_Exception extends Exception
-{
 
+class Exception extends \Exception
+{
     /**
      * The backtrace for this exception.
      *
@@ -26,7 +27,7 @@ class SimpleSAML_Error_Exception extends Exception
     /**
      * The cause of this exception.
      *
-     * @var SimpleSAML_Error_Exception
+     * @var Exception
      */
     private $cause;
 
@@ -34,14 +35,14 @@ class SimpleSAML_Error_Exception extends Exception
     /**
      * Constructor for this error.
      *
-     * Note that the cause will be converted to a SimpleSAML_Error_UnserializableException unless it is a subclass of
-     * SimpleSAML_Error_Exception.
+     * Note that the cause will be converted to a SimpleSAML\Error\UnserializableException unless it is a subclass of
+     * SimpleSAML\Error\Exception.
      *
      * @param string         $message Exception message
      * @param int            $code Error code
-     * @param Exception|null $cause The cause of this exception.
+     * @param \Exception|null $cause The cause of this exception.
      */
-    public function __construct($message, $code = 0, Exception $cause = null)
+    public function __construct($message, $code = 0, \Exception $cause = null)
     {
         assert(is_string($message));
         assert(is_int($code));
@@ -51,43 +52,40 @@ class SimpleSAML_Error_Exception extends Exception
         $this->initBacktrace($this);
 
         if ($cause !== null) {
-            $this->cause = SimpleSAML_Error_Exception::fromException($cause);
+            $this->cause = Exception::fromException($cause);
         }
     }
 
 
     /**
-     * Convert any exception into a SimpleSAML_Error_Exception.
+     * Convert any exception into a \SimpleSAML\Error\Exception.
      *
-     * @param Exception $e The exception.
+     * @param \Exception $e The exception.
      *
-     * @return SimpleSAML_Error_Exception The new exception.
+     * @return Exception The new exception.
      */
-    public static function fromException(Exception $e)
+    public static function fromException(\Exception $e)
     {
-
-        if ($e instanceof SimpleSAML_Error_Exception) {
+        if ($e instanceof Exception) {
             return $e;
         }
-        return new SimpleSAML_Error_UnserializableException($e);
+        return new UnserializableException($e);
     }
 
 
     /**
      * Load the backtrace from the given exception.
      *
-     * @param Exception $exception The exception we should fetch the backtrace from.
+     * @param \Exception $exception The exception we should fetch the backtrace from.
      */
-    protected function initBacktrace(Exception $exception)
+    protected function initBacktrace(\Exception $exception)
     {
-
         $this->backtrace = array();
 
         // position in the top function on the stack
         $pos = $exception->getFile().':'.$exception->getLine();
 
         foreach ($exception->getTrace() as $t) {
-
             $function = $t['function'];
             if (array_key_exists('class', $t)) {
                 $function = $t['class'].'::'.$function;
@@ -120,7 +118,7 @@ class SimpleSAML_Error_Exception extends Exception
     /**
      * Retrieve the cause of this exception.
      *
-     * @return SimpleSAML_Error_Exception|null The cause of this exception.
+     * @return Exception|null The cause of this exception.
      */
     public function getCause()
     {
@@ -169,7 +167,7 @@ class SimpleSAML_Error_Exception extends Exception
     public function formatBacktrace($anonymize = false)
     {
         $ret = array();
-        $basedir = SimpleSAML_Configuration::getInstance()->getBaseDir();
+        $basedir = \SimpleSAML\Configuration::getInstance()->getBaseDir();
 
         $e = $this;
         do {
@@ -199,7 +197,7 @@ class SimpleSAML_Error_Exception extends Exception
     protected function logBacktrace($level = \SimpleSAML\Logger::DEBUG)
     {
         // see if debugging is enabled for backtraces
-        $debug = SimpleSAML_Configuration::getInstance()->getArrayize('debug', array('backtraces' => false));
+        $debug = \SimpleSAML\Configuration::getInstance()->getArrayize('debug', array('backtraces' => false));
 
         if (!(in_array('backtraces', $debug, true) // implicitly enabled
               || (array_key_exists('backtraces', $debug) && $debug['backtraces'] === true) // explicitly set
@@ -236,10 +234,10 @@ class SimpleSAML_Error_Exception extends Exception
     public function log($default_level)
     {
         $fn = array(
-            SimpleSAML\Logger::ERR     => 'logError',
-            SimpleSAML\Logger::WARNING => 'logWarning',
-            SimpleSAML\Logger::INFO    => 'logInfo',
-            SimpleSAML\Logger::DEBUG   => 'logDebug',
+            \SimpleSAML\Logger::ERR     => 'logError',
+            \SimpleSAML\Logger::WARNING => 'logWarning',
+            \SimpleSAML\Logger::INFO    => 'logInfo',
+            \SimpleSAML\Logger::DEBUG   => 'logDebug',
         );
         call_user_func(array($this, $fn[$default_level]), $default_level);
     }
@@ -252,7 +250,7 @@ class SimpleSAML_Error_Exception extends Exception
      */
     public function logError()
     {
-        SimpleSAML\Logger::error($this->getClass().': '.$this->getMessage());
+        \SimpleSAML\Logger::error($this->getClass().': '.$this->getMessage());
         $this->logBacktrace(\SimpleSAML\Logger::ERR);
     }
 
@@ -264,7 +262,7 @@ class SimpleSAML_Error_Exception extends Exception
      */
     public function logWarning()
     {
-        SimpleSAML\Logger::warning($this->getClass().': '.$this->getMessage());
+        \SimpleSAML\Logger::warning($this->getClass().': '.$this->getMessage());
         $this->logBacktrace(\SimpleSAML\Logger::WARNING);
     }
 
@@ -276,7 +274,7 @@ class SimpleSAML_Error_Exception extends Exception
      */
     public function logInfo()
     {
-        SimpleSAML\Logger::info($this->getClass().': '.$this->getMessage());
+        \SimpleSAML\Logger::info($this->getClass().': '.$this->getMessage());
         $this->logBacktrace(\SimpleSAML\Logger::INFO);
     }
 
@@ -288,7 +286,7 @@ class SimpleSAML_Error_Exception extends Exception
      */
     public function logDebug()
     {
-        SimpleSAML\Logger::debug($this->getClass().': '.$this->getMessage());
+        \SimpleSAML\Logger::debug($this->getClass().': '.$this->getMessage());
         $this->logBacktrace(\SimpleSAML\Logger::DEBUG);
     }
 
@@ -303,7 +301,6 @@ class SimpleSAML_Error_Exception extends Exception
      */
     public function __sleep()
     {
-
         $ret = array_keys((array) $this);
 
         foreach ($ret as $i => $e) {
diff --git a/lib/SimpleSAML/Error/InvalidCredential.php b/lib/SimpleSAML/Error/InvalidCredential.php
index 5a3f7d8a4f15fd823a8a67159555d6bc81a6b1bc..98d3b85d7b993e0ea9d1e0816dd3778c56548f54 100644
--- a/lib/SimpleSAML/Error/InvalidCredential.php
+++ b/lib/SimpleSAML/Error/InvalidCredential.php
@@ -1,11 +1,15 @@
 <?php
+
+namespace SimpleSAML\Error;
+
 /**
  * Exception indicating wrong password given by user.
- * 
+ *
  * @author Thomas Graff <thomas.graff@uninett.no>
  * @package SimpleSAMLphp_base
  *
  */
-class SimpleSAML_Error_InvalidCredential extends SimpleSAML_Error_User{
-	
+
+class InvalidCredential extends User
+{
 }
diff --git a/lib/SimpleSAML/Error/MetadataNotFound.php b/lib/SimpleSAML/Error/MetadataNotFound.php
index 9fe5a498a6e7eb93812d908d8b9b4f9a98234c10..93e086c14e75116ef4e9dafab5091ba8e46abdbe 100644
--- a/lib/SimpleSAML/Error/MetadataNotFound.php
+++ b/lib/SimpleSAML/Error/MetadataNotFound.php
@@ -1,26 +1,28 @@
 <?php
 
+namespace SimpleSAML\Error;
+
 /**
  * Error for missing metadata.
  *
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Error_MetadataNotFound extends SimpleSAML_Error_Error {
-
-
-	/**
-	 * Create the error
-	 *
-	 * @param string $entityId  The entityID we were unable to locate.
-	 */
-	public function __construct($entityId) {
-		assert(is_string($entityId));
 
-		$this->includeTemplate = 'core:no_metadata.tpl.php';
-		parent::__construct(array(
-				'METADATANOTFOUND',
-				'%ENTITYID%' => htmlspecialchars(var_export($entityId, TRUE))
-		));
-	}
+class MetadataNotFound extends Error
+{
+    /**
+     * Create the error
+     *
+     * @param string $entityId  The entityID we were unable to locate.
+     */
+    public function __construct($entityId)
+    {
+        assert(is_string($entityId));
 
+        $this->includeTemplate = 'core:no_metadata.tpl.php';
+        parent::__construct(array(
+                'METADATANOTFOUND',
+                '%ENTITYID%' => htmlspecialchars(var_export($entityId, true))
+        ));
+    }
 }
diff --git a/lib/SimpleSAML/Error/NoPassive.php b/lib/SimpleSAML/Error/NoPassive.php
index 8966dc8b527497999edea34fc9db2cc47451fa1e..43b42cf46b1110e3e4787adfdf5b36aa1e6668b0 100644
--- a/lib/SimpleSAML/Error/NoPassive.php
+++ b/lib/SimpleSAML/Error/NoPassive.php
@@ -1,14 +1,16 @@
 <?php
 
+namespace SimpleSAML\Error;
 
 /**
- * Class SimpleSAML_Error_NoPassive
+ * Class NoPassive
  *
  * @deprecated This class has been deprecated and will be removed in SimpleSAMLphp 2.0. Please use
- * SimpleSAML\Module\saml\Error\NoPassive instead.
+ * \SimpleSAML\Module\saml\Error\NoPassive instead.
  *
  * @see \SimpleSAML\Module\saml\Error\NoPassive
  */
-class SimpleSAML_Error_NoPassive extends SimpleSAML_Error_Exception {
 
+class NoPassive extends Exception
+{
 }
diff --git a/lib/SimpleSAML/Error/NoState.php b/lib/SimpleSAML/Error/NoState.php
index 1c92da92728a3d8086f484fb8f9f383903e58294..d0281beb01eb4d6bc0c2a8dcbb4255d042947adf 100644
--- a/lib/SimpleSAML/Error/NoState.php
+++ b/lib/SimpleSAML/Error/NoState.php
@@ -1,20 +1,22 @@
 <?php
 
+namespace SimpleSAML\Error;
+
 /**
  * Exception which will show a page telling the user
  * that we don't know what to do.
  *
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Error_NoState extends SimpleSAML_Error_Error {
-
-
-	/**
-	 * Create the error
-	 */
-	public function __construct() {
-		$this->includeTemplate = 'core:no_state.tpl.php';
-		parent::__construct('NOSTATE');
-	}
 
+class NoState extends Error
+{
+    /**
+     * Create the error
+     */
+    public function __construct()
+    {
+        $this->includeTemplate = 'core:no_state.tpl.php';
+        parent::__construct('NOSTATE');
+    }
 }
diff --git a/lib/SimpleSAML/Error/NotFound.php b/lib/SimpleSAML/Error/NotFound.php
index 0c1f460a3367d6f03c2d45b2d0a0bc40f07cb59a..79f6049221186ec8e24e59bf21c4a40e39d8d714 100644
--- a/lib/SimpleSAML/Error/NotFound.php
+++ b/lib/SimpleSAML/Error/NotFound.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Error;
+
 /**
  * Exception which will show a 404 Not Found error page.
  *
@@ -9,60 +11,62 @@
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Error_NotFound extends SimpleSAML_Error_Error {
-
-
-	/**
-	 * Reason why the given page could not be found.
-	 */
-	private $reason;
 
+class NotFound extends Error
+{
+    /**
+     * Reason why the given page could not be found.
+     */
+    private $reason;
 
-	/**
-	 * Create a new NotFound error
-	 *
-	 * @param string $reason  Optional description of why the given page could not be found.
-	 */
-	public function __construct($reason = NULL) {
 
-		assert($reason === null || is_string($reason));
+    /**
+     * Create a new NotFound error
+     *
+     * @param string $reason  Optional description of why the given page could not be found.
+     */
+    public function __construct($reason = null)
+    {
+        assert($reason === null || is_string($reason));
 
-		$url = \SimpleSAML\Utils\HTTP::getSelfURL();
+        $url = \SimpleSAML\Utils\HTTP::getSelfURL();
 
-		if($reason === NULL) {
-			parent::__construct(array('NOTFOUND', '%URL%' => $url));
-			$this->message = "The requested page '$url' could not be found.";
-		} else {
-			parent::__construct(array('NOTFOUNDREASON', '%URL%' => $url, '%REASON%' => $reason));
-			$this->message = "The requested page '$url' could not be found. ".$reason;
-		}
+        if ($reason === null) {
+            parent::__construct(array('NOTFOUND', '%URL%' => $url));
+            $this->message = "The requested page '$url' could not be found.";
+        } else {
+            parent::__construct(array('NOTFOUNDREASON', '%URL%' => $url, '%REASON%' => $reason));
+            $this->message = "The requested page '$url' could not be found. ".$reason;
+        }
 
-		$this->reason = $reason;
-		$this->httpCode = 404;
-	}
+        $this->reason = $reason;
+        $this->httpCode = 404;
+    }
 
 
-	/**
-	 * Retrieve the reason why the given page could not be found.
-	 *
-	 * @return string|NULL  The reason why the page could not be found.
-	 */
-	public function getReason() {
-		return $this->reason;
-	}
+    /**
+     * Retrieve the reason why the given page could not be found.
+     *
+     * @return string|null  The reason why the page could not be found.
+     */
+    public function getReason()
+    {
+        return $this->reason;
+    }
 
 
-	/**
-	 * NotFound exceptions don't need to display a backtrace, as they are very simple and the trace is usually trivial,
-	 * so just log the message without any backtrace at all.
-	 *
-	 * @param bool $anonymize Whether to anonymize the trace or not.
-	 *
-	 * @return array
-	 */
-	public function format($anonymize = false) {
-		return array(
-			$this->getClass().': '.$this->getMessage(),
-		);
-	}
+    /**
+     * NotFound exceptions don't need to display a backtrace, as they are very simple and the trace is usually trivial,
+     * so just log the message without any backtrace at all.
+     *
+     * @param bool $anonymize Whether to anonymize the trace or not.
+     *
+     * @return array
+     */
+    public function format($anonymize = false)
+    {
+        return array(
+            $this->getClass().': '.$this->getMessage(),
+        );
+    }
 }
diff --git a/lib/SimpleSAML/Error/ProxyCountExceeded.php b/lib/SimpleSAML/Error/ProxyCountExceeded.php
index 0af64d51e740db277e523d89284290d6b16a3122..6b325f3b61a59d4d5ae6bd064e65ae46e13ab48c 100644
--- a/lib/SimpleSAML/Error/ProxyCountExceeded.php
+++ b/lib/SimpleSAML/Error/ProxyCountExceeded.php
@@ -1,14 +1,16 @@
 <?php
 
+namespace SimpleSAML\Error;
 
 /**
- * Class SimpleSAML_Error_ProxyCountExceeded
+ * Class ProxyCountExceeded
  *
  * @deprecated This class has been deprecated and will be removed in SimpleSAMLphp 2.0. Please use
- * SimpleSAML\Module\saml\Error\ProxyCountExceeded instead.
+ * \SimpleSAML\Module\saml\Error\ProxyCountExceeded instead.
  *
  * @see \SimpleSAML\Module\saml\Error\ProxyCountExceeded
  */
-class SimpleSAML_Error_ProxyCountExceeded extends SimpleSAML_Error_Exception {
 
+class ProxyCountExceeded extends Exception
+{
 }
diff --git a/lib/SimpleSAML/Error/UnserializableException.php b/lib/SimpleSAML/Error/UnserializableException.php
index 6c55bece1381dcc74eac1ada769fcf65d5333002..54f4eb34feb9a98d40aabc48e985e7687be37b94 100644
--- a/lib/SimpleSAML/Error/UnserializableException.php
+++ b/lib/SimpleSAML/Error/UnserializableException.php
@@ -1,55 +1,59 @@
 <?php
 
+namespace SimpleSAML\Error;
+
 /**
  * Class for saving normal exceptions for serialization.
  *
- * This class is used by the SimpleSAML_Auth_State class when it needs
+ * This class is used by the \SimpleSAML\Auth\State class when it needs
  * to serialize an exception which doesn't subclass the
- * SimpleSAML_Error_Exception class.
+ * \SimpleSAML\Error\Exception class.
  *
  * It creates a new exception which contains the backtrace and message
  * of the original exception.
  *
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Error_UnserializableException extends SimpleSAML_Error_Exception {
-
-	/**
-	 * The classname of the original exception.
-	 *
-	 * @var string
-	 */
-	private $class;
-
-
-	/**
-	 * Create a serializable exception representing an unserializable exception.
-	 *
-	 * @param Exception $original  The original exception.
-	 */
-	public function __construct(Exception $original) {
-
-		$this->class = get_class($original);
-		$msg = $original->getMessage();
-		$code = $original->getCode();
-
-		if (!is_int($code)) {
-			// PDOException uses a string as the code. Filter it out here.
-			$code = -1;
-		}
-
-		parent::__construct($msg, $code);
-		$this->initBacktrace($original);
-	}
-
-
-	/**
-	 * Retrieve the class of this exception.
-	 *
-	 * @return string  The classname.
-	 */
-	public function getClass() {
-		return $this->class;
-	}
 
+class UnserializableException extends Exception
+{
+    /**
+     * The classname of the original exception.
+     *
+     * @var string
+     */
+    private $class;
+
+
+    /**
+     * Create a serializable exception representing an unserializable exception.
+     *
+     * @param \Exception $original  The original exception.
+     */
+    public function __construct(\Exception $original)
+    {
+
+        $this->class = get_class($original);
+        $msg = $original->getMessage();
+        $code = $original->getCode();
+
+        if (!is_int($code)) {
+            // PDOException uses a string as the code. Filter it out here.
+            $code = -1;
+        }
+
+        parent::__construct($msg, $code);
+        $this->initBacktrace($original);
+    }
+
+
+    /**
+     * Retrieve the class of this exception.
+     *
+     * @return string  The classname.
+     */
+    public function getClass()
+    {
+        return $this->class;
+    }
 }
diff --git a/lib/SimpleSAML/Error/User.php b/lib/SimpleSAML/Error/User.php
index 2f674be18f97d6f59063810f5cde54820974a9dd..b2da0e47e1a644ba4df559616cc44d8b8829acc7 100644
--- a/lib/SimpleSAML/Error/User.php
+++ b/lib/SimpleSAML/Error/User.php
@@ -1,13 +1,16 @@
 <?php
 
+namespace SimpleSAML\Error;
+
 /**
  * Baseclass for user error exceptions
- * 
- * 
+ *
+ *
  * @author Thomas Graff <thomas.graff@uninett.no>
  * @package SimpleSAMLphp_base
  *
  */
-class SimpleSAML_Error_User extends SimpleSAML_Error_Exception{
-	
+
+class User extends Exception
+{
 }
diff --git a/lib/SimpleSAML/Error/UserAborted.php b/lib/SimpleSAML/Error/UserAborted.php
index 6bd2762afae00d4b0aad0630092cb550683af820..7be00d20ee67a3ba621b8122b749ea11e2028c0f 100644
--- a/lib/SimpleSAML/Error/UserAborted.php
+++ b/lib/SimpleSAML/Error/UserAborted.php
@@ -1,19 +1,22 @@
 <?php
 
+namespace SimpleSAML\Error;
+
 /**
  * Exception indicating user aborting the authentication process.
  *
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Error_UserAborted extends SimpleSAML_Error_Error {
-
-	/**
-	 * Create the error
-	 *
-	 * @param Exception|NULL $cause  The exception that caused this error.
-	 */
-	public function __construct(Exception $cause = NULL) {
-		parent::__construct('USERABORTED', $cause);
-	}
 
+class UserAborted extends Error
+{
+    /**
+     * Create the error
+     *
+     * @param \Exception|null $cause  The exception that caused this error.
+     */
+    public function __construct(\Exception $cause = null)
+    {
+        parent::__construct('USERABORTED', $cause);
+    }
 }
diff --git a/lib/SimpleSAML/Error/UserNotFound.php b/lib/SimpleSAML/Error/UserNotFound.php
index c536f724301e96596e805ed63dcf828f488f2335..14e55078644b47719645733fff5b70e0b2a749cb 100644
--- a/lib/SimpleSAML/Error/UserNotFound.php
+++ b/lib/SimpleSAML/Error/UserNotFound.php
@@ -1,12 +1,15 @@
 <?php
 
+namespace SimpleSAML\Error;
+
 /**
  * Exception indicating user not found by authsource.
- * 
+ *
  * @author Thomas Graff <thomas.graff@uninett.no>
  * @package SimpleSAMLphp_base
  *
  */
-class SimpleSAML_Error_UserNotFound extends SimpleSAML_Error_User{
-	
+
+class UserNotFound extends User
+{
 }
diff --git a/lib/SimpleSAML/IdP.php b/lib/SimpleSAML/IdP.php
index 4789d6e4bee8d21efd9d68a8be5fdb84b5c101b5..6110df9c7abad24956ff47c8e434bf31609744fb 100644
--- a/lib/SimpleSAML/IdP.php
+++ b/lib/SimpleSAML/IdP.php
@@ -1,5 +1,8 @@
 <?php
 
+namespace SimpleSAML;
+
+use SimpleSAML\Error\Exception;
 
 /**
  * IdP class.
@@ -8,9 +11,9 @@
  *
  * @package SimpleSAMLphp
  */
-class SimpleSAML_IdP
-{
 
+class IdP
+{
     /**
      * A cache for resolving IdP id's.
      *
@@ -18,7 +21,6 @@ class SimpleSAML_IdP
      */
     private static $idpCache = array();
 
-
     /**
      * The identifier for this IdP.
      *
@@ -26,7 +28,6 @@ class SimpleSAML_IdP
      */
     private $id;
 
-
     /**
      * The "association group" for this IdP.
      *
@@ -37,29 +38,26 @@ class SimpleSAML_IdP
      */
     private $associationGroup;
 
-
     /**
      * The configuration for this IdP.
      *
-     * @var SimpleSAML_Configuration
+     * @var Configuration
      */
     private $config;
 
-
     /**
      * Our authsource.
      *
-     * @var \SimpleSAML\Auth\Simple
+     * @var Auth\Simple
      */
     private $authSource;
 
-
     /**
      * Initialize an IdP.
      *
      * @param string $id The identifier of this IdP.
      *
-     * @throws SimpleSAML_Error_Exception If the IdP is disabled or no such auth source was found.
+     * @throws Exception If the IdP is disabled or no such auth source was found.
      */
     private function __construct($id)
     {
@@ -67,22 +65,22 @@ class SimpleSAML_IdP
 
         $this->id = $id;
 
-        $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-        $globalConfig = SimpleSAML_Configuration::getInstance();
+        $metadata = Metadata\MetaDataStorageHandler::getMetadataHandler();
+        $globalConfig = Configuration::getInstance();
 
         if (substr($id, 0, 6) === 'saml2:') {
             if (!$globalConfig->getBoolean('enable.saml20-idp', false)) {
-                throw new SimpleSAML_Error_Exception('enable.saml20-idp disabled in config.php.');
+                throw new Exception('enable.saml20-idp disabled in config.php.');
             }
             $this->config = $metadata->getMetaDataConfig(substr($id, 6), 'saml20-idp-hosted');
         } elseif (substr($id, 0, 6) === 'saml1:') {
             if (!$globalConfig->getBoolean('enable.shib13-idp', false)) {
-                throw new SimpleSAML_Error_Exception('enable.shib13-idp disabled in config.php.');
+                throw new Exception('enable.shib13-idp disabled in config.php.');
             }
             $this->config = $metadata->getMetaDataConfig(substr($id, 6), 'shib13-idp-hosted');
         } elseif (substr($id, 0, 5) === 'adfs:') {
             if (!$globalConfig->getBoolean('enable.adfs-idp', false)) {
-                throw new SimpleSAML_Error_Exception('enable.adfs-idp disabled in config.php.');
+                throw new Exception('enable.adfs-idp disabled in config.php.');
             }
             $this->config = $metadata->getMetaDataConfig(substr($id, 5), 'adfs-idp-hosted');
 
@@ -90,7 +88,7 @@ class SimpleSAML_IdP
                 // this makes the ADFS IdP use the same SP associations as the SAML 2.0 IdP
                 $saml2EntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
                 $this->associationGroup = 'saml2:'.$saml2EntityId;
-            } catch (Exception $e) {
+            } catch (\Exception $e) {
                 // probably no SAML 2 IdP configured for this host. Ignore the error
             }
         } else {
@@ -102,10 +100,10 @@ class SimpleSAML_IdP
         }
 
         $auth = $this->config->getString('auth');
-        if (SimpleSAML_Auth_Source::getById($auth) !== null) {
-            $this->authSource = new \SimpleSAML\Auth\Simple($auth);
+        if (Auth\Source::getById($auth) !== null) {
+            $this->authSource = new Auth\Simple($auth);
         } else {
-            throw new SimpleSAML_Error_Exception('No such "'.$auth.'" auth source found.');
+            throw new Exception('No such "'.$auth.'" auth source found.');
         }
     }
 
@@ -126,7 +124,7 @@ class SimpleSAML_IdP
      *
      * @param string $id The identifier of the IdP.
      *
-     * @return SimpleSAML_IdP The IdP.
+     * @return IdP The IdP.
      */
     public static function getById($id)
     {
@@ -147,7 +145,7 @@ class SimpleSAML_IdP
      *
      * @param array &$state The state array.
      *
-     * @return SimpleSAML_IdP The IdP.
+     * @return IdP The IdP.
      */
     public static function getByState(array &$state)
     {
@@ -160,7 +158,7 @@ class SimpleSAML_IdP
     /**
      * Retrieve the configuration for this IdP.
      *
-     * @return SimpleSAML_Configuration The configuration object.
+     * @return Configuration The configuration object.
      */
     public function getConfig()
     {
@@ -181,15 +179,15 @@ class SimpleSAML_IdP
 
         $prefix = substr($assocId, 0, 4);
         $spEntityId = substr($assocId, strlen($prefix) + 1);
-        $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+        $metadata = Metadata\MetaDataStorageHandler::getMetadataHandler();
 
         if ($prefix === 'saml') {
             try {
                 $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote');
-            } catch (Exception $e) {
+            } catch (\Exception $e) {
                 try {
                     $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'shib13-sp-remote');
-                } catch (Exception $e) {
+                } catch (\Exception $e) {
                     return null;
                 }
             }
@@ -223,7 +221,7 @@ class SimpleSAML_IdP
 
         $association['core:IdP'] = $this->id;
 
-        $session = SimpleSAML_Session::getSessionFromRequest();
+        $session = Session::getSessionFromRequest();
         $session->addAssociation($this->associationGroup, $association);
     }
 
@@ -235,7 +233,7 @@ class SimpleSAML_IdP
      */
     public function getAssociations()
     {
-        $session = SimpleSAML_Session::getSessionFromRequest();
+        $session = Session::getSessionFromRequest();
         return $session->getAssociations($this->associationGroup);
     }
 
@@ -249,7 +247,7 @@ class SimpleSAML_IdP
     {
         assert(is_string($assocId));
 
-        $session = SimpleSAML_Session::getSessionFromRequest();
+        $session = Session::getSessionFromRequest();
         $session->terminateAssociation($this->associationGroup, $assocId);
     }
 
@@ -275,12 +273,12 @@ class SimpleSAML_IdP
         assert(is_callable($state['Responder']));
 
         if (isset($state['core:SP'])) {
-            $session = SimpleSAML_Session::getSessionFromRequest();
+            $session = \SimpleSAML\Session::getSessionFromRequest();
             $session->setData(
                 'core:idp-ssotime',
                 $state['core:IdP'].';'.$state['core:SP'],
                 time(),
-                SimpleSAML_Session::DATA_TIMEOUT_SESSION_END
+                Session::DATA_TIMEOUT_SESSION_END
             );
         }
 
@@ -294,14 +292,14 @@ class SimpleSAML_IdP
      *
      * @param array $state The authentication request state array.
      *
-     * @throws SimpleSAML_Error_Exception If we are not authenticated.
+     * @throws Exception If we are not authenticated.
      */
     public static function postAuth(array $state)
     {
-        $idp = SimpleSAML_IdP::getByState($state);
+        $idp = IdP::getByState($state);
 
         if (!$idp->isAuthenticated()) {
-            throw new SimpleSAML_Error_Exception('Not authenticated.');
+            throw new Exception('Not authenticated.');
         }
 
         $state['Attributes'] = $idp->authSource->getAttributes();
@@ -313,7 +311,7 @@ class SimpleSAML_IdP
         }
 
         if (isset($state['core:SP'])) {
-            $session = SimpleSAML_Session::getSessionFromRequest();
+            $session = Session::getSessionFromRequest();
             $previousSSOTime = $session->getData('core:idp-ssotime', $state['core:IdP'].';'.$state['core:SP']);
             if ($previousSSOTime !== null) {
                 $state['PreviousSSOTimestamp'] = $previousSSOTime;
@@ -322,9 +320,9 @@ class SimpleSAML_IdP
 
         $idpMetadata = $idp->getConfig()->toArray();
 
-        $pc = new SimpleSAML_Auth_ProcessingChain($idpMetadata, $spMetadata, 'idp');
+        $pc = new Auth\ProcessingChain($idpMetadata, $spMetadata, 'idp');
 
-        $state['ReturnCall'] = array('SimpleSAML_IdP', 'postAuthProc');
+        $state['ReturnCall'] = array('\SimpleSAML\IdP', 'postAuthProc');
         $state['Destination'] = $spMetadata;
         $state['Source'] = $idpMetadata;
 
@@ -341,12 +339,12 @@ class SimpleSAML_IdP
      *
      * @param array &$state The authentication request state.
      *
-     * @throws SimpleSAML_Error_NoPassive If we were asked to do passive authentication.
+     * @throws Module\saml\Error\NoPassive If we were asked to do passive authentication.
      */
     private function authenticate(array &$state)
     {
         if (isset($state['isPassive']) && (bool) $state['isPassive']) {
-            throw new SimpleSAML_Error_NoPassive('Passive authentication not supported.');
+            throw new Module\saml\Error\NoPassive('Passive authentication not supported.');
         }
 
         $this->authSource->login($state);
@@ -363,13 +361,13 @@ class SimpleSAML_IdP
      *
      * @param array &$state The authentication request state.
      *
-     * @throws SimpleSAML_Error_Exception If there is no auth source defined for this IdP.
+     * @throws Exception If there is no auth source defined for this IdP.
      */
     private function reauthenticate(array &$state)
     {
         $sourceImpl = $this->authSource->getAuthSource();
         if ($sourceImpl === null) {
-            throw new SimpleSAML_Error_Exception('No such auth source defined.');
+            throw new Exception('No such auth source defined.');
         }
 
         $sourceImpl->reauthenticate($state);
@@ -405,7 +403,7 @@ class SimpleSAML_IdP
         }
 
         $state['IdPMetadata'] = $this->getConfig()->toArray();
-        $state['ReturnCallback'] = array('SimpleSAML_IdP', 'postAuth');
+        $state['ReturnCallback'] = array('\SimpleSAML\IdP', 'postAuth');
 
         try {
             if ($needAuth) {
@@ -415,11 +413,11 @@ class SimpleSAML_IdP
                 $this->reauthenticate($state);
             }
             $this->postAuth($state);
-        } catch (SimpleSAML_Error_Exception $e) {
-            SimpleSAML_Auth_State::throwException($state, $e);
         } catch (Exception $e) {
-            $e = new SimpleSAML_Error_UnserializableException($e);
-            SimpleSAML_Auth_State::throwException($state, $e);
+            \SimpleSAML\Auth\State::throwException($state, $e);
+        } catch (\Exception $e) {
+            $e = new Error\UnserializableException($e);
+            Auth\State::throwException($state, $e);
         }
     }
 
@@ -427,9 +425,9 @@ class SimpleSAML_IdP
     /**
      * Find the logout handler of this IdP.
      *
-     * @return \SimpleSAML\IdP\LogoutHandlerInterface The logout handler class.
+     * @return IdP\LogoutHandlerInterface The logout handler class.
      *
-     * @throws SimpleSAML_Error_Exception If we cannot find a logout handler.
+     * @throws Exception If we cannot find a logout handler.
      */
     public function getLogoutHandler()
     {
@@ -437,13 +435,13 @@ class SimpleSAML_IdP
         $logouttype = $this->getConfig()->getString('logouttype', 'traditional');
         switch ($logouttype) {
             case 'traditional':
-                $handler = 'SimpleSAML\IdP\TraditionalLogoutHandler';
+                $handler = '\SimpleSAML\IdP\TraditionalLogoutHandler';
                 break;
             case 'iframe':
-                $handler = 'SimpleSAML\IdP\IFrameLogoutHandler';
+                $handler = '\SimpleSAML\IdP\IFrameLogoutHandler';
                 break;
             default:
-                throw new SimpleSAML_Error_Exception('Unknown logout handler: '.var_export($logouttype, true));
+                throw new Exception('Unknown logout handler: '.var_export($logouttype, true));
         }
 
         return new $handler($this);
@@ -461,7 +459,7 @@ class SimpleSAML_IdP
     {
         assert(isset($state['Responder']));
 
-        $idp = SimpleSAML_IdP::getByState($state);
+        $idp = IdP::getByState($state);
         call_user_func($state['Responder'], $idp, $state);
         assert(false);
     }
@@ -486,13 +484,13 @@ class SimpleSAML_IdP
 
         if ($assocId !== null) {
             $this->terminateAssociation($assocId);
-            $session = SimpleSAML_Session::getSessionFromRequest();
+            $session = Session::getSessionFromRequest();
             $session->deleteData('core:idp-ssotime', $this->id.':'.$state['saml:SPEntityId']);
         }
 
         // terminate the local session
-        $id = SimpleSAML_Auth_State::saveState($state, 'core:Logout:afterbridge');
-        $returnTo = SimpleSAML\Module::getModuleURL('core/idp/resumelogout.php', array('id' => $id));
+        $id = Auth\State::saveState($state, 'core:Logout:afterbridge');
+        $returnTo = Module::getModuleURL('core/idp/resumelogout.php', array('id' => $id));
 
         $this->authSource->logout($returnTo);
 
@@ -507,16 +505,16 @@ class SimpleSAML_IdP
      *
      * This function will never return.
      *
-     * @param string                          $assocId The association that is terminated.
-     * @param string|null                     $relayState The RelayState from the start of the logout.
-     * @param SimpleSAML_Error_Exception|null $error The error that occurred during session termination (if any).
+     * @param string                 $assocId The association that is terminated.
+     * @param string|null            $relayState The RelayState from the start of the logout.
+     * @param Exception|null $error  The error that occurred during session termination (if any).
      */
-    public function handleLogoutResponse($assocId, $relayState, SimpleSAML_Error_Exception $error = null)
+    public function handleLogoutResponse($assocId, $relayState, Exception $error = null)
     {
         assert(is_string($assocId));
         assert(is_string($relayState) || $relayState === null);
 
-        $session = SimpleSAML_Session::getSessionFromRequest();
+        $session = Session::getSessionFromRequest();
         $session->deleteData('core:idp-ssotime', $this->id.';'.substr($assocId, strpos($assocId, ':') + 1));
 
         $handler = $this->getLogoutHandler();
@@ -538,7 +536,7 @@ class SimpleSAML_IdP
         assert(is_string($url));
 
         $state = array(
-            'Responder'       => array('SimpleSAML_IdP', 'finishLogoutRedirect'),
+            'Responder'       => array('\SimpleSAML\IdP', 'finishLogoutRedirect'),
             'core:Logout:URL' => $url,
         );
 
@@ -552,14 +550,14 @@ class SimpleSAML_IdP
      *
      * This function never returns.
      *
-     * @param SimpleSAML_IdP $idp Deprecated. Will be removed.
-     * @param array          &$state The logout state from doLogoutRedirect().
+     * @param IdP      $idp Deprecated. Will be removed.
+     * @param array    &$state The logout state from doLogoutRedirect().
      */
-    public static function finishLogoutRedirect(SimpleSAML_IdP $idp, array $state)
+    public static function finishLogoutRedirect(IdP $idp, array $state)
     {
         assert(isset($state['core:Logout:URL']));
 
-        \SimpleSAML\Utils\HTTP::redirectTrustedURL($state['core:Logout:URL']);
+        Utils\HTTP::redirectTrustedURL($state['core:Logout:URL']);
         assert(false);
     }
 }
diff --git a/lib/SimpleSAML/IdP/IFrameLogoutHandler.php b/lib/SimpleSAML/IdP/IFrameLogoutHandler.php
index 23a1daa85e8e7f506dd3f67a18ee67ff18f959f4..e1f4df2ada8ad367faa18bac493ed729a587ce68 100644
--- a/lib/SimpleSAML/IdP/IFrameLogoutHandler.php
+++ b/lib/SimpleSAML/IdP/IFrameLogoutHandler.php
@@ -5,19 +5,18 @@ namespace SimpleSAML\IdP;
 use SimpleSAML\Module;
 use SimpleSAML\Utils\HTTP;
 
-
 /**
  * Class that handles iframe logout.
  *
  * @package SimpleSAMLphp
  */
+
 class IFrameLogoutHandler implements LogoutHandlerInterface
 {
-
     /**
      * The IdP we are logging out from.
      *
-     * @var \SimpleSAML_IdP
+     * @var \SimpleSAML\IdP
      */
     private $idp;
 
@@ -25,9 +24,9 @@ class IFrameLogoutHandler implements LogoutHandlerInterface
     /**
      * LogoutIFrame constructor.
      *
-     * @param \SimpleSAML_IdP $idp The IdP to log out from.
+     * @param \SimpleSAML\IdP $idp The IdP to log out from.
      */
-    public function __construct(\SimpleSAML_IdP $idp)
+    public function __construct(\SimpleSAML\IdP $idp)
     {
         $this->idp = $idp;
     }
@@ -49,7 +48,7 @@ class IFrameLogoutHandler implements LogoutHandlerInterface
         }
 
         foreach ($associations as $id => &$association) {
-            $idp = \SimpleSAML_IdP::getByState($association);
+            $idp = \SimpleSAML\IdP::getByState($association);
             $association['core:Logout-IFrame:Name'] = $idp->getSPName($id);
             $association['core:Logout-IFrame:State'] = 'onhold';
         }
@@ -67,7 +66,7 @@ class IFrameLogoutHandler implements LogoutHandlerInterface
         }
 
         $params = array(
-            'id' => \SimpleSAML_Auth_State::saveState($state, 'core:Logout-IFrame'),
+            'id' => \SimpleSAML\Auth\State::saveState($state, 'core:Logout-IFrame'),
         );
         if (isset($state['core:Logout-IFrame:InitType'])) {
             $params['type'] = $state['core:Logout-IFrame:InitType'];
@@ -85,9 +84,9 @@ class IFrameLogoutHandler implements LogoutHandlerInterface
      *
      * @param string $assocId The association that is terminated.
      * @param string|null $relayState The RelayState from the start of the logout.
-     * @param \SimpleSAML_Error_Exception|null $error The error that occurred during session termination (if any).
+     * @param \SimpleSAML\Error\Exception|null $error The error that occurred during session termination (if any).
      */
-    public function onResponse($assocId, $relayState, \SimpleSAML_Error_Exception $error = null)
+    public function onResponse($assocId, $relayState, \SimpleSAML\Error\Exception $error = null)
     {
         assert(is_string($assocId));
 
diff --git a/lib/SimpleSAML/IdP/LogoutHandlerInterface.php b/lib/SimpleSAML/IdP/LogoutHandlerInterface.php
index 11589f3d0f56478e114f30b6fbac115fc67a13bb..773bda69470d21ac329985931c57df989e9da1da 100644
--- a/lib/SimpleSAML/IdP/LogoutHandlerInterface.php
+++ b/lib/SimpleSAML/IdP/LogoutHandlerInterface.php
@@ -2,22 +2,20 @@
 
 namespace SimpleSAML\IdP;
 
-
 /**
  * Interface that all logout handlers must implement.
  *
  * @package SimpleSAMLphp
  */
+
 interface LogoutHandlerInterface
 {
-
-
     /**
      * Initialize this logout handler.
      *
-     * @param \SimpleSAML_IdP $idp The IdP we are logging out from.
+     * @param \SimpleSAML\IdP $idp The IdP we are logging out from.
      */
-    public function __construct(\SimpleSAML_IdP $idp);
+    public function __construct(\SimpleSAML\IdP $idp);
 
 
     /**
@@ -38,7 +36,7 @@ interface LogoutHandlerInterface
      *
      * @param string $assocId The association that is terminated.
      * @param string|null $relayState The RelayState from the start of the logout.
-     * @param \SimpleSAML_Error_Exception|null $error The error that occurred during session termination (if any).
+     * @param \SimpleSAML\Error\Exception|null $error The error that occurred during session termination (if any).
      */
-    public function onResponse($assocId, $relayState, \SimpleSAML_Error_Exception $error = null);
+    public function onResponse($assocId, $relayState, \SimpleSAML\Error\Exception $error = null);
 }
diff --git a/lib/SimpleSAML/IdP/TraditionalLogoutHandler.php b/lib/SimpleSAML/IdP/TraditionalLogoutHandler.php
index 864163d4dc683a603474a8867dfc0335d3981061..37218ea88bb41ef8d6a549fe7f0d11fe74972b80 100644
--- a/lib/SimpleSAML/IdP/TraditionalLogoutHandler.php
+++ b/lib/SimpleSAML/IdP/TraditionalLogoutHandler.php
@@ -5,19 +5,18 @@ namespace SimpleSAML\IdP;
 use SimpleSAML\Logger;
 use SimpleSAML\Utils\HTTP;
 
-
 /**
  * Class that handles traditional logout.
  *
  * @package SimpleSAMLphp
  */
+
 class TraditionalLogoutHandler implements LogoutHandlerInterface
 {
-
     /**
      * The IdP we are logging out from.
      *
-     * @var \SimpleSAML_IdP
+     * @var \SimpleSAML\IdP
      */
     private $idp;
 
@@ -25,9 +24,9 @@ class TraditionalLogoutHandler implements LogoutHandlerInterface
     /**
      * TraditionalLogout constructor.
      *
-     * @param \SimpleSAML_IdP $idp The IdP to log out from.
+     * @param \SimpleSAML\IdP $idp The IdP to log out from.
      */
-    public function __construct(\SimpleSAML_IdP $idp)
+    public function __construct(\SimpleSAML\IdP $idp)
     {
         $this->idp = $idp;
     }
@@ -47,13 +46,13 @@ class TraditionalLogoutHandler implements LogoutHandlerInterface
             $this->idp->finishLogout($state);
         }
 
-        $relayState = \SimpleSAML_Auth_State::saveState($state, 'core:LogoutTraditional', true);
+        $relayState = \SimpleSAML\Auth\State::saveState($state, 'core:LogoutTraditional', true);
 
         $id = $association['id'];
         Logger::info('Logging out of '.var_export($id, true).'.');
 
         try {
-            $idp = \SimpleSAML_IdP::getByState($association);
+            $idp = \SimpleSAML\IdP::getByState($association);
             $url = call_user_func(array($association['Handler'], 'getLogoutURL'), $idp, $association, $relayState);
             HTTP::redirectTrustedURL($url);
         } catch (\Exception $e) {
@@ -80,7 +79,7 @@ class TraditionalLogoutHandler implements LogoutHandlerInterface
     {
         $state['core:LogoutTraditional:Remaining'] = $this->idp->getAssociations();
 
-        self::logoutNextSP($state);
+        $this->logoutNextSP($state);
     }
 
 
@@ -91,20 +90,20 @@ class TraditionalLogoutHandler implements LogoutHandlerInterface
      *
      * @param string $assocId The association that is terminated.
      * @param string|null $relayState The RelayState from the start of the logout.
-     * @param \SimpleSAML_Error_Exception|null $error The error that occurred during session termination (if any).
+     * @param \SimpleSAML\Error\Exception|null $error The error that occurred during session termination (if any).
      *
-     * @throws \SimpleSAML_Error_Exception If the RelayState was lost during logout.
+     * @throws \SimpleSAML\Error\Exception If the RelayState was lost during logout.
      */
-    public function onResponse($assocId, $relayState, \SimpleSAML_Error_Exception $error = null)
+    public function onResponse($assocId, $relayState, \SimpleSAML\Error\Exception $error = null)
     {
         assert(is_string($assocId));
         assert(is_string($relayState) || $relayState === null);
 
         if ($relayState === null) {
-            throw new \SimpleSAML_Error_Exception('RelayState lost during logout.');
+            throw new \SimpleSAML\Error\Exception('RelayState lost during logout.');
         }
 
-        $state = \SimpleSAML_Auth_State::loadState($relayState, 'core:LogoutTraditional');
+        $state = \SimpleSAML\Auth\State::loadState($relayState, 'core:LogoutTraditional');
 
         if ($error === null) {
             Logger::info('Logged out of '.var_export($assocId, true).'.');
@@ -115,6 +114,6 @@ class TraditionalLogoutHandler implements LogoutHandlerInterface
             $state['core:Failed'] = true;
         }
 
-        self::logoutNextSP($state);
+        $this->logoutNextSP($state);
     }
 }
diff --git a/lib/SimpleSAML/Locale/Language.php b/lib/SimpleSAML/Locale/Language.php
index 9e5696cec3a93b8290b36fbca28120c98e912d85..9e893c113e8ec6593c2269499bf60a8c19a71bf4 100644
--- a/lib/SimpleSAML/Locale/Language.php
+++ b/lib/SimpleSAML/Locale/Language.php
@@ -23,7 +23,7 @@ class Language
     /**
      * The configuration to use.
      *
-     * @var \SimpleSAML_Configuration
+     * @var \SimpleSAML\Configuration
      */
     private $configuration;
 
@@ -133,9 +133,9 @@ class Language
     /**
      * Constructor
      *
-     * @param \SimpleSAML_Configuration $configuration Configuration object
+     * @param \SimpleSAML\Configuration $configuration Configuration object
      */
-    public function __construct(\SimpleSAML_Configuration $configuration)
+    public function __construct(\SimpleSAML\Configuration $configuration)
     {
         $this->configuration = $configuration;
         $this->availableLanguages = $this->getInstalledLanguages();
@@ -376,7 +376,7 @@ class Language
      */
     public static function getLanguageCookie()
     {
-        $config = \SimpleSAML_Configuration::getInstance();
+        $config = \SimpleSAML\Configuration::getInstance();
         $availableLanguages = $config->getArray('language.available', array('en'));
         $name = $config->getString('language.cookie.name', 'language');
 
@@ -402,7 +402,7 @@ class Language
         assert(is_string($language));
 
         $language = strtolower($language);
-        $config = \SimpleSAML_Configuration::getInstance();
+        $config = \SimpleSAML\Configuration::getInstance();
         $availableLanguages = $config->getArray('language.available', array('en'));
 
         if (!in_array($language, $availableLanguages, true) || headers_sent()) {
diff --git a/lib/SimpleSAML/Locale/Localization.php b/lib/SimpleSAML/Locale/Localization.php
index 1fc1cb74bd4a73d4da96119ff6b908980d455fc6..355d9594a095ffd0b0c4730d77ac54a7e2081a3c 100644
--- a/lib/SimpleSAML/Locale/Localization.php
+++ b/lib/SimpleSAML/Locale/Localization.php
@@ -14,11 +14,10 @@ use Gettext\Translator;
 
 class Localization
 {
-
     /**
      * The configuration to use.
      *
-     * @var \SimpleSAML_Configuration
+     * @var \SimpleSAML\Configuration
      */
     private $configuration;
 
@@ -37,28 +36,43 @@ class Localization
      */
     const GETTEXT_I18N_BACKEND = 'gettext/gettext';
 
-    /*
+    /**
      * The default locale directory
      */
     private $localeDir;
 
-    /*
+    /**
      * Where specific domains are stored
      */
     private $localeDomainMap = array();
 
-    /*
+    /**
      * Pointer to currently active translator
      */
     private $translator;
 
+    /**
+     * Pointer to current Language
+     */
+    private $language;
+
+    /**
+     * Language code representing the current Language
+     */
+    private $langcode;
+
+
+    /**
+     * The language backend to use
+     */
+    public $i18nBackend;
 
     /**
      * Constructor
      *
-     * @param \SimpleSAML_Configuration $configuration Configuration object
+     * @param \SimpleSAML\Configuration $configuration Configuration object
      */
-    public function __construct(\SimpleSAML_Configuration $configuration)
+    public function __construct(\SimpleSAML\Configuration $configuration)
     {
         $this->configuration = $configuration;
         $this->localeDir = $this->configuration->resolvePath('locales');
@@ -248,5 +262,4 @@ class Localization
     {
         return $this->localeDomainMap;
     }
-
 }
diff --git a/lib/SimpleSAML/Locale/Translate.php b/lib/SimpleSAML/Locale/Translate.php
index 9cb0000bd8ebe9835a5ff2985e163a46aed44c5a..e96cd78f110c0a40c8fdc352c75f5c898500582b 100644
--- a/lib/SimpleSAML/Locale/Translate.php
+++ b/lib/SimpleSAML/Locale/Translate.php
@@ -12,11 +12,10 @@ namespace SimpleSAML\Locale;
 
 class Translate
 {
-
     /**
      * The configuration to be used for this translator.
      *
-     * @var \SimpleSAML_Configuration
+     * @var \SimpleSAML\Configuration
      */
     private $configuration;
 
@@ -43,10 +42,10 @@ class Translate
     /**
      * Constructor
      *
-     * @param \SimpleSAML_Configuration $configuration Configuration object
+     * @param \SimpleSAML\Configuration $configuration Configuration object
      * @param string|null               $defaultDictionary The default dictionary where tags will come from.
      */
-    public function __construct(\SimpleSAML_Configuration $configuration, $defaultDictionary = null)
+    public function __construct(\SimpleSAML\Configuration $configuration, $defaultDictionary = null)
     {
         $this->configuration = $configuration;
         $this->language = new Language($configuration);
@@ -259,9 +258,12 @@ class Translate
     public function t(
         $tag,
         $replacements = array(),
-        $fallbackdefault = true, // TODO: remove this for 2.0. Assume true
-        $oldreplacements = array(), // TODO: remove this for 2.0
-        $striptags = false // TODO: remove this for 2.0
+        // TODO: remove this for 2.0. Assume true
+        $fallbackdefault = true,
+        // TODO: remove this for 2.0
+        $oldreplacements = array(),
+        // TODO: remove this for 2.0
+        $striptags = false
     ) {
         $backtrace = debug_backtrace();
         $where = $backtrace[0]['file'].':'.$backtrace[0]['line'];
@@ -366,7 +368,7 @@ class Translate
      * Include a language file from the dictionaries directory.
      *
      * @param string                         $file File name of dictionary to include
-     * @param \SimpleSAML_Configuration|null $otherConfig Optionally provide a different configuration object than the
+     * @param \SimpleSAML\Configuration|null $otherConfig Optionally provide a different configuration object than the
      * one provided in the constructor to be used to find the directory of the dictionary. This allows to combine
      * dictionaries inside the SimpleSAMLphp main code distribution together with external dictionaries. Defaults to
      * null.
@@ -524,10 +526,10 @@ class Translate
         }
 
         // we don't have a translation for the current language, load alternative priorities
-        $sspcfg = \SimpleSAML_Configuration::getInstance();
+        $sspcfg = \SimpleSAML\Configuration::getInstance();
         $langcfg = $sspcfg->getConfigItem('language', null);
         $priorities = array();
-        if ($langcfg instanceof \SimpleSAML_Configuration) {
+        if ($langcfg instanceof \SimpleSAML\Configuration) {
             $priorities = $langcfg->getArray('priorities', array());
         }
 
diff --git a/lib/SimpleSAML/Logger.php b/lib/SimpleSAML/Logger.php
index 8c121bbb9fba3ded150aef20693556f47feedb1c..3c569a1faf9eee0c94975ade725f50e0ede194db 100644
--- a/lib/SimpleSAML/Logger.php
+++ b/lib/SimpleSAML/Logger.php
@@ -2,7 +2,6 @@
 
 namespace SimpleSAML;
 
-
 /**
  * The main logger class for SimpleSAMLphp.
  *
@@ -10,11 +9,9 @@ namespace SimpleSAML;
  * @author Andreas Ă…kre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
  * @author Jaime Pérez Crespo, UNINETT AS <jaime.perez@uninett.no>
  * @package SimpleSAMLphp
- * @version $ID$
  */
 class Logger
 {
-
     /**
      * @var \SimpleSAML\Logger\LoggingHandlerInterface|false|null
      */
@@ -268,11 +265,11 @@ class Logger
     public static function flush()
     {
         try {
-            $s = \SimpleSAML_Session::getSessionFromRequest();
+            $s = Session::getSessionFromRequest();
         } catch (\Exception $e) {
             // loading session failed. We don't care why, at this point we have a transient session, so we use that
             self::error('Cannot load or create session: '.$e->getMessage());
-            $s = \SimpleSAML_Session::getSessionFromRequest();
+            $s = Session::getSessionFromRequest();
         }
         self::$trackid = $s->getTrackID();
 
@@ -362,8 +359,8 @@ class Logger
         );
 
         // get the configuration
-        $config = \SimpleSAML_Configuration::getInstance();
-        assert($config instanceof \SimpleSAML_Configuration);
+        $config = Configuration::getInstance();
+        assert($config instanceof Configuration);
 
         // setting minimum log_level
         self::$logLevel = $config->getInteger('logging.level', self::INFO);
@@ -373,7 +370,7 @@ class Logger
             $handler = $config->getString('logging.handler', 'syslog');
         }
 
-        if (class_exists($handler)) {
+        if (!array_key_exists($handler, $known_handlers) && class_exists($handler)) {
             if (!in_array('SimpleSAML\Logger\LoggingHandlerInterface', class_implements($handler), true)) {
                 throw new \Exception("The logging handler '$handler' is invalid.");
             }
diff --git a/lib/SimpleSAML/Logger/ErrorLogLoggingHandler.php b/lib/SimpleSAML/Logger/ErrorLogLoggingHandler.php
index 845103cf2dc4c0f6108d81331c85e684ecc3aaf1..9af1f63bc7caf1f8ef8cc36e56af63e83e2b71aa 100644
--- a/lib/SimpleSAML/Logger/ErrorLogLoggingHandler.php
+++ b/lib/SimpleSAML/Logger/ErrorLogLoggingHandler.php
@@ -14,7 +14,6 @@ use SimpleSAML\Logger;
  */
 class ErrorLogLoggingHandler implements LoggingHandlerInterface
 {
-
     /**
      * This array contains the mappings from syslog log level to names.
      */
@@ -40,9 +39,9 @@ class ErrorLogLoggingHandler implements LoggingHandlerInterface
     /**
      * ErrorLogLoggingHandler constructor.
      *
-     * @param \SimpleSAML_Configuration $config The configuration object for this handler.
+     * @param \SimpleSAML\Configuration $config The configuration object for this handler.
      */
-    public function __construct(\SimpleSAML_Configuration $config)
+    public function __construct(\SimpleSAML\Configuration $config)
     {
         $this->processname = $config->getString('logging.processname', 'SimpleSAMLphp');
     }
diff --git a/lib/SimpleSAML/Logger/FileLoggingHandler.php b/lib/SimpleSAML/Logger/FileLoggingHandler.php
index 475541f1bfdd60bcbfa699dbe6d3305b28d0f2a0..beb9e27bbac46b69ced81cfa42f5426eb03b7986 100644
--- a/lib/SimpleSAML/Logger/FileLoggingHandler.php
+++ b/lib/SimpleSAML/Logger/FileLoggingHandler.php
@@ -42,7 +42,7 @@ class FileLoggingHandler implements LoggingHandlerInterface
     /**
      * Build a new logging handler based on files.
      */
-    public function __construct(\SimpleSAML_Configuration $config)
+    public function __construct(\SimpleSAML\Configuration $config)
     {
         // get the metadata handler option from the configuration
         $this->logFile = $config->getPathValue('loggingdir', 'log/').
@@ -107,7 +107,7 @@ class FileLoggingHandler implements LoggingHandlerInterface
             }
 
             $string = str_replace($formats, $replacements, $string);
-            file_put_contents($this->logFile, $string.PHP_EOL, FILE_APPEND);
+            file_put_contents($this->logFile, $string.\PHP_EOL, FILE_APPEND);
         }
     }
 }
diff --git a/lib/SimpleSAML/Logger/LoggingHandlerInterface.php b/lib/SimpleSAML/Logger/LoggingHandlerInterface.php
index c7b00eb01a125423972f195eeff8530471b80496..a9b939ddd0b7b2c6356766faa8634d8ec8164a2e 100644
--- a/lib/SimpleSAML/Logger/LoggingHandlerInterface.php
+++ b/lib/SimpleSAML/Logger/LoggingHandlerInterface.php
@@ -13,11 +13,11 @@ interface LoggingHandlerInterface
 {
 
     /**
-     * Constructor for log handlers. It must accept receiving a \SimpleSAML_Configuration object.
+     * Constructor for log handlers. It must accept receiving a \SimpleSAML\Configuration object.
      *
-     * @param \SimpleSAML_Configuration $config The configuration to use in this log handler.
+     * @param \SimpleSAML\Configuration $config The configuration to use in this log handler.
      */
-    public function __construct(\SimpleSAML_Configuration $config);
+    public function __construct(\SimpleSAML\Configuration $config);
 
 
     /**
diff --git a/lib/SimpleSAML/Logger/StandardErrorLoggingHandler.php b/lib/SimpleSAML/Logger/StandardErrorLoggingHandler.php
index 0f35fcf54be79b4ceae982a94cc26b8e44aeec3a..3413e68cea3f4cb0e965c32e9ac899a8126aad57 100644
--- a/lib/SimpleSAML/Logger/StandardErrorLoggingHandler.php
+++ b/lib/SimpleSAML/Logger/StandardErrorLoggingHandler.php
@@ -16,7 +16,7 @@ class StandardErrorLoggingHandler extends FileLoggingHandler
      *
      * It runs the parent constructor and sets the log file to be the standard error descriptor.
      */
-    public function __construct(\SimpleSAML_Configuration $config)
+    public function __construct(\SimpleSAML\Configuration $config)
     {
         $this->processname = $config->getString('logging.processname', 'SimpleSAMLphp');
         $this->logFile = 'php://stderr';
diff --git a/lib/SimpleSAML/Logger/SyslogLoggingHandler.php b/lib/SimpleSAML/Logger/SyslogLoggingHandler.php
index ce2739798e3d1b74da2dabed99046be18cb37eb3..0330c3d134b53c8a7fd32ae846eaf2195814d9bd 100644
--- a/lib/SimpleSAML/Logger/SyslogLoggingHandler.php
+++ b/lib/SimpleSAML/Logger/SyslogLoggingHandler.php
@@ -20,7 +20,7 @@ class SyslogLoggingHandler implements LoggingHandlerInterface
     /**
      * Build a new logging handler based on syslog.
      */
-    public function __construct(\SimpleSAML_Configuration $config)
+    public function __construct(\SimpleSAML\Configuration $config)
     {
         $facility = $config->getInteger('logging.facility', defined('LOG_LOCAL5') ? constant('LOG_LOCAL5') : LOG_USER);
 
diff --git a/lib/SimpleSAML/Memcache.php b/lib/SimpleSAML/Memcache.php
index 65f2cba99d36fdf87b827836a1c2b89c0bd2a80d..ab53ad46cd6c7fe594d84b9c04d0cec6b52091d9 100644
--- a/lib/SimpleSAML/Memcache.php
+++ b/lib/SimpleSAML/Memcache.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML;
 
 /**
  * This file implements functions to read and write to a group of memcache
@@ -17,9 +18,9 @@
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Memcache
-{
 
+class Memcache
+{
     /**
      * Cache of the memcache servers we are using.
      *
@@ -28,11 +29,11 @@ class SimpleSAML_Memcache
     private static $serverGroups = null;
 
 
-  /**
-   * The flavor of memcache PHP extension we are using.
-   *
-   * @var string
-   */
+   /**
+    * The flavor of memcache PHP extension we are using.
+    *
+    * @var string
+    */
     private static $extension = '';
 
 
@@ -45,7 +46,7 @@ class SimpleSAML_Memcache
      */
     public static function get($key)
     {
-        SimpleSAML\Logger::debug("loading key $key from memcache");
+        \SimpleSAML\Logger::debug("loading key $key from memcache");
 
         $latestInfo = null;
         $latestTime = 0.0;
@@ -76,19 +77,19 @@ class SimpleSAML_Memcache
              * - 'data': The data.
              */
             if (!is_array($info)) {
-                SimpleSAML\Logger::warning(
+                \SimpleSAML\Logger::warning(
                     'Retrieved invalid data from a memcache server. Data was not an array.'
                 );
                 continue;
             }
             if (!array_key_exists('timestamp', $info)) {
-                SimpleSAML\Logger::warning(
+                \SimpleSAML\Logger::warning(
                     'Retrieved invalid data from a memcache server. Missing timestamp.'
                 );
                 continue;
             }
             if (!array_key_exists('data', $info)) {
-                SimpleSAML\Logger::warning(
+                \SimpleSAML\Logger::warning(
                     'Retrieved invalid data from a memcache server. Missing data.'
                 );
                 continue;
@@ -121,17 +122,17 @@ class SimpleSAML_Memcache
         if ($latestData === null) {
             if ($allDown) {
                 // all servers are down, panic!
-                $e = new SimpleSAML_Error_Error('MEMCACHEDOWN', null, 503);
-                throw new SimpleSAML_Error_Exception('All memcache servers are down', 503, $e);
+                $e = new \SimpleSAML\Error\Error('MEMCACHEDOWN', null, 503);
+                throw new \SimpleSAML\Error\Exception('All memcache servers are down', 503, $e);
             }
             // we didn't find any data matching the key
-            SimpleSAML\Logger::debug("key $key not found in memcache");
+            \SimpleSAML\Logger::debug("key $key not found in memcache");
             return null;
         }
 
         if ($mustUpdate) {
             // we found data matching the key, but some of the servers need updating
-            SimpleSAML\Logger::debug("Memcache servers out of sync for $key, forcing sync");
+            \SimpleSAML\Logger::debug("Memcache servers out of sync for $key, forcing sync");
             self::set($key, $latestData);
         }
 
@@ -148,7 +149,7 @@ class SimpleSAML_Memcache
      */
     public static function set($key, $value, $expire = null)
     {
-        SimpleSAML\Logger::debug("saving key $key to memcache");
+        \SimpleSAML\Logger::debug("saving key $key to memcache");
         $savedInfo = array(
             'timestamp' => microtime(true),
             'data'      => $value
@@ -162,10 +163,9 @@ class SimpleSAML_Memcache
 
         // store this object to all groups of memcache servers
         foreach (self::getMemcacheServers() as $server) {
-            if (self::$extension === 'memcached') {
+            if (self::$extension === '\memcached') {
                 $server->set($key, $savedInfoSerialized, $expire);
-            }
-            else {
+            } else {
                 $server->set($key, $savedInfoSerialized, 0, $expire);
             }
         }
@@ -180,7 +180,7 @@ class SimpleSAML_Memcache
     public static function delete($key)
     {
         assert(is_string($key));
-        SimpleSAML\Logger::debug("deleting key $key from memcache");
+        \SimpleSAML\Logger::debug("deleting key $key from memcache");
 
         // store this object to all groups of memcache servers
         foreach (self::getMemcacheServers() as $server) {
@@ -207,16 +207,16 @@ class SimpleSAML_Memcache
      *    The timeout for contacting this server, in seconds.
      *    The default value is 3 seconds.
      *
-     * @param Memcache $memcache The Memcache object we should add this server to.
+     * @param \Memcache $memcache The Memcache object we should add this server to.
      * @param array    $server An associative array with the configuration options for the server to add.
      *
-     * @throws Exception If any configuration option for the server is invalid.
+     * @throws \Exception If any configuration option for the server is invalid.
      */
     private static function addMemcacheServer($memcache, $server)
     {
         // the hostname option is required
         if (!array_key_exists('hostname', $server)) {
-            throw new Exception(
+            throw new \Exception(
                 "hostname setting missing from server in the 'memcache_store.servers' configuration option."
             );
         }
@@ -225,7 +225,7 @@ class SimpleSAML_Memcache
 
         // the hostname must be a valid string
         if (!is_string($hostname)) {
-            throw new Exception(
+            throw new \Exception(
                 "Invalid hostname for server in the 'memcache_store.servers' configuration option. The hostname is".
                 ' supposed to be a string.'
             );
@@ -245,7 +245,7 @@ class SimpleSAML_Memcache
             // get the port number from the array, and validate it
             $port = (int) $server['port'];
             if (($port <= 0) || ($port > 65535)) {
-                throw new Exception(
+                throw new \Exception(
                     "Invalid port for server in the 'memcache_store.servers' configuration option. The port number".
                     ' is supposed to be an integer between 0 and 65535.'
                 );
@@ -264,7 +264,7 @@ class SimpleSAML_Memcache
             // get the weight and validate it
             $weight = (int) $server['weight'];
             if ($weight <= 0) {
-                throw new Exception(
+                throw new \Exception(
                     "Invalid weight for server in the 'memcache_store.servers' configuration option. The weight is".
                     ' supposed to be a positive integer.'
                 );
@@ -279,7 +279,7 @@ class SimpleSAML_Memcache
             // get the timeout and validate it
             $timeout = (int) $server['timeout'];
             if ($timeout <= 0) {
-                throw new Exception(
+                throw new \Exception(
                     "Invalid timeout for server in the 'memcache_store.servers' configuration option. The timeout is".
                     ' supposed to be a positive integer.'
                 );
@@ -290,7 +290,7 @@ class SimpleSAML_Memcache
         }
 
         // add this server to the Memcache object
-        if (self::$extension === 'memcached') {
+        if (self::$extension === '\memcached') {
             $memcache->addServer($hostname, $port);
         } else {
             $memcache->addServer($hostname, $port, true, $weight, $timeout, $timeout, true);
@@ -304,26 +304,26 @@ class SimpleSAML_Memcache
      *
      * @param array $group Array of servers which should be created as a group.
      *
-     * @return Memcache A Memcache object of the servers in the group
+     * @return \Memcache A Memcache object of the servers in the group
      *
-     * @throws Exception If the servers configuration is invalid.
+     * @throws \Exception If the servers configuration is invalid.
      */
     private static function loadMemcacheServerGroup(array $group)
     {
-        $class = class_exists('Memcache') ? 'Memcache' : (class_exists('Memcached') ? 'Memcached' : FALSE);
+        $class = class_exists('\Memcache') ? '\Memcache' : (class_exists('\Memcached') ? '\Memcached' : false);
         if (!$class) {
-            throw new Exception('Missing Memcached implementation. You must install either the Memcache or Memcached extension.');
+            throw new \Exception('Missing Memcached implementation. You must install either the Memcache or Memcached extension.');
         }
         self::$extension = strtolower($class);
 
-        // create the Memcache object
+        // create the \Memcache object
         $memcache = new $class();
 
         // iterate over all the servers in the group and add them to the Memcache object
         foreach ($group as $index => $server) {
             // make sure that we don't have an index. An index would be a sign of invalid configuration
             if (!is_int($index)) {
-                throw new Exception(
+                throw new \Exception(
                     "Invalid index on element in the 'memcache_store.servers' configuration option. Perhaps you".
                     ' have forgotten to add an array(...) around one of the server groups? The invalid index was: '.
                     $index
@@ -332,7 +332,7 @@ class SimpleSAML_Memcache
 
             // make sure that the server object is an array. Each server is an array with name-value pairs
             if (!is_array($server)) {
-                throw new Exception(
+                throw new \Exception(
                     'Invalid value for the server with index '.$index.
                     '. Remeber that the \'memcache_store.servers\' configuration option'.
                     ' contains an array of arrays of arrays.'
@@ -350,9 +350,9 @@ class SimpleSAML_Memcache
      * This function gets a list of all configured memcache servers. This list is initialized based
      * on the content of 'memcache_store.servers' in the configuration.
      *
-     * @return Memcache[] Array with Memcache objects.
+     * @return \Memcache[] Array with Memcache objects.
      *
-     * @throws Exception If the servers configuration is invalid.
+     * @throws \Exception If the servers configuration is invalid.
      */
     private static function getMemcacheServers()
     {
@@ -365,7 +365,7 @@ class SimpleSAML_Memcache
         self::$serverGroups = array();
 
         // load the configuration
-        $config = SimpleSAML_Configuration::getInstance();
+        $config = \SimpleSAML\Configuration::getInstance();
 
 
         $groups = $config->getArray('memcache_store.servers');
@@ -374,7 +374,7 @@ class SimpleSAML_Memcache
         foreach ($groups as $index => $group) {
             // make sure that the group doesn't have an index. An index would be a sign of invalid configuration
             if (!is_int($index)) {
-                throw new Exception(
+                throw new \Exception(
                     "Invalid index on element in the 'memcache_store.servers'".
                     ' configuration option. Perhaps you have forgotten to add an array(...)'.
                     ' around one of the server groups? The invalid index was: '.$index
@@ -386,7 +386,7 @@ class SimpleSAML_Memcache
              * an array of name => value pairs for that server.
              */
             if (!is_array($group)) {
-                throw new Exception(
+                throw new \Exception(
                     "Invalid value for the server with index ".$index.
                     ". Remeber that the 'memcache_store.servers' configuration option".
                     ' contains an array of arrays of arrays.'
@@ -411,20 +411,20 @@ class SimpleSAML_Memcache
      *
      * @return integer The value which should be passed in the set(...) calls to the memcache objects.
      *
-     * @throws Exception If the option 'memcache_store.expires' has a negative value.
+     * @throws \Exception If the option 'memcache_store.expires' has a negative value.
      */
     private static function getExpireTime()
     {
         // get the configuration instance
-        $config = SimpleSAML_Configuration::getInstance();
-        assert($config instanceof SimpleSAML_Configuration);
+        $config = \SimpleSAML\Configuration::getInstance();
+        assert($config instanceof \SimpleSAML\Configuration);
 
         // get the expire-value from the configuration
         $expire = $config->getInteger('memcache_store.expires', 0);
 
         // it must be a positive integer
         if ($expire < 0) {
-            throw new Exception(
+            throw new \Exception(
                 "The value of 'memcache_store.expires' in the configuration can't be a negative integer."
             );
         }
@@ -450,21 +450,21 @@ class SimpleSAML_Memcache
      *
      * @return array Array with the names of each stat and an array with the value for each server group.
      *
-     * @throws Exception If memcache server status couldn't be retrieved.
+     * @throws \Exception If memcache server status couldn't be retrieved.
      */
     public static function getStats()
     {
         $ret = array();
 
         foreach (self::getMemcacheServers() as $sg) {
-            $stats = $sg->getExtendedStats();
+            $stats = method_exists($sg, 'getExtendedStats') ? $sg->getExtendedStats() : $sg->getStats();
             foreach ($stats as $server => $data) {
                 if ($data === false) {
-                    throw new Exception('Failed to get memcache server status.');
+                    throw new \Exception('Failed to get memcache server status.');
                 }
             }
 
-            $stats = SimpleSAML\Utils\Arrays::transpose($stats);
+            $stats = \SimpleSAML\Utils\Arrays::transpose($stats);
 
             $ret = array_merge_recursive($ret, $stats);
         }
@@ -484,11 +484,10 @@ class SimpleSAML_Memcache
         $ret = array();
 
         foreach (self::getMemcacheServers() as $sg) {
-            $stats = $sg->getExtendedStats();
+            $stats = method_exists($sg, 'getExtendedStats') ? $sg->getExtendedStats() : $sg->getStats();
             $ret[] = $stats;
         }
 
         return $ret;
     }
-
 }
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php
index 95f23244914728ffa8d9ab4ea5b801c108d0ba6f..426d3cc630f9c8c4af0c60e6853c13cca2f5841f 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML\Metadata;
 
 /**
  * This file defines a class for metadata handling.
@@ -7,16 +8,15 @@
  * @author Andreas Ă…kre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Metadata_MetaDataStorageHandler
-{
-
 
+class MetaDataStorageHandler
+{
     /**
      * This static variable contains a reference to the current
      * instance of the metadata handler. This variable will be null if
      * we haven't instantiated a metadata handler yet.
      *
-     * @var SimpleSAML_Metadata_MetaDataStorageHandler
+     * @var MetaDataStorageHandler
      */
     private static $metadataHandler = null;
 
@@ -25,7 +25,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
      * This is a list of all the metadata sources we have in our metadata
      * chain. When we need metadata, we will look through this chain from start to end.
      *
-     * @var SimpleSAML_Metadata_MetaDataStorageSource[]
+     * @var MetaDataStorageSource[]
      */
     private $sources;
 
@@ -35,12 +35,12 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
      * The metadata handler will be instantiated if this is the first call
      * to this function.
      *
-     * @return SimpleSAML_Metadata_MetaDataStorageHandler The current metadata handler instance.
+     * @return MetaDataStorageHandler The current metadata handler instance.
      */
     public static function getMetadataHandler()
     {
         if (self::$metadataHandler === null) {
-            self::$metadataHandler = new SimpleSAML_Metadata_MetaDataStorageHandler();
+            self::$metadataHandler = new MetaDataStorageHandler();
         }
 
         return self::$metadataHandler;
@@ -53,7 +53,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
      */
     protected function __construct()
     {
-        $config = SimpleSAML_Configuration::getInstance();
+        $config = \SimpleSAML\Configuration::getInstance();
 
         $sourcesConfig = $config->getArray('metadata.sources', null);
 
@@ -64,9 +64,9 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
         }
 
         try {
-            $this->sources = SimpleSAML_Metadata_MetaDataStorageSource::parseSources($sourcesConfig);
-        } catch (Exception $e) {
-            throw new Exception(
+            $this->sources = MetaDataStorageSource::parseSources($sourcesConfig);
+        } catch (\Exception $e) {
+            throw new \Exception(
                 "Invalid configuration of the 'metadata.sources' configuration option: ".$e->getMessage()
             );
         }
@@ -80,7 +80,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
      * @param string $set The set we the property comes from.
      *
      * @return string The auto-generated metadata property.
-     * @throws Exception If the metadata cannot be generated automatically.
+     * @throws \Exception If the metadata cannot be generated automatically.
      */
     public function getGenerated($property, $set)
     {
@@ -90,13 +90,13 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
             if (array_key_exists($property, $metadataSet)) {
                 return $metadataSet[$property];
             }
-        } catch (Exception $e) {
+        } catch (\Exception $e) {
             // probably metadata wasn't found. In any case we continue by generating the metadata
         }
 
         // get the configuration
-        $config = SimpleSAML_Configuration::getInstance();
-        assert($config instanceof SimpleSAML_Configuration);
+        $config = \SimpleSAML\Configuration::getInstance();
+        assert($config instanceof \SimpleSAML\Configuration);
 
         $baseurl = \SimpleSAML\Utils\HTTP::getSelfURLHost().$config->getBasePath();
 
@@ -124,7 +124,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
             }
         }
 
-        throw new Exception('Could not generate metadata property '.$property.' for set '.$set.'.');
+        throw new \Exception('Could not generate metadata property '.$property.' for set '.$set.'.');
     }
 
 
@@ -149,9 +149,9 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
                 if (array_key_exists('expire', $le)) {
                     if ($le['expire'] < time()) {
                         unset($srcList[$key]);
-                        SimpleSAML\Logger::warning(
+                        \SimpleSAML\Logger::warning(
                             "Dropping metadata entity ".var_export($key, true).", expired ".
-                            SimpleSAML\Utils\Time::generateTimestamp($le['expire'])."."
+                            \SimpleSAML\Utils\Time::generateTimestamp($le['expire'])."."
                         );
                     }
                 }
@@ -189,7 +189,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
      * @param string $type Do you want to return the metaindex or the entityID. [entityid|metaindex]
      *
      * @return string The entity id which is associated with the current hostname/path combination.
-     * @throws Exception If no default metadata can be found in the set for the current host.
+     * @throws \Exception If no default metadata can be found in the set for the current host.
      */
     public function getMetaDataCurrentEntityID($set, $type = 'entityid')
     {
@@ -224,7 +224,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
         }
 
         // we were unable to find the hostname/path in any metadata source
-        throw new Exception(
+        throw new \Exception(
             'Could not find any default metadata entities in set ['.$set.'] for host ['.$currenthost.' : '.
             $currenthostwithpath.']'
         );
@@ -263,8 +263,8 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
      * @param string $set The set of metadata we are looking up the entity id in.
      *
      * @return array The metadata array describing the specified entity.
-     * @throws Exception If metadata for the specified entity is expired.
-     * @throws SimpleSAML_Error_MetadataNotFound If no metadata for the entity specified can be found.
+     * @throws \Exception If metadata for the specified entity is expired.
+     * @throws \SimpleSAML\Error\MetadataNotFound If no metadata for the entity specified can be found.
      */
     public function getMetaData($index, $set)
     {
@@ -280,10 +280,9 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
             $metadata = $source->getMetaData($index, $set);
 
             if ($metadata !== null) {
-
                 if (array_key_exists('expire', $metadata)) {
                     if ($metadata['expire'] < time()) {
-                        throw new Exception(
+                        throw new \Exception(
                             'Metadata for the entity ['.$index.'] expired '.
                             (time() - $metadata['expire']).' seconds ago.'
                         );
@@ -297,7 +296,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
             }
         }
 
-        throw new SimpleSAML_Error_MetadataNotFound($index);
+        throw new \SimpleSAML\Error\MetadataNotFound($index);
     }
 
 
@@ -309,8 +308,8 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
      * @param string $entityId The entity ID we are looking up.
      * @param string $set The metadata set we are searching.
      *
-     * @return SimpleSAML_Configuration The configuration object representing the metadata.
-     * @throws SimpleSAML_Error_MetadataNotFound If no metadata for the entity specified can be found.
+     * @return \SimpleSAML\Configuration The configuration object representing the metadata.
+     * @throws \SimpleSAML\Error\MetadataNotFound If no metadata for the entity specified can be found.
      */
     public function getMetaDataConfig($entityId, $set)
     {
@@ -318,7 +317,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
         assert(is_string($set));
 
         $metadata = $this->getMetaData($entityId, $set);
-        return SimpleSAML_Configuration::loadFromArray($metadata, $set.'/'.var_export($entityId, true));
+        return \SimpleSAML\Configuration::loadFromArray($metadata, $set.'/'.var_export($entityId, true));
     }
 
 
@@ -328,7 +327,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
      * @param string $sha1 The SHA1 digest of the entity ID.
      * @param string $set The metadata set we are searching.
      *
-     * @return null|SimpleSAML_Configuration The metadata corresponding to the entity, or null if the entity cannot be
+     * @return null|\SimpleSAML\Configuration The metadata corresponding to the entity, or null if the entity cannot be
      * found.
      */
     public function getMetaDataConfigForSha1($sha1, $set)
@@ -347,11 +346,10 @@ class SimpleSAML_Metadata_MetaDataStorageHandler
             $result = array_merge($srcList, $result);
         }
         foreach ($result as $remote_provider) {
-
             if (sha1($remote_provider['entityid']) == $sha1) {
                 $remote_provider['metadata-set'] = $set;
 
-                return SimpleSAML_Configuration::loadFromArray(
+                return \SimpleSAML\Configuration::loadFromArray(
                     $remote_provider,
                     $set.'/'.var_export($remote_provider['entityid'], true)
                 );
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatFile.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatFile.php
index 09ce8b2890c942f9cb8df5686e389f59f748d258..6901c15a39dbd8f10f8b7d3e8ec64a54021a4258 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatFile.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatFile.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML\Metadata;
 
 /**
  * This file defines a flat file metadata source.
@@ -9,9 +10,9 @@
  * @author Andreas Ă…kre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Metadata_MetaDataStorageHandlerFlatFile extends SimpleSAML_Metadata_MetaDataStorageSource
-{
 
+class MetaDataStorageHandlerFlatFile extends MetaDataStorageSource
+{
     /**
      * This is the directory we will load metadata files from. The path will always end
      * with a '/'.
@@ -43,7 +44,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerFlatFile extends SimpleSAML_Meta
         assert(is_array($config));
 
         // get the configuration
-        $globalConfig = SimpleSAML_Configuration::getInstance();
+        $globalConfig = \SimpleSAML\Configuration::getInstance();
 
         // find the path to the directory we should search for metadata in
         if (array_key_exists('directory', $config)) {
@@ -82,7 +83,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerFlatFile extends SimpleSAML_Meta
         include($metadatasetfile);
 
         if (!is_array($metadata)) {
-            throw new Exception('Could not load metadata set ['.$set.'] from file: '.$metadatasetfile);
+            throw new \Exception('Could not load metadata set ['.$set.'] from file: '.$metadatasetfile);
         }
 
         return $metadata;
@@ -138,7 +139,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerFlatFile extends SimpleSAML_Meta
         } elseif ($set === 'adfs-idp-hosted') {
             return 'urn:federation:'.\SimpleSAML\Utils\HTTP::getSelfHost().':idp';
         } else {
-            throw new Exception('Can not generate dynamic EntityID for metadata of this type: ['.$set.']');
+            throw new \Exception('Can not generate dynamic EntityID for metadata of this type: ['.$set.']');
         }
     }
 }
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php
index 0e3720e8b0911d33962d097f2e70ff9ab5f263f5..47eec7be89eea4c67b371ecf3cb45bd5af74aeff 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML\Metadata;
 
 /**
  * Class for handling metadata files stored in a database.
@@ -8,12 +9,11 @@
  * mooknarf@gmail.com and patched to work with the latest version
  * of SimpleSAMLphp
  *
- * @author Tyler Antonio, University of Alberta <tantonio@ualberta.ca>
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Metadata_MetaDataStorageHandlerPdo extends SimpleSAML_Metadata_MetaDataStorageSource
-{
 
+class MetaDataStorageHandlerPdo extends MetaDataStorageSource
+{
     /**
      * The PDO object
      */
@@ -62,7 +62,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerPdo extends SimpleSAML_Metadata_
     {
         assert(is_array($config));
 
-        $this->db = SimpleSAML\Database::getInstance();
+        $this->db = \SimpleSAML\Database::getInstance();
     }
 
 
@@ -76,7 +76,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerPdo extends SimpleSAML_Metadata_
      *     given file.
      *
      * @throws Exception If a database error occurs.
-     * @throws SimpleSAML_Error_Exception If the metadata can be retrieved from the database, but cannot be decoded.
+     * @throws \SimpleSAML\Error\Exception If the metadata can be retrieved from the database, but cannot be decoded.
      */
     private function load($set)
     {
@@ -95,7 +95,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerPdo extends SimpleSAML_Metadata_
             while ($d = $stmt->fetch()) {
                 $data = json_decode($d['entity_data'], true);
                 if ($data === null) {
-                    throw new SimpleSAML_Error_Exception("Cannot decode metadata for entity '${d['entity_id']}'");
+                    throw new \SimpleSAML\Error\Exception("Cannot decode metadata for entity '${d['entity_id']}'");
                 }
                 if (!array_key_exists('entityid', $data)) {
                     $data['entityid'] = $d['entity_id'];
@@ -105,7 +105,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerPdo extends SimpleSAML_Metadata_
 
             return $metadata;
         } else {
-            throw new Exception('PDO metadata handler: Database error: '.var_export($this->db->getLastError(), true));
+            throw new \Exception('PDO metadata handler: Database error: '.var_export($this->db->getLastError(), true));
         }
     }
 
@@ -142,6 +142,49 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerPdo extends SimpleSAML_Metadata_
         return $metadataSet;
     }
 
+    /**      
+     * Retrieve a metadata entry.
+     *      
+     * @param string $entityId The entityId we are looking up.
+     * @param string $set The set we are looking for metadata in.
+     *
+     * @return array An associative array with metadata for the given entity, or NULL if we are unable to
+     *         locate the entity.
+     */
+    public function getMetaData($entityId, $set)      
+    {       
+        assert(is_string($entityId));
+        assert(is_string($set));
+
+        $tableName = $this->getTableName($set);
+
+        if (!in_array($set, $this->supportedSets, true)) {
+            return null;
+        }
+
+        $stmt = $this->db->read("SELECT entity_id, entity_data FROM $tableName WHERE entity_id=:entityId", array('entityId' => $entityId));
+        if ($stmt->execute()) {
+            $rowCount = 0;
+            $data = null;
+
+            while ($d = $stmt->fetch()) {
+                if (++$rowCount > 1) {
+                    \SimpleSAML\Logger::warning("Duplicate match for $entityId in set $set");
+                    break;
+                }
+                $data = json_decode($d['entity_data'], true);
+                if ($data === null) {
+                    throw new \SimpleSAML\Error\Exception("Cannot decode metadata for entity '${d['entity_id']}'");
+                }
+                if (!array_key_exists('entityid', $data)) {
+                    $data['entityid'] = $d['entity_id'];
+                }
+            }
+            return $data;
+        } else {
+            throw new \Exception('PDO metadata handler: Database error: '.var_export($this->db->getLastError(), true));
+        }
+    }
 
     private function generateDynamicHostedEntityID($set)
     {
@@ -163,7 +206,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerPdo extends SimpleSAML_Metadata_
         } elseif ($set === 'adfs-idp-hosted') {
             return 'urn:federation:'.\SimpleSAML\Utils\HTTP::getSelfHost().':idp';
         } else {
-            throw new Exception('Can not generate dynamic EntityID for metadata of this type: ['.$set.']');
+            throw new \Exception('Can not generate dynamic EntityID for metadata of this type: ['.$set.']');
         }
     }
 
@@ -261,5 +304,4 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerPdo extends SimpleSAML_Metadata_
         }
         return $stmt;
     }
-
 }
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php
index a9ec6f3c41ae02382db0fcd54cd1218c7fc68b5b..7b9d478f5a0c5ac3c84346ec7db03d762a012324 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php
@@ -1,14 +1,15 @@
 <?php
 
+namespace SimpleSAML\Metadata;
 
 /**
  * Class for handling metadata files in serialized format.
  *
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Metadata_MetaDataStorageHandlerSerialize extends SimpleSAML_Metadata_MetaDataStorageSource
-{
 
+class MetaDataStorageHandlerSerialize extends MetaDataStorageSource
+{
     /**
      * The file extension we use for our metadata files.
      *
@@ -36,9 +37,9 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSerialize extends SimpleSAML_Met
     {
         assert(is_array($config));
 
-        $globalConfig = SimpleSAML_Configuration::getInstance();
+        $globalConfig = \SimpleSAML\Configuration::getInstance();
 
-        $cfgHelp = SimpleSAML_Configuration::loadFromArray($config, 'serialize metadata source');
+        $cfgHelp = \SimpleSAML\Configuration::loadFromArray($config, 'serialize metadata source');
 
         $this->directory = $cfgHelp->getString('directory');
 
@@ -77,14 +78,13 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSerialize extends SimpleSAML_Met
 
         $dh = @opendir($this->directory);
         if ($dh === false) {
-            SimpleSAML\Logger::warning(
+            \SimpleSAML\Logger::warning(
                 'Serialize metadata handler: Unable to open directory: '.var_export($this->directory, true)
             );
             return $ret;
         }
 
         while (($entry = readdir($dh)) !== false) {
-
             if ($entry[0] === '.') {
                 // skip '..', '.' and hidden files
                 continue;
@@ -93,7 +93,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSerialize extends SimpleSAML_Met
             $path = $this->directory.'/'.$entry;
 
             if (!is_dir($path)) {
-                SimpleSAML\Logger::warning(
+                \SimpleSAML\Logger::warning(
                     'Serialize metadata handler: Metadata directory contained a file where only directories should '.
                     'exist: '.var_export($path, true)
                 );
@@ -130,7 +130,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSerialize extends SimpleSAML_Met
 
         $dh = @opendir($dir);
         if ($dh === false) {
-            SimpleSAML\Logger::warning('Serialize metadata handler: Unable to open directory: '.var_export($dir, true));
+            \SimpleSAML\Logger::warning('Serialize metadata handler: Unable to open directory: '.var_export($dir, true));
             return $ret;
         }
 
@@ -183,7 +183,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSerialize extends SimpleSAML_Met
         $data = @file_get_contents($filePath);
         if ($data === false) {
             $error = error_get_last();
-            SimpleSAML\Logger::warning(
+            \SimpleSAML\Logger::warning(
                 'Error reading file '.$filePath.': '.$error['message']
             );
             return null;
@@ -191,7 +191,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSerialize extends SimpleSAML_Met
 
         $data = @unserialize($data);
         if ($data === false) {
-            SimpleSAML\Logger::warning('Error unserializing file: '.$filePath);
+            \SimpleSAML\Logger::warning('Error unserializing file: '.$filePath);
             return null;
         }
 
@@ -223,30 +223,30 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSerialize extends SimpleSAML_Met
 
         $dir = dirname($filePath);
         if (!is_dir($dir)) {
-            SimpleSAML\Logger::info('Creating directory: '.$dir);
+            \SimpleSAML\Logger::info('Creating directory: '.$dir);
             $res = @mkdir($dir, 0777, true);
             if ($res === false) {
                 $error = error_get_last();
-                SimpleSAML\Logger::error('Failed to create directory '.$dir.': '.$error['message']);
+                \SimpleSAML\Logger::error('Failed to create directory '.$dir.': '.$error['message']);
                 return false;
             }
         }
 
         $data = serialize($metadata);
 
-        SimpleSAML\Logger::debug('Writing: '.$newPath);
+        \SimpleSAML\Logger::debug('Writing: '.$newPath);
 
         $res = file_put_contents($newPath, $data);
         if ($res === false) {
             $error = error_get_last();
-            SimpleSAML\Logger::error('Error saving file '.$newPath.': '.$error['message']);
+            \SimpleSAML\Logger::error('Error saving file '.$newPath.': '.$error['message']);
             return false;
         }
 
         $res = rename($newPath, $filePath);
         if ($res === false) {
             $error = error_get_last();
-            SimpleSAML\Logger::error('Error renaming '.$newPath.' to '.$filePath.': '.$error['message']);
+            \SimpleSAML\Logger::error('Error renaming '.$newPath.' to '.$filePath.': '.$error['message']);
             return false;
         }
 
@@ -268,7 +268,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSerialize extends SimpleSAML_Met
         $filePath = $this->getMetadataPath($entityId, $set);
 
         if (!file_exists($filePath)) {
-            SimpleSAML\Logger::warning(
+            \SimpleSAML\Logger::warning(
                 'Attempted to erase nonexistent metadata entry '.
                 var_export($entityId, true).' in set '.var_export($set, true).'.'
             );
@@ -278,7 +278,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSerialize extends SimpleSAML_Met
         $res = unlink($filePath);
         if ($res === false) {
             $error = error_get_last();
-            SimpleSAML\Logger::error(
+            \SimpleSAML\Logger::error(
                 'Failed to delete file '.$filePath.
                 ': '.$error['message']
             );
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerXML.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerXML.php
index 44dba1fcfe357bf20979a1e7b341983e5778ecf3..11852e706187ef9c19c96bb1d1035a61183dc210 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerXML.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerXML.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML\Metadata;
 
 /**
  * This class implements a metadata source which loads metadata from XML files.
@@ -8,7 +9,8 @@
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Metadata_MetaDataStorageHandlerXML extends SimpleSAML_Metadata_MetaDataStorageSource
+
+class MetaDataStorageHandlerXML extends MetaDataStorageSource
 {
 
     /**
@@ -32,15 +34,17 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerXML extends SimpleSAML_Metadata_
      */
     protected function __construct($config)
     {
-        // get the configuration
-        $globalConfig = SimpleSAML_Configuration::getInstance();
-
+        $src = $srcXml = null;
         if (array_key_exists('file', $config)) {
+            // get the configuration
+            $globalConfig = \SimpleSAML\Configuration::getInstance();
             $src = $globalConfig->resolvePath($config['file']);
         } elseif (array_key_exists('url', $config)) {
             $src = $config['url'];
+        } elseif (array_key_exists('xml', $config)) {
+            $srcXml = $config['xml'];
         } else {
-            throw new Exception("Missing either 'file' or 'url' in XML metadata source configuration.");
+            throw new \Exception("Missing one of 'file', 'url' and 'xml' in XML metadata source configuration.");
         }
 
 
@@ -50,9 +54,14 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerXML extends SimpleSAML_Metadata_
         $IdP20 = array();
         $AAD = array();
 
-        $entities = SimpleSAML_Metadata_SAMLParser::parseDescriptorsFile($src);
+        if(isset($src)) {
+            $entities = SAMLParser::parseDescriptorsFile($src);
+        } elseif(isset($srcXml)) {
+            $entities = SAMLParser::parseDescriptorsString($srcXml);
+        } else {
+            throw new \Exception("Neither source file path/URI nor string data provided");
+        }
         foreach ($entities as $entityId => $entity) {
-
             $md = $entity->getMetadata1xSP();
             if ($md !== null) {
                 $SP1x[$entityId] = $md;
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageSource.php b/lib/SimpleSAML/Metadata/MetaDataStorageSource.php
index bc96feeec691e4dd4339ea455ab0f876931064ca..360b619ce95c97c77bb928471a52bbf384d52976 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageSource.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageSource.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML\Metadata;
 
 /**
  * This abstract class defines an interface for metadata storage sources.
@@ -12,10 +13,9 @@
  * @author Andreas Aakre Solberg, UNINETT AS.
  * @package SimpleSAMLphp
  */
-abstract class SimpleSAML_Metadata_MetaDataStorageSource
-{
-
 
+abstract class MetaDataStorageSource
+{
     /**
      * Parse array with metadata sources.
      *
@@ -26,7 +26,7 @@ abstract class SimpleSAML_Metadata_MetaDataStorageSource
      *
      * @return array  Parsed metadata configuration.
      *
-     * @throws Exception If something is wrong in the configuration.
+     * @throws \Exception If something is wrong in the configuration.
      */
     public static function parseSources($sourcesConfig)
     {
@@ -36,7 +36,7 @@ abstract class SimpleSAML_Metadata_MetaDataStorageSource
 
         foreach ($sourcesConfig as $sourceConfig) {
             if (!is_array($sourceConfig)) {
-                throw new Exception("Found an element in metadata source configuration which wasn't an array.");
+                throw new \Exception("Found an element in metadata source configuration which wasn't an array.");
             }
 
             $sources[] = self::getSource($sourceConfig);
@@ -55,7 +55,7 @@ abstract class SimpleSAML_Metadata_MetaDataStorageSource
      *
      * @return mixed An instance of a metadata source with the given configuration.
      *
-     * @throws Exception If the metadata source type is invalid.
+     * @throws \Exception If the metadata source type is invalid.
      */
     public static function getSource($sourceConfig)
     {
@@ -69,26 +69,26 @@ abstract class SimpleSAML_Metadata_MetaDataStorageSource
 
         switch ($type) {
             case 'flatfile':
-                return new SimpleSAML_Metadata_MetaDataStorageHandlerFlatFile($sourceConfig);
+                return new MetaDataStorageHandlerFlatFile($sourceConfig);
             case 'xml':
-                return new SimpleSAML_Metadata_MetaDataStorageHandlerXML($sourceConfig);
+                return new MetaDataStorageHandlerXML($sourceConfig);
             case 'serialize':
-                return new SimpleSAML_Metadata_MetaDataStorageHandlerSerialize($sourceConfig);
+                return new MetaDataStorageHandlerSerialize($sourceConfig);
             case 'mdx':
             case 'mdq':
-                return new \SimpleSAML\Metadata\Sources\MDQ($sourceConfig);
+                return new Sources\MDQ($sourceConfig);
             case 'pdo':
-                return new SimpleSAML_Metadata_MetaDataStorageHandlerPdo($sourceConfig);
+                return new MetaDataStorageHandlerPdo($sourceConfig);
             default:
                 // metadata store from module
                 try {
-                    $className = SimpleSAML\Module::resolveClass(
+                    $className = \SimpleSAML\Module::resolveClass(
                         $type,
                         'MetadataStore',
-                        'SimpleSAML_Metadata_MetaDataStorageSource'
+                        '\SimpleSAML\Metadata\MetaDataStorageSource'
                     );
-                } catch (Exception $e) {
-                    throw new SimpleSAML\Error\CriticalConfigurationError(
+                } catch (\Exception $e) {
+                    throw new \SimpleSAML\Error\CriticalConfigurationError(
                         "Invalid 'type' for metadata source. Cannot find store '$type'.",
                         null
                     );
@@ -139,7 +139,6 @@ abstract class SimpleSAML_Metadata_MetaDataStorageSource
         }
 
         foreach ($metadataSet as $index => $entry) {
-
             if (!array_key_exists('host', $entry)) {
                 continue;
             }
@@ -159,7 +158,7 @@ abstract class SimpleSAML_Metadata_MetaDataStorageSource
 
 
     /**
-     * This function will go through all the metadata, and check the hint.cidr
+     * This function will go through all the metadata, and check the DiscoHints->IPHint
      * parameter, which defines a network space (ip range) for each remote entry.
      * This function returns the entityID for any of the entities that have an
      * IP range which the IP falls within.
@@ -177,16 +176,27 @@ abstract class SimpleSAML_Metadata_MetaDataStorageSource
         $metadataSet = $this->getMetadataSet($set);
 
         foreach ($metadataSet as $index => $entry) {
+            $cidrHints = array();
+            
+            // support hint.cidr for idp discovery
+            if (array_key_exists('hint.cidr', $entry) && is_array($entry['hint.cidr'])) {
+                $cidrHints = $entry['hint.cidr'];
+            }
 
-            if (!array_key_exists('hint.cidr', $entry)) {
-                continue;
+            // support discohints in idp metadata for idp discovery
+            if (array_key_exists('DiscoHints', $entry) 
+                && array_key_exists('IPHint', $entry['DiscoHints']) 
+                && is_array($entry['DiscoHints']['IPHint'])) {
+                // merge with hints derived from discohints, but prioritize hint.cidr in case it is used
+                $cidrHints = array_merge($entry['DiscoHints']['IPHint'], $cidrHints);
             }
-            if (!is_array($entry['hint.cidr'])) {
+
+            if (empty($cidrHints)) {
                 continue;
             }
 
-            foreach ($entry['hint.cidr'] as $hint_entry) {
-                if (SimpleSAML\Utils\Net::ipCIDRcheck($hint_entry, $ip)) {
+            foreach ($cidrHints as $hint_entry) {
+                if (\SimpleSAML\Utils\Net::ipCIDRcheck($hint_entry, $ip)) {
                     if ($type === 'entityid') {
                         return $entry['entityid'];
                     } else {
@@ -262,5 +272,4 @@ abstract class SimpleSAML_Metadata_MetaDataStorageSource
 
         return null;
     }
-
 }
diff --git a/lib/SimpleSAML/Metadata/SAMLBuilder.php b/lib/SimpleSAML/Metadata/SAMLBuilder.php
index 38d15a6f3660e5827a9392a92f7d98fe397a28e4..0c6c7869b42635f5f9a4212d27f8d3ae393523dc 100644
--- a/lib/SimpleSAML/Metadata/SAMLBuilder.php
+++ b/lib/SimpleSAML/Metadata/SAMLBuilder.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML\Metadata;
 
 /**
  * Class for generating SAML 2.0 metadata from SimpleSAMLphp metadata arrays.
@@ -8,10 +9,9 @@
  *
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Metadata_SAMLBuilder
-{
-
 
+class SAMLBuilder
+{
     /**
      * The EntityDescriptor we are building.
      *
@@ -76,7 +76,7 @@ class SimpleSAML_Metadata_SAMLBuilder
     /**
      * Retrieve the EntityDescriptor element which is generated for this entity.
      *
-     * @return DOMElement The EntityDescriptor element of this entity.
+     * @return \DOMElement The EntityDescriptor element of this entity.
      */
     public function getEntityDescriptor()
     {
@@ -102,7 +102,7 @@ class SimpleSAML_Metadata_SAMLBuilder
 
         $xml = $this->getEntityDescriptor();
         if ($formatted) {
-            SimpleSAML\Utils\XML::formatDOMElement($xml);
+            \SimpleSAML\Utils\XML::formatDOMElement($xml);
         }
 
         return $xml->ownerDocument->saveXML();
@@ -120,9 +120,9 @@ class SimpleSAML_Metadata_SAMLBuilder
         assert(isset($metadata['entityid']));
         assert(isset($metadata['metadata-set']));
 
-        $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
+        $metadata = \SimpleSAML\Configuration::loadFromArray($metadata, $metadata['entityid']);
         $defaultEndpoint = $metadata->getDefaultEndpoint('SingleSignOnService');
-        $e = new sspmod_adfs_SAML2_XML_fed_SecurityTokenServiceType();
+        $e = new \SimpleSAML\Module\adfs\SAML2\XML\fed\SecurityTokenServiceType();
         $e->Location = $defaultEndpoint['Location'];
 
         $this->addCertificate($e, $metadata);
@@ -134,10 +134,10 @@ class SimpleSAML_Metadata_SAMLBuilder
     /**
      * Add extensions to the metadata.
      *
-     * @param SimpleSAML_Configuration    $metadata The metadata to get extensions from.
+     * @param \SimpleSAML\Configuration    $metadata The metadata to get extensions from.
      * @param \SAML2\XML\md\RoleDescriptor $e Reference to the element where the Extensions element should be included.
      */
-    private function addExtensions(SimpleSAML_Configuration $metadata, \SAML2\XML\md\RoleDescriptor $e)
+    private function addExtensions(\SimpleSAML\Configuration $metadata, \SAML2\XML\md\RoleDescriptor $e)
     {
         if ($metadata->hasValue('tags')) {
             $a = new \SAML2\XML\saml\Attribute();
@@ -299,8 +299,7 @@ class SimpleSAML_Metadata_SAMLBuilder
      */
     public function addOrganizationInfo(array $metadata)
     {
-        if (
-            empty($metadata['OrganizationName']) ||
+        if (empty($metadata['OrganizationName']) ||
             empty($metadata['OrganizationDisplayName']) ||
             empty($metadata['OrganizationURL'])
         ) {
@@ -308,9 +307,9 @@ class SimpleSAML_Metadata_SAMLBuilder
             return;
         }
 
-        $orgName = SimpleSAML\Utils\Arrays::arrayize($metadata['OrganizationName'], 'en');
-        $orgDisplayName = SimpleSAML\Utils\Arrays::arrayize($metadata['OrganizationDisplayName'], 'en');
-        $orgURL = SimpleSAML\Utils\Arrays::arrayize($metadata['OrganizationURL'], 'en');
+        $orgName = \SimpleSAML\Utils\Arrays::arrayize($metadata['OrganizationName'], 'en');
+        $orgDisplayName = \SimpleSAML\Utils\Arrays::arrayize($metadata['OrganizationDisplayName'], 'en');
+        $orgURL = \SimpleSAML\Utils\Arrays::arrayize($metadata['OrganizationURL'], 'en');
 
         $this->addOrganization($orgName, $orgDisplayName, $orgURL);
     }
@@ -381,11 +380,11 @@ class SimpleSAML_Metadata_SAMLBuilder
      * Add an AttributeConsumingService element to the metadata.
      *
      * @param \SAML2\XML\md\SPSSODescriptor $spDesc The SPSSODescriptor element.
-     * @param SimpleSAML_Configuration     $metadata The metadata.
+     * @param \SimpleSAML\Configuration     $metadata The metadata.
      */
     private function addAttributeConsumingService(
         \SAML2\XML\md\SPSSODescriptor $spDesc,
-        SimpleSAML_Configuration $metadata
+        \SimpleSAML\Configuration $metadata
     ) {
         $attributes = $metadata->getArray('attributes', array());
         $name = $metadata->getLocalizedString('name', null);
@@ -403,7 +402,11 @@ class SimpleSAML_Metadata_SAMLBuilder
          */
         $attributeconsumer = new \SAML2\XML\md\AttributeConsumingService();
 
-        $attributeconsumer->index = 0;
+        $attributeconsumer->index = $metadata->getInteger('attributes.index', 0);
+
+        if ($metadata->hasValue('attributes.isDefault')) {
+            $attributeconsumer->isDefault = $metadata->getBoolean('attributes.isDefault', false);
+        }
 
         $attributeconsumer->ServiceName = $name;
         $attributeconsumer->ServiceDescription = $metadata->getLocalizedString('description', array());
@@ -458,7 +461,7 @@ class SimpleSAML_Metadata_SAMLBuilder
                 $this->addAttributeAuthority($metadata);
                 break;
             default:
-                SimpleSAML\Logger::warning('Unable to generate metadata for unknown type \''.$set.'\'.');
+                \SimpleSAML\Logger::warning('Unable to generate metadata for unknown type \''.$set.'\'.');
         }
     }
 
@@ -476,7 +479,7 @@ class SimpleSAML_Metadata_SAMLBuilder
         assert(isset($metadata['entityid']));
         assert(isset($metadata['metadata-set']));
 
-        $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
+        $metadata = \SimpleSAML\Configuration::loadFromArray($metadata, $metadata['entityid']);
 
         $e = new \SAML2\XML\md\SPSSODescriptor();
         $e->protocolSupportEnumeration = $protocols;
@@ -531,7 +534,7 @@ class SimpleSAML_Metadata_SAMLBuilder
         assert(isset($metadata['entityid']));
         assert(isset($metadata['metadata-set']));
 
-        $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
+        $metadata = \SimpleSAML\Configuration::loadFromArray($metadata, $metadata['entityid']);
 
         $e = new \SAML2\XML\md\IDPSSODescriptor();
         $e->protocolSupportEnumeration[] = 'urn:oasis:names:tc:SAML:2.0:protocol';
@@ -580,7 +583,7 @@ class SimpleSAML_Metadata_SAMLBuilder
         assert(isset($metadata['entityid']));
         assert(isset($metadata['metadata-set']));
 
-        $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
+        $metadata = \SimpleSAML\Configuration::loadFromArray($metadata, $metadata['entityid']);
 
         $e = new \SAML2\XML\md\SPSSODescriptor();
         $e->protocolSupportEnumeration[] = 'urn:oasis:names:tc:SAML:1.1:protocol';
@@ -615,7 +618,7 @@ class SimpleSAML_Metadata_SAMLBuilder
         assert(isset($metadata['entityid']));
         assert(isset($metadata['metadata-set']));
 
-        $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
+        $metadata = \SimpleSAML\Configuration::loadFromArray($metadata, $metadata['entityid']);
 
         $e = new \SAML2\XML\md\IDPSSODescriptor();
         $e->protocolSupportEnumeration[] = 'urn:oasis:names:tc:SAML:1.1:protocol';
@@ -635,7 +638,7 @@ class SimpleSAML_Metadata_SAMLBuilder
      * Add metadata of a SAML attribute authority.
      *
      * @param array $metadata The AttributeAuthorityDescriptor, in the format returned by
-     * SimpleSAML_Metadata_SAMLParser.
+     * \SimpleSAML\Metadata\SAMLParser.
      */
     public function addAttributeAuthority(array $metadata)
     {
@@ -643,7 +646,7 @@ class SimpleSAML_Metadata_SAMLBuilder
         assert(isset($metadata['entityid']));
         assert(isset($metadata['metadata-set']));
 
-        $metadata = SimpleSAML_Configuration::loadFromArray($metadata, $metadata['entityid']);
+        $metadata = \SimpleSAML\Configuration::loadFromArray($metadata, $metadata['entityid']);
 
         $e = new \SAML2\XML\md\AttributeAuthorityDescriptor();
         $e->protocolSupportEnumeration = $metadata->getArray('protocols', array(\SAML2\Constants::NS_SAMLP));
@@ -750,22 +753,20 @@ class SimpleSAML_Metadata_SAMLBuilder
      * Helper function for adding a certificate to the metadata.
      *
      * @param \SAML2\XML\md\RoleDescriptor $rd The RoleDescriptor the certificate should be added to.
-     * @param SimpleSAML_Configuration    $metadata The metadata of the entity.
+     * @param \SimpleSAML\Configuration    $metadata The metadata of the entity.
      */
-    private function addCertificate(\SAML2\XML\md\RoleDescriptor $rd, SimpleSAML_Configuration $metadata)
+    private function addCertificate(\SAML2\XML\md\RoleDescriptor $rd, \SimpleSAML\Configuration $metadata)
     {
         $keys = $metadata->getPublicKeys();
-        if ($keys !== null) {
-            foreach ($keys as $key) {
-                if ($key['type'] !== 'X509Certificate') {
-                    continue;
-                }
-                if (!isset($key['signing']) || $key['signing'] === true) {
-                    $this->addX509KeyDescriptor($rd, 'signing', $key['X509Certificate']);
-                }
-                if (!isset($key['encryption']) || $key['encryption'] === true) {
-                    $this->addX509KeyDescriptor($rd, 'encryption', $key['X509Certificate']);
-                }
+        foreach ($keys as $key) {
+            if ($key['type'] !== 'X509Certificate') {
+                continue;
+            }
+            if (!isset($key['signing']) || $key['signing'] === true) {
+                $this->addX509KeyDescriptor($rd, 'signing', $key['X509Certificate']);
+            }
+            if (!isset($key['encryption']) || $key['encryption'] === true) {
+                $this->addX509KeyDescriptor($rd, 'encryption', $key['X509Certificate']);
             }
         }
 
diff --git a/lib/SimpleSAML/Metadata/SAMLParser.php b/lib/SimpleSAML/Metadata/SAMLParser.php
index 6051459635f94fad498881d8d4c08dfa5668695a..0ff8fb95e7d09c6d7b008b5a02cfe906c57fa445 100644
--- a/lib/SimpleSAML/Metadata/SAMLParser.php
+++ b/lib/SimpleSAML/Metadata/SAMLParser.php
@@ -1,20 +1,23 @@
 <?php
 
+namespace SimpleSAML\Metadata;
+
+use RobRichards\XMLSecLibs\XMLSecurityKey;
 
 /**
  * This is class for parsing of SAML 1.x and SAML 2.0 metadata.
  *
  * Metadata is loaded by calling the static methods parseFile, parseString or parseElement.
- * These functions returns an instance of SimpleSAML_Metadata_SAMLParser. To get metadata
+ * These functions returns an instance of SAMLParser. To get metadata
  * from this object, use the methods getMetadata1xSP or getMetadata20SP.
  *
  * To parse a file which can contain a collection of EntityDescriptor or EntitiesDescriptor elements, use the
  * parseDescriptorsFile, parseDescriptorsString or parseDescriptorsElement methods. These functions will return
  * an array of SAMLParser elements where each element represents an EntityDescriptor-element.
  */
-class SimpleSAML_Metadata_SAMLParser
-{
 
+class SAMLParser
+{
     /**
      * This is the list of SAML 1.x protocols.
      *
@@ -25,7 +28,6 @@ class SimpleSAML_Metadata_SAMLParser
         'urn:oasis:names:tc:SAML:1.1:protocol',
     );
 
-
     /**
      * This is the list with the SAML 2.0 protocol.
      *
@@ -35,7 +37,6 @@ class SimpleSAML_Metadata_SAMLParser
         'urn:oasis:names:tc:SAML:2.0:protocol',
     );
 
-
     /**
      * This is the entity id we find in the metadata.
      *
@@ -43,7 +44,6 @@ class SimpleSAML_Metadata_SAMLParser
      */
     private $entityId;
 
-
     /**
      * This is an array with the processed SPSSODescriptor elements we have found in this
      * metadata file.
@@ -56,7 +56,6 @@ class SimpleSAML_Metadata_SAMLParser
      */
     private $spDescriptors;
 
-
     /**
      * This is an array with the processed IDPSSODescriptor elements we have found.
      * Each element in the array is an associative array with the elements from parseSSODescriptor and:
@@ -67,7 +66,6 @@ class SimpleSAML_Metadata_SAMLParser
      */
     private $idpDescriptors;
 
-
     /**
      * List of attribute authorities we have found.
      *
@@ -75,7 +73,6 @@ class SimpleSAML_Metadata_SAMLParser
      */
     private $attributeAuthorityDescriptors = array();
 
-
     /**
      * This is an associative array with the organization name for this entity. The key of
      * the associative array is the language code, while the value is a string with the
@@ -85,7 +82,6 @@ class SimpleSAML_Metadata_SAMLParser
      */
     private $organizationName = array();
 
-
     /**
      * This is an associative array with the organization display name for this entity. The key of
      * the associative array is the language code, while the value is a string with the
@@ -95,7 +91,6 @@ class SimpleSAML_Metadata_SAMLParser
      */
     private $organizationDisplayName = array();
 
-
     /**
      * This is an associative array with the organization URI for this entity. The key of
      * the associative array is the language code, while the value is the URI.
@@ -104,7 +99,6 @@ class SimpleSAML_Metadata_SAMLParser
      */
     private $organizationURL = array();
 
-
     /**
      * This is an array of the Contact Persons of this entity.
      *
@@ -112,13 +106,11 @@ class SimpleSAML_Metadata_SAMLParser
      */
     private $contacts = array();
 
-
     /**
      * @var array
      */
     private $scopes;
 
-
     /**
      * @var array
      */
@@ -135,7 +127,6 @@ class SimpleSAML_Metadata_SAMLParser
      */
     private $tags;
 
-
     /**
      * This is an array of elements that may be used to validate this element.
      *
@@ -143,7 +134,6 @@ class SimpleSAML_Metadata_SAMLParser
      */
     private $validators = array();
 
-
     /**
      * The original EntityDescriptor element for this entity, as a base64 encoded string.
      *
@@ -151,12 +141,11 @@ class SimpleSAML_Metadata_SAMLParser
      */
     private $entityDescriptor;
 
-
     /**
      * This is the constructor for the SAMLParser class.
      *
      * @param \SAML2\XML\md\EntityDescriptor $entityElement The EntityDescriptor.
-     * @param int|NULL                      $maxExpireTime The unix timestamp for when this entity should expire, or
+     * @param int|null                      $maxExpireTime The unix timestamp for when this entity should expire, or
      *     NULL if unknown.
      * @param array                         $validators An array of parent elements that may validate this element.
      * @param array                         $parentExtensions An optional array of extensions from the parent element.
@@ -165,7 +154,7 @@ class SimpleSAML_Metadata_SAMLParser
         \SAML2\XML\md\EntityDescriptor $entityElement,
         $maxExpireTime,
         array $validators = array(),
-        array $parentExtensions = null
+        array $parentExtensions = array()
     ) {
         assert($maxExpireTime === null || is_int($maxExpireTime));
 
@@ -191,7 +180,6 @@ class SimpleSAML_Metadata_SAMLParser
 
         // look over the RoleDescriptors
         foreach ($entityElement->RoleDescriptor as $child) {
-
             if ($child instanceof \SAML2\XML\md\SPSSODescriptor) {
                 $this->processSPSSODescriptor($child, $expireTime);
             } elseif ($child instanceof \SAML2\XML\md\IDPSSODescriptor) {
@@ -218,7 +206,7 @@ class SimpleSAML_Metadata_SAMLParser
      *
      * @param string $file The path to the file which contains the metadata.
      *
-     * @return SimpleSAML_Metadata_SAMLParser An instance of this class with the metadata loaded.
+     * @return SAMLParser An instance of this class with the metadata loaded.
      * @throws Exception If the file does not parse as XML.
      */
     public static function parseFile($file)
@@ -227,8 +215,8 @@ class SimpleSAML_Metadata_SAMLParser
 
         try {
             $doc = \SAML2\DOMDocumentFactory::fromString($data);
-        } catch(\Exception $e) {
-            throw new Exception('Failed to read XML from file: '.$file);
+        } catch (\Exception $e) {
+            throw new \Exception('Failed to read XML from file: '.$file);
         }
 
         return self::parseDocument($doc);
@@ -240,15 +228,15 @@ class SimpleSAML_Metadata_SAMLParser
      *
      * @param string $metadata A string which contains XML encoded metadata.
      *
-     * @return SimpleSAML_Metadata_SAMLParser An instance of this class with the metadata loaded.
+     * @return SAMLParser An instance of this class with the metadata loaded.
      * @throws Exception If the string does not parse as XML.
      */
     public static function parseString($metadata)
     {
         try {
             $doc = \SAML2\DOMDocumentFactory::fromString($metadata);
-        } catch(\Exception $e) {
-            throw new Exception('Failed to parse XML string.');
+        } catch (\Exception $e) {
+            throw new \Exception('Failed to parse XML string.');
         }
 
         return self::parseDocument($doc);
@@ -256,15 +244,15 @@ class SimpleSAML_Metadata_SAMLParser
 
 
     /**
-     * This function parses a DOMDocument which is assumed to contain a single EntityDescriptor element.
+     * This function parses a \DOMDocument which is assumed to contain a single EntityDescriptor element.
      *
-     * @param DOMDocument $document The DOMDocument which contains the EntityDescriptor element.
+     * @param \DOMDocument $document The \DOMDocument which contains the EntityDescriptor element.
      *
-     * @return SimpleSAML_Metadata_SAMLParser An instance of this class with the metadata loaded.
+     * @return SAMLParser An instance of this class with the metadata loaded.
      */
     public static function parseDocument($document)
     {
-        assert($document instanceof DOMDocument);
+        assert($document instanceof \DOMDocument);
 
         $entityElement = self::findEntityDescriptor($document);
 
@@ -278,13 +266,12 @@ class SimpleSAML_Metadata_SAMLParser
      * @param \SAML2\XML\md\EntityDescriptor $entityElement A \SAML2\XML\md\EntityDescriptor object which represents a
      *     EntityDescriptor element.
      *
-     * @return SimpleSAML_Metadata_SAMLParser An instance of this class with the metadata loaded.
+     * @return SAMLParser An instance of this class with the metadata loaded.
      */
     public static function parseElement($entityElement)
     {
         assert($entityElement instanceof \SAML2\XML\md\EntityDescriptor);
-
-        return new SimpleSAML_Metadata_SAMLParser($entityElement, null);
+        return new SAMLParser($entityElement, null, array());
     }
 
 
@@ -296,26 +283,25 @@ class SimpleSAML_Metadata_SAMLParser
      *
      * @param string $file The path to the file which contains the EntityDescriptor or EntitiesDescriptor element.
      *
-     * @return SimpleSAML_Metadata_SAMLParser[] An array of SAMLParser instances.
-     * @throws Exception If the file does not parse as XML.
+     * @return SAMLParser[] An array of SAMLParser instances.
+     * @throws \Exception If the file does not parse as XML.
      */
     public static function parseDescriptorsFile($file)
     {
-
         if ($file === null) {
-            throw new Exception('Cannot open file NULL. File name not specified.');
+            throw new \Exception('Cannot open file NULL. File name not specified.');
         }
 
         $data = \SimpleSAML\Utils\HTTP::fetch($file);
 
         try {
             $doc = \SAML2\DOMDocumentFactory::fromString($data);
-        } catch(\Exception $e) {
-            throw new Exception('Failed to read XML from file: '.$file);
+        } catch (\Exception $e) {
+            throw new \Exception('Failed to read XML from file: '.$file);
         }
 
         if ($doc->documentElement === null) {
-            throw new Exception('Opened file is not an XML document: '.$file);
+            throw new \Exception('Opened file is not an XML document: '.$file);
         }
 
         return self::parseDescriptorsElement($doc->documentElement);
@@ -329,16 +315,16 @@ class SimpleSAML_Metadata_SAMLParser
      *
      * @param string $string The string with XML data.
      *
-     * @return SimpleSAML_Metadata_SAMLParser[] An associative array of SAMLParser instances. The key of the array will
+     * @return SAMLParser[] An associative array of SAMLParser instances. The key of the array will
      *     be the entity id.
-     * @throws Exception If the string does not parse as XML.
+     * @throws \Exception If the string does not parse as XML.
      */
     public static function parseDescriptorsString($string)
     {
         try {
             $doc = \SAML2\DOMDocumentFactory::fromString($string);
-        } catch(\Exception $e) {
-            throw new Exception('Failed to parse XML string.');
+        } catch (\Exception $e) {
+            throw new \Exception('Failed to parse XML string.');
         }
 
         return self::parseDescriptorsElement($doc->documentElement);
@@ -349,25 +335,25 @@ class SimpleSAML_Metadata_SAMLParser
      * This function parses a DOMElement which represents either an EntityDescriptor element or an
      * EntitiesDescriptor element. It will return an associative array of SAMLParser instances in both cases.
      *
-     * @param DOMElement|NULL $element The DOMElement which contains the EntityDescriptor element or the
+     * @param \DOMElement|NULL $element The DOMElement which contains the EntityDescriptor element or the
      *     EntitiesDescriptor element.
      *
-     * @return SimpleSAML_Metadata_SAMLParser[] An associative array of SAMLParser instances. The key of the array will
+     * @return SAMLParser[] An associative array of SAMLParser instances. The key of the array will
      *     be the entity id.
-     * @throws Exception if the document is empty or the root is an unexpected node.
+     * @throws \Exception if the document is empty or the root is an unexpected node.
      */
-    public static function parseDescriptorsElement(DOMElement $element = null)
+    public static function parseDescriptorsElement(\DOMElement $element = null)
     {
         if ($element === null) {
-            throw new Exception('Document was empty.');
+            throw new \Exception('Document was empty.');
         }
 
-        if (SimpleSAML\Utils\XML::isDOMNodeOfType($element, 'EntityDescriptor', '@md') === true) {
+        if (\SimpleSAML\Utils\XML::isDOMNodeOfType($element, 'EntityDescriptor', '@md') === true) {
             return self::processDescriptorsElement(new \SAML2\XML\md\EntityDescriptor($element));
-        } elseif (SimpleSAML\Utils\XML::isDOMNodeOfType($element, 'EntitiesDescriptor', '@md') === true) {
+        } elseif (\SimpleSAML\Utils\XML::isDOMNodeOfType($element, 'EntitiesDescriptor', '@md') === true) {
             return self::processDescriptorsElement(new \SAML2\XML\md\EntitiesDescriptor($element));
         } else {
-            throw new Exception('Unexpected root node: ['.$element->namespaceURI.']:'.$element->localName);
+            throw new \Exception('Unexpected root node: ['.$element->namespaceURI.']:'.$element->localName);
         }
     }
 
@@ -382,7 +368,7 @@ class SimpleSAML_Metadata_SAMLParser
      * @param array                                                         $parentExtensions An optional array of
      *     extensions from the parent element.
      *
-     * @return SimpleSAML_Metadata_SAMLParser[] Array of SAMLParser instances.
+     * @return SAMLParser[] Array of SAMLParser instances.
      */
     private static function processDescriptorsElement(
         $element,
@@ -393,9 +379,9 @@ class SimpleSAML_Metadata_SAMLParser
         assert($maxExpireTime === null || is_int($maxExpireTime));
 
         if ($element instanceof \SAML2\XML\md\EntityDescriptor) {
-            $ret = new SimpleSAML_Metadata_SAMLParser($element, $maxExpireTime, $validators, $parentExtensions);
+            $ret = new SAMLParser($element, $maxExpireTime, $validators, $parentExtensions);
             $ret = array($ret->getEntityId() => $ret);
-            /** @var SimpleSAML_Metadata_SAMLParser[] $ret */
+            /** @var SAMLParser[] $ret */
             return $ret;
         }
 
@@ -508,7 +494,7 @@ class SimpleSAML_Metadata_SAMLParser
             $metadata['EntityAttributes'] = $this->entityAttributes;
 
             // check for entity categories
-            if (SimpleSAML\Utils\Config\Metadata::isHiddenFromDiscovery($metadata)) {
+            if (\SimpleSAML\Utils\Config\Metadata::isHiddenFromDiscovery($metadata)) {
                 $metadata['hide.from.discovery'] = true;
             }
         }
@@ -708,6 +694,12 @@ class SimpleSAML_Metadata_SAMLParser
         if (array_key_exists('attributes.NameFormat', $spd)) {
             $ret['attributes.NameFormat'] = $spd['attributes.NameFormat'];
         }
+        if (array_key_exists('attributes.index', $spd)) {
+            $ret['attributes.index'] = $spd['attributes.index'];
+        }
+        if (array_key_exists('attributes.isDefault', $spd)) {
+            $ret['attributes.isDefault'] = $spd['attributes.isDefault'];
+        }
 
         // add name & description
         if (array_key_exists('name', $spd)) {
@@ -1025,7 +1017,6 @@ class SimpleSAML_Metadata_SAMLParser
         }
 
         foreach ($element->Extensions as $e) {
-
             if ($e instanceof \SAML2\XML\shibmd\Scope) {
                 $ret['scope'][] = $e->scope;
                 continue;
@@ -1034,13 +1025,11 @@ class SimpleSAML_Metadata_SAMLParser
             // Entity Attributes are only allowed at entity level extensions and not at RoleDescriptor level
             if ($element instanceof \SAML2\XML\md\EntityDescriptor ||
                 $element instanceof \SAML2\XML\md\EntitiesDescriptor) {
-
-
                 if ($e instanceof \SAML2\XML\mdrpi\RegistrationInfo) {
                     // Registration Authority cannot be overridden (warn only if override attempts to change the value)
                     if (isset($ret['RegistrationInfo']['registrationAuthority'])
                         && $ret['RegistrationInfo']['registrationAuthority'] !== $e->registrationAuthority) {
-                        SimpleSAML\Logger::warning('Invalid attempt to override registrationAuthority \''
+                        \SimpleSAML\Logger::warning('Invalid attempt to override registrationAuthority \''
                           . $ret['RegistrationInfo']['registrationAuthority'] . "' with '{$e->registrationAuthority}'");
                     } else {
                         $ret['RegistrationInfo']['registrationAuthority'] = $e->registrationAuthority;
@@ -1077,7 +1066,6 @@ class SimpleSAML_Metadata_SAMLParser
             // UIInfo elements are only allowed at RoleDescriptor level extensions
             if ($element instanceof \SAML2\XML\md\RoleDescriptor) {
                 if ($e instanceof \SAML2\XML\mdui\UIInfo) {
-
                     $ret['UIInfo']['DisplayName'] = $e->DisplayName;
                     $ret['UIInfo']['Description'] = $e->Description;
                     $ret['UIInfo']['InformationURL'] = $e->InformationURL;
@@ -1115,7 +1103,6 @@ class SimpleSAML_Metadata_SAMLParser
 
             // DiscoHints elements are only allowed at IDPSSODescriptor level extensions
             if ($element instanceof \SAML2\XML\md\IDPSSODescriptor) {
-
                 if ($e instanceof \SAML2\XML\mdui\DiscoHints) {
                     $ret['DiscoHints']['IPHint'] = $e->IPHint;
                     $ret['DiscoHints']['DomainHint'] = $e->DomainHint;
@@ -1128,12 +1115,12 @@ class SimpleSAML_Metadata_SAMLParser
             }
 
             if ($e->localName === 'Attribute' && $e->namespaceURI === \SAML2\Constants::NS_SAML) {
-                $attribute = $e->getXML();
+                $attribute = $e->xml;
 
                 $name = $attribute->getAttribute('Name');
                 $values = array_map(
-                    array('SimpleSAML\Utils\XML', 'getDOMText'),
-                    SimpleSAML\Utils\XML::getDOMChildren($attribute, 'AttributeValue', '@saml2')
+                    array('\SimpleSAML\Utils\XML', 'getDOMText'),
+                    \SimpleSAML\Utils\XML::getDOMChildren($attribute, 'AttributeValue', '@saml2')
                 );
 
                 if ($name === 'tags') {
@@ -1402,24 +1389,24 @@ class SimpleSAML_Metadata_SAMLParser
      *
      * This function will throw an exception if it is unable to locate the node.
      *
-     * @param DOMDocument $doc The DOMDocument where we should find the EntityDescriptor node.
+     * @param \DOMDocument $doc The \DOMDocument where we should find the EntityDescriptor node.
      *
-     * @return \SAML2\XML\md\EntityDescriptor The DOMEntity which represents the EntityDescriptor.
-     * @throws Exception If the document is empty or the first element is not an EntityDescriptor element.
+     * @return \SAML2\XML\md\EntityDescriptor The \DOMEntity which represents the EntityDescriptor.
+     * @throws \Exception If the document is empty or the first element is not an EntityDescriptor element.
      */
     private static function findEntityDescriptor($doc)
     {
-        assert($doc instanceof DOMDocument);
+        assert($doc instanceof \DOMDocument);
 
         // find the EntityDescriptor DOMElement. This should be the first (and only) child of the DOMDocument
         $ed = $doc->documentElement;
 
         if ($ed === null) {
-            throw new Exception('Failed to load SAML metadata from empty XML document.');
+            throw new \Exception('Failed to load SAML metadata from empty XML document.');
         }
 
-        if (SimpleSAML\Utils\XML::isDOMNodeOfType($ed, 'EntityDescriptor', '@md') === false) {
-            throw new Exception('Expected first element in the metadata document to be an EntityDescriptor element.');
+        if (\SimpleSAML\Utils\XML::isDOMNodeOfType($ed, 'EntityDescriptor', '@md') === false) {
+            throw new \Exception('Expected first element in the metadata document to be an EntityDescriptor element.');
         }
 
         return new \SAML2\XML\md\EntityDescriptor($ed);
@@ -1441,25 +1428,25 @@ class SimpleSAML_Metadata_SAMLParser
             assert(is_string($cert));
             $certFile = \SimpleSAML\Utils\Config::getCertPath($cert);
             if (!file_exists($certFile)) {
-                throw new Exception(
+                throw new \Exception(
                     'Could not find certificate file ['.$certFile.'], which is needed to validate signature'
                 );
             }
             $certData = file_get_contents($certFile);
 
             foreach ($this->validators as $validator) {
-                $key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'public'));
+                $key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, array('type' => 'public'));
                 $key->loadKey($certData);
                 try {
                     if ($validator->validate($key)) {
                         return true;
                     }
-                } catch (Exception $e) {
+                } catch (\Exception $e) {
                     // this certificate did not sign this element, skip
                 }
             }
         }
-        SimpleSAML\Logger::debug('Could not validate signature');
+        \SimpleSAML\Logger::debug('Could not validate signature');
         return false;
     }
 
@@ -1482,7 +1469,6 @@ class SimpleSAML_Metadata_SAMLParser
         $candidates = array();
         foreach ($this->validators as $validator) {
             foreach ($validator->getValidatingCertificates() as $cert) {
-
                 $fp = strtolower(sha1(base64_decode($cert)));
                 $candidates[] = $fp;
                 if ($fp === $fingerprint) {
@@ -1490,7 +1476,7 @@ class SimpleSAML_Metadata_SAMLParser
                 }
             }
         }
-        SimpleSAML\Logger::debug('Fingerprint was ['.$fingerprint.'] not one of ['.join(', ', $candidates).']');
+        \SimpleSAML\Logger::debug('Fingerprint was ['.$fingerprint.'] not one of ['.join(', ', $candidates).']');
         return false;
     }
 }
diff --git a/lib/SimpleSAML/Metadata/Signer.php b/lib/SimpleSAML/Metadata/Signer.php
index 3d3f2eaf9601f7b4235029799076ac5d78afc76e..eb87586ace868e05f5dc47ec60ab7a5ff96dc35d 100644
--- a/lib/SimpleSAML/Metadata/Signer.php
+++ b/lib/SimpleSAML/Metadata/Signer.php
@@ -1,5 +1,9 @@
 <?php
 
+namespace SimpleSAML\Metadata;
+
+use RobRichards\XMLSecLibs\XMLSecurityKey;
+use RobRichards\XMLSecLibs\XMLSecurityDSig;
 
 /**
  * This class implements a helper function for signing of metadata.
@@ -7,16 +11,16 @@
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Metadata_Signer
-{
 
+class Signer
+{
     /**
      * This functions finds what key & certificate files should be used to sign the metadata
      * for the given entity.
      *
-     * @param SimpleSAML_Configuration $config Our SimpleSAML_Configuration instance.
-     * @param array                    $entityMetadata The metadata of the entity.
-     * @param string                   $type A string which describes the type entity this is, e.g. 'SAML 2 IdP' or
+     * @param \SimpleSAML\Configuration $config Our \SimpleSAML\Configuration instance.
+     * @param array                     $entityMetadata The metadata of the entity.
+     * @param string                    $type A string which describes the type entity this is, e.g. 'SAML 2 IdP' or
      *     'Shib 1.3 SP'.
      *
      * @return array An associative array with the keys 'privatekey', 'certificate', and optionally 'privatekey_pass'.
@@ -28,12 +32,10 @@ class SimpleSAML_Metadata_Signer
         if (array_key_exists('metadata.sign.privatekey', $entityMetadata)
             || array_key_exists('metadata.sign.certificate', $entityMetadata)
         ) {
-
             if (!array_key_exists('metadata.sign.privatekey', $entityMetadata)
                 || !array_key_exists('metadata.sign.certificate', $entityMetadata)
             ) {
-
-                throw new Exception(
+                throw new \Exception(
                     'Missing either the "metadata.sign.privatekey" or the'.
                     ' "metadata.sign.certificate" configuration option in the metadata for'.
                     ' the '.$type.' "'.$entityMetadata['entityid'].'". If one of'.
@@ -58,7 +60,7 @@ class SimpleSAML_Metadata_Signer
         $certificate = $config->getString('metadata.sign.certificate', null);
         if ($privatekey !== null || $certificate !== null) {
             if ($privatekey === null || $certificate === null) {
-                throw new Exception(
+                throw new \Exception(
                     'Missing either the "metadata.sign.privatekey" or the'.
                     ' "metadata.sign.certificate" configuration option in the global'.
                     ' configuration. If one of these options is specified, then the other'.
@@ -79,11 +81,10 @@ class SimpleSAML_Metadata_Signer
         if (array_key_exists('privatekey', $entityMetadata)
             || array_key_exists('certificate', $entityMetadata)
         ) {
-
             if (!array_key_exists('privatekey', $entityMetadata)
                 || !array_key_exists('certificate', $entityMetadata)
             ) {
-                throw new Exception(
+                throw new \Exception(
                     'Both the "privatekey" and the "certificate" option must'.
                     ' be set in the metadata for the '.$type.' "'.
                     $entityMetadata['entityid'].'" before it is possible to sign metadata'.
@@ -103,7 +104,7 @@ class SimpleSAML_Metadata_Signer
             return $ret;
         }
 
-        throw new Exception(
+        throw new \Exception(
             'Could not find what key & certificate should be used to sign the metadata'.
             ' for the '.$type.' "'.$entityMetadata['entityid'].'".'
         );
@@ -113,20 +114,20 @@ class SimpleSAML_Metadata_Signer
     /**
      * Determine whether metadata signing is enabled for the given metadata.
      *
-     * @param SimpleSAML_Configuration $config Our SimpleSAML_Configuration instance.
-     * @param array                    $entityMetadata The metadata of the entity.
-     * @param string                   $type A string which describes the type entity this is, e.g. 'SAML 2 IdP' or
+     * @param \SimpleSAML\Configuration $config Our \SimpleSAML\Configuration instance.
+     * @param array                     $entityMetadata The metadata of the entity.
+     * @param string                    $type A string which describes the type entity this is, e.g. 'SAML 2 IdP' or
      *     'Shib 1.3 SP'.
      *
      * @return boolean True if metadata signing is enabled, false otherwise.
-     * @throws Exception If the value of the 'metadata.sign.enable' option is not a boolean.
+     * @throws \Exception If the value of the 'metadata.sign.enable' option is not a boolean.
      */
     private static function isMetadataSigningEnabled($config, $entityMetadata, $type)
     {
         // first check the metadata for the entity
         if (array_key_exists('metadata.sign.enable', $entityMetadata)) {
             if (!is_bool($entityMetadata['metadata.sign.enable'])) {
-                throw new Exception(
+                throw new \Exception(
                     'Invalid value for the "metadata.sign.enable" configuration option for'.
                     ' the '.$type.' "'.$entityMetadata['entityid'].'". This option'.
                     ' should be a boolean.'
@@ -148,7 +149,7 @@ class SimpleSAML_Metadata_Signer
      * This method will look for the 'metadata.sign.algorithm' key in the $entityMetadata array, or look for such
      * a configuration option in the $config object.
      *
-     * @param SimpleSAML_Configuration $config The global configuration.
+     * @param \SimpleSAML\Configuration $config The global configuration.
      * @param array $entityMetadata An array containing the metadata related to this entity.
      * @param string $type A string describing the type of entity. E.g. 'SAML 2 IdP' or 'Shib 1.3 SP'.
      *
@@ -156,8 +157,6 @@ class SimpleSAML_Metadata_Signer
      * algorithms to use, respectively.
      *
      * @throws \SimpleSAML\Error\CriticalConfigurationError
-     *
-     * @todo change to SHA256 by default.
      */
     private static function getMetadataSigningAlgorithm($config, $entityMetadata, $type)
     {
@@ -171,7 +170,7 @@ class SimpleSAML_Metadata_Signer
             }
             $alg = $entityMetadata['metadata.sign.algorithm'];
         } else {
-            $alg = $config->getString('metadata.sign.algorithm', XMLSecurityKey::RSA_SHA1);
+            $alg = $config->getString('metadata.sign.algorithm', XMLSecurityKey::RSA_SHA256);
         }
 
         $supported_algs = array(
@@ -214,11 +213,11 @@ class SimpleSAML_Metadata_Signer
      * @param string $type A string which describes the type entity this is, e.g. 'SAML 2 IdP' or 'Shib 1.3 SP'.
      *
      * @return string The $metadataString with the signature embedded.
-     * @throws Exception If the certificate or private key cannot be loaded, or the metadata doesn't parse properly.
+     * @throws \Exception If the certificate or private key cannot be loaded, or the metadata doesn't parse properly.
      */
     public static function sign($metadataString, $entityMetadata, $type)
     {
-        $config = SimpleSAML_Configuration::getInstance();
+        $config = \SimpleSAML\Configuration::getInstance();
 
         // check if metadata signing is enabled
         if (!self::isMetadataSigningEnabled($config, $entityMetadata, $type)) {
@@ -230,13 +229,13 @@ class SimpleSAML_Metadata_Signer
 
         $keyFile = \SimpleSAML\Utils\Config::getCertPath($keyCertFiles['privatekey']);
         if (!file_exists($keyFile)) {
-            throw new Exception('Could not find private key file ['.$keyFile.'], which is needed to sign the metadata');
+            throw new \Exception('Could not find private key file ['.$keyFile.'], which is needed to sign the metadata');
         }
         $keyData = file_get_contents($keyFile);
 
         $certFile = \SimpleSAML\Utils\Config::getCertPath($keyCertFiles['certificate']);
         if (!file_exists($certFile)) {
-            throw new Exception(
+            throw new \Exception(
                 'Could not find certificate file ['.$certFile.'], which is needed to sign the metadata'
             );
         }
@@ -246,8 +245,8 @@ class SimpleSAML_Metadata_Signer
         // convert the metadata to a DOM tree
         try {
             $xml = \SAML2\DOMDocumentFactory::fromString($metadataString);
-        } catch(Exception $e) {
-            throw new Exception('Error parsing self-generated metadata.');
+        } catch (\Exception $e) {
+            throw new \Exception('Error parsing self-generated metadata.');
         }
 
         $signature_cf = self::getMetadataSigningAlgorithm($config, $entityMetadata, $type);
diff --git a/lib/SimpleSAML/Metadata/Sources/MDQ.php b/lib/SimpleSAML/Metadata/Sources/MDQ.php
index d85a09ba158a7ce2d9b655d9b3a41bc536598540..bb0b053f8462eaa7418426ead3a50fdd080699ca 100644
--- a/lib/SimpleSAML/Metadata/Sources/MDQ.php
+++ b/lib/SimpleSAML/Metadata/Sources/MDQ.php
@@ -13,9 +13,9 @@ use SimpleSAML\Utils\HTTP;
  * @author Tamas Frank, NIIFI
  * @package SimpleSAMLphp
  */
-class MDQ extends \SimpleSAML_Metadata_MetaDataStorageSource
-{
 
+class MDQ extends \SimpleSAML\Metadata\MetaDataStorageSource
+{
     /**
      * The URL of MDQ server (url:port)
      *
@@ -80,7 +80,7 @@ class MDQ extends \SimpleSAML_Metadata_MetaDataStorageSource
         }
 
         if (array_key_exists('cachedir', $config)) {
-            $globalConfig = \SimpleSAML_Configuration::getInstance();
+            $globalConfig = \SimpleSAML\Configuration::getInstance();
             $this->cacheDir = $globalConfig->resolvePath($config['cachedir']);
         } else {
             $this->cacheDir = null;
@@ -216,13 +216,13 @@ class MDQ extends \SimpleSAML_Metadata_MetaDataStorageSource
     /**
      * Retrieve metadata for the correct set from a SAML2Parser.
      *
-     * @param \SimpleSAML_Metadata_SAMLParser $entity A SAML2Parser representing an entity.
+     * @param \SimpleSAML\Metadata\SAMLParser $entity A SAML2Parser representing an entity.
      * @param string                         $set The metadata set we are looking for.
      *
      * @return array|NULL  The associative array with the metadata, or NULL if no metadata for
      *                     the given set was found.
      */
-    private static function getParsedSet(\SimpleSAML_Metadata_SAMLParser $entity, $set)
+    private static function getParsedSet(\SimpleSAML\Metadata\SAMLParser $entity, $set)
     {
         assert(is_string($set));
 
@@ -248,7 +248,7 @@ class MDQ extends \SimpleSAML_Metadata_MetaDataStorageSource
 
 
     /**
-     * Overriding this function from the superclass SimpleSAML_Metadata_MetaDataStorageSource.
+     * Overriding this function from the superclass \SimpleSAML\Metadata\MetaDataStorageSource.
      *
      * This function retrieves metadata for the given entity id in the given set of metadata.
      * It will return NULL if it is unable to locate the metadata.
@@ -262,7 +262,8 @@ class MDQ extends \SimpleSAML_Metadata_MetaDataStorageSource
      *
      * @return array An associative array with metadata for the given entity, or NULL if we are unable to
      *         locate the entity.
-     * @throws \Exception If an error occurs while downloading metadata, validating the signature or writing to cache.
+     * @throws \Exception If an error occurs while validating the signature or the metadata is in an
+     *         incorrect set.
      */
     public function getMetaData($index, $set)
     {
@@ -272,7 +273,13 @@ class MDQ extends \SimpleSAML_Metadata_MetaDataStorageSource
         Logger::info(__CLASS__.': loading metadata entity ['.$index.'] from ['.$set.']');
 
         // read from cache if possible
-        $data = $this->getFromCache($set, $index);
+        try {
+            $data = $this->getFromCache($set, $index);
+        } catch (\Exception $e) {
+            Logger::error($e->getMessage());
+            // proceed with fetching metadata even if the cache is broken
+            $data = null;
+        }
 
         if ($data !== null && array_key_exists('expires', $data) && $data['expires'] < time()) {
             // metadata has expired
@@ -292,18 +299,19 @@ class MDQ extends \SimpleSAML_Metadata_MetaDataStorageSource
         try {
             $xmldata = HTTP::fetch($mdq_url);
         } catch (\Exception $e) {
-            Logger::warning('Fetching metadata for '.$index.': '.$e->getMessage());
+            // Avoid propagating the exception, make sure we can handle the error later
+            $xmldata = false;
         }
 
         if (empty($xmldata)) {
             $error = error_get_last();
-            throw new \Exception(
-                'Error downloading metadata for "'.$index.'" from "'.$mdq_url.'": '.$error['message']
-            );
+            Logger::info('Unable to fetch metadata for "'.$index.'" from '.$mdq_url.': '.
+                (is_array($error) ? $error['message'] : 'no error available'));
+            return null;
         }
 
         /** @var string $xmldata */
-        $entity = \SimpleSAML_Metadata_SAMLParser::parseString($xmldata);
+        $entity = \SimpleSAML\Metadata\SAMLParser::parseString($xmldata);
         Logger::debug(__CLASS__.': completed parsing of ['.$mdq_url.']');
 
         if ($this->validateFingerprint !== null) {
@@ -317,7 +325,12 @@ class MDQ extends \SimpleSAML_Metadata_MetaDataStorageSource
             throw new \Exception(__CLASS__.': no metadata for set "'.$set.'" available from "'.$index.'".');
         }
 
-        $this->writeToCache($set, $index, $data);
+        try {
+            $this->writeToCache($set, $index, $data);
+        } catch (\Exception $e) {
+            // Proceed without writing to cache
+            Logger::error('Error writing MDQ result to cache: '.$e->getMessage());
+        }
 
         return $data;
     }
diff --git a/lib/SimpleSAML/Module.php b/lib/SimpleSAML/Module.php
index 6c9b3c6e0e9f7052f1ce9ea2105ee7fa2e5364fb..675a2d9d093d1f6437814b2f1a2cefa9579985c5 100644
--- a/lib/SimpleSAML/Module.php
+++ b/lib/SimpleSAML/Module.php
@@ -1,4 +1,5 @@
 <?php
+
 namespace SimpleSAML;
 
 /**
@@ -11,7 +12,6 @@ namespace SimpleSAML;
  */
 class Module
 {
-
     /**
      * A list containing the modules currently installed.
      *
@@ -58,7 +58,7 @@ class Module
      */
     public static function isModuleEnabled($module)
     {
-        $config = \SimpleSAML_Configuration::getOptionalConfig();
+        $config = Configuration::getOptionalConfig();
         return self::isModuleEnabledWithConf($module, $config->getArray('module.enable', array()));
     }
 
@@ -152,7 +152,7 @@ class Module
      *
      * This function takes a string on the form "<module>:<class>" and converts it to a class
      * name. It can also check that the given class is a subclass of a specific class. The
-     * resolved classname will be "sspmod_<module>_<$type>_<class>.
+     * resolved classname will be "\SimleSAML\Module\<module>\<$type>\<class>.
      *
      * It is also possible to specify a full classname instead of <module>:<class>.
      *
@@ -276,14 +276,14 @@ class Module
      * @param string $hook The name of the hook.
      * @param mixed  &$data The data which should be passed to each hook. Will be passed as a reference.
      *
-     * @throws \SimpleSAML_Error_Exception If an invalid hook is found in a module.
+     * @throws \SimpleSAML\Error\Exception If an invalid hook is found in a module.
      */
     public static function callHooks($hook, &$data = null)
     {
         assert(is_string($hook));
 
         $modules = self::getModules();
-        $config = \SimpleSAML_Configuration::getOptionalConfig()->getArray('module.enable', array());
+        $config = Configuration::getOptionalConfig()->getArray('module.enable', array());
         sort($modules);
         foreach ($modules as $module) {
             if (!self::isModuleEnabledWithConf($module, $config)) {
@@ -301,7 +301,7 @@ class Module
             require_once(self::$module_info[$module]['hooks'][$hook]['file']);
 
             if (!is_callable(self::$module_info[$module]['hooks'][$hook]['func'])) {
-                throw new \SimpleSAML_Error_Exception('Invalid hook \''.$hook.'\' for module \''.$module.'\'.');
+                throw new \SimpleSAML\Error\Exception('Invalid hook \''.$hook.'\' for module \''.$module.'\'.');
             }
 
             $fn = self::$module_info[$module]['hooks'][$hook]['func'];
diff --git a/lib/SimpleSAML/Session.php b/lib/SimpleSAML/Session.php
index 6eb306cf8f9d4571f3c702239b907dd3eda09415..3432ca53b3be17a56a9516ccef418d09c68fec18 100644
--- a/lib/SimpleSAML/Session.php
+++ b/lib/SimpleSAML/Session.php
@@ -1,4 +1,9 @@
 <?php
+
+namespace SimpleSAML;
+
+use SimpleSAML\Error;
+
 /**
  * The Session class holds information about a user session, and everything attached to it.
  *
@@ -16,9 +21,9 @@
  * @author Jaime Pérez Crespo, UNINETT AS <jaime.perez@uninett.no>
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Session implements Serializable
-{
 
+class Session implements \Serializable
+{
     /**
      * This is a timeout value for setData, which indicates that the data
      * should never be deleted, i.e. lasts the whole session lifetime.
@@ -39,7 +44,7 @@ class SimpleSAML_Session implements Serializable
     /**
      * This variable holds the instance of the session - Singleton approach.
      *
-     * Warning: do not set the instance manually, call SimpleSAML_Session::load() instead.
+     * Warning: do not set the instance manually, call Session::load() instead.
      */
     private static $instance = null;
 
@@ -129,9 +134,9 @@ class SimpleSAML_Session implements Serializable
      *
      * This is an array with authentication data for the various authsources.
      *
-     * @var array|null  Associative array of associative arrays.
+     * @var array  Associative array of associative arrays.
      */
-    private $authData;
+    private $authData = array();
 
 
     /**
@@ -142,19 +147,17 @@ class SimpleSAML_Session implements Serializable
      */
     private function __construct($transient = false)
     {
-        $this->authData = array();
-
         if (php_sapi_name() === 'cli' || defined('STDIN')) {
             $this->trackid = 'CL'.bin2hex(openssl_random_pseudo_bytes(4));
-            SimpleSAML\Logger::setTrackId($this->trackid);
+            Logger::setTrackId($this->trackid);
             $this->transient = $transient;
             return;
         }
 
         if ($transient) { // transient session
-            $sh = \SimpleSAML\SessionHandler::getSessionHandler();
+            $sh = SessionHandler::getSessionHandler();
             $this->trackid = 'TR'.bin2hex(openssl_random_pseudo_bytes(4));
-            SimpleSAML\Logger::setTrackId($this->trackid);
+            Logger::setTrackId($this->trackid);
             $this->transient = true;
 
             /*
@@ -166,18 +169,18 @@ class SimpleSAML_Session implements Serializable
                 $this->sessionId = $sh->newSessionId();
             }
         } else { // regular session
-            $sh = \SimpleSAML\SessionHandler::getSessionHandler();
+            $sh = SessionHandler::getSessionHandler();
             $this->sessionId = $sh->newSessionId();
             $sh->setCookie($sh->getSessionCookieName(), $this->sessionId, $sh->getCookieParams());
 
 
             $this->trackid = bin2hex(openssl_random_pseudo_bytes(5));
-            SimpleSAML\Logger::setTrackId($this->trackid);
+            Logger::setTrackId($this->trackid);
 
             $this->markDirty();
 
             // initialize data for session check function if defined
-            $globalConfig = SimpleSAML_Configuration::getInstance();
+            $globalConfig = Configuration::getInstance();
             $checkFunction = $globalConfig->getArray('session.check_function', null);
             if (isset($checkFunction)) {
                 assert(is_callable($checkFunction));
@@ -237,8 +240,8 @@ class SimpleSAML_Session implements Serializable
     /**
      * Retrieves the current session. Creates a new session if there's not one.
      *
-     * @return SimpleSAML_Session The current session.
-     * @throws Exception When session couldn't be initialized and the session fallback is disabled by configuration.
+     * @return Session The current session.
+     * @throws \Exception When session couldn't be initialized and the session fallback is disabled by configuration.
      */
     public static function getSessionFromRequest()
     {
@@ -251,18 +254,18 @@ class SimpleSAML_Session implements Serializable
         $session = null;
         try {
             $session = self::getSession();
-        } catch (Exception $e) {
+        } catch (\Exception $e) {
             /*
              * For some reason, we were unable to initialize this session. Note that this error might be temporary, and
              * it's possible that we can recover from it in subsequent requests, so we should not try to create a new
              * session here. Therefore, use just a transient session and throw the exception for someone else to handle
              * it.
              */
-            SimpleSAML\Logger::error('Error loading session: '.$e->getMessage());
+            Logger::error('Error loading session: '.$e->getMessage());
             self::useTransientSession();
-            if ($e instanceof SimpleSAML_Error_Exception) {
+            if ($e instanceof Error\Exception) {
                 $cause = $e->getCause();
-                if ($cause instanceof Exception) {
+                if ($cause instanceof \Exception) {
                     throw $cause;
                 }
             }
@@ -270,7 +273,7 @@ class SimpleSAML_Session implements Serializable
         }
 
         // if getSession() found it, use it
-        if ($session instanceof SimpleSAML_Session) {
+        if ($session instanceof Session) {
             return self::load($session);
         }
 
@@ -286,20 +289,20 @@ class SimpleSAML_Session implements Serializable
 
         // try to create a new session
         try {
-            self::load(new SimpleSAML_Session());
-        } catch (\SimpleSAML\Error\CannotSetCookie $e) {
+            self::load(new Session());
+        } catch (Error\CannotSetCookie $e) {
             // can't create a regular session because we can't set cookies. Use transient.
-            $c = SimpleSAML_Configuration::getInstance();
+            $c = Configuration::getInstance();
             self::useTransientSession();
 
-            if ($e->getCode() === \SimpleSAML\Error\CannotSetCookie::SECURE_COOKIE) {
-                throw new \SimpleSAML\Error\CriticalConfigurationError(
+            if ($e->getCode() === Error\CannotSetCookie::SECURE_COOKIE) {
+                throw new Error\CriticalConfigurationError(
                     $e->getMessage(),
                     null,
                     $c->toArray()
                 );
             }
-            SimpleSAML\Logger::error('Error creating session: '.$e->getMessage());
+            Logger::error('Error creating session: '.$e->getMessage());
         }
 
         // we must have a session now, either regular or transient
@@ -311,14 +314,14 @@ class SimpleSAML_Session implements Serializable
      *
      * @param string|null $sessionId The session we should get, or null to get the current session.
      *
-     * @return SimpleSAML_Session|null The session that is stored in the session handler, or null if the session wasn't
+     * @return Session|null The session that is stored in the session handler, or null if the session wasn't
      * found.
      */
     public static function getSession($sessionId = null)
     {
         assert(is_string($sessionId) || $sessionId === null);
 
-        $sh = \SimpleSAML\SessionHandler::getSessionHandler();
+        $sh = SessionHandler::getSessionHandler();
 
         if ($sessionId === null) {
             $checkToken = true;
@@ -342,7 +345,7 @@ class SimpleSAML_Session implements Serializable
         assert($session instanceof self);
 
         if ($checkToken) {
-            $globalConfig = SimpleSAML_Configuration::getInstance();
+            $globalConfig = Configuration::getInstance();
 
             if ($session->authToken !== null) {
                 $authTokenCookieName = $globalConfig->getString(
@@ -350,11 +353,11 @@ class SimpleSAML_Session implements Serializable
                     'SimpleSAMLAuthToken'
                 );
                 if (!isset($_COOKIE[$authTokenCookieName])) {
-                    SimpleSAML\Logger::warning('Missing AuthToken cookie.');
+                    Logger::warning('Missing AuthToken cookie.');
                     return null;
                 }
-                if (!SimpleSAML\Utils\Crypto::secureCompare($session->authToken, $_COOKIE[$authTokenCookieName])) {
-                    SimpleSAML\Logger::warning('Invalid AuthToken cookie.');
+                if (!Utils\Crypto::secureCompare($session->authToken, $_COOKIE[$authTokenCookieName])) {
+                    Logger::warning('Invalid AuthToken cookie.');
                     return null;
                 }
             }
@@ -365,7 +368,7 @@ class SimpleSAML_Session implements Serializable
                 assert(is_callable($checkFunction));
                 $check = call_user_func($checkFunction, $session);
                 if ($check !== true) {
-                    SimpleSAML\Logger::warning('Session did not pass check function.');
+                    Logger::warning('Session did not pass check function.');
                     return null;
                 }
             }
@@ -384,12 +387,12 @@ class SimpleSAML_Session implements Serializable
      *
      * Warning: never set self::$instance yourself, call this method instead.
      *
-     * @param SimpleSAML_Session $session The session to load.
-     * @return SimpleSAML_Session The session we just loaded, just for convenience.
+     * @param Session $session The session to load.
+     * @return Session The session we just loaded, just for convenience.
      */
-    private static function load(SimpleSAML_Session $session)
+    private static function load(Session $session)
     {
-        SimpleSAML\Logger::setTrackId($session->getTrackID());
+        Logger::setTrackId($session->getTrackID());
         self::$instance = $session;
         return self::$instance;
     }
@@ -407,7 +410,7 @@ class SimpleSAML_Session implements Serializable
             return;
         }
 
-        self::load(new SimpleSAML_Session(true));
+        self::load(new Session(true));
     }
 
     /**
@@ -439,15 +442,15 @@ class SimpleSAML_Session implements Serializable
         $this->dirty = false;
         $this->callback_registered = false;
 
-        $sh = \SimpleSAML\SessionHandler::getSessionHandler();
+        $sh = SessionHandler::getSessionHandler();
 
         try {
             $sh->saveSession($this);
-        } catch (Exception $e) {
-            if (!($e instanceof SimpleSAML_Error_Exception)) {
-                $e = new SimpleSAML_Error_UnserializableException($e);
+        } catch (\Exception $e) {
+            if (!($e instanceof Error\Exception)) {
+                $e = new Error\UnserializableException($e);
             }
-            SimpleSAML\Logger::error('Unable to save session.');
+            Logger::error('Unable to save session.');
             $e->logError();
         }
     }
@@ -462,8 +465,8 @@ class SimpleSAML_Session implements Serializable
     public function cleanup()
     {
         $this->save();
-        $sh = \SimpleSAML\SessionHandler::getSessionHandler();
-        if ($sh instanceof \SimpleSAML\SessionHandlerPHP) {
+        $sh = SessionHandler::getSessionHandler();
+        if ($sh instanceof SessionHandlerPHP) {
             $sh->restorePrevious();
         }
     }
@@ -552,7 +555,7 @@ class SimpleSAML_Session implements Serializable
         assert(is_int($expire) || $expire === null);
 
         if ($expire === null) {
-            $globalConfig = SimpleSAML_Configuration::getInstance();
+            $globalConfig = Configuration::getInstance();
             $expire = time() + $globalConfig->getInteger('session.rememberme.lifetime', 14 * 86400);
         }
         $this->rememberMeExpire = $expire;
@@ -569,14 +572,14 @@ class SimpleSAML_Session implements Serializable
      * @param string     $authority The authority the user logged in with.
      * @param array|null $data The authentication data for this authority.
      *
-     * @throws \SimpleSAML\Error\CannotSetCookie If the authentication token cannot be set for some reason.
+     * @throws Error\CannotSetCookie If the authentication token cannot be set for some reason.
      */
     public function doLogin($authority, array $data = null)
     {
         assert(is_string($authority));
         assert(is_array($data) || $data === null);
 
-        SimpleSAML\Logger::debug('Session: doLogin("'.$authority.'")');
+        Logger::debug('Session: doLogin("'.$authority.'")');
 
         $this->markDirty();
 
@@ -591,7 +594,7 @@ class SimpleSAML_Session implements Serializable
 
         $data['Authority'] = $authority;
 
-        $globalConfig = SimpleSAML_Configuration::getInstance();
+        $globalConfig = Configuration::getInstance();
         if (!isset($data['AuthnInstant'])) {
             $data['AuthnInstant'] = time();
         }
@@ -627,22 +630,21 @@ class SimpleSAML_Session implements Serializable
 
         $this->authData[$authority] = $data;
 
-        $this->authToken = SimpleSAML\Utils\Random::generateID();
-        $sessionHandler = \SimpleSAML\SessionHandler::getSessionHandler();
+        $this->authToken = Utils\Random::generateID();
+        $sessionHandler = SessionHandler::getSessionHandler();
 
         if (!$this->transient && (!empty($data['RememberMe']) || $this->rememberMeExpire) &&
             $globalConfig->getBoolean('session.rememberme.enable', false)
         ) {
-
             $this->setRememberMeExpire();
         } else {
             try {
-                SimpleSAML\Utils\HTTP::setCookie(
+                Utils\HTTP::setCookie(
                     $globalConfig->getString('session.authtoken.cookiename', 'SimpleSAMLAuthToken'),
                     $this->authToken,
                     $sessionHandler->getCookieParams()
                 );
-            } catch (SimpleSAML\Error\CannotSetCookie $e) {
+            } catch (Error\CannotSetCookie $e) {
                 /*
                  * Something went wrong when setting the auth token. We cannot recover from this, so we better log a
                  * message and throw an exception. The user is not properly logged in anyway, so clear all login
@@ -650,7 +652,7 @@ class SimpleSAML_Session implements Serializable
                  */
                 unset($this->authToken);
                 unset($this->authData[$authority]);
-                \SimpleSAML\Logger::error('Cannot set authentication token cookie: '.$e->getMessage());
+                Logger::error('Cannot set authentication token cookie: '.$e->getMessage());
                 throw $e;
             }
         }
@@ -665,10 +667,10 @@ class SimpleSAML_Session implements Serializable
      */
     public function doLogout($authority)
     {
-        SimpleSAML\Logger::debug('Session: doLogout('.var_export($authority, true).')');
+        Logger::debug('Session: doLogout('.var_export($authority, true).')');
 
         if (!isset($this->authData[$authority])) {
-            SimpleSAML\Logger::debug('Session: Already logged out of '.$authority.'.');
+            Logger::debug('Session: Already logged out of '.$authority.'.');
             return;
         }
 
@@ -688,7 +690,7 @@ class SimpleSAML_Session implements Serializable
      *
      * @param string $authority The authentication source we are logging out from.
      *
-     * @throws Exception If the handler is not a valid function or method.
+     * @throws \Exception If the handler is not a valid function or method.
      */
     private function callLogoutHandlers($authority)
     {
@@ -704,7 +706,7 @@ class SimpleSAML_Session implements Serializable
                 $classname = $handler[0];
                 $functionname = $handler[1];
 
-                throw new Exception(
+                throw new \Exception(
                     'Logout handler is not a valid function: '.$classname.'::'.
                     $functionname
                 );
@@ -731,7 +733,7 @@ class SimpleSAML_Session implements Serializable
         assert(is_string($authority));
 
         if (!isset($this->authData[$authority])) {
-            SimpleSAML\Logger::debug(
+            Logger::debug(
                 'Session: '.var_export($authority, true).
                 ' not valid because we are not authenticated.'
             );
@@ -739,11 +741,11 @@ class SimpleSAML_Session implements Serializable
         }
 
         if ($this->authData[$authority]['Expire'] <= time()) {
-            SimpleSAML\Logger::debug('Session: '.var_export($authority, true).' not valid because it is expired.');
+            Logger::debug('Session: '.var_export($authority, true).' not valid because it is expired.');
             return false;
         }
 
-        SimpleSAML\Logger::debug('Session: Valid session found with '.var_export($authority, true).'.');
+        Logger::debug('Session: Valid session found with '.var_export($authority, true).'.');
 
         return true;
     }
@@ -755,15 +757,19 @@ class SimpleSAML_Session implements Serializable
      */
     public function updateSessionCookies($params = null)
     {
-        $sessionHandler = \SimpleSAML\SessionHandler::getSessionHandler();
+        assert(is_null($params) || is_array($params));
+
+        $sessionHandler = SessionHandler::getSessionHandler();
 
         if ($this->sessionId !== null) {
             $sessionHandler->setCookie($sessionHandler->getSessionCookieName(), $this->sessionId, $params);
         }
 
+        $params = array_merge($sessionHandler->getCookieParams(), is_array($params) ? $params : array());
+
         if ($this->authToken !== null) {
-            $globalConfig = SimpleSAML_Configuration::getInstance();
-            \SimpleSAML\Utils\HTTP::setCookie(
+            $globalConfig = Configuration::getInstance();
+            Utils\HTTP::setCookie(
                 $globalConfig->getString('session.authtoken.cookiename', 'SimpleSAMLAuthToken'),
                 $this->authToken,
                 $params
@@ -785,7 +791,7 @@ class SimpleSAML_Session implements Serializable
         $this->markDirty();
 
         if ($expire === null) {
-            $globalConfig = SimpleSAML_Configuration::getInstance();
+            $globalConfig = Configuration::getInstance();
             $expire = time() + $globalConfig->getInteger('session.duration', 8 * 60 * 60);
         }
 
@@ -799,7 +805,7 @@ class SimpleSAML_Session implements Serializable
      * @param string $classname The class which contains the logout handler.
      * @param string $functionname The logout handler function.
      *
-     * @throws Exception If the handler is not a valid function or method.
+     * @throws \Exception If the handler is not a valid function or method.
      */
     public function registerLogoutHandler($authority, $classname, $functionname)
     {
@@ -808,7 +814,7 @@ class SimpleSAML_Session implements Serializable
         $logout_handler = array($classname, $functionname);
 
         if (!is_callable($logout_handler)) {
-            throw new Exception(
+            throw new \Exception(
                 'Logout handler is not a vaild function: '.$classname.'::'.
                 $functionname
             );
@@ -846,7 +852,7 @@ class SimpleSAML_Session implements Serializable
     /**
      * This function stores data in the data store.
      *
-     * The timeout value can be SimpleSAML_Session::DATA_TIMEOUT_SESSION_END, which indicates
+     * The timeout value can be Session::DATA_TIMEOUT_SESSION_END, which indicates
      * that the data should never be deleted.
      *
      * @param string   $type The type of the data. This is checked when retrieving data from the store.
@@ -856,7 +862,7 @@ class SimpleSAML_Session implements Serializable
      * This parameter is optional. The default value is set in 'session.datastore.timeout',
      * and the default is 4 hours.
      *
-     * @throws Exception If the data couldn't be stored.
+     * @throws \Exception If the data couldn't be stored.
      *
      */
     public function setData($type, $id, $data, $timeout = null)
@@ -870,12 +876,12 @@ class SimpleSAML_Session implements Serializable
 
         if ($timeout === null) {
             // use the default timeout
-            $configuration = SimpleSAML_Configuration::getInstance();
+            $configuration = Configuration::getInstance();
 
             $timeout = $configuration->getInteger('session.datastore.timeout', null);
             if ($timeout !== null) {
                 if ($timeout <= 0) {
-                    throw new Exception(
+                    throw new \Exception(
                         'The value of the session.datastore.timeout'.
                         ' configuration option should be a positive integer.'
                     );
@@ -1035,7 +1041,7 @@ class SimpleSAML_Session implements Serializable
      */
     public function hasSessionCookie()
     {
-        $sh = \SimpleSAML\SessionHandler::getSessionHandler();
+        $sh = SessionHandler::getSessionHandler();
         return $sh->hasSessionCookie();
     }
 
@@ -1043,7 +1049,7 @@ class SimpleSAML_Session implements Serializable
     /**
      * Add an SP association for an IdP.
      *
-     * This function is only for use by the SimpleSAML_IdP class.
+     * This function is only for use by the IdP class.
      *
      * @param string $idp The IdP id.
      * @param array  $association The association we should add.
@@ -1071,7 +1077,7 @@ class SimpleSAML_Session implements Serializable
     /**
      * Retrieve the associations for an IdP.
      *
-     * This function is only for use by the SimpleSAML_IdP class.
+     * This function is only for use by the IdP class.
      *
      * @param string $idp The IdP id.
      *
@@ -1107,7 +1113,7 @@ class SimpleSAML_Session implements Serializable
     /**
      * Remove an SP association for an IdP.
      *
-     * This function is only for use by the SimpleSAML_IdP class.
+     * This function is only for use by the IdP class.
      *
      * @param string $idp The IdP id.
      * @param string $associationId The id of the association.
diff --git a/lib/SimpleSAML/SessionHandler.php b/lib/SimpleSAML/SessionHandler.php
index 7c18ac210c4afbe0b1da6118e442877b38e8e317..945a75d6ac032e5cbee24b97ef52413904cd61a8 100644
--- a/lib/SimpleSAML/SessionHandler.php
+++ b/lib/SimpleSAML/SessionHandler.php
@@ -82,9 +82,9 @@ abstract class SessionHandler
     /**
      * Save the session.
      *
-     * @param \SimpleSAML_Session $session The session object we should save.
+     * @param \SimpleSAML\Session $session The session object we should save.
      */
-    abstract public function saveSession(\SimpleSAML_Session $session);
+    abstract public function saveSession(Session $session);
 
 
     /**
@@ -92,11 +92,21 @@ abstract class SessionHandler
      *
      * @param string|null $sessionId The ID of the session we should load, or null to use the default.
      *
-     * @return \SimpleSAML_Session|null The session object, or null if it doesn't exist.
+     * @return \SimpleSAML\Session|null The session object, or null if it doesn't exist.
      */
     abstract public function loadSession($sessionId = null);
 
 
+    /**
+     * Check whether the session cookie is set.
+     *
+     * This function will only return false if is is certain that the cookie isn't set.
+     *
+     * @return bool True if it was set, false if not.
+     */
+    abstract public function hasSessionCookie();
+
+
     /**
      * Set a session cookie.
      *
@@ -119,7 +129,7 @@ abstract class SessionHandler
      */
     private static function createSessionHandler()
     {
-        $store = \SimpleSAML\Store::getInstance();
+        $store = Store::getInstance();
         if ($store === false) {
             self::$sessionHandler = new SessionHandlerPHP();
         } else {
@@ -129,19 +139,6 @@ abstract class SessionHandler
     }
 
 
-    /**
-     * Check whether the session cookie is set.
-     *
-     * This function will only return false if is is certain that the cookie isn't set.
-     *
-     * @return bool True if it was set, false if not.
-     */
-    public function hasSessionCookie()
-    {
-        return true;
-    }
-
-
     /**
      * Get the cookie parameters that should be used for session cookies.
      *
@@ -150,7 +147,7 @@ abstract class SessionHandler
      */
     public function getCookieParams()
     {
-        $config = \SimpleSAML_Configuration::getInstance();
+        $config = Configuration::getInstance();
 
         return array(
             'lifetime' => $config->getInteger('session.cookie.lifetime', 0),
diff --git a/lib/SimpleSAML/SessionHandlerCookie.php b/lib/SimpleSAML/SessionHandlerCookie.php
index b94e8f716e1b993093c80ee2592b884da31c5778..a9995081b0cdf7752b50dff2b0c7068535895259 100644
--- a/lib/SimpleSAML/SessionHandlerCookie.php
+++ b/lib/SimpleSAML/SessionHandlerCookie.php
@@ -44,7 +44,7 @@ abstract class SessionHandlerCookie extends SessionHandler
         // call the constructor in the base class in case it should become necessary in the future
         parent::__construct();
 
-        $config = \SimpleSAML_Configuration::getInstance();
+        $config = Configuration::getInstance();
         $this->cookie_name = $config->getString('session.cookie.name', 'SimpleSAMLSessionID');
     }
 
@@ -57,7 +57,7 @@ abstract class SessionHandlerCookie extends SessionHandler
     public function newSessionId()
     {
         $this->session_id = self::createSessionID();
-        \SimpleSAML_Session::createSession($this->session_id);
+        Session::createSession($this->session_id);
 
         return $this->session_id;
     }
diff --git a/lib/SimpleSAML/SessionHandlerPHP.php b/lib/SimpleSAML/SessionHandlerPHP.php
index 067c384d050d683bea83ace4144558eedd76f4ba..dbcd10062d2a55177dd99ed8bfc2f309d24f1bd4 100644
--- a/lib/SimpleSAML/SessionHandlerPHP.php
+++ b/lib/SimpleSAML/SessionHandlerPHP.php
@@ -46,7 +46,7 @@ class SessionHandlerPHP extends SessionHandler
         // call the parent constructor in case it should become necessary in the future
         parent::__construct();
 
-        $config = \SimpleSAML_Configuration::getInstance();
+        $config = Configuration::getInstance();
         $this->cookie_name = $config->getString('session.phpsession.cookiename', null);
 
         if (session_status() === PHP_SESSION_ACTIVE) {
@@ -76,13 +76,15 @@ class SessionHandlerPHP extends SessionHandler
 
         $params = $this->getCookieParams();
 
-        session_set_cookie_params(
-            $params['lifetime'],
-            $params['path'],
-            $params['domain'],
-            $params['secure'],
-            $params['httponly']
-        );
+        if (!headers_sent()) {
+            session_set_cookie_params(
+                $params['lifetime'],
+                $params['path'],
+                $params['domain'],
+                $params['secure'],
+                $params['httponly']
+            );
+        }
 
         $savepath = $config->getString('session.phpsession.savepath', null);
         if (!empty($savepath)) {
@@ -112,8 +114,8 @@ class SessionHandlerPHP extends SessionHandler
              */
             session_cache_limiter('');
         }
-        @session_start();
         session_cache_limiter($cacheLimiter);
+        @session_start();
     }
 
 
@@ -123,7 +125,7 @@ class SessionHandlerPHP extends SessionHandler
      * Use this method to restore a previous PHP session existing before SimpleSAMLphp initialized its own session.
      *
      * WARNING: do not use this method directly, unless you know what you are doing. Calling this method directly,
-     * outside of SimpleSAML_Session, could cause SimpleSAMLphp's session to be lost or mess the application's one. The
+     * outside of \SimpleSAML\Session, could cause SimpleSAMLphp's session to be lost or mess the application's one. The
      * session must always be saved properly before calling this method. If you don't understand what this is about,
      * don't use this method.
      */
@@ -166,7 +168,7 @@ class SessionHandlerPHP extends SessionHandler
     {
         // generate new (secure) session id
         $sessionId = bin2hex(openssl_random_pseudo_bytes(16));
-        \SimpleSAML_Session::createSession($sessionId);
+        Session::createSession($sessionId);
 
         return $sessionId;
     }
@@ -177,7 +179,7 @@ class SessionHandlerPHP extends SessionHandler
      *
      * @return string|null The session id saved in the cookie or null if no session cookie was set.
      *
-     * @throws \SimpleSAML_Error_Exception If the cookie is marked as secure but we are not using HTTPS.
+     * @throws \SimpleSAML\Error\Exception If the cookie is marked as secure but we are not using HTTPS.
      */
     public function getCookieSessionId()
     {
@@ -191,7 +193,7 @@ class SessionHandlerPHP extends SessionHandler
         $session_cookie_params = session_get_cookie_params();
 
         if ($session_cookie_params['secure'] && !HTTP::isHTTPS()) {
-            throw new \SimpleSAML_Error_Exception('Session start with secure cookie not allowed on http.');
+            throw new \SimpleSAML\Error\Exception('Session start with secure cookie not allowed on http.');
         }
 
         $this->sessionStart();
@@ -213,9 +215,9 @@ class SessionHandlerPHP extends SessionHandler
     /**
      * Save the current session to the PHP session array.
      *
-     * @param \SimpleSAML_Session $session The session object we should save.
+     * @param \SimpleSAML\Session $session The session object we should save.
      */
-    public function saveSession(\SimpleSAML_Session $session)
+    public function saveSession(\SimpleSAML\Session $session)
     {
         $_SESSION['SimpleSAMLphp_SESSION'] = serialize($session);
     }
@@ -226,9 +228,9 @@ class SessionHandlerPHP extends SessionHandler
      *
      * @param string|null $sessionId The ID of the session we should load, or null to use the default.
      *
-     * @return \SimpleSAML_Session|null The session object, or null if it doesn't exist.
+     * @return \SimpleSAML\Session|null The session object, or null if it doesn't exist.
      *
-     * @throws \SimpleSAML_Error_Exception If it wasn't possible to disable session cookies or we are trying to load a
+     * @throws \SimpleSAML\Error\Exception If it wasn't possible to disable session cookies or we are trying to load a
      * PHP session with a specific identifier and it doesn't match with the current session identifier.
      */
     public function loadSession($sessionId = null)
@@ -240,13 +242,13 @@ class SessionHandlerPHP extends SessionHandler
                 // session not initiated with getCookieSessionId(), start session without setting cookie
                 $ret = ini_set('session.use_cookies', '0');
                 if ($ret === false) {
-                    throw new \SimpleSAML_Error_Exception('Disabling PHP option session.use_cookies failed.');
+                    throw new \SimpleSAML\Error\Exception('Disabling PHP option session.use_cookies failed.');
                 }
 
                 session_id($sessionId);
                 $this->sessionStart();
             } elseif ($sessionId !== session_id()) {
-                throw new \SimpleSAML_Error_Exception('Cannot load PHP session with a specific ID.');
+                throw new \SimpleSAML\Error\Exception('Cannot load PHP session with a specific ID.');
             }
         } elseif (session_id() === '') {
             self::getCookieSessionId();
@@ -286,17 +288,17 @@ class SessionHandlerPHP extends SessionHandler
      * @return array The cookie parameters for our sessions.
      * @link http://www.php.net/manual/en/function.session-get-cookie-params.php
      *
-     * @throws \SimpleSAML_Error_Exception If both 'session.phpsession.limitedpath' and 'session.cookie.path' options
+     * @throws \SimpleSAML\Error\Exception If both 'session.phpsession.limitedpath' and 'session.cookie.path' options
      * are set at the same time in the configuration.
      */
     public function getCookieParams()
     {
-        $config = \SimpleSAML_Configuration::getInstance();
+        $config = Configuration::getInstance();
 
         $ret = parent::getCookieParams();
 
         if ($config->hasValue('session.phpsession.limitedpath') && $config->hasValue('session.cookie.path')) {
-            throw new \SimpleSAML_Error_Exception(
+            throw new \SimpleSAML\Error\Exception(
                 'You cannot set both the session.phpsession.limitedpath and session.cookie.path options.'
             );
         } elseif ($config->hasValue('session.phpsession.limitedpath')) {
diff --git a/lib/SimpleSAML/SessionHandlerStore.php b/lib/SimpleSAML/SessionHandlerStore.php
index 328654249eccfcc1564be9b706feb944b02b56be..f40b9eb958c6c1871c4fbbc2629412876c30a006 100644
--- a/lib/SimpleSAML/SessionHandlerStore.php
+++ b/lib/SimpleSAML/SessionHandlerStore.php
@@ -38,7 +38,7 @@ class SessionHandlerStore extends SessionHandlerCookie
      *
      * @param string|null $sessionId The ID of the session we should load, or null to use the default.
      *
-     * @return \SimpleSAML_Session|null The session object, or null if it doesn't exist.
+     * @return \SimpleSAML\Session|null The session object, or null if it doesn't exist.
      */
     public function loadSession($sessionId = null)
     {
@@ -54,7 +54,7 @@ class SessionHandlerStore extends SessionHandlerCookie
 
         $session = $this->store->get('session', $sessionId);
         if ($session !== null) {
-            assert($session instanceof \SimpleSAML_Session);
+            assert($session instanceof Session);
             return $session;
         }
 
@@ -65,13 +65,13 @@ class SessionHandlerStore extends SessionHandlerCookie
     /**
      * Save a session to the data store.
      *
-     * @param \SimpleSAML_Session $session The session object we should save.
+     * @param \SimpleSAML\Session $session The session object we should save.
      */
-    public function saveSession(\SimpleSAML_Session $session)
+    public function saveSession(Session $session)
     {
         $sessionId = $session->getSessionId();
 
-        $config = \SimpleSAML_Configuration::getInstance();
+        $config = Configuration::getInstance();
         $sessionDuration = $config->getInteger('session.duration', 8 * 60 * 60);
         $expire = time() + $sessionDuration;
 
diff --git a/lib/SimpleSAML/Stats.php b/lib/SimpleSAML/Stats.php
index e710a373ef1c31e59a49bf3d1a8d7919e76d1712..5a1dbf47fea703bbf92b4481365595fac05b595b 100644
--- a/lib/SimpleSAML/Stats.php
+++ b/lib/SimpleSAML/Stats.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML;
 
 /**
  * Statistics handler class.
@@ -8,9 +9,9 @@
  *
  * @package SimpleSAMLphp
  */
-class SimpleSAML_Stats
-{
 
+class Stats
+{
     /**
      * Whether this class is initialized.
      *
@@ -30,14 +31,14 @@ class SimpleSAML_Stats
     /**
      * Create an output from a configuration object.
      *
-     * @param SimpleSAML_Configuration $config The configuration object.
+     * @param \SimpleSAML\Configuration $config The configuration object.
      *
      * @return mixed A new instance of the configured class.
      */
-    private static function createOutput(SimpleSAML_Configuration $config)
+    private static function createOutput(\SimpleSAML\Configuration $config)
     {
         $cls = $config->getString('class');
-        $cls = SimpleSAML\Module::resolveClass($cls, 'Stats_Output', 'SimpleSAML_Stats_Output');
+        $cls = \SimpleSAML\Module::resolveClass($cls, 'Stats_Output', '\SimpleSAML\Stats\Output');
 
         $output = new $cls($config);
         return $output;
@@ -50,7 +51,7 @@ class SimpleSAML_Stats
     private static function initOutputs()
     {
 
-        $config = SimpleSAML_Configuration::getInstance();
+        $config = \SimpleSAML\Configuration::getInstance();
         $outputCfgs = $config->getConfigList('statistics.out', array());
 
         self::$outputs = array();
@@ -97,5 +98,4 @@ class SimpleSAML_Stats
             $out->emit($data);
         }
     }
-
 }
diff --git a/lib/SimpleSAML/Stats/Output.php b/lib/SimpleSAML/Stats/Output.php
index 8b019c8c9de4ccefa253a7e7016b3462afc2a875..a4a05ed44b0f318d9ec339fc9ac1d6687b10b160 100644
--- a/lib/SimpleSAML/Stats/Output.php
+++ b/lib/SimpleSAML/Stats/Output.php
@@ -1,20 +1,21 @@
 <?php
 
+namespace SimpleSAML\Stats;
 
 /**
  * Interface for statistics outputs.
  *
  * @package SimpleSAMLphp
  */
-abstract class SimpleSAML_Stats_Output
-{
 
+abstract class Output
+{
     /**
      * Initialize the output.
      *
-     * @param SimpleSAML_Configuration $config The configuration for this output.
+     * @param \SimpleSAML\Configuration $config The configuration for this output.
      */
-    public function __construct(SimpleSAML_Configuration $config)
+    public function __construct(\SimpleSAML\Configuration $config)
     {
         // do nothing by default
     }
diff --git a/lib/SimpleSAML/Store.php b/lib/SimpleSAML/Store.php
index 8f25b59c9194f2fc20843e7c30a428e33aa5f01e..3beb66eba1b0ea8e774adc133e1f864c05098fd2 100644
--- a/lib/SimpleSAML/Store.php
+++ b/lib/SimpleSAML/Store.php
@@ -34,7 +34,7 @@ abstract class Store
             return self::$instance;
         }
 
-        $config = \SimpleSAML_Configuration::getInstance();
+        $config = Configuration::getInstance();
         $storeType = $config->getString('store.type', null);
         if ($storeType === null) {
             $storeType = $config->getString('session.handler', 'phpsession');
diff --git a/lib/SimpleSAML/Store/Memcache.php b/lib/SimpleSAML/Store/Memcache.php
index 8f9fcfbea9ff51f6b53f9ef2e2a0304d0d84166a..f865d462d468abf3fcaa62d0b85fb0bd431d4793 100644
--- a/lib/SimpleSAML/Store/Memcache.php
+++ b/lib/SimpleSAML/Store/Memcache.php
@@ -2,7 +2,7 @@
 
 namespace SimpleSAML\Store;
 
-use \SimpleSAML_Configuration as Configuration;
+use \SimpleSAML\Configuration;
 use \SimpleSAML\Store;
 
 /**
@@ -42,7 +42,7 @@ class Memcache extends Store
         assert(is_string($type));
         assert(is_string($key));
 
-        return \SimpleSAML_Memcache::get($this->prefix . '.' . $type . '.' . $key);
+        return \SimpleSAML\Memcache::get($this->prefix . '.' . $type . '.' . $key);
     }
 
 
@@ -64,7 +64,7 @@ class Memcache extends Store
             $expire = 0;
         }
 
-        \SimpleSAML_Memcache::set($this->prefix . '.' . $type . '.' . $key, $value, $expire);
+        \SimpleSAML\Memcache::set($this->prefix . '.' . $type . '.' . $key, $value, $expire);
     }
 
 
@@ -79,6 +79,6 @@ class Memcache extends Store
         assert(is_string($type));
         assert(is_string($key));
 
-        \SimpleSAML_Memcache::delete($this->prefix . '.' . $type . '.' . $key);
+        \SimpleSAML\Memcache::delete($this->prefix . '.' . $type . '.' . $key);
     }
 }
diff --git a/lib/SimpleSAML/Store/Redis.php b/lib/SimpleSAML/Store/Redis.php
index 2f568e3600544953edfd2c43384ffe1be654850e..1841670ba8b1f7dfdebad3352a834816bbce320f 100644
--- a/lib/SimpleSAML/Store/Redis.php
+++ b/lib/SimpleSAML/Store/Redis.php
@@ -2,7 +2,7 @@
 
 namespace SimpleSAML\Store;
 
-use \SimpleSAML_Configuration as Configuration;
+use \SimpleSAML\Configuration;
 use \SimpleSAML\Store;
 
 /**
@@ -98,7 +98,8 @@ class Redis extends Store
         if ($expire === null) {
             $this->redis->set("{$type}.{$key}", $serialized);
         } else {
-            $this->redis->setex("{$type}.{$key}", $expire, $serialized);
+            // setex expire time is in seconds (not unix timestamp)
+            $this->redis->setex("{$type}.{$key}", $expire - time(), $serialized);
         }
     }
 
diff --git a/lib/SimpleSAML/Store/SQL.php b/lib/SimpleSAML/Store/SQL.php
index e2c176b42af28463c48765ad64222b698fd817b2..593db01425e878a468e71368d2974fa8e1994a95 100644
--- a/lib/SimpleSAML/Store/SQL.php
+++ b/lib/SimpleSAML/Store/SQL.php
@@ -2,7 +2,7 @@
 
 namespace SimpleSAML\Store;
 
-use \SimpleSAML_Configuration as Configuration;
+use \SimpleSAML\Configuration;
 use \SimpleSAML\Logger;
 use \SimpleSAML\Store;
 
@@ -48,16 +48,20 @@ class SQL extends Store
     /**
      * Initialize the SQL data store.
      */
-    protected function __construct()
+    public function __construct()
     {
         $config = Configuration::getInstance();
 
         $dsn = $config->getString('store.sql.dsn');
         $username = $config->getString('store.sql.username', null);
         $password = $config->getString('store.sql.password', null);
+        $options = $config->getArray('store.sql.options', null);
         $this->prefix = $config->getString('store.sql.prefix', 'simpleSAMLphp');
-
-        $this->pdo = new \PDO($dsn, $username, $password);
+        try {
+            $this->pdo = new \PDO($dsn, $username, $password, $options);
+        } catch (\PDOException $e) {
+            throw new \Exception("Database error: " . $e->getMessage());
+        }
         $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
 
         $this->driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
@@ -99,25 +103,61 @@ class SQL extends Store
      */
     private function initKVTable()
     {
-        if ($this->getTableVersion('kvstore') === 1) {
-            // Table initialized
-            return;
-        }
+        $current_version = $this->getTableVersion('kvstore');
 
         $text_t = 'TEXT';
         if ($this->driver === 'mysql') {
             // TEXT data type has size constraints that can be hit at some point, so we use LONGTEXT instead
             $text_t = 'LONGTEXT';
         }
-        $query = 'CREATE TABLE '.$this->prefix.
-                 '_kvstore (_type VARCHAR(30) NOT NULL, _key VARCHAR(50) NOT NULL, _value '.$text_t.
-                 ' NOT NULL, _expire TIMESTAMP, PRIMARY KEY (_key, _type))';
-        $this->pdo->exec($query);
 
-        $query = 'CREATE INDEX '.$this->prefix.'_kvstore_expire ON '.$this->prefix.'_kvstore (_expire)';
-        $this->pdo->exec($query);
+        /**
+         * Queries for updates, grouped by version.
+         * New updates can be added as a new array in this array
+         */
+        $table_updates = array(
+            array(
+                'CREATE TABLE '.$this->prefix.
+                '_kvstore (_type VARCHAR(30) NOT NULL, _key VARCHAR(50) NOT NULL, _value '.$text_t.
+                ' NOT NULL, _expire TIMESTAMP, PRIMARY KEY (_key, _type))',
+                'CREATE INDEX '.$this->prefix.'_kvstore_expire ON '.$this->prefix.'_kvstore (_expire)'
+            ),
+            /**
+             * This upgrade removes the default NOT NULL constraint on the _expire field in MySQL.
+             * Because SQLite does not support field alterations, the approach is to:
+             *     Create a new table without the NOT NULL constraint
+             *     Copy the current data to the new table
+             *     Drop the old table
+             *     Rename the new table correctly
+             *     Readd the index
+             */
+            array(
+                'CREATE TABLE '.$this->prefix.
+                '_kvstore_new (_type VARCHAR(30) NOT NULL, _key VARCHAR(50) NOT NULL, _value '.$text_t.
+                ' NOT NULL, _expire TIMESTAMP NULL, PRIMARY KEY (_key, _type))',
+                'INSERT INTO '.$this->prefix.'_kvstore_new SELECT * FROM ' . $this->prefix.'_kvstore',
+                'DROP TABLE '.$this->prefix.'_kvstore',
+                'ALTER TABLE '.$this->prefix.'_kvstore_new RENAME TO ' . $this->prefix . '_kvstore',
+                'CREATE INDEX '.$this->prefix.'_kvstore_expire ON '.$this->prefix.'_kvstore (_expire)'
+            )
+        );
+
+        $latest_version = count($table_updates);
+
+        if ($current_version == $latest_version) {
+            return;
+        }
+
+        // Only run queries for after the current version
+        $updates_to_run = array_slice($table_updates, $current_version);
+
+        foreach ($updates_to_run as $version_updates) {
+            foreach ($version_updates as $query) {
+                $this->pdo->exec($query);
+            }
+        }
 
-        $this->setTableVersion('kvstore', 1);
+        $this->setTableVersion('kvstore', $latest_version);
     }
 
 
diff --git a/lib/SimpleSAML/Utilities.php b/lib/SimpleSAML/Utilities.php
index 68cd10b877b755f358603245fda896ee4e714b96..d253408f126c8a550e79f69323b7db8b7a47b2a9 100644
--- a/lib/SimpleSAML/Utilities.php
+++ b/lib/SimpleSAML/Utilities.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML;
 
 /**
  * Misc static functions that is used several places.in example parsing and id generation.
@@ -9,9 +10,9 @@
  *
  * @deprecated This entire class will be removed in SimpleSAMLphp 2.0.
  */
-class SimpleSAML_Utilities
-{
 
+class Utilities
+{
     /**
      * @deprecated This property will be removed in SSP 2.0. Please use SimpleSAML\Logger::isErrorMasked() instead.
      */
@@ -112,11 +113,11 @@ class SimpleSAML_Utilities
 
 
     /**
-     * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML_Auth_State::parseStateID() instead.
+     * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Auth\State::parseStateID() instead.
      */
     public static function parseStateID($stateId)
     {
-        return SimpleSAML_Auth_State::parseStateID($stateId);
+        return \SimpleSAML\Auth\State::parseStateID($stateId);
     }
 
 
@@ -149,7 +150,7 @@ class SimpleSAML_Utilities
      */
     public static function generateID()
     {
-        return SimpleSAML\Utils\Random::generateID();
+        return \SimpleSAML\Utils\Random::generateID();
     }
 
 
@@ -159,7 +160,7 @@ class SimpleSAML_Utilities
      */
     public static function generateTimestamp($instant = null)
     {
-        return SimpleSAML\Utils\Time::generateTimestamp($instant);
+        return \SimpleSAML\Utils\Time::generateTimestamp($instant);
     }
 
 
@@ -168,16 +169,16 @@ class SimpleSAML_Utilities
      */
     public static function parseDuration($duration, $timestamp = null)
     {
-        return SimpleSAML\Utils\Time::parseDuration($duration, $timestamp);
+        return \SimpleSAML\Utils\Time::parseDuration($duration, $timestamp);
     }
 
 
     /**
-     * @deprecated This method will be removed in SSP 2.0. Please raise a SimpleSAML_Error_Error exception instead.
+     * @deprecated This method will be removed in SSP 2.0. Please raise a SimpleSAML\Error\Error exception instead.
      */
-    public static function fatalError($trackId = 'na', $errorCode = null, Exception $e = null)
+    public static function fatalError($trackId = 'na', $errorCode = null, \Exception $e = null)
     {
-        throw new SimpleSAML_Error_Error($errorCode, $e);
+        throw new \SimpleSAML\Error\Error($errorCode, $e);
     }
 
 
@@ -186,7 +187,7 @@ class SimpleSAML_Utilities
      */
     public static function ipCIDRcheck($cidr, $ip = null)
     {
-        return SimpleSAML\Utils\Net::ipCIDRcheck($cidr, $ip);
+        return \SimpleSAML\Utils\Net::ipCIDRcheck($cidr, $ip);
     }
 
 
@@ -213,7 +214,7 @@ class SimpleSAML_Utilities
         }
 
         if (strlen($url) > 2048) {
-            SimpleSAML\Logger::warning('Redirecting to a URL longer than 2048 bytes.');
+            \SimpleSAML\Logger::warning('Redirecting to a URL longer than 2048 bytes.');
         }
 
         // Set the location header
@@ -292,7 +293,7 @@ class SimpleSAML_Utilities
      */
     public static function transposeArray($in)
     {
-        return SimpleSAML\Utils\Arrays::transpose($in);
+        return \SimpleSAML\Utils\Arrays::transpose($in);
     }
 
 
@@ -300,18 +301,18 @@ class SimpleSAML_Utilities
      * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\XML::isDOMNodeOfType()
      *     instead.
      */
-    public static function isDOMElementOfType(DOMNode $element, $name, $nsURI)
+    public static function isDOMElementOfType(\DOMNode $element, $name, $nsURI)
     {
-        return SimpleSAML\Utils\XML::isDOMNodeOfType($element, $name, $nsURI);
+        return \SimpleSAML\Utils\XML::isDOMNodeOfType($element, $name, $nsURI);
     }
 
 
     /**
      * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\XML::getDOMChildren() instead.
      */
-    public static function getDOMChildren(DOMElement $element, $localName, $namespaceURI)
+    public static function getDOMChildren(\DOMElement $element, $localName, $namespaceURI)
     {
-        return SimpleSAML\Utils\XML::getDOMChildren($element, $localName, $namespaceURI);
+        return \SimpleSAML\Utils\XML::getDOMChildren($element, $localName, $namespaceURI);
     }
 
 
@@ -320,7 +321,7 @@ class SimpleSAML_Utilities
      */
     public static function getDOMText($element)
     {
-        return SimpleSAML\Utils\XML::getDOMText($element);
+        return \SimpleSAML\Utils\XML::getDOMText($element);
     }
 
 
@@ -419,7 +420,7 @@ class SimpleSAML_Utilities
      */
     public static function parseAttributes($attributes)
     {
-        return SimpleSAML\Utils\Attributes::normalizeAttributesArray($attributes);
+        return \SimpleSAML\Utils\Attributes::normalizeAttributesArray($attributes);
     }
 
 
@@ -428,7 +429,7 @@ class SimpleSAML_Utilities
      */
     public static function getSecretSalt()
     {
-        return SimpleSAML\Utils\Config::getSecretSalt();
+        return \SimpleSAML\Utils\Config::getSecretSalt();
     }
 
 
@@ -463,27 +464,27 @@ class SimpleSAML_Utilities
     /**
      * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\Crypto::loadPublicKey() instead.
      */
-    public static function loadPublicKey(SimpleSAML_Configuration $metadata, $required = false, $prefix = '')
+    public static function loadPublicKey(\SimpleSAML\Configuration $metadata, $required = false, $prefix = '')
     {
-        return SimpleSAML\Utils\Crypto::loadPublicKey($metadata, $required, $prefix);
+        return \SimpleSAML\Utils\Crypto::loadPublicKey($metadata, $required, $prefix);
     }
 
 
     /**
      * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\Crypto::loadPrivateKey() instead.
      */
-    public static function loadPrivateKey(SimpleSAML_Configuration $metadata, $required = false, $prefix = '')
+    public static function loadPrivateKey(\SimpleSAML\Configuration $metadata, $required = false, $prefix = '')
     {
-        return SimpleSAML\Utils\Crypto::loadPrivateKey($metadata, $required, $prefix);
+        return \SimpleSAML\Utils\Crypto::loadPrivateKey($metadata, $required, $prefix);
     }
 
 
     /**
      * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\XML::formatDOMElement() instead.
      */
-    public static function formatDOMElement(DOMElement $root, $indentBase = '')
+    public static function formatDOMElement(\DOMElement $root, $indentBase = '')
     {
-        SimpleSAML\Utils\XML::formatDOMElement($root, $indentBase);
+        \SimpleSAML\Utils\XML::formatDOMElement($root, $indentBase);
     }
 
 
@@ -492,7 +493,7 @@ class SimpleSAML_Utilities
      */
     public static function formatXMLString($xml, $indentBase = '')
     {
-        return SimpleSAML\Utils\XML::formatXMLString($xml, $indentBase);
+        return \SimpleSAML\Utils\XML::formatXMLString($xml, $indentBase);
     }
 
 
@@ -501,7 +502,7 @@ class SimpleSAML_Utilities
      */
     public static function arrayize($data, $index = 0)
     {
-        return SimpleSAML\Utils\Arrays::arrayize($data, $index);
+        return \SimpleSAML\Utils\Arrays::arrayize($data, $index);
     }
 
 
@@ -510,7 +511,7 @@ class SimpleSAML_Utilities
      */
     public static function isAdmin()
     {
-        return SimpleSAML\Utils\Auth::isAdmin();
+        return \SimpleSAML\Utils\Auth::isAdmin();
     }
 
 
@@ -519,7 +520,7 @@ class SimpleSAML_Utilities
      */
     public static function getAdminLoginURL($returnTo = null)
     {
-        return SimpleSAML\Utils\Auth::getAdminLoginURL($returnTo);
+        return \SimpleSAML\Utils\Auth::getAdminLoginURL($returnTo);
     }
 
 
@@ -560,18 +561,18 @@ class SimpleSAML_Utilities
         assert(is_string($destination));
         assert(is_array($post));
 
-        $postId = SimpleSAML\Utils\Random::generateID();
+        $postId = \SimpleSAML\Utils\Random::generateID();
         $postData = array(
             'post' => $post,
             'url'  => $destination,
         );
 
-        $session = SimpleSAML_Session::getSessionFromRequest();
+        $session = \SimpleSAML\Session::getSessionFromRequest();
         $session->setData('core_postdatalink', $postId, $postData);
 
-        $redirInfo = base64_encode(SimpleSAML\Utils\Crypto::aesEncrypt($session->getSessionId().':'.$postId));
+        $redirInfo = base64_encode(\SimpleSAML\Utils\Crypto::aesEncrypt($session->getSessionId().':'.$postId));
 
-        $url = SimpleSAML\Module::getModuleURL('core/postredirect.php', array('RedirInfo' => $redirInfo));
+        $url = \SimpleSAML\Module::getModuleURL('core/postredirect.php', array('RedirInfo' => $redirInfo));
         $url = preg_replace("#^https:#", "http:", $url);
 
         return $url;
@@ -610,7 +611,7 @@ class SimpleSAML_Utilities
      */
     public static function getTempDir()
     {
-        return SimpleSAML\Utils\System::getTempDir();
+        return \SimpleSAML\Utils\System::getTempDir();
     }
 
 
@@ -619,7 +620,7 @@ class SimpleSAML_Utilities
      */
     public static function maskErrors($mask)
     {
-        SimpleSAML\Logger::maskErrors($mask);
+        \SimpleSAML\Logger::maskErrors($mask);
     }
 
 
@@ -628,7 +629,7 @@ class SimpleSAML_Utilities
      */
     public static function popErrorMask()
     {
-        SimpleSAML\Logger::popErrorMask();
+        \SimpleSAML\Logger::popErrorMask();
     }
 
 
@@ -675,7 +676,7 @@ class SimpleSAML_Utilities
      */
     public static function aesEncrypt($clear)
     {
-        return SimpleSAML\Utils\Crypto::aesEncrypt($clear);
+        return \SimpleSAML\Utils\Crypto::aesEncrypt($clear);
     }
 
 
@@ -684,7 +685,7 @@ class SimpleSAML_Utilities
      */
     public static function aesDecrypt($encData)
     {
-        return SimpleSAML\Utils\Crypto::aesDecrypt($encData);
+        return \SimpleSAML\Utils\Crypto::aesDecrypt($encData);
     }
 
 
@@ -693,7 +694,7 @@ class SimpleSAML_Utilities
      */
     public static function isWindowsOS()
     {
-        return SimpleSAML\Utils\System::getOS() === SimpleSAML\Utils\System::WINDOWS;
+        return \SimpleSAML\Utils\System::getOS() === \SimpleSAML\Utils\System::WINDOWS;
     }
 
 
diff --git a/lib/SimpleSAML/Utils/Arrays.php b/lib/SimpleSAML/Utils/Arrays.php
index b7af49d0189ad8cdfafa03de912c5912083b8a13..0a5129230b98a50eac339225f2fb72ad0b441ed4 100644
--- a/lib/SimpleSAML/Utils/Arrays.php
+++ b/lib/SimpleSAML/Utils/Arrays.php
@@ -12,7 +12,7 @@ class Arrays
     /**
      * Put a non-array variable into an array.
      *
-     * @param array $data The data to place into an array.
+     * @param mixed $data The data to place into an array.
      * @param mixed $index The index or key of the array where to place the data. Defaults to 0.
      *
      * @return array An array with one element containing $data, with key $index, or $data itself if it's already an
diff --git a/lib/SimpleSAML/Utils/Attributes.php b/lib/SimpleSAML/Utils/Attributes.php
index 00e934f5e192e3332be5078cc7ce493bd8fdef02..f06efbfd628e92ebf2d1e1c49c4b9fad227fa2bd 100644
--- a/lib/SimpleSAML/Utils/Attributes.php
+++ b/lib/SimpleSAML/Utils/Attributes.php
@@ -1,4 +1,5 @@
 <?php
+
 namespace SimpleSAML\Utils;
 
 /**
@@ -7,9 +8,9 @@ namespace SimpleSAML\Utils;
  * @author Jaime Perez, UNINETT AS <jaime.perez@uninett.no>
  * @package SimpleSAML
  */
+
 class Attributes
 {
-
     /**
      * Look for an attribute in a normalized attributes array, failing if it's not there.
      *
@@ -21,7 +22,7 @@ class Attributes
      * $allow_multiple is set to true, the first value will be returned.
      *
      * @throws \InvalidArgumentException If $attributes is not an array or $expected is not a string.
-     * @throws \SimpleSAML_Error_Exception If the expected attribute was not found in the attributes array.
+     * @throws \SimpleSAML\Error\Exception If the expected attribute was not found in the attributes array.
      */
     public static function getExpectedAttribute($attributes, $expected, $allow_multiple = false)
     {
@@ -38,7 +39,7 @@ class Attributes
         }
 
         if (!array_key_exists($expected, $attributes)) {
-            throw new \SimpleSAML_Error_Exception("No such attribute '".$expected."' found.");
+            throw new \SimpleSAML\Error\Exception("No such attribute '".$expected."' found.");
         }
         $attribute = $attributes[$expected];
 
@@ -47,11 +48,10 @@ class Attributes
         }
 
         if (count($attribute) === 0) {
-            throw new \SimpleSAML_Error_Exception("Empty attribute '".$expected."'.'");
-
+            throw new \SimpleSAML\Error\Exception("Empty attribute '".$expected."'.'");
         } elseif (count($attribute) > 1) {
             if ($allow_multiple === false) {
-                throw new \SimpleSAML_Error_Exception(
+                throw new \SimpleSAML\Error\Exception(
                     'More than one value found for the attribute, multiple values not allowed.'
                 );
             }
diff --git a/lib/SimpleSAML/Utils/Auth.php b/lib/SimpleSAML/Utils/Auth.php
index 5360f74da0082e23911da5a27261a989a8892a78..ad6c4df4b06a05fc40fbefbcffd95dd036c760fd 100644
--- a/lib/SimpleSAML/Utils/Auth.php
+++ b/lib/SimpleSAML/Utils/Auth.php
@@ -10,7 +10,6 @@ use SimpleSAML\Module;
  */
 class Auth
 {
-
     /**
      * Retrieve a admin login URL.
      *
@@ -41,7 +40,7 @@ class Auth
      */
     public static function isAdmin()
     {
-        $session = \SimpleSAML_Session::getSessionFromRequest();
+        $session = \SimpleSAML\Session::getSessionFromRequest();
         return $session->isValid('admin') || $session->isValid('login-admin');
     }
 
@@ -52,7 +51,7 @@ class Auth
      * a login page if the current user doesn't have admin access.
      *
      * @return void This function will only return if the user is admin.
-     * @throws \SimpleSAML_Error_Exception If no "admin" authentication source was configured.
+     * @throws \SimpleSAML\Error\Exception If no "admin" authentication source was configured.
      *
      * @author Olav Morken, UNINETT AS <olav.morken@uninett.no>
      * @author Jaime Perez, UNINETT AS <jaime.perez@uninett.no>
@@ -64,13 +63,13 @@ class Auth
         }
 
         // not authenticated as admin user, start authentication
-        if (\SimpleSAML_Auth_Source::getById('admin') !== null) {
+        if (\SimpleSAML\Auth\Source::getById('admin') !== null) {
             $as = new \SimpleSAML\Auth\Simple('admin');
             $as->login();
         } else {
-            throw new \SimpleSAML_Error_Exception(
+            throw new \SimpleSAML\Error\Exception(
                 'Cannot find "admin" auth source, and admin privileges are required.'
             );
         }
     }
-}
\ No newline at end of file
+}
diff --git a/lib/SimpleSAML/Utils/Config.php b/lib/SimpleSAML/Utils/Config.php
index fa044516bd42e2cd13cfec721993b0e28d493ce9..77cdd0b257f693c12297057120ef2a6839300418 100644
--- a/lib/SimpleSAML/Utils/Config.php
+++ b/lib/SimpleSAML/Utils/Config.php
@@ -25,7 +25,7 @@ class Config
             throw new \InvalidArgumentException('Invalid input parameters.');
         }
 
-        $globalConfig = \SimpleSAML_Configuration::getInstance();
+        $globalConfig = \SimpleSAML\Configuration::getInstance();
         $base = $globalConfig->getPathValue('certdir', 'cert/');
         return System::resolvePath($path, $base);
     }
@@ -48,7 +48,7 @@ class Config
      */
     public static function getSecretSalt()
     {
-        $secretSalt = \SimpleSAML_Configuration::getInstance()->getString('secretsalt');
+        $secretSalt = \SimpleSAML\Configuration::getInstance()->getString('secretsalt');
         if ($secretSalt === 'defaultsecretsalt') {
             throw new \InvalidArgumentException('The "secretsalt" configuration option must be set to a secret value.');
         }
@@ -69,6 +69,11 @@ class Config
         $configDir    = dirname(dirname(dirname(__DIR__))) . '/config';
         /** @var string|false $configDirEnv */
         $configDirEnv = getenv('SIMPLESAMLPHP_CONFIG_DIR');
+        
+        if($configDirEnv === false) {
+            $configDirEnv = getenv('REDIRECT_SIMPLESAMLPHP_CONFIG_DIR');
+        }
+        
         if ($configDirEnv !== false) {
             if (!is_dir($configDirEnv)) {
                 throw new \InvalidArgumentException(
diff --git a/lib/SimpleSAML/Utils/Config/Metadata.php b/lib/SimpleSAML/Utils/Config/Metadata.php
index 632ec04cca8156bb31e1c7ee0ea452a48466d30e..d1974308f4987cfbe431bffe1e1f261a1f980f7c 100644
--- a/lib/SimpleSAML/Utils/Config/Metadata.php
+++ b/lib/SimpleSAML/Utils/Config/Metadata.php
@@ -117,8 +117,8 @@ class Metadata
 
         // check attributes is an associative array
         if (isset($contact['attributes'])) {
-            if (empty($contact['attributes']) 
-                || !is_array($contact['attributes']) 
+            if (empty($contact['attributes'])
+                || !is_array($contact['attributes'])
                 || count(array_filter(array_keys($contact['attributes']), 'is_string')) === 0
             ) {
                 throw new \InvalidArgumentException('"attributes" must be an array and cannot be empty.');
diff --git a/lib/SimpleSAML/Utils/Crypto.php b/lib/SimpleSAML/Utils/Crypto.php
index b9bca595c067bf724b33fb634439badf2b3abc25..d689b1f06bb195d4d709243473fa6dfcce9a609f 100644
--- a/lib/SimpleSAML/Utils/Crypto.php
+++ b/lib/SimpleSAML/Utils/Crypto.php
@@ -2,14 +2,17 @@
 
 namespace SimpleSAML\Utils;
 
+use SimpleSAML\Configuration;
+use SimpleSAML\Error;
+
 /**
  * A class for cryptography-related functions.
  *
  * @package SimpleSAMLphp
  */
+
 class Crypto
 {
-
     /**
      * Decrypt data using AES-256-CBC and the key provided as a parameter.
      *
@@ -18,7 +21,7 @@ class Crypto
      *
      * @return string The decrypted data.
      * @throws \InvalidArgumentException If $ciphertext is not a string.
-     * @throws \SimpleSAML_Error_Exception If the openssl module is not loaded.
+     * @throws Error\Exception If the openssl module is not loaded.
      *
      * @see \SimpleSAML\Utils\Crypto::aesDecrypt()
      */
@@ -37,7 +40,7 @@ class Crypto
             );
         }
         if (!function_exists("openssl_decrypt")) {
-            throw new \SimpleSAML_Error_Exception("The openssl PHP module is not loaded.");
+            throw new Error\Exception("The openssl PHP module is not loaded.");
         }
 
         // derive encryption and authentication keys from the secret
@@ -57,12 +60,12 @@ class Crypto
                 $iv
             );
 
-            if ($plaintext != false) {
+            if ($plaintext !== false) {
                 return $plaintext;
             }
         }
 
-        throw new \SimpleSAML_Error_Exception("Failed to decrypt ciphertext.");
+        throw new Error\Exception("Failed to decrypt ciphertext.");
     }
 
 
@@ -73,7 +76,7 @@ class Crypto
      *
      * @return string The decrypted data.
      * @throws \InvalidArgumentException If $ciphertext is not a string.
-     * @throws \SimpleSAML_Error_Exception If the openssl module is not loaded.
+     * @throws Error\Exception If the openssl module is not loaded.
      *
      * @author Andreas Solberg, UNINETT AS <andreas.solberg@uninett.no>
      * @author Jaime Perez, UNINETT AS <jaime.perez@uninett.no>
@@ -92,7 +95,7 @@ class Crypto
      *
      * @return string An HMAC of the encrypted data, the IV and the encrypted data, concatenated.
      * @throws \InvalidArgumentException If $data is not a string.
-     * @throws \SimpleSAML_Error_Exception If the openssl module is not loaded.
+     * @throws Error\Exception If the openssl module is not loaded.
      *
      * @see \SimpleSAML\Utils\Crypto::aesEncrypt()
      */
@@ -103,7 +106,7 @@ class Crypto
         }
 
         if (!function_exists("openssl_encrypt")) {
-            throw new \SimpleSAML_Error_Exception('The openssl PHP module is not loaded.');
+            throw new Error\Exception('The openssl PHP module is not loaded.');
         }
 
         // derive encryption and authentication keys from the secret
@@ -123,7 +126,7 @@ class Crypto
         );
 
         if ($ciphertext === false) {
-            throw new \SimpleSAML_Error_Exception("Failed to encrypt plaintext.");
+            throw new Error\Exception("Failed to encrypt plaintext.");
         }
 
         // return the ciphertext with proper authentication
@@ -138,7 +141,7 @@ class Crypto
      *
      * @return string An HMAC of the encrypted data, the IV and the encrypted data, concatenated.
      * @throws \InvalidArgumentException If $data is not a string.
-     * @throws \SimpleSAML_Error_Exception If the openssl module is not loaded.
+     * @throws Error\Exception If the openssl module is not loaded.
      *
      * @author Andreas Solberg, UNINETT AS <andreas.solberg@uninett.no>
      * @author Jaime Perez, UNINETT AS <jaime.perez@uninett.no>
@@ -176,7 +179,7 @@ class Crypto
      * - 'PEM': Data for the private key, in PEM-format.
      * - 'password': Password for the private key.
      *
-     * @param \SimpleSAML_Configuration $metadata The metadata array the private key should be loaded from.
+     * @param \SimpleSAML\Configuration $metadata The metadata array the private key should be loaded from.
      * @param bool                      $required Whether the private key is required. If this is true, a
      * missing key will cause an exception. Defaults to false.
      * @param string                    $prefix The prefix which should be used when reading from the metadata
@@ -186,13 +189,13 @@ class Crypto
      *
      * @return array|NULL Extracted private key, or NULL if no private key is present.
      * @throws \InvalidArgumentException If $required is not boolean or $prefix is not a string.
-     * @throws \SimpleSAML_Error_Exception If no private key is found in the metadata, or it was not possible to load
+     * @throws Error\Exception If no private key is found in the metadata, or it was not possible to load
      *     it.
      *
      * @author Andreas Solberg, UNINETT AS <andreas.solberg@uninett.no>
      * @author Olav Morken, UNINETT AS <olav.morken@uninett.no>
      */
-    public static function loadPrivateKey(\SimpleSAML_Configuration $metadata, $required = false, $prefix = '', $full_path = false)
+    public static function loadPrivateKey(Configuration $metadata, $required = false, $prefix = '', $full_path = false)
     {
         if (!is_bool($required) || !is_string($prefix) || !is_bool($full_path)) {
             throw new \InvalidArgumentException('Invalid input parameters.');
@@ -202,7 +205,7 @@ class Crypto
         if ($file === null) {
             // no private key found
             if ($required) {
-                throw new \SimpleSAML_Error_Exception('No private key found in metadata.');
+                throw new Error\Exception('No private key found in metadata.');
             } else {
                 return null;
             }
@@ -214,7 +217,7 @@ class Crypto
 
         $data = @file_get_contents($file);
         if ($data === false) {
-            throw new \SimpleSAML_Error_Exception('Unable to load private key from file "'.$file.'"');
+            throw new Error\Exception('Unable to load private key from file "'.$file.'"');
         }
 
         $ret = array(
@@ -246,30 +249,30 @@ class Crypto
      * - 'certFingerprint': Array of valid certificate fingerprints. (Deprecated. Only present if this is a
      *   certificate.)
      *
-     * @param \SimpleSAML_Configuration $metadata The metadata.
+     * @param \SimpleSAML\Configuration $metadata The metadata.
      * @param bool                      $required Whether the private key is required. If this is TRUE, a missing key
      *     will cause an exception. Default is FALSE.
      * @param string                    $prefix The prefix which should be used when reading from the metadata array.
      *     Defaults to ''.
      *
      * @return array|NULL Public key or certificate data, or NULL if no public key or certificate was found.
-     * @throws \InvalidArgumentException If $metadata is not an instance of \SimpleSAML_Configuration, $required is not
+     * @throws \InvalidArgumentException If $metadata is not an instance of \SimpleSAML\Configuration, $required is not
      *     boolean or $prefix is not a string.
-     * @throws \SimpleSAML_Error_Exception If no private key is found in the metadata, or it was not possible to load
+     * @throws Error\Exception If no private key is found in the metadata, or it was not possible to load
      *     it.
      *
      * @author Andreas Solberg, UNINETT AS <andreas.solberg@uninett.no>
      * @author Olav Morken, UNINETT AS <olav.morken@uninett.no>
      * @author Lasse Birnbaum Jensen
      */
-    public static function loadPublicKey(\SimpleSAML_Configuration $metadata, $required = false, $prefix = '')
+    public static function loadPublicKey(Configuration $metadata, $required = false, $prefix = '')
     {
         if (!is_bool($required) || !is_string($prefix)) {
             throw new \InvalidArgumentException('Invalid input parameters.');
         }
 
         $keys = $metadata->getPublicKeys(null, false, $prefix);
-        if ($keys !== null) {
+        if (!empty($keys)) {
             foreach ($keys as $key) {
                 if ($key['type'] !== 'X509Certificate') {
                     continue;
@@ -309,7 +312,7 @@ class Crypto
 
         // no public key/certificate available
         if ($required) {
-            throw new \SimpleSAML_Error_Exception('No public key / certificate found in metadata.');
+            throw new Error\Exception('No public key / certificate found in metadata.');
         } else {
             return null;
         }
@@ -355,7 +358,7 @@ class Crypto
      *
      * @return string The hashed password.
      * @throws \InvalidArgumentException If the input parameters are not strings.
-     * @throws \SimpleSAML_Error_Exception If the algorithm specified is not supported.
+     * @throws Error\Exception If the algorithm specified is not supported.
      *
      * @see hash_algos()
      *
@@ -389,7 +392,7 @@ class Crypto
             return $alg_str.base64_encode($hash.$salt);
         }
 
-        throw new \SimpleSAML_Error_Exception('Hashing algorithm \''.strtolower($algorithm).'\' is not supported');
+        throw new Error\Exception('Hashing algorithm \''.strtolower($algorithm).'\' is not supported');
     }
 
 
@@ -433,7 +436,7 @@ class Crypto
      *
      * @return boolean True if the hash corresponds with the given password, false otherwise.
      * @throws \InvalidArgumentException If the input parameters are not strings.
-     * @throws \SimpleSAML_Error_Exception If the algorithm specified is not supported.
+     * @throws Error\Exception If the algorithm specified is not supported.
      *
      * @author Dyonisius Visser, TERENA <visser@terena.org>
      */
@@ -466,6 +469,6 @@ class Crypto
             return $hash === $password;
         }
 
-        throw new \SimpleSAML_Error_Exception('Hashing algorithm \''.strtolower($alg).'\' is not supported');
+        throw new Error\Exception('Hashing algorithm \''.strtolower($alg).'\' is not supported');
     }
 }
diff --git a/lib/SimpleSAML/Utils/HTTP.php b/lib/SimpleSAML/Utils/HTTP.php
index bb8d30c9c935ba8a8b618167a4557d59bd891b32..f840450db804c8c76f7ec1af615f7441c6b88ee8 100644
--- a/lib/SimpleSAML/Utils/HTTP.php
+++ b/lib/SimpleSAML/Utils/HTTP.php
@@ -1,8 +1,11 @@
 <?php
 namespace SimpleSAML\Utils;
 
-use SimpleSAML\Module;
+use SimpleSAML\Configuration;
 use SimpleSAML\Logger;
+use SimpleSAML\Module;
+use SimpleSAML\Session;
+use SimpleSAML\Error;
 
 /**
  * HTTP-related utility methods.
@@ -11,28 +14,27 @@ use SimpleSAML\Logger;
  */
 class HTTP
 {
-
     /**
      * Obtain a URL where we can redirect to securely post a form with the given data to a specific destination.
      *
      * @param string $destination The destination URL.
      * @param array  $data An associative array containing the data to be posted to $destination.
      *
-     * @throws \SimpleSAML_Error_Exception If the current session is transient.
+     * @throws Error\Exception If the current session is transient.
      * @return string  A URL which allows to securely post a form to $destination.
      *
      * @author Jaime Perez, UNINETT AS <jaime.perez@uninett.no>
      */
     private static function getSecurePOSTRedirectURL($destination, $data)
     {
-        $session = \SimpleSAML_Session::getSessionFromRequest();
+        $session = Session::getSessionFromRequest();
         $id = self::savePOSTData($session, $destination, $data);
 
         // get the session ID
         $session_id = $session->getSessionId();
         if (is_null($session_id)) {
             // this is a transient session, it is pointless to continue
-            throw new \SimpleSAML_Error_Exception('Cannot save POST data to a transient session.');
+            throw new Error\Exception('Cannot save POST data to a transient session.');
         }
 
         // encrypt the session ID and the random ID
@@ -68,7 +70,7 @@ class HTTP
             if (!is_numeric($port)) {
                 array_push($decomposed, $port);
             }
-            $current = implode($decomposed, ":");
+            $current = implode(":", $decomposed);
         }
         return $current;
     }
@@ -108,15 +110,14 @@ class HTTP
      */
     public static function getServerPort()
     {
-        $port = (isset($_SERVER['SERVER_PORT'])) ? $_SERVER['SERVER_PORT'] : '80';
-        if (self::getServerHTTPS()) {
-            if ($port !== '443') {
-                return ':'.$port;
-            }
-        } else {
-            if ($port !== '80') {
-                return ':'.$port;
-            }
+        $default_port = self::getServerHTTPS() ? '443' : '80';
+        $port = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : $default_port;
+
+        // Take care of edge-case where SERVER_PORT is an integer
+        $port = strval($port);
+        
+        if ($port !== $default_port) {
+            return ':'.$port;
         }
         return '';
     }
@@ -176,7 +177,7 @@ class HTTP
 
             // disable caching of this response
             header('Pragma: no-cache');
-            header('Cache-Control: no-cache, must-revalidate');
+            header('Cache-Control: no-cache, no-store, must-revalidate');
         }
 
         // show a minimal web page with a clickable link to the URL
@@ -206,7 +207,7 @@ class HTTP
     /**
      * Save the given HTTP POST data and the destination where it should be posted to a given session.
      *
-     * @param \SimpleSAML_Session $session The session where to temporarily store the data.
+     * @param \SimpleSAML\Session $session The session where to temporarily store the data.
      * @param string              $destination The destination URL where the form should be posted.
      * @param array               $data An associative array with the data to be posted to $destination.
      *
@@ -215,7 +216,7 @@ class HTTP
      * @author Andjelko Horvat
      * @author Jaime Perez, UNINETT AS <jaime.perez@uninett.no>
      */
-    private static function savePOSTData(\SimpleSAML_Session $session, $destination, $data)
+    private static function savePOSTData(Session $session, $destination, $data)
     {
         // generate a random ID to avoid replay attacks
         $id = Random::generateID();
@@ -290,7 +291,7 @@ class HTTP
             throw new \InvalidArgumentException('Invalid input parameters.');
         }
 
-        $session = \SimpleSAML_Session::getSessionFromRequest();
+        $session = Session::getSessionFromRequest();
         if ($session->hasSessionCookie()) {
             return;
         }
@@ -315,7 +316,7 @@ class HTTP
      * @return string The normalized URL itself if it is allowed. An empty string if the $url parameter is empty as
      * defined by the empty() function.
      * @throws \InvalidArgumentException If the URL is malformed.
-     * @throws \SimpleSAML_Error_Exception If the URL is not allowed by configuration.
+     * @throws Error\Exception If the URL is not allowed by configuration.
      *
      * @author Jaime Perez, UNINETT AS <jaime.perez@uninett.no>
      */
@@ -327,30 +328,38 @@ class HTTP
         $url = self::normalizeURL($url);
 
         if (filter_var($url, FILTER_VALIDATE_URL) === false) {
-            throw new \SimpleSAML_Error_Exception('Invalid URL: '.$url);
+            throw new Error\Exception('Invalid URL: '.$url);
         }
 
         // get the white list of domains
         if ($trustedSites === null) {
-            $trustedSites = \SimpleSAML_Configuration::getInstance()->getValue('trusted.url.domains', array());
+            $trustedSites = Configuration::getInstance()->getValue('trusted.url.domains', array());
         }
 
         // validates the URL's host is among those allowed
         if (is_array($trustedSites)) {
             assert(is_array($trustedSites));
-            preg_match('@^http(s?)://([^/:]+)((?::\d+)?)@i', $url, $matches);
-            $hostname = $matches[2];
+            $components = parse_url($url);
+            $hostname = $components['host'];
+
+            // check for userinfo
+            if ((isset($components['user']) && strpos($components['user'], '\\') !== false) ||
+                (isset($components['pass']) && strpos($components['pass'], '\\') !== false)
+            ) {
+                throw new Error\Exception('Invalid URL: '.$url);
+            }
 
             // allow URLs with standard ports specified (non-standard ports must then be allowed explicitly)
-            if (!empty($matches[3]) &&
-                (($matches[1] === '' && $matches[3] !== ':80') || ($matches[1]) === 's' && $matches[3] !== ':443')
+            if (isset($components['port']) &&
+                (($components['scheme'] === 'http' && $components['port'] !== 80) ||
+                 ($components['scheme'] === 'https' && $components['port'] !== 443))
             ) {
-                $hostname = $hostname.$matches[3];
+                $hostname = $hostname.':'.$components['port'];
             }
 
             $self_host = self::getSelfHostWithNonStandardPort();
 
-            $trustedRegex = \SimpleSAML_Configuration::getInstance()->getValue('trusted.url.regex', false);
+            $trustedRegex = Configuration::getInstance()->getValue('trusted.url.regex', false);
 
             $trusted = false;
             if ($trustedRegex) {
@@ -372,7 +381,7 @@ class HTTP
 
             // throw exception due to redirection to untrusted site
             if (!$trusted) {
-                throw new \SimpleSAML_Error_Exception('URL not allowed: '.$url);
+                throw new Error\Exception('URL not allowed: '.$url);
             }
         }
         return $url;
@@ -392,7 +401,7 @@ class HTTP
      * @return string|array An array if $getHeaders is set, containing the data and the headers respectively; string
      *  otherwise.
      * @throws \InvalidArgumentException If the input parameters are invalid.
-     * @throws \SimpleSAML_Error_Exception If the file or URL cannot be retrieved.
+     * @throws Error\Exception If the file or URL cannot be retrieved.
      *
      * @author Andjelko Horvat
      * @author Olav Morken, UNINETT AS <olav.morken@uninett.no>
@@ -404,7 +413,7 @@ class HTTP
             throw new \InvalidArgumentException('Invalid input parameters.');
         }
 
-        $config = \SimpleSAML_Configuration::getInstance();
+        $config = Configuration::getInstance();
 
         $proxy = $config->getString('proxy', null);
         if ($proxy !== null) {
@@ -413,7 +422,7 @@ class HTTP
             }
             $proxy_auth = $config->getString('proxy.auth', false);
             if ($proxy_auth !== false) {
-                $context['http']['header'] = "Proxy-Authorization: Basic".base64_encode($proxy_auth);
+                $context['http']['header'] = "Proxy-Authorization: Basic ".base64_encode($proxy_auth);
             }
             if (!isset($context['http']['request_fulluri'])) {
                 $context['http']['request_fulluri'] = true;
@@ -444,10 +453,10 @@ class HTTP
         }
 
         $context = stream_context_create($context);
-        $data = file_get_contents($url, false, $context);
+        $data = @file_get_contents($url, false, $context);
         if ($data === false) {
             $error = error_get_last();
-            throw new \SimpleSAML_Error_Exception('Error fetching '.var_export($url, true).':'.
+            throw new Error\Exception('Error fetching '.var_export($url, true).':'.
                 (is_array($error) ? $error['message'] : 'no error available'));
         }
 
@@ -589,14 +598,13 @@ class HTTP
      */
     public static function getBaseURL()
     {
-        $globalConfig = \SimpleSAML_Configuration::getInstance();
+        $globalConfig = Configuration::getInstance();
         $baseURL = $globalConfig->getString('baseurlpath', 'simplesaml/');
 
         if (preg_match('#^https?://.*/?$#D', $baseURL, $matches)) {
             // full URL in baseurlpath, override local server values
             return rtrim($baseURL, '/').'/';
-        } elseif (
-            (preg_match('#^/?([^/]?.*/)$#D', $baseURL, $matches)) ||
+        } elseif ((preg_match('#^/?([^/]?.*/)$#D', $baseURL, $matches)) ||
             (preg_match('#^\*(.*)/$#D', $baseURL, $matches)) ||
             ($baseURL === '')
         ) {
@@ -663,14 +671,14 @@ class HTTP
             throw new \InvalidArgumentException('Invalid input parameters.');
         }
 
-        $config = \SimpleSAML_Configuration::getInstance();
+        $config = Configuration::getInstance();
         $allowed = $config->getBoolean('enable.http_post', false);
 
         if ($allowed && preg_match("#^http:#", $destination) && self::isHTTPS()) {
             // we need to post the data to HTTP
             $url = self::getSecurePOSTRedirectURL($destination, $data);
         } else { // post the data directly
-            $session = \SimpleSAML_Session::getSessionFromRequest();
+            $session = Session::getSessionFromRequest();
             $id = self::savePOSTData($session, $destination, $data);
             $url = Module::getModuleURL('core/postredirect.php', array('RedirId' => $id));
         }
@@ -753,7 +761,7 @@ class HTTP
      */
     public static function getSelfURL()
     {
-        $cfg = \SimpleSAML_Configuration::getInstance();
+        $cfg = Configuration::getInstance();
         $baseDir = $cfg->getBaseDir();
         $cur_path = realpath($_SERVER['SCRIPT_FILENAME']);
         // make sure we got a string from realpath()
@@ -784,15 +792,14 @@ class HTTP
              * for this case in the configuration. First, check if that's the case.
              */
 
-            /** @var \SimpleSAML_Configuration $appcfg */
+            /** @var \SimpleSAML\Configuration $appcfg */
             $appcfg = $cfg->getConfigItem('application', null);
-            $appurl = ($appcfg instanceof \SimpleSAML_Configuration) ? $appcfg->getString('baseURL', '') : '';
+            $appurl = ($appcfg instanceof Configuration) ? $appcfg->getString('baseURL', '') : '';
             if (!empty($appurl)) {
                 $protocol = parse_url($appurl, PHP_URL_SCHEME);
                 $hostname = parse_url($appurl, PHP_URL_HOST);
                 $port = parse_url($appurl, PHP_URL_PORT);
                 $port = !empty($port) ? ':'.$port : '';
-
             } else { // no base URL specified for app, just use the current URL
                 $protocol = 'http';
                 $protocol .= (self::getServerHTTPS()) ? 's' : '';
@@ -964,7 +971,7 @@ class HTTP
 
     /**
      * This function redirects to the specified URL after performing the appropriate security checks on it.
-     * Particularly, it will make sure that the provided URL is allowed by the 'redirect.trustedsites' directive in the
+     * Particularly, it will make sure that the provided URL is allowed by the 'trusted.url.domains' directive in the
      * configuration.
      *
      * If the aforementioned option is not set or the URL does correspond to a trusted site, it performs a redirection
@@ -1200,7 +1207,7 @@ class HTTP
             throw new \InvalidArgumentException('Invalid input parameters.');
         }
 
-        $config = \SimpleSAML_Configuration::getInstance();
+        $config = Configuration::getInstance();
         $allowed = $config->getBoolean('enable.http_post', false);
 
         if ($allowed && preg_match("#^http:#", $destination) && self::isHTTPS()) {
@@ -1208,7 +1215,7 @@ class HTTP
             self::redirect(self::getSecurePOSTRedirectURL($destination, $data));
         }
 
-        $p = new \SimpleSAML_XHTML_Template($config, 'post.php');
+        $p = new \SimpleSAML\XHTML\Template($config, 'post.php');
         $p->data['destination'] = $destination;
         $p->data['post'] = $data;
         $p->show();
diff --git a/lib/SimpleSAML/Utils/HttpAdapter.php b/lib/SimpleSAML/Utils/HttpAdapter.php
new file mode 100644
index 0000000000000000000000000000000000000000..71c611508ba17ea4351eb840a2bf7c95fa22ea4e
--- /dev/null
+++ b/lib/SimpleSAML/Utils/HttpAdapter.php
@@ -0,0 +1,211 @@
+<?php
+
+namespace SimpleSAML\Utils;
+
+/**
+ * Provides a non-static wrapper for the HTTP utility class.
+ *
+ * @package SimpleSAML\Utils
+ */
+class HttpAdapter
+{
+    /**
+     * @see HTTP::getServerHTTPS()
+     */
+    public function getServerHTTPS()
+    {
+        return HTTP::getServerHTTPS();
+    }
+
+    /**
+     * @see HTTP::getServerPort()
+     */
+    public function getServerPort()
+    {
+        return HTTP::getServerPort();
+    }
+
+    /**
+     * @see HTTP::addURLParameters()
+     */
+    public function addURLParameters($url, $parameters)
+    {
+        return HTTP::addURLParameters($url, $parameters);
+    }
+
+    /**
+     * @see HTTP::checkSessionCookie()
+     */
+    public function checkSessionCookie($retryURL = null)
+    {
+        HTTP::checkSessionCookie($retryURL);
+    }
+
+    /**
+     * @see HTTP::checkURLAllowed()
+     */
+    public function checkURLAllowed($url, array $trustedSites = null)
+    {
+        return HTTP::checkURLAllowed($url, $trustedSites);
+    }
+
+    /**
+     * @see HTTP::fetch()
+     */
+    public function fetch($url, $context = array(), $getHeaders = false)
+    {
+        return HTTP::fetch($url, $context, $getHeaders);
+    }
+
+    /**
+     * @see HTTP::getAcceptLanguage()
+     */
+    public function getAcceptLanguage()
+    {
+        return HTTP::getAcceptLanguage();
+    }
+
+    /**
+     * @see HTTP::guessBasePath()
+     */
+    public function guessBasePath()
+    {
+        return HTTP::guessBasePath();
+    }
+
+    /**
+     * @see HTTP::getBaseURL()
+     */
+    public function getBaseURL()
+    {
+        return HTTP::getBaseURL();
+    }
+
+    /**
+     * @see HTTP::getFirstPathElement()
+     */
+    public function getFirstPathElement($trailingslash = true)
+    {
+        return HTTP::getFirstPathElement($trailingslash);
+    }
+
+    /**
+     * @see HTTP::getPOSTRedirectURL()
+     */
+    public function getPOSTRedirectURL($destination, $data)
+    {
+        return HTTP::getPOSTRedirectURL($destination, $data);
+    }
+
+    /**
+     * @see HTTP::getSelfHost()
+     */
+    public function getSelfHost()
+    {
+        return HTTP::getSelfHost();
+    }
+
+    /**
+     * @see HTTP::getSelfHostWithNonStandardPort()
+     */
+    public function getSelfHostWithNonStandardPort()
+    {
+        return HTTP::getSelfHostWithNonStandardPort();
+    }
+
+    /**
+     * @see HTTP::getSelfHostWithPath()
+     */
+    public function getSelfHostWithPath()
+    {
+        return HTTP::getSelfHostWithPath();
+    }
+
+    /**
+     * @see HTTP::getSelfURL()
+     */
+    public function getSelfURL()
+    {
+        return HTTP::getSelfURL();
+    }
+
+    /**
+     * @see HTTP::getSelfURLHost()
+     */
+    public function getSelfURLHost()
+    {
+        return HTTP::getSelfURLHost();
+    }
+
+    /**
+     * @see HTTP::getSelfURLNoQuery()
+     */
+    public function getSelfURLNoQuery()
+    {
+        return HTTP::getSelfURLNoQuery();
+    }
+
+    /**
+     * @see HTTP::isHTTPS()
+     */
+    public function isHTTPS()
+    {
+        return HTTP::isHTTPS();
+    }
+
+    /**
+     * @see HTTP::normalizeURL()
+     */
+    public function normalizeURL($url)
+    {
+        return HTTP::normalizeURL($url);
+    }
+
+    /**
+     * @see HTTP::parseQueryString()
+     */
+    public function parseQueryString($query_string)
+    {
+        return HTTP::parseQueryString($query_string);
+    }
+
+    /**
+     * @see HTTP::redirectTrustedURL()
+     */
+    public function redirectTrustedURL($url, $parameters = array())
+    {
+        HTTP::redirectTrustedURL($url, $parameters);
+    }
+
+    /**
+     * @see HTTP::redirectUntrustedURL()
+     */
+    public function redirectUntrustedURL($url, $parameters = array())
+    {
+        HTTP::redirectUntrustedURL($url, $parameters);
+    }
+
+    /**
+     * @see HTTP::resolveURL()
+     */
+    public function resolveURL($url, $base = null)
+    {
+        return HTTP::resolveURL($url, $base);
+    }
+
+    /**
+     * @see HTTP::setCookie()
+     */
+    public function setCookie($name, $value, $params = null, $throw = true)
+    {
+        HTTP::setCookie($name, $value, $params, $throw);
+    }
+
+    /**
+     * @see HTTP::submitPOSTData()
+     */
+    public function submitPOSTData($destination, $data)
+    {
+        HTTP::submitPOSTData($destination, $data);
+    }
+}
diff --git a/lib/SimpleSAML/Utils/Random.php b/lib/SimpleSAML/Utils/Random.php
index b53ace2e5a5f40e1af4632c40db0a3a4421018ac..86937294e2b5c6ed3ca907bbc51ad5705a092fc7 100644
--- a/lib/SimpleSAML/Utils/Random.php
+++ b/lib/SimpleSAML/Utils/Random.php
@@ -27,4 +27,4 @@ class Random
     {
         return '_'.bin2hex(openssl_random_pseudo_bytes((int)((self::ID_LENGTH - 1)/2)));
     }
-}
\ No newline at end of file
+}
diff --git a/lib/SimpleSAML/Utils/System.php b/lib/SimpleSAML/Utils/System.php
index 43c0b9b55431568f5d4ce3d0585ec5e7fb1343b0..6769ae9b6d83597d8e8078856e93560c38d75213 100644
--- a/lib/SimpleSAML/Utils/System.php
+++ b/lib/SimpleSAML/Utils/System.php
@@ -1,14 +1,17 @@
 <?php
+
 namespace SimpleSAML\Utils;
 
+use SimpleSAML\Error;
+
 /**
  * System-related utility methods.
  *
  * @package SimpleSAMLphp
  */
+
 class System
 {
-
     const WINDOWS = 1;
     const LINUX = 2;
     const OSX = 3;
@@ -60,7 +63,7 @@ class System
      * This function retrieves the path to a directory where temporary files can be saved.
      *
      * @return string Path to a temporary directory, without a trailing directory separator.
-     * @throws \SimpleSAML_Error_Exception If the temporary directory cannot be created or it exists and does not belong
+     * @throws Error\Exception If the temporary directory cannot be created or it exists and does not belong
      * to the current user.
      *
      * @author Andreas Solberg, UNINETT AS <andreas.solberg@uninett.no>
@@ -69,7 +72,7 @@ class System
      */
     public static function getTempDir()
     {
-        $globalConfig = \SimpleSAML_Configuration::getInstance();
+        $globalConfig = \SimpleSAML\Configuration::getInstance();
 
         $tempDir = rtrim(
             $globalConfig->getString(
@@ -82,7 +85,7 @@ class System
         if (!is_dir($tempDir)) {
             if (!mkdir($tempDir, 0700, true)) {
                 $error = error_get_last();
-                throw new \SimpleSAML_Error_Exception(
+                throw new Error\Exception(
                     'Error creating temporary directory "'.$tempDir.'": '.
                     (is_array($error) ? $error['message'] : 'no error available')
                 );
@@ -91,7 +94,7 @@ class System
             // check that the owner of the temp directory is the current user
             $stat = lstat($tempDir);
             if ($stat['uid'] !== posix_getuid()) {
-                throw new \SimpleSAML_Error_Exception(
+                throw new Error\Exception(
                     'Temporary directory "'.$tempDir.'" does not belong to the current user.'
                 );
             }
@@ -118,17 +121,24 @@ class System
     public static function resolvePath($path, $base = null)
     {
         if ($base === null) {
-            $config = \SimpleSAML_Configuration::getInstance();
+            $config = \SimpleSAML\Configuration::getInstance();
             $base = $config->getBaseDir();
         }
 
+        // normalise directory separator
+        $base = str_replace('\\', '/', $base);
+        $path = str_replace('\\', '/', $path);
+
         // remove trailing slashes
         $base = rtrim($base, '/');
+        $path = rtrim($path, '/');
 
         // check for absolute path
         if (substr($path, 0, 1) === '/') {
             // absolute path. */
             $ret = '/';
+        } elseif (static::pathContainsDriveLetter($path)) {
+            $ret = '';
         } else {
             // path relative to base
             $ret = $base;
@@ -141,7 +151,7 @@ class System
             } elseif ($d === '..') {
                 $ret = dirname($ret);
             } else {
-                if (substr($ret, -1) !== '/') {
+                if ($ret && substr($ret, -1) !== '/') {
                     $ret .= '/';
                 }
                 $ret .= $d;
@@ -163,7 +173,7 @@ class System
      * @param int    $mode The permissions to apply to the file. Defaults to 0600.
      *
      * @throws \InvalidArgumentException If any of the input parameters doesn't have the proper types.
-     * @throws \SimpleSAML_Error_Exception If the file cannot be saved, permissions cannot be changed or it is not
+     * @throws Error\Exception If the file cannot be saved, permissions cannot be changed or it is not
      *     possible to write to the target file.
      *
      * @author Andreas Solberg, UNINETT AS <andreas.solberg@uninett.no>
@@ -184,7 +194,7 @@ class System
         $res = @file_put_contents($tmpFile, $data);
         if ($res === false) {
             $error = error_get_last();
-            throw new \SimpleSAML_Error_Exception(
+            throw new Error\Exception(
                 'Error saving file "'.$tmpFile.'": '.
                 (is_array($error) ? $error['message'] : 'no error available')
             );
@@ -195,7 +205,7 @@ class System
                 unlink($tmpFile);
                 $error = error_get_last();
                 //$error = (is_array($error) ? $error['message'] : 'no error available');
-                throw new \SimpleSAML_Error_Exception(
+                throw new Error\Exception(
                     'Error changing file mode of "'.$tmpFile.'": '.
                     (is_array($error) ? $error['message'] : 'no error available')
                 );
@@ -205,7 +215,7 @@ class System
         if (!rename($tmpFile, $filename)) {
             unlink($tmpFile);
             $error = error_get_last();
-            throw new \SimpleSAML_Error_Exception(
+            throw new Error\Exception(
                 'Error moving "'.$tmpFile.'" to "'.$filename.'": '.
                 (is_array($error) ? $error['message'] : 'no error available')
             );
@@ -215,4 +225,18 @@ class System
             opcache_invalidate($filename);
         }
     }
+
+    /**
+     * Check if the supplied path contains a Windows-style drive letter.
+     *
+     * @param string $path
+     *
+     * @return bool
+     */
+    private static function pathContainsDriveLetter($path)
+    {
+        $letterAsciiValue = ord(strtoupper(substr($path, 0, 1)));
+        return substr($path, 1, 1) === ':'
+                && $letterAsciiValue >= 65 && $letterAsciiValue <= 90;
+    }
 }
diff --git a/lib/SimpleSAML/Utils/Time.php b/lib/SimpleSAML/Utils/Time.php
index be8d47b2d9986a55c12d849bc490a42e59dcaef9..78246f9415fdd9d886b8c75c7d7c072b01821a9e 100644
--- a/lib/SimpleSAML/Utils/Time.php
+++ b/lib/SimpleSAML/Utils/Time.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Time-related utility methods.
  *
@@ -9,10 +10,8 @@ namespace SimpleSAML\Utils;
 
 use SimpleSAML\Logger;
 
-
 class Time
 {
-
     /**
      * Whether the timezone has been initialized or not.
      *
@@ -45,7 +44,7 @@ class Time
      *
      * @author Olav Morken, UNINETT AS <olav.morken@uninett.no>
      *
-     * @throws \SimpleSAML_Error_Exception If the timezone set in the configuration is invalid.
+     * @throws \SimpleSAML\Error\Exception If the timezone set in the configuration is invalid.
      *
      * @return void
      */
@@ -55,12 +54,12 @@ class Time
             return;
         }
 
-        $globalConfig = \SimpleSAML_Configuration::getInstance();
+        $globalConfig = \SimpleSAML\Configuration::getInstance();
 
         $timezone = $globalConfig->getString('timezone', null);
         if ($timezone !== null) {
             if (!date_default_timezone_set($timezone)) {
-                throw new \SimpleSAML_Error_Exception('Invalid timezone set in the "timezone" option in config.php.');
+                throw new \SimpleSAML\Error\Exception('Invalid timezone set in the "timezone" option in config.php.');
             }
             self::$tz_initialized = true;
             return;
diff --git a/lib/SimpleSAML/Utils/XML.php b/lib/SimpleSAML/Utils/XML.php
index 3f540d96a4ea1c07ba06057a224093b4847ced07..002212e1652ffe8f0e606548bad58cc109d5cd94 100644
--- a/lib/SimpleSAML/Utils/XML.php
+++ b/lib/SimpleSAML/Utils/XML.php
@@ -25,7 +25,7 @@ class XML
      *
      * @throws \InvalidArgumentException If $message is not a string or $type is not a string containing one of the
      *     values allowed.
-     * @throws \SimpleSAML_Error_Exception If $message contains a doctype declaration.
+     * @throws \SimpleSAML\Error\Exception If $message contains a doctype declaration.
      *
      * @return void
      *
@@ -41,12 +41,12 @@ class XML
 
         // a SAML message should not contain a doctype-declaration
         if (strpos($message, '<!DOCTYPE') !== false) {
-            throw new \SimpleSAML_Error_Exception('XML contained a doctype declaration.');
+            throw new \SimpleSAML\Error\Exception('XML contained a doctype declaration.');
         }
 
         // see if debugging is enabled for XML validation
-        $debug = \SimpleSAML_Configuration::getInstance()->getArrayize('debug', array('validatexml' => false));
-        $enabled = \SimpleSAML_Configuration::getInstance()->getBoolean('debug.validatexml', false);
+        $debug = \SimpleSAML\Configuration::getInstance()->getArrayize('debug', array('validatexml' => false));
+        $enabled = \SimpleSAML\Configuration::getInstance()->getBoolean('debug.validatexml', false);
 
         if (!(in_array('validatexml', $debug, true) // implicitly enabled
               || (array_key_exists('validatexml', $debug) && $debug['validatexml'] === true) // explicitly enabled
@@ -98,7 +98,7 @@ class XML
         }
 
         // see if debugging is enabled for SAML messages
-        $debug = \SimpleSAML_Configuration::getInstance()->getArrayize('debug', array('saml' => false));
+        $debug = \SimpleSAML\Configuration::getInstance()->getArrayize('debug', array('saml' => false));
 
         if (!(in_array('saml', $debug, true) // implicitly enabled
               || (array_key_exists('saml', $debug) && $debug['saml'] === true) // explicitly enabled
@@ -309,7 +309,7 @@ class XML
      * @param \DOMElement $element The element we should extract text from.
      *
      * @return string The text content of the element.
-     * @throws \SimpleSAML_Error_Exception If the element contains a non-text child node.
+     * @throws \SimpleSAML\Error\Exception If the element contains a non-text child node.
      *
      * @author Olav Morken, UNINETT AS <olav.morken@uninett.no>
      */
@@ -321,7 +321,7 @@ class XML
             /** @var \DOMElement $child */
             $child = $element->childNodes->item($i);
             if (!($child instanceof \DOMText)) {
-                throw new \SimpleSAML_Error_Exception($element->localName.' contained a non-text child node.');
+                throw new \SimpleSAML\Error\Exception($element->localName.' contained a non-text child node.');
             }
 
             $txt .= $child->wholeText;
@@ -429,7 +429,7 @@ class XML
         }
 
         if ($res) {
-            $config = \SimpleSAML_Configuration::getInstance();
+            $config = \SimpleSAML\Configuration::getInstance();
             /** @var string $schemaPath */
             $schemaPath = $config->resolvePath('schemas');
             $schemaPath .= './';
diff --git a/lib/SimpleSAML/XHTML/EMail.php b/lib/SimpleSAML/XHTML/EMail.php
index 335df2bf40b397780bb1e3a4ec164f6864e32232..14d67c9dfc1e28e8a95d369cc1e48205dfa86f6e 100644
--- a/lib/SimpleSAML/XHTML/EMail.php
+++ b/lib/SimpleSAML/XHTML/EMail.php
@@ -1,40 +1,54 @@
 <?php
 
+namespace SimpleSAML\XHTML;
+
 /**
  * A minimalistic Emailer class. Creates and sends HTML emails.
  *
  * @author Andreas kre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
  * @package SimpleSAMLphp
  */
-class SimpleSAML_XHTML_EMail {
-
-
-	private $to = NULL;
-	private $cc = NULL;
-	private $body = NULL;
-	private $from = NULL;
-	private $replyto = NULL;
-	private $subject = NULL;
-	private $headers = array();
-	
-
-	/**
-	 * Constructor
-	 */
-	function __construct($to, $subject, $from = NULL, $cc = NULL, $replyto = NULL) {
-		$this->to = $to;
-		$this->cc = $cc;
-		$this->from = $from;
-		$this->replyto = $replyto;
-		$this->subject = $subject;
-	}
-
-	function setBody($body) {
-		$this->body = $body;
-	}
-	
-	private function getHTML($body) {
-		return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+
+class EMail
+{
+    private $to = null;
+    private $cc = null;
+    private $body = null;
+    private $from = null;
+    private $replyto = null;
+    private $subject = null;
+    private $headers = array();
+
+
+    /**
+     * Constructor
+     */
+    public function __construct($to, $subject, $from = null, $cc = null, $replyto = null)
+    {
+        $this->to = $to;
+        $this->cc = $cc;
+        $this->from = $from;
+        $this->replyto = $replyto;
+        $this->subject = $subject;
+    }
+
+    /*
+     * @param string $body
+     * @return void
+     */
+    public function setBody($body)
+    {
+        $this->body = $body;
+    }
+
+
+    /*
+     * @param string $body
+     * @return string
+     */
+    private function getHTML($body)
+    {
+        return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
@@ -58,23 +72,34 @@ pre {
 </div>
 </body>
 </html>';
-	}
-
-	function send() {
-		if ($this->to == NULL) throw new Exception('EMail field [to] is required and not set.');
-		if ($this->subject == NULL) throw new Exception('EMail field [subject] is required and not set.');
-		if ($this->body == NULL) throw new Exception('EMail field [body] is required and not set.');
-		
-		$random_hash = bin2hex(openssl_random_pseudo_bytes(16));
-		
-		if (isset($this->from))
-			$this->headers[]= 'From: ' . $this->from;
-		if (isset($this->replyto))
-			$this->headers[]= 'Reply-To: ' . $this->replyto;
-
-		$this->headers[] = 'Content-Type: multipart/alternative; boundary="simplesamlphp-' . $random_hash . '"'; 
-		
-		$message = '
+    }
+
+
+    /*
+     * @return void
+     */
+    public function send()
+    {
+        if ($this->to === null) {
+            throw new \Exception('EMail field [to] is required and not set.');
+        } elseif ($this->subject === null) {
+            throw new \Exception('EMail field [subject] is required and not set.');
+        } elseif ($this->body === null) {
+            throw new \Exception('EMail field [body] is required and not set.');
+        }
+
+        $random_hash = bin2hex(openssl_random_pseudo_bytes(16));
+
+        if (isset($this->from)) {
+            $this->headers[]= 'From: ' . $this->from;
+        }
+        if (isset($this->replyto)) {
+            $this->headers[]= 'Reply-To: ' . $this->replyto;
+        }
+
+        $this->headers[] = 'Content-Type: multipart/alternative; boundary="simplesamlphp-' . $random_hash . '"';
+
+        $message = '
 --simplesamlphp-' . $random_hash . '
 Content-Type: text/plain; charset="utf-8" 
 Content-Transfer-Encoding: 8bit
@@ -89,11 +114,12 @@ Content-Transfer-Encoding: 8bit
 
 --simplesamlphp-' . $random_hash . '--
 ';
-		$headers = implode("\n", $this->headers);
-
-		$mail_sent = @mail($this->to, $this->subject, $message, $headers);
-		SimpleSAML\Logger::debug('Email: Sending e-mail to [' . $this->to . '] : ' . ($mail_sent ? 'OK' : 'Failed'));
-		if (!$mail_sent) throw new Exception('Error when sending e-mail');
-	}
+        $headers = implode("\n", $this->headers);
 
+        $mail_sent = @mail($this->to, $this->subject, $message, $headers);
+        \SimpleSAML\Logger::debug('Email: Sending e-mail to [' . $this->to . '] : ' . ($mail_sent ? 'OK' : 'Failed'));
+        if (!$mail_sent) {
+            throw new \Exception('Error when sending e-mail');
+        }
+    }
 }
diff --git a/lib/SimpleSAML/XHTML/IdPDisco.php b/lib/SimpleSAML/XHTML/IdPDisco.php
index 70b06d7172c5640e9d217e79d02e5ffcd401b73d..33faec23514e2b7a4115dc98e6496a4a9ef2f716 100644
--- a/lib/SimpleSAML/XHTML/IdPDisco.php
+++ b/lib/SimpleSAML/XHTML/IdPDisco.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML\XHTML;
 
 /**
  * This class implements a generic IdP discovery service, for use in various IdP
@@ -13,13 +14,13 @@
  * @author Andreas Ă…kre Solberg <andreas@uninett.no>, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class SimpleSAML_XHTML_IdPDisco
-{
 
+class IdPDisco
+{
     /**
      * An instance of the configuration class.
      *
-     * @var SimpleSAML_Configuration
+     * @var \SimpleSAML\Configuration
      */
     protected $config;
 
@@ -34,7 +35,7 @@ class SimpleSAML_XHTML_IdPDisco
     /**
      * An instance of the metadata handler, which will allow us to fetch metadata about IdPs.
      *
-     * @var SimpleSAML_Metadata_MetaDataStorageHandler
+     * @var \SimpleSAML\Metadata\MetaDataStorageHandler
      */
     protected $metadata;
 
@@ -42,7 +43,7 @@ class SimpleSAML_XHTML_IdPDisco
     /**
      * The users session.
      *
-     * @var SimpleSAML_Session
+     * @var \SimpleSAML\Session
      */
     protected $session;
 
@@ -118,9 +119,9 @@ class SimpleSAML_XHTML_IdPDisco
         assert(is_string($instance));
 
         // initialize standard classes
-        $this->config = SimpleSAML_Configuration::getInstance();
-        $this->metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-        $this->session = SimpleSAML_Session::getSessionFromRequest();
+        $this->config = \SimpleSAML\Configuration::getInstance();
+        $this->metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
+        $this->session = \SimpleSAML\Session::getSessionFromRequest();
         $this->instance = $instance;
         $this->metadataSets = $metadataSets;
 
@@ -128,7 +129,7 @@ class SimpleSAML_XHTML_IdPDisco
 
         // standard discovery service parameters
         if (!array_key_exists('entityID', $_GET)) {
-            throw new Exception('Missing parameter: entityID');
+            throw new \Exception('Missing parameter: entityID');
         } else {
             $this->spEntityId = $_GET['entityID'];
         }
@@ -142,7 +143,7 @@ class SimpleSAML_XHTML_IdPDisco
         $this->log('returnIdParam initially set to ['.$this->returnIdParam.']');
 
         if (!array_key_exists('return', $_GET)) {
-            throw new Exception('Missing parameter: return');
+            throw new \Exception('Missing parameter: return');
         } else {
             $this->returnURL = \SimpleSAML\Utils\HTTP::checkURLAllowed($_GET['return']);
         }
@@ -175,7 +176,7 @@ class SimpleSAML_XHTML_IdPDisco
      */
     protected function log($message)
     {
-        SimpleSAML\Logger::info('idpDisco.'.$this->instance.': '.$message);
+        \SimpleSAML\Logger::info('idpDisco.'.$this->instance.': '.$message);
     }
 
 
@@ -249,7 +250,7 @@ class SimpleSAML_XHTML_IdPDisco
             try {
                 $this->metadata->getMetaData($idp, $metadataSet);
                 return $idp;
-            } catch (Exception $e) {
+            } catch (\Exception $e) {
                 // continue
             }
         }
@@ -582,10 +583,10 @@ class SimpleSAML_XHTML_IdPDisco
                 $templateFile = 'selectidp-links.php';
                 break;
             default:
-                throw new Exception('Invalid value for the \'idpdisco.layout\' option.');
+                throw new \Exception('Invalid value for the \'idpdisco.layout\' option.');
         }
 
-        $t = new SimpleSAML_XHTML_Template($this->config, $templateFile, 'disco');
+        $t = new Template($this->config, $templateFile, 'disco');
         $t->data['idplist'] = $idpList;
         $t->data['preferredidp'] = $preferredIdP;
         $t->data['return'] = $this->returnURL;
diff --git a/lib/SimpleSAML/XHTML/Template.php b/lib/SimpleSAML/XHTML/Template.php
index d3d3ef32a0828b81547dfe42ce11321bc58047fc..30b5363ab316213c33d9839d3e8959b67532b3bb 100644
--- a/lib/SimpleSAML/XHTML/Template.php
+++ b/lib/SimpleSAML/XHTML/Template.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML\XHTML;
 
 /**
  * A minimalistic XHTML PHP based template system implemented for SimpleSAMLphp.
@@ -8,15 +9,12 @@
  * @package SimpleSAMLphp
  */
 
-
 use JaimePerez\TwigConfigurableI18n\Twig\Environment as Twig_Environment;
 use JaimePerez\TwigConfigurableI18n\Twig\Extensions\Extension\I18n as Twig_Extensions_Extension_I18n;
 use \SimpleSAML\XHTML\TemplateLoader;
 
-
-class SimpleSAML_XHTML_Template
+class Template
 {
-
     /**
      * The data associated with this template, accessible within the template itself.
      *
@@ -41,7 +39,7 @@ class SimpleSAML_XHTML_Template
     /**
      * The configuration to use in this template.
      *
-     * @var SimpleSAML_Configuration
+     * @var \SimpleSAML\Configuration
      */
     private $configuration;
 
@@ -76,9 +74,9 @@ class SimpleSAML_XHTML_Template
      *
      * Used to intercept certain parts of the template handling, while keeping away unwanted/unexpected hooks. Set
      * the 'theme.controller' configuration option to a class that implements the
-     * SimpleSAML\XHTML\TemplateControllerInterface interface to use it.
+     * \SimpleSAML\XHTML\TemplateControllerInterface interface to use it.
      *
-     * @var SimpleSAML\XHTML\TemplateControllerInterface
+     * @var \SimpleSAML\XHTML\TemplateControllerInterface
      */
     private $controller;
 
@@ -97,11 +95,11 @@ class SimpleSAML_XHTML_Template
     /**
      * Constructor
      *
-     * @param SimpleSAML_Configuration $configuration Configuration object
+     * @param \SimpleSAML\Configuration $configuration Configuration object
      * @param string                   $template Which template file to load
      * @param string|null              $defaultDictionary The default dictionary where tags will come from.
      */
-    public function __construct(\SimpleSAML_Configuration $configuration, $template, $defaultDictionary = null)
+    public function __construct(\SimpleSAML\Configuration $configuration, $template, $defaultDictionary = null)
     {
         $this->configuration = $configuration;
         $this->template = $template;
@@ -112,12 +110,12 @@ class SimpleSAML_XHTML_Template
         list($this->module) = $this->findModuleAndTemplateName($template);
 
         // parse config to find theme and module theme is in, if any
-        list($this->theme['module'], $this->theme['name']) = self::findModuleAndTemplateName(
+        list($this->theme['module'], $this->theme['name']) = $this->findModuleAndTemplateName(
             $this->configuration->getString('theme.use', 'default')
         );
 
         // initialize internationalization system
-        $this->translator = new SimpleSAML\Locale\Translate($configuration, $defaultDictionary);
+        $this->translator = new \SimpleSAML\Locale\Translate($configuration, $defaultDictionary);
         $this->localization = new \SimpleSAML\Locale\Localization($configuration);
 
         // check if we need to attach a theme controller
@@ -158,15 +156,15 @@ class SimpleSAML_XHTML_Template
     /**
      * Set up the places where twig can look for templates.
      *
-     * @return Twig_Loader_Filesystem|false The twig template loader or false if the template does not exist.
-     * @throws Twig_Error_Loader In case a failure occurs.
+     * @return \Twig_Loader_Filesystem The twig template loader or false if the template does not exist.
+     * @throws \Twig_Error_Loader In case a failure occurs.
      */
     private function setupTwigTemplatepaths()
     {
         $filename = $this->normalizeTemplateName($this->template);
 
         // get namespace if any
-        list($namespace, $filename) = self::findModuleAndTemplateName($filename);
+        list($namespace, $filename) = $this->findModuleAndTemplateName($filename);
         $this->twig_template = ($namespace !== null) ? '@'.$namespace.'/'.$filename : $filename;
         $loader = new TemplateLoader();
         $templateDirs = $this->findThemeTemplateDirs();
@@ -232,8 +230,8 @@ class SimpleSAML_XHTML_Template
             );
         } // TODO: add a branch for the old SimpleSAMLphp backend
 
-        $twig = new Twig_Environment($loader, $options);
-        $twig->addExtension(new Twig_Extensions_Extension_I18n());
+        $twig = new \Twig_Environment($loader, $options);
+        $twig->addExtension(new \Twig_Extensions_Extension_I18n());
 
         // initialize some basic context
         $langParam = $this->configuration->getString('language.parameter.name', 'language');
@@ -283,9 +281,9 @@ class SimpleSAML_XHTML_Template
         // setup directories & namespaces
         $themeDir = \SimpleSAML\Module::getModuleDir($this->theme['module']).'/themes/'.$this->theme['name'];
         $subdirs = scandir($themeDir);
-        if (!$subdirs) { // no subdirectories in the theme directory, nothing to do here
+        if (empty($subdirs)) { // no subdirectories in the theme directory, nothing to do here
             // this is probably wrong, log a message
-            \SimpleSAML\Logger::warning('Emtpy theme directory for theme "'.$this->theme['name'].'".');
+            \SimpleSAML\Logger::warning('Empty theme directory for theme "'.$this->theme['name'].'".');
             return array();
         }
 
@@ -304,6 +302,28 @@ class SimpleSAML_XHTML_Template
     }
 
 
+    /**
+     * Get the template directory of a module, if it exists.
+     *
+     * @return string The templates directory of a module.
+     *
+     * @throws \InvalidArgumentException If the module is not enabled or it has no templates directory.
+     */
+    private function getModuleTemplateDir($module)
+    {
+        if (!\SimpleSAML\Module::isModuleEnabled($module)) {
+            throw new \InvalidArgumentException('The module \''.$module.'\' is not enabled.');
+        }
+        $moduledir = \SimpleSAML\Module::getModuleDir($module);
+        // check if module has a /templates dir, if so, append
+        $templatedir = $moduledir.'/templates';
+        if (!is_dir($templatedir)) {
+            throw new \InvalidArgumentException('The module \''.$module.'\' has no templates directory.');
+        }
+        return $templatedir;
+    }
+
+
     /**
      * Add the templates from a given module.
      *
@@ -311,12 +331,12 @@ class SimpleSAML_XHTML_Template
      *
      * @param string $module The module where we need to search for templates.
      *
-     * @throws InvalidArgumentException If the module is not enabled or it has no templates directory.
+     * @throws \InvalidArgumentException If the module is not enabled or it has no templates directory.
      */
     public function addTemplatesFromModule($module)
     {
         $dir = TemplateLoader::getModuleTemplateDir($module);
-        /** @var Twig_Loader_Filesystem $loader */
+        /** @var \Twig_Loader_Filesystem $loader */
         $loader = $this->twig->getLoader();
         $loader->addPath($dir, $module);
     }
@@ -431,7 +451,7 @@ class SimpleSAML_XHTML_Template
      *
      * @return string The absolute path to the template file.
      *
-     * @throws Exception If the template file couldn't be found.
+     * @throws \Exception If the template file couldn't be found.
      */
     private function findTemplatePath($template, $throw_exception = true)
     {
@@ -483,7 +503,7 @@ class SimpleSAML_XHTML_Template
             $error = 'Template: Could not find template file ['.$template.'] at ['.$filename.']';
             \SimpleSAML\Logger::critical($_SERVER['PHP_SELF'].' - '.$error);
 
-            throw new Exception($error);
+            throw new \Exception($error);
         } else {
             // missing template expected, return NULL
             return null;
@@ -505,7 +525,7 @@ class SimpleSAML_XHTML_Template
     /**
      * Get the current instance of Twig in use.
      *
-     * @return false|Twig_Environment The Twig instance in use, or false if Twig is not used.
+     * @return false|\Twig_Environment The Twig instance in use, or false if Twig is not used.
      */
     public function getTwig()
     {
@@ -687,7 +707,7 @@ class SimpleSAML_XHTML_Template
      * @see \SimpleSAML\Locale\Translate::noop()
      * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Locale\Translate::noop() instead.
      */
-    static public function noop($tag)
+    public static function noop($tag)
     {
         return $tag;
     }
diff --git a/lib/SimpleSAML/XHTML/TemplateControllerInterface.php b/lib/SimpleSAML/XHTML/TemplateControllerInterface.php
index bd54907c48a9e5d4152062e36a19add335ad83ee..8d6f4e733ee95f3f082f8cda06fe4f631f74622e 100644
--- a/lib/SimpleSAML/XHTML/TemplateControllerInterface.php
+++ b/lib/SimpleSAML/XHTML/TemplateControllerInterface.php
@@ -7,7 +7,8 @@ namespace SimpleSAML\XHTML;
  *
  * @package SimpleSAMLphp
  */
-interface TemplateControllerInterface {
+interface TemplateControllerInterface
+{
 
     /**
      * Implement to modify the twig environment after its initialization (e.g. add filters or extensions).
diff --git a/lib/SimpleSAML/XML/Parser.php b/lib/SimpleSAML/XML/Parser.php
index b43fe49a76eccb329d6fa83bd321f3578287ca97..b8dda85226cccc11fd715fefa9e2fb9b01796535 100644
--- a/lib/SimpleSAML/XML/Parser.php
+++ b/lib/SimpleSAML/XML/Parser.php
@@ -50,7 +50,7 @@ class Parser
     public function getValue($xpath, $required = false)
     {
         $result = $this->simplexml->xpath($xpath);
-        if (! $result or !is_array($result)) {
+        if (!is_array($result) || empty($result)) {
             if ($required) {
                 throw new \Exception('Could not get value from XML document using the following XPath expression: ' . $xpath);
             } else {
diff --git a/lib/SimpleSAML/XML/Shib13/AuthnRequest.php b/lib/SimpleSAML/XML/Shib13/AuthnRequest.php
index f52fea212cfa4f379ccb94e6676d1a7abd93cd70..e1c83c02fd773b73ea7dda0f688852db85677fe1 100644
--- a/lib/SimpleSAML/XML/Shib13/AuthnRequest.php
+++ b/lib/SimpleSAML/XML/Shib13/AuthnRequest.php
@@ -36,7 +36,7 @@ class AuthnRequest
 
     public function createRedirect($destination, $shire)
     {
-        $metadata = \SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+        $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
         $idpmetadata = $metadata->getMetaDataConfig($destination, 'shib13-idp-remote');
 
         $desturl = $idpmetadata->getDefaultEndpoint('SingleSignOnService', array('urn:mace:shibboleth:1.0:profiles:AuthnRequest'));
diff --git a/lib/SimpleSAML/XML/Shib13/AuthnResponse.php b/lib/SimpleSAML/XML/Shib13/AuthnResponse.php
index 28a9fc14cfe830fb3bdf3803a189b255df33a676..c380fa17220ce3d22d8cbfe3d52167451666aee6 100644
--- a/lib/SimpleSAML/XML/Shib13/AuthnResponse.php
+++ b/lib/SimpleSAML/XML/Shib13/AuthnResponse.php
@@ -20,7 +20,6 @@ use SimpleSAML\XML\Validator;
 
 class AuthnResponse
 {
-
     /**
      * @var \SimpleSAML\XML\Validator This variable contains an XML validator for this message.
      */
@@ -98,11 +97,11 @@ class AuthnResponse
         $issuer = $this->getIssuer();
 
         // Get the metadata of the issuer
-        $metadata = \SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+        $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
         $md = $metadata->getMetaDataConfig($issuer, 'shib13-idp-remote');
 
         $publicKeys = $md->getPublicKeys('signing');
-        if ($publicKeys !== null) {
+        if (!empty($publicKeys)) {
             $certFingerprints = array();
             foreach ($publicKeys as $key) {
                 if ($key['type'] !== 'X509Certificate') {
@@ -120,7 +119,7 @@ class AuthnResponse
             // Validate against CA
             $this->validator->validateCA(Config::getCertPath($md->getString('caFile')));
         } else {
-            throw new \SimpleSAML_Error_Exception('Missing certificate in Shibboleth 1.3 IdP Remote metadata for identity provider [' . $issuer . '].');
+            throw new \SimpleSAML\Error\Exception('Missing certificate in Shibboleth 1.3 IdP Remote metadata for identity provider [' . $issuer . '].');
         }
 
         return true;
@@ -149,7 +148,7 @@ class AuthnResponse
             $node = dom_import_simplexml($node);
         }
 
-        assert($node instanceof DOMNode);
+        assert($node instanceof \DOMNode);
 
         return $this->validator->isNodeValidated($node);
     }
@@ -166,13 +165,13 @@ class AuthnResponse
     private function doXPathQuery($query, $node = null)
     {
         assert(is_string($query));
-        assert($this->dom instanceof DOMDocument);
+        assert($this->dom instanceof \DOMDocument);
 
         if ($node === null) {
             $node = $this->dom->documentElement;
         }
 
-        assert($node instanceof DOMNode);
+        assert($node instanceof \DOMNode);
 
         $xPath = new \DOMXpath($this->dom);
         $xPath->registerNamespace('shibp', self::SHIB_PROTOCOL_NS);
@@ -202,7 +201,7 @@ class AuthnResponse
     
     public function getAttributes()
     {
-        $metadata = \SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+        $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
         $md = $metadata->getMetadata($this->getIssuer(), 'shib13-idp-remote');
         $base64 = isset($md['base64attributes']) ? $md['base64attributes'] : false;
 
@@ -300,13 +299,13 @@ class AuthnResponse
     /**
      * Build a authentication response.
      *
-     * @param \SimpleSAML_Configuration $idp Metadata for the IdP the response is sent from.
-     * @param \SimpleSAML_Configuration $sp Metadata for the SP the response is sent to.
+     * @param \SimpleSAML\Configuration $idp Metadata for the IdP the response is sent from.
+     * @param \SimpleSAML\Configuration $sp Metadata for the SP the response is sent to.
      * @param string $shire The endpoint on the SP the response is sent to.
      * @param array|null $attributes The attributes which should be included in the response.
      * @return string The response.
      */
-    public function generate(\SimpleSAML_Configuration $idp, \SimpleSAML_Configuration $sp, $shire, $attributes)
+    public function generate(\SimpleSAML\Configuration $idp, \SimpleSAML\Configuration $sp, $shire, $attributes)
     {
         assert(is_string($shire));
         assert($attributes === null || is_array($attributes));
diff --git a/lib/SimpleSAML/XML/Signer.php b/lib/SimpleSAML/XML/Signer.php
index 5ab89acd661a71d4d72f420b0731e875a7718148..70d856cd3b246e0b25f2372a8a81c054fea133ea 100644
--- a/lib/SimpleSAML/XML/Signer.php
+++ b/lib/SimpleSAML/XML/Signer.php
@@ -20,28 +20,26 @@ use SimpleSAML\Utils\Config;
 
 class Signer
 {
-
-
     /**
      * @var string The name of the ID attribute.
      */
-    private $idAttrName;
+    private $idAttrName = '';
 
     /**
      * @var XMLSecurityKey|bool  The private key (as an XMLSecurityKey).
      */
-    private $privateKey;
+    private $privateKey = false;
 
     /**
      * @var string The certificate (as text).
      */
-    private $certificate;
+    private $certificate = '';
 
 
     /**
-     * @var string Extra certificates which should be included in the response.
+     * @var array Extra certificates which should be included in the response.
      */
-    private $extraCertificates;
+    private $extraCertificates = array();
 
 
     /**
@@ -54,8 +52,8 @@ class Signer
      *  - privatekey       The file with the private key, relative to the cert-directory.
      *  - privatekey_pass  The passphrase for the private key.
      *  - certificate      The file with the certificate, relative to the cert-directory.
-     *  - privatekey_array The private key, as an array returned from SimpleSAML_Utilities::loadPrivateKey.
-     *  - publickey_array  The public key, as an array returned from SimpleSAML_Utilities::loadPublicKey.
+     *  - privatekey_array The private key, as an array returned from \SimpleSAML\Utils\Crypto::loadPrivateKey.
+     *  - publickey_array  The public key, as an array returned from \SimpleSAML\Utils\Crypto::loadPublicKey.
      *  - id               The name of the ID attribute.
      *
      * @param array $options  Associative array with options for the constructor. Defaults to an empty array.
@@ -64,11 +62,6 @@ class Signer
     {
         assert(is_array($options));
 
-        $this->idAttrName = false;
-        $this->privateKey = false;
-        $this->certificate = false;
-        $this->extraCertificates = array();
-
         if (array_key_exists('privatekey', $options)) {
             $pass = null;
             if (array_key_exists('privatekey_pass', $options)) {
@@ -100,7 +93,7 @@ class Signer
      * Set the private key from an array.
      *
      * This function loads the private key from an array matching what is returned
-     * by SimpleSAML_Utilities::loadPrivateKey(...).
+     * by \SimpleSAML\Utils\Crypto::loadPrivateKey(...).
      *
      * @param array $privatekey  The private key.
      */
@@ -109,7 +102,7 @@ class Signer
         assert(is_array($privatekey));
         assert(array_key_exists('PEM', $privatekey));
 
-        $this->privateKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private'));
+        $this->privateKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, array('type' => 'private'));
         if (array_key_exists('password', $privatekey)) {
             $this->privateKey->passphrase = $privatekey['password'];
         }
@@ -162,7 +155,7 @@ class Signer
      * Set the public key / certificate we should include in the signature.
      *
      * This function loads the public key from an array matching what is returned
-     * by SimpleSAML_Utilities::loadPublicKey(...).
+     * by \SimpleSAML\Utils\Crypto::loadPublicKey(...).
      *
      * @param array $publickey The public key.
      * @throws \Exception
@@ -208,10 +201,11 @@ class Signer
             throw new \Exception('Could not find certificate file "' . $certFile . '".');
         }
 
-        $this->certificate = file_get_contents($certFile);
-        if ($this->certificate === false) {
+        $cert = file_get_contents($certFile);
+        if ($cert === false) {
             throw new \Exception('Unable to read certificate file "' . $certFile . '".');
         }
+        $this->certificate = $cert;
     }
 
 
@@ -291,13 +285,13 @@ class Signer
         $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);
 
         $options = array();
-        if ($this->idAttrName !== false) {
+        if (!empty($this->idAttrName)) {
             $options['id_name'] = $this->idAttrName;
         }
 
         $objXMLSecDSig->addReferenceList(
             array($node),
-            XMLSecurityDSig::SHA1,
+            XMLSecurityDSig::SHA256,
             array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N),
             $options
         );
@@ -306,10 +300,8 @@ class Signer
         $objXMLSecDSig->sign($this->privateKey);
 
 
-        if ($this->certificate !== false) {
-            // Add the certificate to the signature
-            $objXMLSecDSig->add509Cert($this->certificate, true);
-        }
+        // Add the certificate to the signature
+        $objXMLSecDSig->add509Cert($this->certificate, true);
 
         // Add extra certificates
         foreach ($this->extraCertificates as $certificate) {
diff --git a/lib/SimpleSAML/XML/Validator.php b/lib/SimpleSAML/XML/Validator.php
index 04a1174fcdaa94aa382a45057d83014d338afadf..00eaf11cd84f30989bb35dc6460067b5e4b1be9c 100644
--- a/lib/SimpleSAML/XML/Validator.php
+++ b/lib/SimpleSAML/XML/Validator.php
@@ -23,7 +23,7 @@ class Validator
     private $x509Certificate;
 
     /**
-     * @var array This variable contains the nodes which are signed.
+     * @var array|null This variable contains the nodes which are signed.
      */
     private $validNodes = null;
 
@@ -36,7 +36,7 @@ class Validator
      * take the following values:
      * - NULL/FALSE: No validation will be performed. This is the default.
      * - A string: Assumed to be a PEM-encoded certificate / public key.
-     * - An array: Assumed to be an array returned by SimpleSAML_Utilities::loadPublicKey.
+     * - An array: Assumed to be an array returned by \SimpleSAML\Utils\Crypto::loadPublicKey.
      *
      * @param \DOMNode $xmlNode The XML node which contains the Signature element.
      * @param string|array $idAttribute The ID attribute which is used in node references. If
@@ -325,7 +325,8 @@ class Validator
         assert(is_string($caFile));
 
         // Clear openssl errors
-        while (openssl_error_string() !== false);
+        while (openssl_error_string() !== false) {
+        }
 
         $res = openssl_x509_checkpurpose($certificate, X509_PURPOSE_ANY, array($caFile));
 
diff --git a/metadata-templates/saml20-idp-hosted.php b/metadata-templates/saml20-idp-hosted.php
index 81a2007267ccc0e46573b2a8ba7cb025a626e1df..7acd4037369f3084a6a632139a92396f8350a9b7 100644
--- a/metadata-templates/saml20-idp-hosted.php
+++ b/metadata-templates/saml20-idp-hosted.php
@@ -23,26 +23,6 @@ $metadata['__DYNAMIC:1__'] = array(
 	 */
 	'auth' => 'example-userpass',
 
-	/*
-	 * WARNING: SHA-1 is disallowed starting January the 1st, 2014.
-	 *
-	 * Uncomment the following option to start using SHA-256 for your signatures.
-	 * Currently, SimpleSAMLphp defaults to SHA-1, which has been deprecated since
-	 * 2011, and will be disallowed by NIST as of 2014. Please refer to the following
-	 * document for more information:
-	 * 
-	 * http://csrc.nist.gov/publications/nistpubs/800-131A/sp800-131A.pdf
-	 *
-	 * If you are uncertain about service providers supporting SHA-256 or other
-	 * algorithms of the SHA-2 family, you can configure it individually in the
-	 * SP-remote metadata set for those that support it. Once you are certain that
-	 * all your configured SPs support SHA-2, you can safely remove the configuration
-	 * options in the SP-remote metadata set and uncomment the following option.
-	 *
-	 * Please refer to the IdP hosted reference for more information.
-	 */
-	//'signature.algorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
-
 	/* Uncomment the following to use the uri NameFormat on attributes. */
 	/*
 	'attributes.NameFormat' => 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri',
diff --git a/metadata-templates/saml20-sp-remote.php b/metadata-templates/saml20-sp-remote.php
index 46262cee186653c68fffc1414e2f11fea2369371..b74e90492073f3d1c33d76025ded319134ef1ebe 100644
--- a/metadata-templates/saml20-sp-remote.php
+++ b/metadata-templates/saml20-sp-remote.php
@@ -25,3 +25,17 @@ $metadata['google.com'] = array(
 	'simplesaml.nameidattribute' => 'uid',
 	'simplesaml.attributes' => FALSE,
 );
+
+$metadata['https://legacy.example.edu'] = array(
+	'AssertionConsumerService' => 'https://legacy.example.edu/saml/acs',
+        /*
+         * Currently, SimpleSAMLphp defaults to the SHA-256 hashing algorithm.
+	 * Uncomment the following option to use SHA-1 for signatures directed
+	 * at this specific service provider if it does not support SHA-256 yet.
+         *
+         * WARNING: SHA-1 is disallowed starting January the 1st, 2014.
+         * Please refer to the following document for more information:
+         * http://csrc.nist.gov/publications/nistpubs/800-131A/sp800-131A.pdf
+         */
+        //'signature.algorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha1',
+);
diff --git a/modules/.gitignore b/modules/.gitignore
index 14877bd3f2741c9f668795c886c2879baf0c5065..bcf421d67f52f500e81e413b477073bad1cd8d50 100644
--- a/modules/.gitignore
+++ b/modules/.gitignore
@@ -7,7 +7,6 @@
 !/authcrypt/
 !/authfacebook/
 !/authlinkedin/
-!/authmyspace/
 !/authorize/
 !/authtwitter/
 !/authwindowslive/
diff --git a/modules/adfs/lib/IdP/ADFS.php b/modules/adfs/lib/IdP/ADFS.php
index 8efdb93c547cc5c443c4984a2ec388f62d0fcd34..8187aff89c12ad28206e9d0a22f1cba0e49e66c5 100644
--- a/modules/adfs/lib/IdP/ADFS.php
+++ b/modules/adfs/lib/IdP/ADFS.php
@@ -1,39 +1,50 @@
 <?php
 
-class sspmod_adfs_IdP_ADFS
+namespace SimpleSAML\Module\adfs\IdP;
+
+use RobRichards\XMLSecLibs\XMLSecurityDSig;
+use RobRichards\XMLSecLibs\XMLSecurityKey;
+
+class ADFS
 {
-    public static function receiveAuthnRequest(SimpleSAML_IdP $idp)
+    public static function receiveAuthnRequest(\SimpleSAML\IdP $idp)
     {
         try {
             parse_str($_SERVER['QUERY_STRING'], $query);
 
             $requestid = $query['wctx'];
             $issuer = $query['wtrealm'];
-            $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+
+            $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
             $spMetadata = $metadata->getMetaDataConfig($issuer, 'adfs-sp-remote');
 
-            SimpleSAML\Logger::info('ADFS - IdP.prp: Incoming Authentication request: '.$issuer.' id '.$requestid);
-        } catch(Exception $exception) {
-            throw new SimpleSAML_Error_Error('PROCESSAUTHNREQUEST', $exception);
+            \SimpleSAML\Logger::info('ADFS - IdP.prp: Incoming Authentication request: '.$issuer.' id '.$requestid);
+        } catch (\Exception $exception) {
+            throw new \SimpleSAML\Error\Error('PROCESSAUTHNREQUEST', $exception);
         }
 
         $state = array(
-            'Responder' => array('sspmod_adfs_IdP_ADFS', 'sendResponse'),
+            'Responder' => array('\SimpleSAML\Module\adfs\IdP\ADFS', 'sendResponse'),
             'SPMetadata' => $spMetadata->toArray(),
             'ForceAuthn' => false,
             'isPassive' => false,
             'adfs:wctx' => $requestid,
+            'adfs:wreply' => false
         );
 
+        if (isset($query['wreply']) && !empty($query['wreply'])) {
+            $state['adfs:wreply'] = \SimpleSAML\Utils\HTTP::checkURLAllowed($query['wreply']);
+        }
+
         $idp->handleAuthenticationRequest($state);		
     }
 
-    private static function generateResponse($issuer, $target, $nameid, $attributes)
+    private static function generateResponse($issuer, $target, $nameid, $attributes, $assertionLifetime)
     {
-        $issueInstant = SimpleSAML\Utils\Time::generateTimestamp();
-        $notBefore = SimpleSAML\Utils\Time::generateTimestamp(time() - 30);
-        $assertionExpire = SimpleSAML\Utils\Time::generateTimestamp(time() + 60 * 5);
-        $assertionID = SimpleSAML\Utils\Random::generateID();
+        $issueInstant = \SimpleSAML\Utils\Time::generateTimestamp();
+        $notBefore = \SimpleSAML\Utils\Time::generateTimestamp(time() - 30);
+        $assertionExpire = \SimpleSAML\Utils\Time::generateTimestamp(time() + $assertionLifetime);
+        $assertionID = \SimpleSAML\Utils\Random::generateID();
         $nameidFormat = 'http://schemas.xmlsoap.org/claims/UPN';
         $nameid = htmlspecialchars($nameid);
 
@@ -62,7 +73,7 @@ MSG;
                 continue;
             }
 
-            list($namespace, $name) = SimpleSAML\Utils\Attributes::getAttributeNamespace($name, 'http://schemas.xmlsoap.org/claims');
+            list($namespace, $name) = \SimpleSAML\Utils\Attributes::getAttributeNamespace($name, 'http://schemas.xmlsoap.org/claims');
             foreach ($values as $value) {
                 if ((!isset($value)) || ($value === '')) {
                     continue;
@@ -93,19 +104,20 @@ MSG;
         return $result;
     }
 
-    private static function signResponse($response, $key, $cert)
+    private static function signResponse($response, $key, $cert, $algo)
     {
         $objXMLSecDSig = new XMLSecurityDSig();
         $objXMLSecDSig->idKeys = array('AssertionID');	
         $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);	
-        $responsedom = \SAML2\DOMDocumentFactory::fromString(str_replace ("\r", "", $response));
+        $responsedom = \SAML2\DOMDocumentFactory::fromString(str_replace("\r", "", $response));
         $firstassertionroot = $responsedom->getElementsByTagName('Assertion')->item(0);
         $objXMLSecDSig->addReferenceList(
-            array($firstassertionroot), XMLSecurityDSig::SHA1,
+            array($firstassertionroot), XMLSecurityDSig::SHA256,
             array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N),
             array('id_name' => 'AssertionID')
         );
-        $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type'=>'private'));
+
+        $objKey = new XMLSecurityKey($algo, array('type' => 'private'));
         $objKey->loadKey($key, true);
         $objXMLSecDSig->sign($objKey);
         if ($cert) {
@@ -143,50 +155,59 @@ MSG;
     {
         $spMetadata = $state["SPMetadata"];
         $spEntityId = $spMetadata['entityid'];
-        $spMetadata = SimpleSAML_Configuration::loadFromArray($spMetadata,
-            '$metadata[' . var_export($spEntityId, true) . ']');
+        $spMetadata = \SimpleSAML\Configuration::loadFromArray($spMetadata, '$metadata['.var_export($spEntityId, true).']');
 
         $attributes = $state['Attributes'];
 
         $nameidattribute = $spMetadata->getValue('simplesaml.nameidattribute');
         if (!empty($nameidattribute)) {
             if (!array_key_exists($nameidattribute, $attributes)) {
-                throw new Exception('simplesaml.nameidattribute does not exist in resulting attribute set');
+                throw new \Exception('simplesaml.nameidattribute does not exist in resulting attribute set');
             }
             $nameid = $attributes[$nameidattribute][0];
         } else {
-            $nameid = SimpleSAML\Utils\Random::generateID();
+            $nameid = \SimpleSAML\Utils\Random::generateID();
         }
 
-        $idp = SimpleSAML_IdP::getByState($state);		
+        $idp = \SimpleSAML\IdP::getByState($state);		
         $idpMetadata = $idp->getConfig();
         $idpEntityId = $idpMetadata->getString('entityid');
 
         $idp->addAssociation(array(
-            'id' => 'adfs:' . $spEntityId,
-            'Handler' => 'sspmod_adfs_IdP_ADFS',
+            'id' => 'adfs:'.$spEntityId,
+            'Handler' => '\SimpleSAML\Module\adfs\IdP\ADFS',
             'adfs:entityID' => $spEntityId,
         ));
 
-        $response = sspmod_adfs_IdP_ADFS::generateResponse($idpEntityId, $spEntityId, $nameid, $attributes);
+        $assertionLifetime = $spMetadata->getInteger('assertion.lifetime', null);
+        if ($assertionLifetime === null) {
+            $assertionLifetime = $idpMetadata->getInteger('assertion.lifetime', 300);
+        }
+
+        $response = ADFS::generateResponse($idpEntityId, $spEntityId, $nameid, $attributes, $assertionLifetime);
 
         $privateKeyFile = \SimpleSAML\Utils\Config::getCertPath($idpMetadata->getString('privatekey'));
         $certificateFile = \SimpleSAML\Utils\Config::getCertPath($idpMetadata->getString('certificate'));
-        $wresult = sspmod_adfs_IdP_ADFS::signResponse($response, $privateKeyFile, $certificateFile);
+
+        $algo = $spMetadata->getString('signature.algorithm', null);
+        if ($algo === null) {
+            $algo = $idpMetadata->getString('signature.algorithm', XMLSecurityKey::RSA_SHA256);
+        }
+        $wresult = ADFS::signResponse($response, $privateKeyFile, $certificateFile, $algo);
 
         $wctx = $state['adfs:wctx'];
-        sspmod_adfs_IdP_ADFS::postResponse($spMetadata->getValue('prp'), $wresult, $wctx);
+        $wreply = $state['adfs:wreply'] ? : $spMetadata->getValue('prp');
+        ADFS::postResponse($wreply, $wresult, $wctx);
     }
 
-    public static function sendLogoutResponse(SimpleSAML_IdP $idp, array $state)
+    public static function sendLogoutResponse(\SimpleSAML\IdP $idp, array $state)
     {
         // NB:: we don't know from which SP the logout request came from
-        $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
         $idpMetadata = $idp->getConfig();
         \SimpleSAML\Utils\HTTP::redirectTrustedURL($idpMetadata->getValue('redirect-after-logout', \SimpleSAML\Utils\HTTP::getBaseURL()));
     }
 
-    public static function receiveLogoutMessage(SimpleSAML_IdP $idp)
+    public static function receiveLogoutMessage(\SimpleSAML\IdP $idp)
     {
         // if a redirect is to occur based on wreply, we will redirect to url as
         // this implies an override to normal sp notification
@@ -196,7 +217,7 @@ MSG;
         }
 
         $state = array(
-            'Responder' => array('sspmod_adfs_IdP_ADFS', 'sendLogoutResponse'),
+            'Responder' => array('\SimpleSAML\Module\adfs\IdP\ADFS', 'sendLogoutResponse'),
         );
         $assocId = null;
         // TODO: verify that this is really no problem for: 
@@ -206,12 +227,11 @@ MSG;
     }
 
     // accepts an association array, and returns a URL that can be accessed to terminate the association
-    public static function getLogoutURL(SimpleSAML_IdP $idp, array $association, $relayState)
+    public static function getLogoutURL(\SimpleSAML\IdP $idp, array $association, $relayState)
     {
-        $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-        $idpMetadata = $idp->getConfig();
+        $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
         $spMetadata = $metadata->getMetaDataConfig($association['adfs:entityID'], 'adfs-sp-remote');
-        $returnTo = SimpleSAML\Module::getModuleURL('adfs/idp/prp.php?assocId=' . urlencode($association["id"]) . '&relayState=' . urlencode($relayState));
-        return $spMetadata->getValue('prp') . '?' . 'wa=wsignoutcleanup1.0&wreply=' . urlencode($returnTo);
+        $returnTo = \SimpleSAML\Module::getModuleURL('adfs/idp/prp.php?assocId='.urlencode($association["id"]).'&relayState='.urlencode($relayState));
+        return $spMetadata->getValue('prp').'?wa=wsignoutcleanup1.0&wreply='.urlencode($returnTo);
     }
 }
diff --git a/modules/adfs/lib/SAML2/XML/fed/Const.php b/modules/adfs/lib/SAML2/XML/fed/Const.php
index d24436ca32e6033db669d6cd5e986b8ae9f39b86..1fd7fb15e9f40dba500737b62683bfbbefdb5121 100644
--- a/modules/adfs/lib/SAML2/XML/fed/Const.php
+++ b/modules/adfs/lib/SAML2/XML/fed/Const.php
@@ -1,10 +1,14 @@
 <?php
+
+namespace SimpleSAML\Module\adfs\SAML2\XML\fed;
+
 /**
  * Class representing fed Constants.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_adfs_SAML2_XML_fed_Const
+
+class FedConst
 {
     /**
      * The namespace for WS-FED protocol.
diff --git a/modules/adfs/lib/SAML2/XML/fed/Endpoint.php b/modules/adfs/lib/SAML2/XML/fed/Endpoint.php
index 24178c713864b96257e0b4518c7ccea141e0e7bf..d3ac56ad346d423bc21b354243dcaebae6112bb3 100644
--- a/modules/adfs/lib/SAML2/XML/fed/Endpoint.php
+++ b/modules/adfs/lib/SAML2/XML/fed/Endpoint.php
@@ -1,18 +1,22 @@
 <?php
+
+namespace SimpleSAML\Module\adfs\SAML2\XML\fed;
+
 /**
  * Class representing fed Endpoint.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_adfs_SAML2_XML_fed_Endpoint
+
+class Endpoint
 {
     /**
      * Add this endpoint to an XML element.
      *
-     * @param DOMElement $parent  The element we should append this endpoint to.
+     * @param \DOMElement $parent  The element we should append this endpoint to.
      * @param string $name  The name of the element we should create.
      */
-    public static function appendXML(DOMElement $parent, $name, $address)
+    public static function appendXML(\DOMElement $parent, $name, $address)
     {
         assert(is_string($name));
         assert(is_string($address));
diff --git a/modules/adfs/lib/SAML2/XML/fed/SecurityTokenServiceType.php b/modules/adfs/lib/SAML2/XML/fed/SecurityTokenServiceType.php
index d162507e2a29c7429de30bd72c4d79af6cbd0280..30f2f62d420b56d4bc3c96be92a6cfde699cf9a9 100644
--- a/modules/adfs/lib/SAML2/XML/fed/SecurityTokenServiceType.php
+++ b/modules/adfs/lib/SAML2/XML/fed/SecurityTokenServiceType.php
@@ -1,17 +1,21 @@
 <?php
+
+namespace SimpleSAML\Module\adfs\SAML2\XML\fed;
+
 /**
  * Class representing SecurityTokenServiceType RoleDescriptor.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_adfs_SAML2_XML_fed_SecurityTokenServiceType extends SAML2_XML_md_RoleDescriptor
+
+class SecurityTokenServiceType extends \SAML2\XML\md\RoleDescriptor
 {
     /**
      * List of supported protocols.
      *
      * @var array
      */
-    public $protocolSupportEnumeration = array(sspmod_adfs_SAML2_XML_fed_Const::NS_FED);
+    public $protocolSupportEnumeration = array(FedConst::NS_FED);
 
     /**
      * The Location of Services.
@@ -23,9 +27,9 @@ class sspmod_adfs_SAML2_XML_fed_SecurityTokenServiceType extends SAML2_XML_md_Ro
     /**
      * Initialize a SecurityTokenServiceType element.
      *
-     * @param DOMElement|null $xml  The XML element we should load.
+     * @param \DOMElement|null $xml  The XML element we should load.
      */
-    public function __construct(DOMElement $xml = null)
+    public function __construct(\DOMElement $xml = null)
     {
         parent::__construct('RoleDescriptor', $xml);
         if ($xml === null) {
@@ -36,19 +40,19 @@ class sspmod_adfs_SAML2_XML_fed_SecurityTokenServiceType extends SAML2_XML_md_Ro
     /**
      * Convert this SecurityTokenServiceType RoleDescriptor to XML.
      *
-     * @param DOMElement $parent  The element we should add this contact to.
-     * @return DOMElement  The new ContactPerson-element.
+     * @param \DOMElement $parent  The element we should add this contact to.
+     * @return \DOMElement  The new ContactPerson-element.
      */
-    public function toXML(DOMElement $parent)
+    public function toXML(\DOMElement $parent)
     {
         assert(is_string($this->Location));
 
         $e = parent::toXML($parent);
-        $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:fed', sspmod_adfs_SAML2_XML_fed_Const::NS_FED);
+        $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:fed', FedConst::NS_FED);
         $e->setAttributeNS(\SAML2\Constants::NS_XSI, 'xsi:type', 'fed:SecurityTokenServiceType');
-        sspmod_adfs_SAML2_XML_fed_TokenTypesOffered::appendXML($e);
-        sspmod_adfs_SAML2_XML_fed_Endpoint::appendXML($e, 'SecurityTokenServiceEndpoint', $this->Location);
-        sspmod_adfs_SAML2_XML_fed_Endpoint::appendXML($e, 'fed:PassiveRequestorEndpoint', $this->Location);
+        TokenTypesOffered::appendXML($e);
+        Endpoint::appendXML($e, 'SecurityTokenServiceEndpoint', $this->Location);
+        Endpoint::appendXML($e, 'fed:PassiveRequestorEndpoint', $this->Location);
 
         return $e;
     }
diff --git a/modules/adfs/lib/SAML2/XML/fed/TokenTypesOffered.php b/modules/adfs/lib/SAML2/XML/fed/TokenTypesOffered.php
index 280b80c3aecd261a764a2d1efb3ad74285bacb2f..8e30f442c7b23a7e823c253c5190b2ce8ae4511a 100644
--- a/modules/adfs/lib/SAML2/XML/fed/TokenTypesOffered.php
+++ b/modules/adfs/lib/SAML2/XML/fed/TokenTypesOffered.php
@@ -1,22 +1,26 @@
 <?php
+
+namespace SimpleSAML\Module\adfs\SAML2\XML\fed;
+
 /**
  * Class representing fed TokenTypesOffered.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_adfs_SAML2_XML_fed_TokenTypesOffered
+
+class TokenTypesOffered
 {
     /**
      * Add tokentypesoffered to an XML element.
      *
-     * @param DOMElement $parent  The element we should append this endpoint to.
+     * @param \DOMElement $parent  The element we should append this endpoint to.
      */
-    public static function appendXML(DOMElement $parent)
+    public static function appendXML(\DOMElement $parent)
     {
-        $e = $parent->ownerDocument->createElementNS(sspmod_adfs_SAML2_XML_fed_Const::NS_FED, 'fed:TokenTypesOffered');
+        $e = $parent->ownerDocument->createElementNS(FedConst::NS_FED, 'fed:TokenTypesOffered');
         $parent->appendChild($e);
 
-        $tokentype = $parent->ownerDocument->createElementNS(sspmod_adfs_SAML2_XML_fed_Const::NS_FED, 'fed:TokenType');
+        $tokentype = $parent->ownerDocument->createElementNS(FedConst::NS_FED, 'fed:TokenType');
         $tokentype->setAttribute('Uri', 'urn:oasis:names:tc:SAML:1.0:assertion');
         $e->appendChild($tokentype);
 
diff --git a/modules/adfs/www/idp/metadata.php b/modules/adfs/www/idp/metadata.php
index bb77b56f6f917861787d61a23a37f347b019ebe3..8308373f342c67ccc9367277d839ba7fe6152efa 100644
--- a/modules/adfs/www/idp/metadata.php
+++ b/modules/adfs/www/idp/metadata.php
@@ -1,11 +1,11 @@
 <?php
 
 // load configuration and metadata
-$config = SimpleSAML_Configuration::getInstance();
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$config = \SimpleSAML\Configuration::getInstance();
+$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 
 if (!$config->getBoolean('enable.adfs-idp', false)) {
-    throw new SimpleSAML_Error_Error('NOACCESS');
+    throw new \SimpleSAML\Error\Error('NOACCESS');
 }
 
 // check if valid local session exists
@@ -94,7 +94,7 @@ try {
         );
 
         if (!$idpmeta->hasValue('OrganizationURL')) {
-            throw new SimpleSAML_Error_Exception('If OrganizationName is set, OrganizationURL must also be set.');
+            throw new \SimpleSAML\Error\Exception('If OrganizationName is set, OrganizationURL must also be set.');
         }
         $metaArray['OrganizationURL'] = $idpmeta->getLocalizedString('OrganizationURL');
     }
@@ -121,7 +121,7 @@ try {
 
     $metaflat = '$metadata['.var_export($idpentityid, true).'] = '.var_export($metaArray, true).';';
 
-    $metaBuilder = new SimpleSAML_Metadata_SAMLBuilder($idpentityid);
+    $metaBuilder = new \SimpleSAML\Metadata\SAMLBuilder($idpentityid);
     $metaBuilder->addSecurityTokenServiceType($metaArray);
     $metaBuilder->addOrganizationInfo($metaArray);
     $technicalContactEmail = $config->getString('technicalcontact_email', null);
@@ -139,12 +139,12 @@ try {
     }
 
     // sign the metadata if enabled
-    $metaxml = SimpleSAML_Metadata_Signer::sign($metaxml, $idpmeta->toArray(), 'ADFS IdP');
+    $metaxml = \SimpleSAML\Metadata\Signer::sign($metaxml, $idpmeta->toArray(), 'ADFS IdP');
 
     if ($output_xhtml) {
         $defaultidp = $config->getString('default-adfs-idp', null);
 
-        $t = new SimpleSAML_XHTML_Template($config, 'metadata.php', 'admin');
+        $t = new \SimpleSAML\XHTML\Template($config, 'metadata.php', 'admin');
 
         $t->data['clipboard.js'] = true;
         $t->data['available_certs'] = $availableCerts;
@@ -174,5 +174,5 @@ try {
         exit(0);
     }
 } catch (Exception $exception) {
-    throw new SimpleSAML_Error_Error('METADATA', $exception);
+    throw new \SimpleSAML\Error\Error('METADATA', $exception);
 }
diff --git a/modules/adfs/www/idp/prp.php b/modules/adfs/www/idp/prp.php
index 99f8db825cd43553196b7a75401972191e133a3b..1f5d85e2b9039013d89759d2550e6ebb7b0df3d3 100644
--- a/modules/adfs/www/idp/prp.php
+++ b/modules/adfs/www/idp/prp.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * ADFS PRP IDP protocol support for SimpleSAMLphp.
  *
@@ -6,23 +7,23 @@
  * @package SimpleSAMLphp
  */
 
-SimpleSAML\Logger::info('ADFS - IdP.prp: Accessing ADFS IdP endpoint prp');
+\SimpleSAML\Logger::info('ADFS - IdP.prp: Accessing ADFS IdP endpoint prp');
 
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 $idpEntityId = $metadata->getMetaDataCurrentEntityID('adfs-idp-hosted');
-$idp = SimpleSAML_IdP::getById('adfs:' . $idpEntityId);
+$idp = \SimpleSAML\IdP::getById('adfs:' . $idpEntityId);
 
 if (isset($_GET['wa'])) {
     if ($_GET['wa'] === 'wsignout1.0') {
-        sspmod_adfs_IdP_ADFS::receiveLogoutMessage($idp);
+        \SimpleSAML\Module\adfs\IdP\ADFS::receiveLogoutMessage($idp);
     } else if ($_GET['wa'] === 'wsignin1.0') {
-        sspmod_adfs_IdP_ADFS::receiveAuthnRequest($idp);
+        \SimpleSAML\Module\adfs\IdP\ADFS::receiveAuthnRequest($idp);
     }
     assert(false);
 } elseif (isset($_GET['assocId'])) {
     // logout response from ADFS SP
     $assocId = $_GET['assocId']; // Association ID of the SP that sent the logout response
     $relayState = $_GET['relayState']; // Data that was sent in the logout request to the SP. Can be null
-    $logoutError = null; // null on success, or an instance of a SimpleSAML_Error_Exception on failure.
+    $logoutError = null; // null on success, or an instance of a \SimpleSAML\Error\Exception on failure.
     $idp->handleLogoutResponse($assocId, $relayState, $logoutError);
 }
diff --git a/modules/authX509/lib/Auth/Process/ExpiryWarning.php b/modules/authX509/lib/Auth/Process/ExpiryWarning.php
index 0a6fe5bf9bb48df307d7baa78ff918c83762f179..3457ff4b48c2d99ed49a8aee8340d36806b2b8fe 100644
--- a/modules/authX509/lib/Auth/Process/ExpiryWarning.php
+++ b/modules/authX509/lib/Auth/Process/ExpiryWarning.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\authX509\Auth\Process;
+
 /**
  * Filter which shows a warning if the user's client certificate is about to expire.
  *
@@ -14,7 +16,8 @@
  * @author Joost van Dijk, SURFnet. <Joost.vanDijk@surfnet.nl>
  * @package SimpleSAMLphp
  */
-class sspmod_authX509_Auth_Process_ExpiryWarning extends SimpleSAML_Auth_ProcessingFilter
+
+class ExpiryWarning extends \SimpleSAML\Auth\ProcessingFilter
 {
 
     private $warndaysbefore = 30;
@@ -35,14 +38,14 @@ class sspmod_authX509_Auth_Process_ExpiryWarning extends SimpleSAML_Auth_Process
         if (array_key_exists('warndaysbefore', $config)) {
             $this->warndaysbefore = $config['warndaysbefore'];
             if (!is_string($this->warndaysbefore)) {
-                throw new Exception('Invalid value for \'warndaysbefore\'-option to authX509::ExpiryWarning filter.');
+                throw new \Exception('Invalid value for \'warndaysbefore\'-option to authX509::ExpiryWarning filter.');
             }
         }
 
         if (array_key_exists('renewurl', $config)) {
             $this->renewurl = $config['renewurl'];
             if (!is_string($this->renewurl)) {
-                throw new Exception('Invalid value for \'renewurl\'-option to authX509::ExpiryWarning filter.');
+                throw new \Exception('Invalid value for \'renewurl\'-option to authX509::ExpiryWarning filter.');
             }
         }
     }
@@ -72,7 +75,7 @@ class sspmod_authX509_Auth_Process_ExpiryWarning extends SimpleSAML_Auth_Process
         $client_cert = $_SERVER['SSL_CLIENT_CERT'];
         $client_cert_data = openssl_x509_parse($client_cert);
         if ($client_cert_data == false) {
-            SimpleSAML\Logger::error('authX509: invalid cert');
+            \SimpleSAML\Logger::error('authX509: invalid cert');
             return;
         }
         $validTo = $client_cert_data['validTo_time_t'];
@@ -83,13 +86,13 @@ class sspmod_authX509_Auth_Process_ExpiryWarning extends SimpleSAML_Auth_Process
             return;
         }
 
-        SimpleSAML\Logger::warning('authX509: user certificate expires in ' . $daysleft . ' days');
+        \SimpleSAML\Logger::warning('authX509: user certificate expires in ' . $daysleft . ' days');
         $state['daysleft'] = $daysleft;
         $state['renewurl'] = $this->renewurl;
 
         /* Save state and redirect. */
-        $id = SimpleSAML_Auth_State::saveState($state, 'warning:expire');
-        $url = SimpleSAML\Module::getModuleURL('authX509/expirywarning.php');
+        $id = \SimpleSAML\Auth\State::saveState($state, 'warning:expire');
+        $url = \SimpleSAML\Module::getModuleURL('authX509/expirywarning.php');
         \SimpleSAML\Utils\HTTP::redirectTrustedURL($url, array('StateId' => $id));
     }
 
diff --git a/modules/authX509/lib/Auth/Source/X509userCert.php b/modules/authX509/lib/Auth/Source/X509userCert.php
index 0cf9083d051c31ab832e0a691f2d1dc5f174bd44..402ebbefbada8b9cd0b57553052d23e99b1f54f6 100644
--- a/modules/authX509/lib/Auth/Source/X509userCert.php
+++ b/modules/authX509/lib/Auth/Source/X509userCert.php
@@ -1,14 +1,16 @@
 <?php
 
+namespace SimpleSAML\Module\authX509\Auth\Source;
+
 /**
  * This class implements x509 certificate authentication with certificate validation against an LDAP directory.
  *
  * @author Emmanuel Dreyfus <manu@netbsd.org>
  * @package SimpleSAMLphp
  */
-class sspmod_authX509_Auth_Source_X509userCert extends SimpleSAML_Auth_Source
-{
 
+class X509userCert extends \SimpleSAML\Auth\Source
+{
     /**
      * x509 attributes to use from the certificate for searching the user in the LDAP directory.
      */
@@ -50,7 +52,7 @@ class sspmod_authX509_Auth_Source_X509userCert extends SimpleSAML_Auth_Source
 
         parent::__construct($info, $config);
 
-        $this->ldapcf = new sspmod_ldap_ConfigHelper(
+        $this->ldapcf = new \SimpleSAML\Module\ldap\ConfigHelper(
             $config,
             'Authentication source ' . var_export($this->authId, true)
         );
@@ -68,13 +70,13 @@ class sspmod_authX509_Auth_Source_X509userCert extends SimpleSAML_Auth_Source
      */
     public function authFailed(&$state)
     {
-        $config = SimpleSAML_Configuration::getInstance();
-        $errorcodes = SimpleSAML\Error\ErrorCodes::getAllErrorCodeMessages();
+        $config = \SimpleSAML\Configuration::getInstance();
 
-        $t = new SimpleSAML_XHTML_Template($config, 'authX509:X509error.php');
-        $t->data['loginurl'] = SimpleSAML\Utils\HTTP::getSelfURL();
+        $t = new \SimpleSAML\XHTML\Template($config, 'authX509:X509error.php');
+        $t->data['loginurl'] = \SimpleSAML\Utils\HTTP::getSelfURL();
         $t->data['errorcode'] = $state['authX509.error'];
-        $t->data['errorcodes'] = SimpleSAML\Error\ErrorCodes::getAllErrorCodeMessages();
+        $t->data['errorcodes'] = \SimpleSAML\Error\ErrorCodes::getAllErrorCodeMessages();
+
         $t->show();
         exit();
     }
@@ -105,7 +107,7 @@ class sspmod_authX509_Auth_Source_X509userCert extends SimpleSAML_Auth_Source
         $client_cert = $_SERVER['SSL_CLIENT_CERT'];
         $client_cert_data = openssl_x509_parse($client_cert);
         if ($client_cert_data === false) {
-            SimpleSAML\Logger::error('authX509: invalid cert');
+            \SimpleSAML\Logger::error('authX509: invalid cert');
             $state['authX509.error'] = "INVALIDCERT";
             $this->authFailed($state);
 
@@ -118,7 +120,7 @@ class sspmod_authX509_Auth_Source_X509userCert extends SimpleSAML_Auth_Source
             // value is scalar
             if (array_key_exists($x509_attr, $client_cert_data['subject'])) {
                 $value = $client_cert_data['subject'][$x509_attr];
-                SimpleSAML\Logger::info('authX509: cert '. $x509_attr.' = '.$value);
+                \SimpleSAML\Logger::info('authX509: cert '. $x509_attr.' = '.$value);
                 $dn = $ldapcf->searchfordn($ldap_attr, $value, true);
                 if ($dn !== null) {
                     break;
@@ -127,7 +129,7 @@ class sspmod_authX509_Auth_Source_X509userCert extends SimpleSAML_Auth_Source
         }
 
         if ($dn === null) {
-            SimpleSAML\Logger::error('authX509: cert has no matching user in LDAP.');
+            \SimpleSAML\Logger::error('authX509: cert has no matching user in LDAP.');
             $state['authX509.error'] = "UNKNOWNCERT";
             $this->authFailed($state);
 
@@ -147,7 +149,7 @@ class sspmod_authX509_Auth_Source_X509userCert extends SimpleSAML_Auth_Source
 
         $ldap_certs = $ldapcf->getAttributes($dn, $this->ldapusercert);
         if ($ldap_certs === false) {
-            SimpleSAML\Logger::error('authX509: no certificate found in LDAP for dn='.$dn);
+            \SimpleSAML\Logger::error('authX509: no certificate found in LDAP for dn='.$dn);
             $state['authX509.error'] = "UNKNOWNCERT";
             $this->authFailed($state);
 
@@ -166,7 +168,7 @@ class sspmod_authX509_Auth_Source_X509userCert extends SimpleSAML_Auth_Source
             $pem = \SimpleSAML\Utils\Crypto::der2pem($ldap_cert);
             $ldap_cert_data = openssl_x509_parse($pem);
             if ($ldap_cert_data === false) {
-                SimpleSAML\Logger::error('authX509: cert in LDAP is invalid for dn='.$dn);
+                \SimpleSAML\Logger::error('authX509: cert in LDAP is invalid for dn='.$dn);
                 continue;
             }
 
@@ -181,7 +183,7 @@ class sspmod_authX509_Auth_Source_X509userCert extends SimpleSAML_Auth_Source
             }
         }
 
-        SimpleSAML\Logger::error('authX509: no matching cert in LDAP for dn='.$dn);
+        \SimpleSAML\Logger::error('authX509: no matching cert in LDAP for dn='.$dn);
         $state['authX509.error'] = "UNKNOWNCERT";
         $this->authFailed($state);
 
@@ -199,7 +201,7 @@ class sspmod_authX509_Auth_Source_X509userCert extends SimpleSAML_Auth_Source
      */
     public function authSuccesful(&$state)
     {
-        SimpleSAML_Auth_Source::completeAuth($state);
+        \SimpleSAML\Auth\Source::completeAuth($state);
 
         assert(false); // should never be reached
         return;
diff --git a/modules/authX509/www/expirywarning.php b/modules/authX509/www/expirywarning.php
index be6e4f664af3bbc1823947dc54b14cd6fbe0d5da..b5b445ca186e634a5654dfdd6bed6d39afabce7e 100644
--- a/modules/authX509/www/expirywarning.php
+++ b/modules/authX509/www/expirywarning.php
@@ -6,26 +6,26 @@
  * @package SimpleSAMLphp
  */
 
-SimpleSAML\Logger::info('AuthX509 - Showing expiry warning to user');
+\SimpleSAML\Logger::info('AuthX509 - Showing expiry warning to user');
 
 if (!array_key_exists('StateId', $_REQUEST)) {
-    throw new SimpleSAML_Error_BadRequest('Missing required StateId query parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing required StateId query parameter.');
 }
 $id = $_REQUEST['StateId'];
-$state = SimpleSAML_Auth_State::loadState($id, 'warning:expire');
+$state = \SimpleSAML\Auth\State::loadState($id, 'warning:expire');
 
 
 if (array_key_exists('proceed', $_REQUEST)) {
     // The user has pressed the proceed-button
-    SimpleSAML_Auth_ProcessingChain::resumeProcessing($state);
+    \SimpleSAML\Auth\ProcessingChain::resumeProcessing($state);
 }
 
-$globalConfig = SimpleSAML_Configuration::getInstance();
+$globalConfig = \SimpleSAML\Configuration::getInstance();
 
-$t = new SimpleSAML_XHTML_Template($globalConfig, 'authX509:X509warning.php');
-$t->data['target'] = SimpleSAML\Module::getModuleURL('authX509/expirywarning.php');
+$t = new \SimpleSAML\XHTML\Template($globalConfig, 'authX509:X509warning.php');
+$t->data['target'] = \SimpleSAML\Module::getModuleURL('authX509/expirywarning.php');
 $t->data['data'] = array('StateId' => $id);
 $t->data['daysleft'] = $state['daysleft'];
 $t->data['renewurl'] = $state['renewurl'];
-$t->data['errorcodes'] = SimpleSAML\Error\ErrorCodes::getAllErrorCodeMessages();
+$t->data['errorcodes'] = \SimpleSAML\Error\ErrorCodes::getAllErrorCodeMessages();
 $t->show();
diff --git a/modules/authYubiKey/lib/Auth/Process/OTP2YubiPrefix.php b/modules/authYubiKey/lib/Auth/Process/OTP2YubiPrefix.php
index 1c37c8c03fd2527705ed7500af698b65949daf51..0fe040ee453d5974a95e3625198624b3c24088f6 100644
--- a/modules/authYubiKey/lib/Auth/Process/OTP2YubiPrefix.php
+++ b/modules/authYubiKey/lib/Auth/Process/OTP2YubiPrefix.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\authYubiKey\Auth\Process;
+
 /*
  * Copyright (C) 2009  Simon Josefsson <simon@yubico.com>.
  *
@@ -42,9 +44,9 @@
  *      );
  *
  */
-class sspmod_authYubiKey_Auth_Process_OTP2YubiPrefix extends SimpleSAML_Auth_ProcessingFilter {
-
 
+class OTP2YubiPrefix extends \SimpleSAML\Auth\ProcessingFilter
+{
 	/**
 	 * Filter out YubiKey 'otp' attribute and replace it with
          * a 'yubiPrefix' attribute that leaves out the dynamic part.
@@ -56,7 +58,7 @@ class sspmod_authYubiKey_Auth_Process_OTP2YubiPrefix extends SimpleSAML_Auth_Pro
 		assert(array_key_exists('Attributes', $state));
 		$attributes = $state['Attributes'];
 
-		SimpleSAML\Logger::debug('OTP2YubiPrefix: enter with attributes: ' . implode(',', array_keys($attributes)));
+		\SimpleSAML\Logger::debug('OTP2YubiPrefix: enter with attributes: ' . implode(',', array_keys($attributes)));
 
 		$otps = $attributes['otp'];
 		$otp = $otps['0'];
@@ -66,11 +68,11 @@ class sspmod_authYubiKey_Auth_Process_OTP2YubiPrefix extends SimpleSAML_Auth_Pro
 
 		$attributes['yubiPrefix'] = array($identity);
 
-		SimpleSAML\Logger::info('OTP2YubiPrefix: otp: ' . $otp . ' identity: ' . $identity . ' (otp keys: ' . implode(',', array_keys($otps)) . ')');
+		\SimpleSAML\Logger::info('OTP2YubiPrefix: otp: ' . $otp . ' identity: ' . $identity . ' (otp keys: ' . implode(',', array_keys($otps)) . ')');
 
 		unset($attributes['otp']);
 
-		SimpleSAML\Logger::debug('OTP2YubiPrefix: leaving with attributes: ' . implode(',', array_keys($attributes)));
+		\SimpleSAML\Logger::debug('OTP2YubiPrefix: leaving with attributes: ' . implode(',', array_keys($attributes)));
 	}
 
 }
diff --git a/modules/authYubiKey/lib/Auth/Source/YubiKey.php b/modules/authYubiKey/lib/Auth/Source/YubiKey.php
index d5ff69f101eba57cc9b8be7623dd61d65ac2b0d4..fcd1726f322beedd61f40d1da7f280678d0a434a 100644
--- a/modules/authYubiKey/lib/Auth/Source/YubiKey.php
+++ b/modules/authYubiKey/lib/Auth/Source/YubiKey.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\authYubiKey\Auth\Source;
+
 /*
  * Copyright (C) 2009  Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
  * Copyright (C) 2009  Simon Josefsson <simon@yubico.com>.
@@ -29,175 +31,173 @@
  * Configure it by adding an entry to config/authsources.php such as this:
  *
  *	'yubikey' => array(
- *		  'authYubiKey:YubiKey',
- *		  'id' => 997,
- *		  'key' => 'b64hmackey',
- *		  ),
+ *	    'authYubiKey:YubiKey',
+ *	    'id' => 997,
+ *	    'key' => 'b64hmackey',
+ *	),
  *
  * To generate your own client id/key you will need one YubiKey, and then
  * go to http://yubico.com/developers/api/
  *
  * @package SimpleSAMLphp
  */
-class sspmod_authYubiKey_Auth_Source_YubiKey extends SimpleSAML_Auth_Source {
-
-	/**
-	 * The string used to identify our states.
-	 */
-	const STAGEID = 'sspmod_authYubiKey_Auth_Source_YubiKey.state';
-
-	/**
-	 * The number of characters of the OTP that is the secure token.
-	 * The rest is the user id.
-	 */
-	const TOKENSIZE = 32;
-
-	/**
-	 * The key of the AuthId field in the state.
-	 */
-	const AUTHID = 'sspmod_authYubiKey_Auth_Source_YubiKey.AuthId';
-
-	/**
-	 * The client id/key for use with the Auth_Yubico PHP module.
-	 */
-	private $yubi_id;
-	private $yubi_key;
-
-	/**
-	 * Constructor for this authentication source.
-	 *
-	 * @param array $info  Information about this authentication source.
-	 * @param array $config  Configuration.
-	 */
-	public function __construct($info, $config) {
-		assert(is_array($info));
-		assert(is_array($config));
-
-		// Call the parent constructor first, as required by the interface
-		parent::__construct($info, $config);
-
-		if (array_key_exists('id', $config)) {
-			$this->yubi_id = $config['id'];
-		}
-
-		if (array_key_exists('key', $config)) {
-			$this->yubi_key = $config['key'];
-		}
-	}
-
-
-	/**
-	 * Initialize login.
-	 *
-	 * This function saves the information about the login, and redirects to a
-	 * login page.
-	 *
-	 * @param array &$state  Information about the current authentication.
-	 */
-	public function authenticate(&$state) {
-		assert(is_array($state));
-
-		// We are going to need the authId in order to retrieve this authentication source later
-		$state[self::AUTHID] = $this->authId;
-
-		$id = SimpleSAML_Auth_State::saveState($state, self::STAGEID);
-
-		$url = SimpleSAML\Module::getModuleURL('authYubiKey/yubikeylogin.php');
-		\SimpleSAML\Utils\HTTP::redirectTrustedURL($url, array('AuthState' => $id));
-	}
-	
-	
-	/**
-	 * Handle login request.
-	 *
-	 * This function is used by the login form (core/www/loginuserpass.php) when the user
-	 * enters a username and password. On success, it will not return. On wrong
-	 * username/password failure, it will return the error code. Other failures will throw an
-	 * exception.
-	 *
-	 * @param string $authStateId  The identifier of the authentication state.
-	 * @param string $otp  The one time password entered-
-	 * @return string  Error code in the case of an error.
-	 */
-	public static function handleLogin($authStateId, $otp) {
-		assert(is_string($authStateId));
-		assert(is_string($otp));
-
-		/* Retrieve the authentication state. */
-		$state = SimpleSAML_Auth_State::loadState($authStateId, self::STAGEID);
-
-		/* Find authentication source. */
-		assert(array_key_exists(self::AUTHID, $state));
-		$source = SimpleSAML_Auth_Source::getById($state[self::AUTHID]);
-		if ($source === NULL) {
-			throw new Exception('Could not find authentication source with id ' . $state[self::AUTHID]);
-		}
-
-
-		try {
-			/* Attempt to log in. */
-			$attributes = $source->login($otp);
-		} catch (SimpleSAML_Error_Error $e) {
-			/* An error occurred during login. Check if it is because of the wrong
-			 * username/password - if it is, we pass that error up to the login form,
-			 * if not, we let the generic error handler deal with it.
-			 */
-			if ($e->getErrorCode() === 'WRONGUSERPASS') {
-				return 'WRONGUSERPASS';
-			}
-
-			/* Some other error occurred. Rethrow exception and let the generic error
-			 * handler deal with it.
-			 */
-			throw $e;
-		}
-
-		$state['Attributes'] = $attributes;
-		SimpleSAML_Auth_Source::completeAuth($state);
-	}
-	
-	/**
-	 * Return the user id part of a one time passord
-	 */
-	public static function getYubiKeyPrefix($otp) {
-		$uid = substr ($otp, 0, strlen ($otp) - self::TOKENSIZE);
-		return $uid;
-	}
-
-	/**
-	 * Attempt to log in using the given username and password.
-	 *
-	 * On a successful login, this function should return the users attributes. On failure,
-	 * it should throw an exception. If the error was caused by the user entering the wrong
-	 * username or password, a SimpleSAML_Error_Error('WRONGUSERPASS') should be thrown.
-	 *
-	 * Note that both the username and the password are UTF-8 encoded.
-	 *
-	 * @param string $username  The username the user wrote.
-	 * @param string $password  The password the user wrote.
-	 * @return array  Associative array with the users attributes.
-	 */
-	protected function login($otp) {
-		assert(is_string($otp));
-
-		require_once dirname(dirname(dirname(dirname(__FILE__)))) . '/libextinc/Yubico.php';
-
-		$attributes = array();
-
-		try {
-			$yubi = new Auth_Yubico($this->yubi_id, $this->yubi_key);
-			$auth = $yubi->verify($otp);
-			$uid = self::getYubiKeyPrefix($otp);
-			$attributes = array('uid' => array($uid));
-		} catch (Exception $e) {
-		  	SimpleSAML\Logger::info('YubiKey:' . $this->authId . ': Validation error (otp ' . $otp . '), debug output: ' . $yubi->getLastResponse());
-
-			throw new SimpleSAML_Error_Error('WRONGUSERPASS', $e);
-		}
-
-		SimpleSAML\Logger::info('YubiKey:' . $this->authId . ': YubiKey otp ' . $otp . ' validated successfully: ' . $yubi->getLastResponse());
-
-		return $attributes;
-	}
 
+class YubiKey extends \SimpleSAML\Auth\Source
+{
+    /**
+     * The string used to identify our states.
+     */
+    const STAGEID = '\SimpleSAML\Module\authYubiKey\Auth\Source\YubiKey.state';
+
+    /**
+     * The number of characters of the OTP that is the secure token.
+     * The rest is the user id.
+     */
+    const TOKENSIZE = 32;
+
+    /**
+     * The key of the AuthId field in the state.
+     */
+    const AUTHID = '\SimpleSAML\Module\authYubiKey\Auth\Source\YubiKey.AuthId';
+
+    /**
+     * The client id/key for use with the Auth_Yubico PHP module.
+     */
+    private $yubi_id;
+    private $yubi_key;
+
+    /**
+     * Constructor for this authentication source.
+     *
+     * @param array $info  Information about this authentication source.
+     * @param array $config  Configuration.
+     */
+    public function __construct($info, $config)
+    {
+        assert(is_array($info));
+        assert(is_array($config));
+
+        // Call the parent constructor first, as required by the interface
+        parent::__construct($info, $config);
+
+        if (array_key_exists('id', $config)) {
+            $this->yubi_id = $config['id'];
+        }
+
+        if (array_key_exists('key', $config)) {
+            $this->yubi_key = $config['key'];
+        }
+    }
+
+
+    /**
+     * Initialize login.
+     *
+     * This function saves the information about the login, and redirects to a
+     * login page.
+     *
+     * @param array &$state  Information about the current authentication.
+     */
+    public function authenticate(&$state)
+    {
+        assert(is_array($state));
+
+        // We are going to need the authId in order to retrieve this authentication source later
+        $state[self::AUTHID] = $this->authId;
+
+        $id = \SimpleSAML\Auth\State::saveState($state, self::STAGEID);
+        $url = \SimpleSAML\Module::getModuleURL('authYubiKey/yubikeylogin.php');
+        \SimpleSAML\Utils\HTTP::redirectTrustedURL($url, array('AuthState' => $id));
+    }
+
+
+    /**
+     * Handle login request.
+     *
+     * This function is used by the login form (core/www/loginuserpass.php) when the user
+     * enters a username and password. On success, it will not return. On wrong
+     * username/password failure, it will return the error code. Other failures will throw an
+     * exception.
+     *
+     * @param string $authStateId  The identifier of the authentication state.
+     * @param string $otp  The one time password entered-
+     * @return string  Error code in the case of an error.
+     */
+    public static function handleLogin($authStateId, $otp)
+    {
+        assert(is_string($authStateId));
+        assert(is_string($otp));
+
+        /* Retrieve the authentication state. */
+        $state = \SimpleSAML\Auth\State::loadState($authStateId, self::STAGEID);
+
+        /* Find authentication source. */
+        assert(array_key_exists(self::AUTHID, $state));
+        $source = \SimpleSAML\Auth\Source::getById($state[self::AUTHID]);
+        if ($source === null) {
+            throw new \Exception('Could not find authentication source with id '.$state[self::AUTHID]);
+        }
+
+        try {
+            /* Attempt to log in. */
+            $attributes = $source->login($otp);
+        } catch (\SimpleSAML\Error\Error $e) {
+            /* An error occurred during login. Check if it is because of the wrong
+             * username/password - if it is, we pass that error up to the login form,
+             * if not, we let the generic error handler deal with it.
+             */
+            if ($e->getErrorCode() === 'WRONGUSERPASS') {
+                return 'WRONGUSERPASS';
+            }
+
+            /* Some other error occurred. Rethrow exception and let the generic error
+             * handler deal with it.
+             */
+            throw $e;
+        }
+
+        $state['Attributes'] = $attributes;
+        \SimpleSAML\Auth\Source::completeAuth($state);
+    }
+
+    /**
+     * Return the user id part of a one time passord
+     */
+    public static function getYubiKeyPrefix($otp)
+    {
+        $uid = substr($otp, 0, strlen ($otp) - self::TOKENSIZE);
+        return $uid;
+    }
+
+    /**
+     * Attempt to log in using the given username and password.
+     *
+     * On a successful login, this function should return the users attributes. On failure,
+     * it should throw an exception. If the error was caused by the user entering the wrong
+     * username or password, a \SimpleSAML\Error\Error('WRONGUSERPASS') should be thrown.
+     *
+     * Note that both the username and the password are UTF-8 encoded.
+     *
+     * @param string $otp
+     * @return array Associative array with the users attributes.
+     */
+    protected function login($otp)
+    {
+        assert(is_string($otp));
+
+        require_once dirname(dirname(dirname(dirname(__FILE__)))).'/libextinc/Yubico.php';
+
+        try {
+            $yubi = new \Auth_Yubico($this->yubi_id, $this->yubi_key);
+            $yubi->verify($otp);
+            $uid = self::getYubiKeyPrefix($otp);
+            $attributes = array('uid' => array($uid));
+        } catch (\Exception $e) {
+            \SimpleSAML\Logger::info('YubiKey:'.$this->authId.': Validation error (otp '.$otp.'), debug output: '.$yubi->getLastResponse());
+            throw new \SimpleSAML\Error\Error('WRONGUSERPASS', $e);
+        }
+
+        \SimpleSAML\Logger::info('YubiKey:'.$this->authId.': YubiKey otp '.$otp.' validated successfully: '.$yubi->getLastResponse());
+        return $attributes;
+    }
 }
diff --git a/modules/authYubiKey/libextinc/Yubico.php b/modules/authYubiKey/libextinc/Yubico.php
index aaf99c998301568d9a16c3a9d5d7f81720c32081..c6b4f4a600e74c76ab94095056a076279a1038e5 100644
--- a/modules/authYubiKey/libextinc/Yubico.php
+++ b/modules/authYubiKey/libextinc/Yubico.php
@@ -66,26 +66,26 @@ class Auth_Yubico
 	 * Yubico client ID
 	 * @var string
 	 */
-	var $_id;
+	private $_id;
 
 	/**
 	 * Yubico client key
 	 * @var string
 	 */
-	var $_key;
+	private $_key;
 
 	/**
 	 * Response from server
 	 * @var string
 	 */
-	var $_response;
+	private $_response;
 
 	/**
 	 * Constructor
 	 *
 	 * Sets up the object
-	 * @param    string  The client identity
-	 * @param    string  The client MAC key (optional)
+	 * @param string $id    The client identity
+	 * @param string $key   The client MAC key (optional)
 	 * @access public
 	 */
 	public function __construct($id, $key = '')
@@ -100,7 +100,7 @@ class Auth_Yubico
 	 * @return string		Output from server.
 	 * @access public
 	 */
-	function getLastResponse()
+	public function getLastResponse()
 	{
 		return $this->_response;
 	}
@@ -114,29 +114,30 @@ class Auth_Yubico
 	 * @return mixed            PEAR error on error, true otherwise
 	 * @access public
 	 */
-	function verify($token)
+	public function verify($token)
 	{
 		$parameters = "id=" . $this->_id . "&otp=" . $token;
 		// Generate signature
-		if($this->_key <> "") {
+		if ($this->_key <> "") {
 			$signature = base64_encode(hash_hmac('sha1', $parameters, $this->_key, true));
 			$parameters .= '&h=' . $signature;
 		}
 		/* Support https. */
 		$url = "https://api.yubico.com/wsapi/verify?" . $parameters;
 
-		$responseMsg = file_get_contents($url);
+		$responseMsg = \SimpleSAML\Utils\HTTP::fetch($url);
 		
-		if(!preg_match("/status=([a-zA-Z0-9_]+)/", $responseMsg, $out)) {
+		if (!preg_match("/status=([a-zA-Z0-9_]+)/", $responseMsg, $out)) {
 			throw new Exception('Could not parse response');
 		}
 
 		$status = $out[1];
 		
 		/* Verify signature. */
-		if($this->_key <> "") {
+		if ($this->_key <> "") {
 			$rows = explode("\r\n", $responseMsg);
-			while (list($key, $val) = each($rows)) {
+            $response = array();
+            foreach ($rows as $val) {
 				// = is also used in BASE64 encoding so we only replace the first = by # which is not used in BASE64
 				$val = preg_replace('/=/', '#', $val, 1);
 				$row = explode("#", $val);
@@ -146,7 +147,7 @@ class Auth_Yubico
 			$check = 'status=' . $response['status'] . '&t='. $response['t'];
 			$checksignature = base64_encode(hash_hmac('sha1', $check, $this->_key, true));
 			
-			if($response['h'] != $checksignature) {
+			if ($response['h'] != $checksignature) {
 				throw new Exception('Checked Signature failed');
 			}
 		}
diff --git a/modules/authYubiKey/www/resources/logo.jpg b/modules/authYubiKey/www/resources/logo.jpg
index 3b7e7f360ddb176fd383a8bea0d6b500fff95cf5..e2fded1a931f2d0ad604be69c7722002f9bb71fe 100644
Binary files a/modules/authYubiKey/www/resources/logo.jpg and b/modules/authYubiKey/www/resources/logo.jpg differ
diff --git a/modules/authYubiKey/www/yubikeylogin.php b/modules/authYubiKey/www/yubikeylogin.php
index 42a418a8f7602a9b2c61029ed657e7e8bae884c7..b73402210bd11e39db4dcf11862a761562ba72af 100644
--- a/modules/authYubiKey/www/yubikeylogin.php
+++ b/modules/authYubiKey/www/yubikeylogin.php
@@ -10,24 +10,23 @@
  */
 
 if (!array_key_exists('AuthState', $_REQUEST)) {
-	throw new SimpleSAML_Error_BadRequest('Missing AuthState parameter.');
+	throw new \SimpleSAML\Error\BadRequest('Missing AuthState parameter.');
 }
 
-$globalConfig = SimpleSAML_Configuration::getInstance();
-$t = new SimpleSAML_XHTML_Template($globalConfig, 'authYubiKey:yubikeylogin.php');
+$globalConfig = \SimpleSAML\Configuration::getInstance();
+$t = new \SimpleSAML\XHTML\Template($globalConfig, 'authYubiKey:yubikeylogin.php');
 
 $errorCode = null;
 if (array_key_exists('otp', $_REQUEST)) {
     // attempt to log in
-    $errorCode = sspmod_authYubiKey_Auth_Source_YubiKey::handleLogin($authStateId, $_REQUEST['otp']);
-
-    $errorCodes = SimpleSAML\Error\ErrorCodes::getAllErrorCodeMessages();
+    $errorCode = \SimpleSAML\Module\authYubiKey\Auth\Source\YubiKey::handleLogin($authStateId, $_REQUEST['otp']);
+    $errorCodes = \SimpleSAML\Error\ErrorCodes::getAllErrorCodeMessages();
     $t->data['errorTitle'] = $errorCodes['title'][$errorCode];
     $t->data['errorDesc'] = $errorCodes['desc'][$errorCode];
 }
 
 $t->data['errorCode'] = $errorCode;
 $t->data['stateParams'] = array('AuthState' => $_REQUEST['authStateId']);
-$t->data['logoUrl'] = SimpleSAML\Module::getModuleURL('authYubiKey/resources/logo.jpg');
-$t->data['devicepicUrl'] = SimpleSAML\Module::getModuleURL('authYubiKey/resources/yubikey.jpg');
+$t->data['logoUrl'] = \SimpleSAML\Module::getModuleURL('authYubiKey/resources/logo.jpg');
+$t->data['devicepicUrl'] = \SimpleSAML\Module::getModuleURL('authYubiKey/resources/yubikey.jpg');
 $t->show();
diff --git a/modules/authcrypt/lib/Auth/Source/Hash.php b/modules/authcrypt/lib/Auth/Source/Hash.php
index 1aca115745fddf89ddbfb2d4951cc8b827021594..bcca962cefb0746f5ea6995efc9c716fc951675e 100644
--- a/modules/authcrypt/lib/Auth/Source/Hash.php
+++ b/modules/authcrypt/lib/Auth/Source/Hash.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML\Module\authcrypt\Auth\Source;
 
 /**
  * Authentication source for username & hashed password.
@@ -10,10 +11,9 @@
  * @author Dyonisius Visser, TERENA.
  * @package SimpleSAMLphp
  */
-class sspmod_authcrypt_Auth_Source_Hash extends sspmod_core_Auth_UserPassBase
-{
-
 
+class Hash extends \SimpleSAML\Module\core\Auth\UserPassBase
+{
     /**
      * Our users, stored in an associative array. The key of the array is "<username>:<passwordhash>",
      * while the value of each element is a new array with the attributes for each user.
@@ -42,22 +42,22 @@ class sspmod_authcrypt_Auth_Source_Hash extends sspmod_core_Auth_UserPassBase
         // Validate and parse our configuration
         foreach ($config as $userpass => $attributes) {
             if (!is_string($userpass)) {
-                throw new Exception('Invalid <username>:<passwordhash> for authentication source '.
+                throw new \Exception('Invalid <username>:<passwordhash> for authentication source '.
                     $this->authId.': '.$userpass);
             }
 
             $userpass = explode(':', $userpass, 2);
             if (count($userpass) !== 2) {
-                throw new Exception('Invalid <username>:<passwordhash> for authentication source '.
+                throw new \Exception('Invalid <username>:<passwordhash> for authentication source '.
                     $this->authId.': '.$userpass[0]);
             }
             $username = $userpass[0];
             $passwordhash = $userpass[1];
 
             try {
-                $attributes = SimpleSAML\Utils\Attributes::normalizeAttributesArray($attributes);
-            } catch (Exception $e) {
-                throw new Exception('Invalid attributes for user '.$username.
+                $attributes = \SimpleSAML\Utils\Attributes::normalizeAttributesArray($attributes);
+            } catch (\Exception $e) {
+                throw new \Exception('Invalid attributes for user '.$username.
                     ' in authentication source '.$this->authId.': '.
                     $e->getMessage());
             }
@@ -72,7 +72,7 @@ class sspmod_authcrypt_Auth_Source_Hash extends sspmod_core_Auth_UserPassBase
      *
      * On a successful login, this function should return the users attributes. On failure,
      * it should throw an exception. If the error was caused by the user entering the wrong
-     * username OR password, a SimpleSAML_Error_Error('WRONGUSERPASS') should be thrown.
+     * username OR password, a \SimpleSAML\Error\Error('WRONGUSERPASS') should be thrown.
      *
      * The username is UTF-8 encoded, and the hash is base64 encoded.
      *
@@ -81,7 +81,7 @@ class sspmod_authcrypt_Auth_Source_Hash extends sspmod_core_Auth_UserPassBase
      *
      * @return array  Associative array with the users attributes.
      *
-     * @throws SimpleSAML_Error_Error if authentication fails.
+     * @throws \SimpleSAML\Error\Error if authentication fails.
      */
     protected function login($username, $password)
     {
@@ -91,13 +91,13 @@ class sspmod_authcrypt_Auth_Source_Hash extends sspmod_core_Auth_UserPassBase
         foreach ($this->users as $userpass => $attrs) {
             $matches = explode(':', $userpass, 2);
             if ($matches[0] === $username) {
-                if (SimpleSAML\Utils\Crypto::pwValid($matches[1], $password)) {
+                if (\SimpleSAML\Utils\Crypto::pwValid($matches[1], $password)) {
                     return $attrs;
                 } else {
-                    SimpleSAML\Logger::debug('Incorrect password "'.$password.'" for user '.$username);
+                    \SimpleSAML\Logger::debug('Incorrect password "'.$password.'" for user '.$username);
                 }
             }
         }
-        throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+        throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
     }
 }
diff --git a/modules/authcrypt/lib/Auth/Source/Htpasswd.php b/modules/authcrypt/lib/Auth/Source/Htpasswd.php
index 84bc7ea3efdd1fc0d05d2eacaab6c4e755eada19..86fcc0b159d52086317da273b6cce966a6c3fe63 100644
--- a/modules/authcrypt/lib/Auth/Source/Htpasswd.php
+++ b/modules/authcrypt/lib/Auth/Source/Htpasswd.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\authcrypt\Auth\Source;
+
 /**
  * Authentication source for Apache 'htpasswd' files.
  *
@@ -9,10 +11,8 @@
 
 use WhiteHat101\Crypt\APR1_MD5;
 
-class sspmod_authcrypt_Auth_Source_Htpasswd extends sspmod_core_Auth_UserPassBase
+class Htpasswd extends \SimpleSAML\Module\core\Auth\UserPassBase
 {
-
-
     /**
      * Our users, stored in an array, where each value is "<username>:<passwordhash>".
      *
@@ -47,15 +47,15 @@ class sspmod_authcrypt_Auth_Source_Htpasswd extends sspmod_core_Auth_UserPassBas
         $this->users = array();
 
         if (!$htpasswd = file_get_contents($config['htpasswd_file'])) {
-            throw new Exception('Could not read '.$config['htpasswd_file']);
+            throw new \Exception('Could not read '.$config['htpasswd_file']);
         }
 
         $this->users = explode("\n", trim($htpasswd));
 
         try {
-            $this->attributes = SimpleSAML\Utils\Attributes::normalizeAttributesArray($config['static_attributes']);
-        } catch (Exception $e) {
-            throw new Exception('Invalid static_attributes in authentication source '.
+            $this->attributes = \SimpleSAML\Utils\Attributes::normalizeAttributesArray($config['static_attributes']);
+        } catch (\Exception $e) {
+            throw new \Exception('Invalid static_attributes in authentication source '.
                 $this->authId.': '.$e->getMessage());
         }
     }
@@ -66,7 +66,7 @@ class sspmod_authcrypt_Auth_Source_Htpasswd extends sspmod_core_Auth_UserPassBas
      *
      * On a successful login, this function should return the username as 'uid' attribute,
      * and merged attributes from the configuration file.
-     * On failure, it should throw an exception. A SimpleSAML_Error_Error('WRONGUSERPASS')
+     * On failure, it should throw an exception. A \SimpleSAML\Error\Error('WRONGUSERPASS')
      * should be thrown in case of a wrong username OR a wrong password, to prevent the
      * enumeration of usernames.
      *
@@ -75,7 +75,7 @@ class sspmod_authcrypt_Auth_Source_Htpasswd extends sspmod_core_Auth_UserPassBas
      *
      * @return array Associative array with the users attributes.
      *
-     * @throws SimpleSAML_Error_Error if authentication fails.
+     * @throws \SimpleSAML\Error\Error if authentication fails.
      */
     protected function login($username, $password)
     {
@@ -91,9 +91,9 @@ class sspmod_authcrypt_Auth_Source_Htpasswd extends sspmod_core_Auth_UserPassBas
                 $attributes = array_merge(array('uid' => array($username)), $this->attributes);
 
                 // Traditional crypt(3)
-                if (SimpleSAML\Utils\Crypto::secureCompare($crypted, crypt($password, $crypted))) {
-                    SimpleSAML\Logger::debug('User '.$username.' authenticated successfully');
-                    SimpleSAML\Logger::warning(
+                if (\SimpleSAML\Utils\Crypto::secureCompare($crypted, crypt($password, $crypted))) {
+                    \SimpleSAML\Logger::debug('User '.$username.' authenticated successfully');
+                    \SimpleSAML\Logger::warning(
                         'CRYPT authentication is insecure. Please consider using something else.'
                     );
                     return $attributes;
@@ -101,21 +101,21 @@ class sspmod_authcrypt_Auth_Source_Htpasswd extends sspmod_core_Auth_UserPassBas
 
                 // Apache's custom MD5
                 if (APR1_MD5::check($password, $crypted)) {
-                    SimpleSAML\Logger::debug('User '.$username.' authenticated successfully');
+                    \SimpleSAML\Logger::debug('User '.$username.' authenticated successfully');
                     return $attributes;
                 }
 
                 // SHA1 or plain-text
-                if (SimpleSAML\Utils\Crypto::pwValid($crypted, $password)) {
-                    SimpleSAML\Logger::debug('User '.$username.' authenticated successfully');
-                    SimpleSAML\Logger::warning(
+                if (\SimpleSAML\Utils\Crypto::pwValid($crypted, $password)) {
+                    \SimpleSAML\Logger::debug('User '.$username.' authenticated successfully');
+                    \SimpleSAML\Logger::warning(
                         'SHA1 and PLAIN TEXT authentication are insecure. Please consider using something else.'
                     );
                     return $attributes;
                 }
-                throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+                throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
             }
         }
-        throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+        throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
     }
 }
diff --git a/modules/authfacebook/extlibinc/base_facebook.php b/modules/authfacebook/extlibinc/base_facebook.php
index a5fd3e9043db0edc0fc683e6d5f596e06f9da660..cd4536db1a59b5b48fe8b396a78aa356b229defd 100644
--- a/modules/authfacebook/extlibinc/base_facebook.php
+++ b/modules/authfacebook/extlibinc/base_facebook.php
@@ -698,7 +698,7 @@ abstract class BaseFacebook
         $this->clearPersistentData('state');
         return $_REQUEST['code'];
       } else {
-        self::errorLog('CSRF state token does not match one provided.');
+        self::errorLog('CSRF state token does not match one provided. ' . $this->state . '!=' . $_REQUEST['state']);
         return false;
       }
     }
diff --git a/modules/authfacebook/lib/Auth/Source/Facebook.php b/modules/authfacebook/lib/Auth/Source/Facebook.php
index 1a85e2bcded8e15813aaef2bed74a4394d787918..78c90c5ebcbfa6bee288a6d1099919ae3f7cf99d 100644
--- a/modules/authfacebook/lib/Auth/Source/Facebook.php
+++ b/modules/authfacebook/lib/Auth/Source/Facebook.php
@@ -1,14 +1,16 @@
 <?php
 
+namespace SimpleSAML\Module\authfacebook\Auth\Source;
+
 /**
  * Authenticate using Facebook Platform.
  *
  * @author Andreas Ă…kre Solberg, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class sspmod_authfacebook_Auth_Source_Facebook extends SimpleSAML_Auth_Source {
-
 
+class Facebook extends \SimpleSAML\Auth\Source
+{
 	/**
 	 * The string used to identify our states.
 	 */
@@ -67,7 +69,7 @@ class sspmod_authfacebook_Auth_Source_Facebook extends SimpleSAML_Auth_Source {
 		// Call the parent constructor first, as required by the interface
 		parent::__construct($info, $config);
 
-		$cfgParse = SimpleSAML_Configuration::loadFromArray($config, 'authsources[' . var_export($this->authId, TRUE) . ']');
+		$cfgParse = \SimpleSAML\Configuration::loadFromArray($config, 'authsources[' . var_export($this->authId, TRUE) . ']');
 		
 		$this->api_key = $cfgParse->getString('api_key');
 		$this->secret = $cfgParse->getString('secret');
@@ -86,14 +88,14 @@ class sspmod_authfacebook_Auth_Source_Facebook extends SimpleSAML_Auth_Source {
 
 		// We are going to need the authId in order to retrieve this authentication source later
 		$state[self::AUTHID] = $this->authId;
-		$stateID = SimpleSAML_Auth_State::saveState($state, self::STAGE_INIT);
+		\SimpleSAML\Auth\State::saveState($state, self::STAGE_INIT);
 		
-		$facebook = new sspmod_authfacebook_Facebook(array('appId' => $this->api_key, 'secret' => $this->secret), $state);
+		$facebook = new \SimpleSAML\Module\authfacebook\Facebook(array('appId' => $this->api_key, 'secret' => $this->secret), $state);
 		$facebook->destroySession();
 
-		$linkback = SimpleSAML\Module::getModuleURL('authfacebook/linkback.php', array('AuthState' => $stateID));
+		$linkback = \SimpleSAML\Module::getModuleURL('authfacebook/linkback.php');
 		$url = $facebook->getLoginUrl(array('redirect_uri' => $linkback, 'scope' => $this->req_perms));
-		SimpleSAML_Auth_State::saveState($state, self::STAGE_INIT);
+		\SimpleSAML\Auth\State::saveState($state, self::STAGE_INIT);
 
 		\SimpleSAML\Utils\HTTP::redirectTrustedURL($url);
 	}
@@ -102,19 +104,19 @@ class sspmod_authfacebook_Auth_Source_Facebook extends SimpleSAML_Auth_Source {
 	public function finalStep(&$state) {
 		assert(is_array($state));
 
-		$facebook = new sspmod_authfacebook_Facebook(array('appId' => $this->api_key, 'secret' => $this->secret), $state);
+		$facebook = new \SimpleSAML\Module\authfacebook\Facebook(array('appId' => $this->api_key, 'secret' => $this->secret), $state);
 		$uid = $facebook->getUser();
 
 		if (isset($uid) && $uid) {
 			try {
 				$info = $facebook->api("/" . $uid . ($this->user_fields ? "?fields=" . $this->user_fields : ""));
-			} catch (FacebookApiException $e) {
-				throw new SimpleSAML_Error_AuthSource($this->authId, 'Error getting user profile.', $e);
+			} catch (\FacebookApiException $e) {
+				throw new \SimpleSAML\Error\AuthSource($this->authId, 'Error getting user profile.', $e);
 			}
 		}
 
 		if (!isset($info)) {
-			throw new SimpleSAML_Error_AuthSource($this->authId, 'Error getting user profile.');
+			throw new \SimpleSAML\Error\AuthSource($this->authId, 'Error getting user profile.');
 		}
 		
 		$attributes = array();
@@ -133,7 +135,7 @@ class sspmod_authfacebook_Auth_Source_Facebook extends SimpleSAML_Auth_Source {
 		$attributes['facebook_targetedID'] = array('http://facebook.com!' . $uid);
 		$attributes['facebook_cn'] = array($info['name']);
 
-		SimpleSAML\Logger::debug('Facebook Returned Attributes: '. implode(", ", array_keys($attributes)));
+		\SimpleSAML\Logger::debug('Facebook Returned Attributes: '. implode(", ", array_keys($attributes)));
 
 		$state['Attributes'] = $attributes;
 	
diff --git a/modules/authfacebook/lib/Facebook.php b/modules/authfacebook/lib/Facebook.php
index 9cea590a7f4356430219b1d7f636cc1281dfbc79..edae09bd500904255337bddb2d2ebbc351728c2d 100644
--- a/modules/authfacebook/lib/Facebook.php
+++ b/modules/authfacebook/lib/Facebook.php
@@ -1,12 +1,15 @@
 <?php
 
+namespace SimpleSAML\Module\authfacebook;
+
 require_once(dirname(dirname(__FILE__)) . '/extlibinc/base_facebook.php');
 
 /**
  * Extends the BaseFacebook class with the intent of using
  * PHP sessions to store user ids and access tokens.
  */
-class sspmod_authfacebook_Facebook extends BaseFacebook
+
+class Facebook extends \BaseFacebook
 {
   const FBSS_COOKIE_NAME = 'fbss';
 
@@ -20,6 +23,9 @@ class sspmod_authfacebook_Facebook extends BaseFacebook
   // SimpleSAMLphp state array
   protected $ssp_state;
 
+  // \SimpleSAML\Auth\State
+  protected $state;
+
   /**
    * Identical to the parent constructor, except that
    * we start a PHP session to store the user ID and
@@ -48,7 +54,7 @@ class sspmod_authfacebook_Facebook extends BaseFacebook
     $cookie_name = $this->getSharedSessionCookieName();
     if (isset($_COOKIE[$cookie_name])) {
       $data = $this->parseSignedRequest($_COOKIE[$cookie_name]);
-      if ($data && !empty($data['domain']) &&
+      if (!empty($data) && !empty($data['domain']) &&
           self::isAllowedDomain($this->getHttpHost(), $data['domain'])) {
         // good case
         $this->sharedSessionID = $data['id'];
@@ -71,7 +77,7 @@ class sspmod_authfacebook_Facebook extends BaseFacebook
       setcookie($cookie_name, $cookie_value, $expire, '/', '.'.$base_domain);
     } else {
       // @codeCoverageIgnoreStart
-      SimpleSAML\Logger::debug(
+      \SimpleSAML\Logger::debug(
         'Shared session ID cookie could not be set! You must ensure you '.
         'create the Facebook instance before headers have been sent. This '.
         'will cause authentication issues after the first request.'
@@ -88,7 +94,7 @@ class sspmod_authfacebook_Facebook extends BaseFacebook
    */
   protected function setPersistentData($key, $value) {
     if (!in_array($key, self::$kSupportedKeys)) {
-      SimpleSAML\Logger::debug("Unsupported key passed to setPersistentData: " . var_export($key, TRUE));
+      \SimpleSAML\Logger::debug("Unsupported key passed to setPersistentData: " . var_export($key, TRUE));
       return;
     }
 
@@ -98,7 +104,7 @@ class sspmod_authfacebook_Facebook extends BaseFacebook
 
   protected function getPersistentData($key, $default = false) {
     if (!in_array($key, self::$kSupportedKeys)) {
-      SimpleSAML\Logger::debug("Unsupported key passed to getPersistentData: " . var_export($key, TRUE));
+      \SimpleSAML\Logger::debug("Unsupported key passed to getPersistentData: " . var_export($key, TRUE));
       return $default;
     }
 
@@ -109,7 +115,7 @@ class sspmod_authfacebook_Facebook extends BaseFacebook
 
   protected function clearPersistentData($key) {
     if (!in_array($key, self::$kSupportedKeys)) {
-      SimpleSAML\Logger::debug("Unsupported key passed to clearPersistentData: " . var_export($key, TRUE));
+      \SimpleSAML\Logger::debug("Unsupported key passed to clearPersistentData: " . var_export($key, TRUE));
       return;
     }
 
@@ -146,4 +152,11 @@ class sspmod_authfacebook_Facebook extends BaseFacebook
     }
     return implode('_', $parts);
   }
+
+  protected function establishCSRFTokenState() {
+     if ($this->state === null) {
+          $this->state = \SimpleSAML\Auth\State::getStateId($this->ssp_state);
+          $this->setPersistentData('state', $this->state);
+     }
+  }
 }
diff --git a/modules/authfacebook/www/linkback.php b/modules/authfacebook/www/linkback.php
index 6ca8855bcc9c5d22dacb518933970861dd28412f..4d856e5ff3ee536a5dbd27fc2ea29e75855be989 100644
--- a/modules/authfacebook/www/linkback.php
+++ b/modules/authfacebook/www/linkback.php
@@ -3,33 +3,37 @@
 /**
  * Handle linkback() response from Facebook.
  */
- 
-if (!array_key_exists('AuthState', $_REQUEST) || empty($_REQUEST['AuthState'])) {
-	throw new SimpleSAML_Error_BadRequest('Missing state parameter on facebook linkback endpoint.');
+
+// For backwards compatability look for AuthState first
+if (array_key_exists('AuthState', $_REQUEST) && !empty($_REQUEST['AuthState'])) {
+    $state = \SimpleSAML\Auth\State::loadState($_REQUEST['AuthState'], \SimpleSAML\Module\authfacebook\Auth\Source\Facebook::STAGE_INIT);
+} elseif (array_key_exists('state', $_REQUEST) && !empty($_REQUEST['state'])) {
+    $state = \SimpleSAML\Auth\State::loadState($_REQUEST['state'], \SimpleSAML\Module\authfacebook\Auth\Source\Facebook::STAGE_INIT);
+} else {
+    throw new \SimpleSAML\Error\BadRequest('Missing state parameter on facebook linkback endpoint.');
 }
-$state = SimpleSAML_Auth_State::loadState($_REQUEST['AuthState'], sspmod_authfacebook_Auth_Source_Facebook::STAGE_INIT);
 
 // Find authentication source
-if (!array_key_exists(sspmod_authfacebook_Auth_Source_Facebook::AUTHID, $state)) {
-	throw new SimpleSAML_Error_BadRequest('No data in state for ' . sspmod_authfacebook_Auth_Source_Facebook::AUTHID);
+if (!array_key_exists(\SimpleSAML\Module\authfacebook\Auth\Source\Facebook::AUTHID, $state)) {
+    throw new \SimpleSAML\Error\BadRequest('No data in state for ' . \SimpleSAML\Module\authfacebook\Auth\Source\Facebook::AUTHID);
 }
-$sourceId = $state[sspmod_authfacebook_Auth_Source_Facebook::AUTHID];
+$sourceId = $state[\SimpleSAML\Module\authfacebook\Auth\Source\Facebook::AUTHID];
 
-$source = SimpleSAML_Auth_Source::getById($sourceId);
-if ($source === NULL) {
-	throw new SimpleSAML_Error_BadRequest('Could not find authentication source with id ' . var_export($sourceId, TRUE));
+$source = \SimpleSAML\Auth\Source::getById($sourceId);
+if ($source === null) {
+    throw new \SimpleSAML\Error\BadRequest('Could not find authentication source with id ' . var_export($sourceId, TRUE));
 }
 
 try {
-	if (isset($_REQUEST['error_reason']) && $_REQUEST['error_reason'] == 'user_denied') {
-		throw new SimpleSAML_Error_UserAborted();
-	}
+    if (isset($_REQUEST['error_reason']) && $_REQUEST['error_reason'] == 'user_denied') {
+        throw new \SimpleSAML\Error\UserAborted();
+    }
 
-	$source->finalStep($state);
-} catch (SimpleSAML_Error_Exception $e) {
-	SimpleSAML_Auth_State::throwException($state, $e);
-} catch (Exception $e) {
-	SimpleSAML_Auth_State::throwException($state, new SimpleSAML_Error_AuthSource($sourceId, 'Error on facebook linkback endpoint.', $e));
+    $source->finalStep($state);
+} catch (\SimpleSAML\Error\Exception $e) {
+    \SimpleSAML\Auth\State::throwException($state, $e);
+} catch (\Exception $e) {
+    \SimpleSAML\Auth\State::throwException($state, new \SimpleSAML\Error\AuthSource($sourceId, 'Error on facebook linkback endpoint.', $e));
 }
 
-SimpleSAML_Auth_Source::completeAuth($state);
+\SimpleSAML\Auth\Source::completeAuth($state);
diff --git a/modules/authlinkedin/lib/Auth/Source/LinkedIn.php b/modules/authlinkedin/lib/Auth/Source/LinkedIn.php
index ff961df0c66492fe1d03c0ed10ceedb7f350aa16..892dcb7c7c6410180620e5c038674fb8d16391da 100644
--- a/modules/authlinkedin/lib/Auth/Source/LinkedIn.php
+++ b/modules/authlinkedin/lib/Auth/Source/LinkedIn.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\authlinkedin\Auth\Source;
+
 require_once(dirname(dirname(dirname(dirname(dirname(__FILE__))))) . '/oauth/libextinc/OAuth.php');
 
 /**
@@ -8,9 +10,9 @@ require_once(dirname(dirname(dirname(dirname(dirname(__FILE__))))) . '/oauth/lib
  * @author Brook Schofield, TERENA.
  * @package SimpleSAMLphp
  */
-class sspmod_authlinkedin_Auth_Source_LinkedIn extends SimpleSAML_Auth_Source 
-{
 
+class LinkedIn extends \SimpleSAML\Auth\Source 
+{
     /**
      * The string used to identify our states.
      */
@@ -41,12 +43,12 @@ class sspmod_authlinkedin_Auth_Source_LinkedIn extends SimpleSAML_Auth_Source
         parent::__construct($info, $config);
 
         if (!array_key_exists('key', $config))
-            throw new Exception('LinkedIn authentication source is not properly configured: missing [key]');
+            throw new \Exception('LinkedIn authentication source is not properly configured: missing [key]');
 
         $this->key = $config['key'];
 
         if (!array_key_exists('secret', $config))
-            throw new Exception('LinkedIn authentication source is not properly configured: missing [secret]');
+            throw new \Exception('LinkedIn authentication source is not properly configured: missing [secret]');
 
         $this->secret = $config['secret'];
 
@@ -72,18 +74,18 @@ class sspmod_authlinkedin_Auth_Source_LinkedIn extends SimpleSAML_Auth_Source
         // We are going to need the authId in order to retrieve this authentication source later
         $state[self::AUTHID] = $this->authId;
 
-        $stateID = SimpleSAML_Auth_State::getStateId($state);
-        SimpleSAML\Logger::debug('authlinkedin auth state id = ' . $stateID);
+        $stateID = \SimpleSAML\Auth\State::getStateId($state);
+        \SimpleSAML\Logger::debug('authlinkedin auth state id = ' . $stateID);
 
-        $consumer = new sspmod_oauth_Consumer($this->key, $this->secret);
+        $consumer = new \SimpleSAML\Module\oauth\Consumer($this->key, $this->secret);
 
         // Get the request token
         $requestToken = $consumer->getRequestToken(
             'https://api.linkedin.com/uas/oauth/requestToken',
-            array('oauth_callback' => SimpleSAML\Module::getModuleUrl('authlinkedin') . '/linkback.php?stateid=' . $stateID)
+            array('oauth_callback' => \SimpleSAML\Module::getModuleUrl('authlinkedin') . '/linkback.php?stateid=' . $stateID)
         );
 
-        SimpleSAML\Logger::debug(
+        \SimpleSAML\Logger::debug(
             "Got a request token from the OAuth service provider [" .
             $requestToken->key . "] with the secret [" . $requestToken->secret . "]"
         );
@@ -91,7 +93,7 @@ class sspmod_authlinkedin_Auth_Source_LinkedIn extends SimpleSAML_Auth_Source
         $state['authlinkedin:requestToken'] = $requestToken;
 
         // Update the state
-        SimpleSAML_Auth_State::saveState($state, self::STAGE_INIT);
+        \SimpleSAML\Auth\State::saveState($state, self::STAGE_INIT);
 
         // Authorize the request token
         $consumer->getAuthorizeRequest('https://www.linkedin.com/uas/oauth/authenticate', $requestToken);
@@ -102,9 +104,9 @@ class sspmod_authlinkedin_Auth_Source_LinkedIn extends SimpleSAML_Auth_Source
     {
         $requestToken = $state['authlinkedin:requestToken'];
 
-        $consumer = new sspmod_oauth_Consumer($this->key, $this->secret);
+        $consumer = new \SimpleSAML\Module\oauth\Consumer($this->key, $this->secret);
 
-        SimpleSAML\Logger::debug(
+        \SimpleSAML\Logger::debug(
             "oauth: Using this request token [" .
             $requestToken->key . "] with the secret [" . $requestToken->secret . "]"
         );
@@ -115,7 +117,7 @@ class sspmod_authlinkedin_Auth_Source_LinkedIn extends SimpleSAML_Auth_Source
             array('oauth_verifier' => $state['authlinkedin:oauth_verifier'])
         );
 
-        SimpleSAML\Logger::debug(
+        \SimpleSAML\Logger::debug(
             "Got an access token from the OAuth service provider [" .
             $accessToken->key . "] with the secret [" . $accessToken->secret . "]"
         );
@@ -135,7 +137,7 @@ class sspmod_authlinkedin_Auth_Source_LinkedIn extends SimpleSAML_Auth_Source
             $attributes['linkedin_user'] = array($userdata['id'] . '@linkedin.com');
         }
 
-        SimpleSAML\Logger::debug('LinkedIn Returned Attributes: '. implode(", ",array_keys($attributes)));
+        \SimpleSAML\Logger::debug('LinkedIn Returned Attributes: '. implode(", ",array_keys($attributes)));
 
         $state['Attributes'] = $attributes;
     }
diff --git a/modules/authlinkedin/www/linkback.php b/modules/authlinkedin/www/linkback.php
index ee6731f1e71330d96bae7d76f17af941596087d4..58770b8b45c85e251efc5a974a58e398bdfb615d 100644
--- a/modules/authlinkedin/www/linkback.php
+++ b/modules/authlinkedin/www/linkback.php
@@ -5,27 +5,27 @@
  */
 
 if (!array_key_exists('stateid', $_REQUEST)) {
-    throw new Exception('Lost OAuth Client State');
+    throw new \Exception('Lost OAuth Client State');
 }
-$state = SimpleSAML_Auth_State::loadState($_REQUEST['stateid'], sspmod_authlinkedin_Auth_Source_LinkedIn::STAGE_INIT);
+$state = \SimpleSAML\Auth\State::loadState($_REQUEST['stateid'], \SimpleSAML\Module\authlinkedin\Auth\Source\LinkedIn::STAGE_INIT);
 
 // http://developer.linkedin.com/docs/DOC-1008#2_Redirect_the_User_to_our_Authorization_Server
 if (array_key_exists('oauth_verifier', $_REQUEST)) {
-	$state['authlinkedin:oauth_verifier'] = $_REQUEST['oauth_verifier'];
+    $state['authlinkedin:oauth_verifier'] = $_REQUEST['oauth_verifier'];
 } else {
-	throw new Exception('OAuth verifier not returned.');;
+    throw new Exception('OAuth verifier not returned.');;
 }
 
 // Find authentication source
-assert(array_key_exists(sspmod_authlinkedin_Auth_Source_LinkedIn::AUTHID, $state));
-$sourceId = $state[sspmod_authlinkedin_Auth_Source_LinkedIn::AUTHID];
+assert(array_key_exists(\SimpleSAML\Module\authlinkedin\Auth\Source\LinkedIn::AUTHID, $state));
+$sourceId = $state[\SimpleSAML\Module\authlinkedin\Auth\Source\LinkedIn::AUTHID];
 
-$source = SimpleSAML_Auth_Source::getById($sourceId);
-if ($source === NULL) {
-	throw new Exception('Could not find authentication source with id ' . $sourceId);
+$source = \SimpleSAML\Auth\Source::getById($sourceId);
+if ($source === null) {
+    throw new \Exception('Could not find authentication source with id ' . $sourceId);
 }
 
 $source->finalStep($state);
 
-SimpleSAML_Auth_Source::completeAuth($state);
+\SimpleSAML\Auth\Source::completeAuth($state);
 
diff --git a/modules/authmyspace/default-disable b/modules/authmyspace/default-disable
deleted file mode 100644
index fa0bd82e2df7bd79d57593d35bc53c1f9d3ef71f..0000000000000000000000000000000000000000
--- a/modules/authmyspace/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/authmyspace/docs/oauthmyspace.md b/modules/authmyspace/docs/oauthmyspace.md
deleted file mode 100644
index 98b97b805a83545e2f3f560b853be4a1af213fe8..0000000000000000000000000000000000000000
--- a/modules/authmyspace/docs/oauthmyspace.md
+++ /dev/null
@@ -1,25 +0,0 @@
-Using the MySpace authentication source with SimpleSAMLphp
-==========================================================
-
-Remember to configure `authsources.php`, with both your Client ID and Secret key.
-
-To get an API key and a secret, register the application at:
-
- * <http://developer.myspace.com/Modules/Apps/Pages/CreateAppAccount.aspx>
-
-Create a MySpace ID App and set the callback evaluation URL to be:
-
- * `http://sp.example.org/`
-
-Replace `sp.example.org` with your hostname.
-
-## Testing authentication
-
-On the SimpleSAMLphp frontpage, go to the *Authentication* tab, and use the link:
-
-  * *Test configured authentication sources*
-
-Then choose the *myspace* authentication source.
-
-Expected behaviour would then be that you are sent to MySpace, and asked to login.
-There is no consent screen for attribute release.
diff --git a/modules/authmyspace/lib/Auth/Source/MySpace.php b/modules/authmyspace/lib/Auth/Source/MySpace.php
deleted file mode 100644
index 26b8a1c57d39114e0098f8a636daeb12fc5fba55..0000000000000000000000000000000000000000
--- a/modules/authmyspace/lib/Auth/Source/MySpace.php
+++ /dev/null
@@ -1,137 +0,0 @@
-<?php
-
-require_once(dirname(dirname(dirname(dirname(dirname(__FILE__))))) . '/oauth/libextinc/OAuth.php');
-
-/**
- * Authenticate using MySpace.
- *
- * @author Brook Schofield, TERENA.
- * @package SimpleSAMLphp
- */
-class sspmod_authmyspace_Auth_Source_MySpace extends SimpleSAML_Auth_Source {
-
-	/**
-	 * The string used to identify our states.
-	 */
-	const STAGE_INIT = 'authmyspace:init';
-
-	/**
-	 * The key of the AuthId field in the state.
-	 */
-	const AUTHID = 'authmyspace:AuthId';
-
-	private $key;
-	private $secret;
-
-
-	/**
-	 * Constructor for this authentication source.
-	 *
-	 * @param array $info  Information about this authentication source.
-	 * @param array $config  Configuration.
-	 */
-	public function __construct($info, $config) {
-		assert(is_array($info));
-		assert(is_array($config));
-
-		// Call the parent constructor first, as required by the interface
-		parent::__construct($info, $config);
-
-		if (!array_key_exists('key', $config))
-			throw new Exception('MySpace authentication source is not properly configured: missing [key]');
-
-		$this->key = $config['key'];
-
-		if (!array_key_exists('secret', $config))
-			throw new Exception('MySpace authentication source is not properly configured: missing [secret]');
-
-		$this->secret = $config['secret'];
-	}
-
-
-	/**
-	 * Log-in using MySpace platform
-	 *
-	 * @param array &$state  Information about the current authentication.
-	 */
-	public function authenticate(&$state) {
-		assert(is_array($state));
-
-		// We are going to need the authId in order to retrieve this authentication source later
-		$state[self::AUTHID] = $this->authId;
-
-		$consumer = new sspmod_oauth_Consumer($this->key, $this->secret);
-
-		// Get the request token
-		$requestToken = $consumer->getRequestToken('http://api.myspace.com/request_token');
-		SimpleSAML\Logger::debug("Got a request token from the OAuth service provider [" .
-			$requestToken->key . "] with the secret [" . $requestToken->secret . "]");
-
-		$state['authmyspace:requestToken'] = $requestToken;
-
-		$stateID = SimpleSAML_Auth_State::saveState($state, self::STAGE_INIT);
-		SimpleSAML\Logger::debug('authmyspace auth state id = ' . $stateID);
-
-		// Authorize the request token
-		$consumer->getAuthorizeRequest('http://api.myspace.com/authorize', $requestToken, TRUE, SimpleSAML\Module::getModuleUrl('authmyspace') . '/linkback.php?stateid=' . $stateID);
-
-	}
-
-
-
-	public function finalStep(&$state) {
-
-		$requestToken = $state['authmyspace:requestToken'];
-
-		$consumer = new sspmod_oauth_Consumer($this->key, $this->secret);
-
-		SimpleSAML\Logger::debug("oauth: Using this request token [" .
-			$requestToken->key . "] with the secret [" . $requestToken->secret . "]");
-
-		// Replace the request token with an access token
-		$accessToken = $consumer->getAccessToken('http://api.myspace.com/access_token', $requestToken);
-		SimpleSAML\Logger::debug("Got an access token from the OAuth service provider [" .
-			$accessToken->key . "] with the secret [" . $accessToken->secret . "]");
-
-		// People API -  http://developerwiki.myspace.com/index.php?title=People_API
-		$userdata = $consumer->getUserInfo('http://api.myspace.com/1.0/people/@me/@self?fields=@all', $accessToken);
-
-		$attributes = array();
-
-		if (is_array($userdata['person'])) {
-			foreach($userdata['person'] AS $key => $value) {
-				if (is_string($value) || is_int($value))
-					$attributes['myspace.' . $key] = array((string)$value);
-
-				if (is_array($value)) {
-					foreach($value AS $key2 => $value2) {
-						if (is_string($value2) || is_int($value2))
-							$attributes['myspace.' . $key . '.' . $key2] = array((string)$value2);
-					}
-				}
-			}
-
-			if (array_key_exists('id', $userdata['person']) ) {
-
-				// person-id in the format of myspace.com.person.1234567890
-				if (preg_match('/(\d+)$/',$userdata['person']['id'],$matches)) {
-					$attributes['myspace_targetedID'] = array('http://myspace.com!' . $matches[1]);
-					$attributes['myspace_uid'] = array($matches[1]);
-					$attributes['myspace_user'] = array($matches[1] . '@myspace.com');
-				}
-			}
-
-			// profileUrl in the format http://www.myspace.com/username
-			if (array_key_exists('profileUrl', $userdata['person']) ) {
-				if (preg_match('@/([^/]+)$@',$userdata['person']['profileUrl'],$matches)) {
-					$attributes['myspace_username'] = array($matches[1]);
-					$attributes['myspace_user'] = array($matches[1] . '@myspace.com');
-				}
-			}
-		}
-
-		SimpleSAML\Logger::debug('MySpace Returned Attributes: '. implode(", ",array_keys($attributes)));
-
-		$state['Attributes'] = $attributes;
-	}
-}
diff --git a/modules/authmyspace/www/linkback.php b/modules/authmyspace/www/linkback.php
deleted file mode 100644
index 296807844bbe3ceea677da673e362e682e643cf4..0000000000000000000000000000000000000000
--- a/modules/authmyspace/www/linkback.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-/**
- * Handle linkback() response from MySpace.
- */
-
-if (!array_key_exists('stateid', $_REQUEST)) {
-	throw new Exception('State Lost - not returned by MySpace Auth');
-}
-$state = SimpleSAML_Auth_State::loadState($_REQUEST['stateid'], sspmod_authmyspace_Auth_Source_MySpace::STAGE_INIT);
-
-if (array_key_exists('oauth_problem', $_REQUEST)) {
-	// oauth_problem of 'user_refused' means user chose not to login with MySpace
-	if (strcmp($_REQUEST['oauth_problem'],'user_refused') == 0) {
-		$e = new SimpleSAML_Error_UserAborted();
-		SimpleSAML_Auth_State::throwException($state, $e);
-	}
-
-	// Error
-	$e = new SimpleSAML_Error_Error('Authentication failed: ' . $_REQUEST['oauth_problem']);
-	SimpleSAML_Auth_State::throwException($state, $e);
-}
-
-if (array_key_exists('oauth_verifier', $_REQUEST)) {
-	$state['authmyspace:oauth_verifier'] = $_REQUEST['oauth_verifier'];
-} else {
-	throw new Exception('OAuth verifier not returned.');;
-}
-
-// Find authentication source
-assert(array_key_exists(sspmod_authmyspace_Auth_Source_MySpace::AUTHID, $state));
-$sourceId = $state[sspmod_authmyspace_Auth_Source_MySpace::AUTHID];
-
-$source = SimpleSAML_Auth_Source::getById($sourceId);
-if ($source === NULL) {
-	throw new Exception('Could not find authentication source with id ' . $sourceId);
-}
-
-$source->finalStep($state);
-
-SimpleSAML_Auth_Source::completeAuth($state);
-
diff --git a/modules/authorize/lib/Auth/Process/Authorize.php b/modules/authorize/lib/Auth/Process/Authorize.php
index 68c5ad009f1f712359baf7878934847593e032af..8bac338e6352827d5a4db731d5e620e2d3135348 100644
--- a/modules/authorize/lib/Auth/Process/Authorize.php
+++ b/modules/authorize/lib/Auth/Process/Authorize.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\authorize\Auth\Process;
+
 /**
  * Filter to authorize only certain users.
  * See docs directory.
@@ -7,8 +9,9 @@
  * @author Ernesto Revilla, Yaco Sistemas SL., Ryan Panning
  * @package SimpleSAMLphp
  */
-class sspmod_authorize_Auth_Process_Authorize extends SimpleSAML_Auth_ProcessingFilter {
 
+class Authorize extends \SimpleSAML\Auth\ProcessingFilter
+{
 	/**
 	 * Flag to deny/unauthorize the user a attribute filter IS found
 	 *
@@ -61,10 +64,10 @@ class sspmod_authorize_Auth_Process_Authorize extends SimpleSAML_Auth_Processing
 			if (is_string($values))
 				$values = array($values);
 			if (!is_array($values))
-				throw new Exception('Filter Authorize: Attribute values is neither string nor array: ' . var_export($attribute, TRUE));
+				throw new \Exception('Filter Authorize: Attribute values is neither string nor array: ' . var_export($attribute, TRUE));
 			foreach ($values as $value){
 				if(!is_string($value)) {
-					throw new Exception('Filter Authorize: Each value should be a string for attribute: ' . var_export($attribute, TRUE) . ' value: ' . var_export($value, TRUE) . ' Config is: ' . var_export($config, TRUE));
+					throw new \Exception('Filter Authorize: Each value should be a string for attribute: ' . var_export($attribute, TRUE) . ' value: ' . var_export($value, TRUE) . ' Config is: ' . var_export($config, TRUE));
 				}
 			}
 			$this->valid_attribute_values[$attribute] = $values;
@@ -124,9 +127,9 @@ class sspmod_authorize_Auth_Process_Authorize extends SimpleSAML_Auth_Processing
 	 */
 	protected function unauthorized(&$request) {
 		// Save state and redirect to 403 page
-		$id = SimpleSAML_Auth_State::saveState($request,
+		$id = \SimpleSAML\Auth\State::saveState($request,
 			'authorize:Authorize');
-		$url = SimpleSAML\Module::getModuleURL(
+		$url = \SimpleSAML\Module::getModuleURL(
 			'authorize/authorize_403.php');
 		\SimpleSAML\Utils\HTTP::redirectTrustedURL($url, array('StateId' => $id));
 	}
diff --git a/modules/authorize/www/authorize_403.php b/modules/authorize/www/authorize_403.php
index e6a6094869b1a7b21444c51604148d13761b7599..158fe11a9bffdf51348937aa09427d8a77238e00 100644
--- a/modules/authorize/www/authorize_403.php
+++ b/modules/authorize/www/authorize_403.php
@@ -6,14 +6,14 @@
  */
 
 if (!array_key_exists('StateId', $_REQUEST)) {
-    throw new SimpleSAML_Error_BadRequest('Missing required StateId query parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing required StateId query parameter.');
 }
-$state = SimpleSAML_Auth_State::loadState($_REQUEST['StateId'], 'authorize:Authorize');
+$state = \SimpleSAML\Auth\State::loadState($_REQUEST['StateId'], 'authorize:Authorize');
 
-$globalConfig = SimpleSAML_Configuration::getInstance();
-$t = new SimpleSAML_XHTML_Template($globalConfig, 'authorize:authorize_403.php');
+$globalConfig = \SimpleSAML\Configuration::getInstance();
+$t = new \SimpleSAML\XHTML\Template($globalConfig, 'authorize:authorize_403.php');
 if (isset($state['Source']['auth'])) {
-    $t->data['LogoutURL'] = SimpleSAML\Module::getModuleURL('core/authenticate.php', array('as' => $state['Source']['auth']))."&logout";
+    $t->data['LogoutURL'] = \SimpleSAML\Module::getModuleURL('core/authenticate.php', array('as' => $state['Source']['auth']))."&logout";
 }
 header('HTTP/1.0 403 Forbidden');
 $t->show();
diff --git a/modules/authtwitter/lib/Auth/Source/Twitter.php b/modules/authtwitter/lib/Auth/Source/Twitter.php
index 9be9fd90d72ff01fb99e9ba074350f3d3b8341e6..3bf984f9c8718534206afc17c95c9880c8e521c1 100644
--- a/modules/authtwitter/lib/Auth/Source/Twitter.php
+++ b/modules/authtwitter/lib/Auth/Source/Twitter.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\authtwitter\Auth\Source;
+
 require_once(dirname(dirname(dirname(dirname(dirname(__FILE__))))) . '/oauth/libextinc/OAuth.php');
 
 /**
@@ -8,8 +10,9 @@ require_once(dirname(dirname(dirname(dirname(dirname(__FILE__))))) . '/oauth/lib
  * @author Andreas Ă…kre Solberg, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class sspmod_authtwitter_Auth_Source_Twitter extends SimpleSAML_Auth_Source {
 
+class Twitter extends \SimpleSAML\Auth\Source
+{
 	/**
 	 * The string used to identify our states.
 	 */
@@ -20,10 +23,25 @@ class sspmod_authtwitter_Auth_Source_Twitter extends SimpleSAML_Auth_Source {
 	 */
 	const AUTHID = 'twitter:AuthId';
 
+    /**
+     * @var string
+     */
 	private $key;
-	private $secret;
+
+    /**
+     * @var string
+     */
+    private $secret;
+
+    /**
+     * @var bool
+     */
 	private $force_login;
 
+    /**
+     * @var bool
+     */
+    private $include_email;
 
 	/**
 	 * Constructor for this authentication source.
@@ -31,19 +49,20 @@ class sspmod_authtwitter_Auth_Source_Twitter extends SimpleSAML_Auth_Source {
 	 * @param array $info  Information about this authentication source.
 	 * @param array $config  Configuration.
 	 */
-	public function __construct($info, $config) {
+	public function __construct($info, $config)
+    {
 		assert(is_array($info));
 		assert(is_array($config));
 
 		// Call the parent constructor first, as required by the interface
 		parent::__construct($info, $config);
 
-		$configObject = SimpleSAML_Configuration::loadFromArray($config, 'authsources[' . var_export($this->authId, TRUE) . ']');
+		$configObject = \SimpleSAML\Configuration::loadFromArray($config, 'authsources[' . var_export($this->authId, true) . ']');
 
 		$this->key = $configObject->getString('key');
 		$this->secret = $configObject->getString('secret');
-		$this->force_login = $configObject->getBoolean('force_login', FALSE);
-		$this->include_email = $configObject->getBoolean('include_email', FALSE);
+		$this->force_login = $configObject->getBoolean('force_login', false);
+		$this->include_email = $configObject->getBoolean('include_email', false);
 	}
 
 
@@ -52,23 +71,24 @@ class sspmod_authtwitter_Auth_Source_Twitter extends SimpleSAML_Auth_Source {
 	 *
 	 * @param array &$state  Information about the current authentication.
 	 */
-	public function authenticate(&$state) {
+	public function authenticate(&$state)
+    {
 		assert(is_array($state));
 
 		// We are going to need the authId in order to retrieve this authentication source later
 		$state[self::AUTHID] = $this->authId;
 		
-		$stateID = SimpleSAML_Auth_State::saveState($state, self::STAGE_INIT);
+		$stateID = \SimpleSAML\Auth\State::saveState($state, self::STAGE_INIT);
 		
-		$consumer = new sspmod_oauth_Consumer($this->key, $this->secret);
+		$consumer = new \SimpleSAML\Module\oauth\Consumer($this->key, $this->secret);
 		// Get the request token
-		$linkback = SimpleSAML\Module::getModuleURL('authtwitter/linkback.php', array('AuthState' => $stateID));
+		$linkback = \SimpleSAML\Module::getModuleURL('authtwitter/linkback.php', array('AuthState' => $stateID));
 		$requestToken = $consumer->getRequestToken('https://api.twitter.com/oauth/request_token', array('oauth_callback' => $linkback));
-		SimpleSAML\Logger::debug("Got a request token from the OAuth service provider [" .
+		\SimpleSAML\Logger::debug("Got a request token from the OAuth service provider [" .
 			$requestToken->key . "] with the secret [" . $requestToken->secret . "]");
 
 		$state['authtwitter:authdata:requestToken'] = $requestToken;
-		SimpleSAML_Auth_State::saveState($state, self::STAGE_INIT);
+		\SimpleSAML\Auth\State::saveState($state, self::STAGE_INIT);
 
 		// Authorize the request token
 		$url = 'https://api.twitter.com/oauth/authenticate';
@@ -79,30 +99,31 @@ class sspmod_authtwitter_Auth_Source_Twitter extends SimpleSAML_Auth_Source {
 	}
 	
 	
-	public function finalStep(&$state) {
+	public function finalStep(&$state)
+    {
 		$requestToken = $state['authtwitter:authdata:requestToken'];
 		$parameters = array();
 
 		if (!isset($_REQUEST['oauth_token'])) {
-			throw new SimpleSAML_Error_BadRequest("Missing oauth_token parameter.");
+			throw new \SimpleSAML\Error\BadRequest("Missing oauth_token parameter.");
 		}
 		if ($requestToken->key !== (string)$_REQUEST['oauth_token']) {
-			throw new SimpleSAML_Error_BadRequest("Invalid oauth_token parameter.");
+			throw new \SimpleSAML\Error\BadRequest("Invalid oauth_token parameter.");
 		}
 
 		if (!isset($_REQUEST['oauth_verifier'])) {
-			throw new SimpleSAML_Error_BadRequest("Missing oauth_verifier parameter.");
+			throw new \SimpleSAML\Error\BadRequest("Missing oauth_verifier parameter.");
 		}
 		$parameters['oauth_verifier'] = (string)$_REQUEST['oauth_verifier'];
 		
-		$consumer = new sspmod_oauth_Consumer($this->key, $this->secret);
+		$consumer = new \SimpleSAML\Module\oauth\Consumer($this->key, $this->secret);
 		
-		SimpleSAML\Logger::debug("oauth: Using this request token [" .
+		\SimpleSAML\Logger::debug("oauth: Using this request token [" .
 			$requestToken->key . "] with the secret [" . $requestToken->secret . "]");
 
 		// Replace the request token with an access token
 		$accessToken = $consumer->getAccessToken('https://api.twitter.com/oauth/access_token', $requestToken, $parameters);
-		SimpleSAML\Logger::debug("Got an access token from the OAuth service provider [" .
+		\SimpleSAML\Logger::debug("Got an access token from the OAuth service provider [" .
 			$accessToken->key . "] with the secret [" . $accessToken->secret . "]");
 
 		$verify_credentials_url = 'https://api.twitter.com/1.1/account/verify_credentials.json';
@@ -112,13 +133,14 @@ class sspmod_authtwitter_Auth_Source_Twitter extends SimpleSAML_Auth_Source {
 		$userdata = $consumer->getUserInfo($verify_credentials_url, $accessToken);
 		
 		if (!isset($userdata['id_str']) || !isset($userdata['screen_name'])) {
-			throw new SimpleSAML_Error_AuthSource($this->authId, 'Authentication error: id_str and screen_name not set.');
+			throw new \SimpleSAML\Error\AuthSource($this->authId, 'Authentication error: id_str and screen_name not set.');
 		}
 
 		$attributes = array();
-		foreach($userdata AS $key => $value) {
-			if (is_string($value))
+		foreach ($userdata as $key => $value) {
+			if (is_string($value)) {
 				$attributes['twitter.' . $key] = array((string)$value);
+            }
 		}
 		
 		$attributes['twitter_at_screen_name'] = array('@' . $userdata['screen_name']);
@@ -127,5 +149,4 @@ class sspmod_authtwitter_Auth_Source_Twitter extends SimpleSAML_Auth_Source {
 			
 		$state['Attributes'] = $attributes;
 	}
-
 }
diff --git a/modules/authtwitter/www/linkback.php b/modules/authtwitter/www/linkback.php
index 2886f8d9aea04f9565d6e1082a049c7db03bcc3c..fc0184059e40859c949c2e046575a76f5c976878 100644
--- a/modules/authtwitter/www/linkback.php
+++ b/modules/authtwitter/www/linkback.php
@@ -5,31 +5,31 @@
  */
 
 if (!array_key_exists('AuthState', $_REQUEST) || empty($_REQUEST['AuthState'])) {
-	throw new SimpleSAML_Error_BadRequest('Missing state parameter on twitter linkback endpoint.');
+    throw new \SimpleSAML\Error\BadRequest('Missing state parameter on twitter linkback endpoint.');
 }
-$state = SimpleSAML_Auth_State::loadState($_REQUEST['AuthState'], sspmod_authtwitter_Auth_Source_Twitter::STAGE_INIT);
+$state = \SimpleSAML\Auth\State::loadState($_REQUEST['AuthState'], \SimpleSAML\Module\authtwitter\Auth\Source\Twitter::STAGE_INIT);
 
 // Find authentication source
-if (!array_key_exists(sspmod_authtwitter_Auth_Source_Twitter::AUTHID, $state)) {
-	throw new SimpleSAML_Error_BadRequest('No data in state for ' . sspmod_authtwitter_Auth_Source_Twitter::AUTHID);
+if (!array_key_exists(\SimpleSAML\Module\authtwitter\Auth\Source\Twitter::AUTHID, $state)) {
+    throw new \SimpleSAML\Error\BadRequest('No data in state for ' . \SimpleSAML\Module\authtwitter\Auth\Source\Twitter::AUTHID);
 }
-$sourceId = $state[sspmod_authtwitter_Auth_Source_Twitter::AUTHID];
+$sourceId = $state[\SimpleSAML\Module\authtwitter\Auth\Source\Twitter::AUTHID];
 
-$source = SimpleSAML_Auth_Source::getById($sourceId);
-if ($source === NULL) {
-	throw new SimpleSAML_Error_BadRequest('Could not find authentication source with id ' . var_export($sourceId, TRUE));
+$source = \SimpleSAML\Auth\Source::getById($sourceId);
+if ($source === null) {
+    throw new \SimpleSAML\Error\BadRequest('Could not find authentication source with id ' . var_export($sourceId, TRUE));
 }
 
 try {
-	if (array_key_exists('denied', $_REQUEST)) {
-		throw new SimpleSAML_Error_UserAborted();
-	}
+    if (array_key_exists('denied', $_REQUEST)) {
+        throw new \SimpleSAML\Error\UserAborted();
+    }
 
-	$source->finalStep($state);
-} catch (SimpleSAML_Error_Exception $e) {
-	SimpleSAML_Auth_State::throwException($state, $e);
-} catch (Exception $e) {
-	SimpleSAML_Auth_State::throwException($state, new SimpleSAML_Error_AuthSource($sourceId, 'Error on authtwitter linkback endpoint.', $e));
+    $source->finalStep($state);
+} catch (\SimpleSAML\Error\Exception $e) {
+    \SimpleSAML\Auth\State::throwException($state, $e);
+} catch (\Exception $e) {
+    \SimpleSAML\Auth\State::throwException($state, new \SimpleSAML\Error\AuthSource($sourceId, 'Error on authtwitter linkback endpoint.', $e));
 }
 
-SimpleSAML_Auth_Source::completeAuth($state);
+\SimpleSAML\Auth\Source::completeAuth($state);
diff --git a/modules/authwindowslive/docs/windowsliveid.md b/modules/authwindowslive/docs/windowsliveid.md
index 390edae2931bffadf1a955b68962817d1658a32d..a26c8fe49a51d6257104c623e1ac5b95c130c14c 100644
--- a/modules/authwindowslive/docs/windowsliveid.md
+++ b/modules/authwindowslive/docs/windowsliveid.md
@@ -5,8 +5,8 @@ Remember to configure `authsources.php`, with both your Client ID and Secret key
 
 To get an API key and a secret, register the application at:
 
- * <http://msdn.microsoft.com/en-us/library/ff751474.aspx>
- * <https://manage.dev.live.com>
+ * <https://msdn.microsoft.com/en-us/library/ff751474.aspx>
+ * <https://apps.dev.microsoft.com/>
 
 ## Testing authentication
 
diff --git a/modules/authwindowslive/lib/Auth/Source/LiveID.php b/modules/authwindowslive/lib/Auth/Source/LiveID.php
index 39fbfd1595f1762391885cd0b8adf0a80db6d4a4..474d6d800fbb45914972284e1da0a1422c428542 100644
--- a/modules/authwindowslive/lib/Auth/Source/LiveID.php
+++ b/modules/authwindowslive/lib/Auth/Source/LiveID.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\authwindowslive\Auth\Source;
+
 /**
  * Authenticate using LiveID.
  *
@@ -7,9 +9,8 @@
  * @author Guy Halse, TENET.
  * @package SimpleSAMLphp
  */
-class sspmod_authwindowslive_Auth_Source_LiveID extends SimpleSAML_Auth_Source
+class LiveID extends \SimpleSAML\Auth\Source
 {
-
     /**
      * The string used to identify our states.
      */
@@ -30,7 +31,7 @@ class sspmod_authwindowslive_Auth_Source_LiveID extends SimpleSAML_Auth_Source
      * @param array $info  Information about this authentication source.
      * @param array $config  Configuration.
      *
-     * @throws Exception In case of misconfiguration.
+     * @throws \Exception In case of misconfiguration.
      */
     public function __construct($info, $config)
     {
@@ -41,13 +42,13 @@ class sspmod_authwindowslive_Auth_Source_LiveID extends SimpleSAML_Auth_Source
         parent::__construct($info, $config);
 
         if (!array_key_exists('key', $config)) {
-            throw new Exception('LiveID authentication source is not properly configured: missing [key]');
+            throw new \Exception('LiveID authentication source is not properly configured: missing [key]');
         }
 
         $this->key = $config['key'];
 
         if (!array_key_exists('secret', $config)) {
-            throw new Exception('LiveID authentication source is not properly configured: missing [secret]');
+            throw new \Exception('LiveID authentication source is not properly configured: missing [secret]');
         }
 
         $this->secret = $config['secret'];
@@ -66,9 +67,9 @@ class sspmod_authwindowslive_Auth_Source_LiveID extends SimpleSAML_Auth_Source
         // we are going to need the authId in order to retrieve this authentication source later
         $state[self::AUTHID] = $this->authId;
 
-        $stateID = SimpleSAML_Auth_State::saveState($state, self::STAGE_INIT);
+        $stateID = \SimpleSAML\Auth\State::saveState($state, self::STAGE_INIT);
 
-        SimpleSAML\Logger::debug('authwindowslive auth state id = ' . $stateID);
+        \SimpleSAML\Logger::debug('authwindowslive auth state id = ' . $stateID);
 
         // authenticate the user
         // documentation at:
@@ -77,7 +78,7 @@ class sspmod_authwindowslive_Auth_Source_LiveID extends SimpleSAML_Auth_Source
                 . '?client_id=' . $this->key
                 . '&response_type=code'
                 . '&response_mode=query'
-                . '&redirect_uri=' . urlencode(SimpleSAML\Module::getModuleUrl('authwindowslive') . '/linkback.php')
+                . '&redirect_uri=' . urlencode(\SimpleSAML\Module::getModuleUrl('authwindowslive') . '/linkback.php')
                 . '&state=' . urlencode($stateID)
                 . '&scope=' . urlencode('openid https://graph.microsoft.com/user.read')
         ;
@@ -89,11 +90,11 @@ class sspmod_authwindowslive_Auth_Source_LiveID extends SimpleSAML_Auth_Source
     /**
      * @param $state
      *
-     * @throws Exception
+     * @throws \Exception
      */
     public function finalStep(&$state)
     {
-        SimpleSAML\Logger::debug(
+        \SimpleSAML\Logger::debug(
             "authwindowslive oauth: Using this verification code [".$state['authwindowslive:verification_code']."]"
         );
 
@@ -104,7 +105,7 @@ class sspmod_authwindowslive_Auth_Source_LiveID extends SimpleSAML_Auth_Source
                 . '&client_secret=' . urlencode($this->secret)
                 . '&scope=' . urlencode('https://graph.microsoft.com/user.read')
                 . '&grant_type=authorization_code'
-                . '&redirect_uri=' . urlencode(SimpleSAML\Module::getModuleUrl('authwindowslive') . '/linkback.php')
+                . '&redirect_uri=' . urlencode(\SimpleSAML\Module::getModuleUrl('authwindowslive') . '/linkback.php')
                 . '&code=' . urlencode($state['authwindowslive:verification_code']);
 
         $context = array(
@@ -121,13 +122,13 @@ class sspmod_authwindowslive_Auth_Source_LiveID extends SimpleSAML_Auth_Source
 
         // error checking of $response to make sure we can proceed
         if (!array_key_exists('access_token', $response)) {
-            throw new Exception(
+            throw new \Exception(
                 '['.$response['error'].'] '.$response['error_description'].
                 "\r\nNo access_token returned - cannot proceed\r\n" . implode(', ', $response['error_codes'])
             );
         }
 
-        SimpleSAML\Logger::debug(
+        \SimpleSAML\Logger::debug(
             "authwindowslive: Got an access token from the OAuth service provider [".$response['access_token']."]"
         );
 
@@ -139,7 +140,7 @@ class sspmod_authwindowslive_Auth_Source_LiveID extends SimpleSAML_Auth_Source
 
         // this is the simplest case
         if (!array_key_exists('@odata.context', $userdata) || array_key_exists('error', $userdata)) {
-            throw new Exception(
+            throw new \Exception(
                 'Unable to retrieve userdata from Microsoft Graph ['.$userdata['error']['code'].'] '.
                 $userdata['error']['message']
             );
@@ -155,7 +156,7 @@ class sspmod_authwindowslive_Auth_Source_LiveID extends SimpleSAML_Auth_Source
         }
 
 
-        SimpleSAML\Logger::debug('LiveID Returned Attributes: '. implode(", ", array_keys($attributes)));
+        \SimpleSAML\Logger::debug('LiveID Returned Attributes: '. implode(", ", array_keys($attributes)));
 
         $state['Attributes'] = $attributes;
     }
diff --git a/modules/authwindowslive/www/linkback.php b/modules/authwindowslive/www/linkback.php
index e6b1ea2c3b50a8b06e60c6dc8875746dc2e94ed2..31637deb7578f4e357a54ff9d7c3a79c0dd00c6a 100644
--- a/modules/authwindowslive/www/linkback.php
+++ b/modules/authwindowslive/www/linkback.php
@@ -5,9 +5,9 @@
  */
 
 if (!array_key_exists('state', $_REQUEST)) {
-    throw new Exception('Lost OAuth Client State');
+    throw new \Exception('Lost OAuth Client State');
 }
-$state = SimpleSAML_Auth_State::loadState($_REQUEST['state'], sspmod_authwindowslive_Auth_Source_LiveID::STAGE_INIT);
+$state = \SimpleSAML\Auth\State::loadState($_REQUEST['state'], \SimpleSAML\Module\authwindowslive\Auth\Source\LiveID::STAGE_INIT);
 
 // http://msdn.microsoft.com/en-us/library/ff749771.aspx
 if (array_key_exists('code', $_REQUEST)) {
@@ -24,23 +24,23 @@ if (array_key_exists('code', $_REQUEST)) {
     // to preserve support for this, so this is left in as a placeholder.
     // redirect them to their original page so they can choose another auth mechanism
     if ($_REQUEST['error'] === 'user_denied') {
-        $e = new SimpleSAML_Error_UserAborted();
-        SimpleSAML_Auth_State::throwException($state, $e);
+        $e = new \SimpleSAML\Error\UserAborted();
+        \SimpleSAML\Auth\State::throwException($state, $e);
     }
 
     // error
-    throw new Exception('Authentication failed: ['.$_REQUEST['error'].'] '.$_REQUEST['error_description']);
+    throw new \Exception('Authentication failed: ['.$_REQUEST['error'].'] '.$_REQUEST['error_description']);
 }
 
 // find authentication source
-assert(array_key_exists(sspmod_authwindowslive_Auth_Source_LiveID::AUTHID, $state));
-$sourceId = $state[sspmod_authwindowslive_Auth_Source_LiveID::AUTHID];
+assert(array_key_exists(\SimpleSAML\Module\authwindowslive\Auth\Source\LiveID::AUTHID, $state));
+$sourceId = $state[\SimpleSAML\Module\authwindowslive\Auth\Source\LiveID::AUTHID];
 
-$source = SimpleSAML_Auth_Source::getById($sourceId);
+$source = \SimpleSAML\Auth\Source::getById($sourceId);
 if ($source === null) {
-    throw new Exception('Could not find authentication source with id '.$sourceId);
+    throw new \Exception('Could not find authentication source with id '.$sourceId);
 }
 
 $source->finalStep($state);
 
-SimpleSAML_Auth_Source::completeAuth($state);
+\SimpleSAML\Auth\Source::completeAuth($state);
diff --git a/modules/cas/lib/Auth/Source/CAS.php b/modules/cas/lib/Auth/Source/CAS.php
index ca700d57ef3958ca0d70c8489161f3ae84f796d0..e58f36f11c0ffaf0487b2d5615c0a48ffed1e2d7 100644
--- a/modules/cas/lib/Auth/Source/CAS.php
+++ b/modules/cas/lib/Auth/Source/CAS.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\cas\Auth\Source;
+
 /**
  * Authenticate using CAS.
  *
@@ -8,228 +10,245 @@
  * @author Danny Bollaert, UGent.
  * @package SimpleSAMLphp
  */
-class sspmod_cas_Auth_Source_CAS  extends SimpleSAML_Auth_Source  {
-
-	/**
-	 * The string used to identify our states.
-	 */
-	const STAGE_INIT = 'sspmod_cas_Auth_Source_CAS.state';
-
-	/**
-	 * The key of the AuthId field in the state.
-	 */
-	const AUTHID = 'sspmod_cas_Auth_Source_CAS.AuthId';
-
-
-	/**
-	 * @var array with ldap configuration
-	 */
-	private $_ldapConfig;
-
-	/**
-	 * @var cas configuration
-	 */
-	private $_casConfig;
-
-	/**
-	 * @var cas chosen validation method
-	 */
-	private $_validationMethod;
-	/**
-	 * @var cas login method
-	 */
-	private $_loginMethod;
-
-
-	/**
-	 * Constructor for this authentication source.
-	 *
-	 * @param array $info  Information about this authentication source.
-	 * @param array $config  Configuration.
-	 */
-	public function __construct($info, $config) {
-		assert(is_array($info));
-		assert(is_array($config));
-
-		// Call the parent constructor first, as required by the interface
-		parent::__construct($info, $config);
-
-		if (!array_key_exists('cas', $config)){
-			throw new Exception('cas authentication source is not properly configured: missing [cas]');
-		}
-
-		if (!array_key_exists('ldap', $config)){
-			throw new Exception('ldap authentication source is not properly configured: missing [ldap]');
-		}
-
-		$this->_casConfig = $config['cas'];
-		$this->_ldapConfig = $config['ldap'];
-
-		if(isset($this->_casConfig['serviceValidate'])){
-			$this->_validationMethod = 'serviceValidate';
-		}elseif(isset($this->_casConfig['validate'])){
-			$this->_validationMethod = 'validate';
-		}else{
-			throw new Exception("validate or serviceValidate not specified");
-		}
-
-		if(isset($this->_casConfig['login'])){
-			$this->_loginMethod =  $this->_casConfig['login'];
-		}else{
-			throw new Exception("cas login URL not specified");
-		}
-	}
-
-
-	/**
-	 * This the most simple version of validating, this provides only authentication validation
-	 *
-	 * @param string $ticket
-	 * @param string $service
-	 * @return list username and attributes
-	 */
-	private function casValidate($ticket, $service){
-		$url = \SimpleSAML\Utils\HTTP::addURLParameters($this->_casConfig['validate'], array(
-				'ticket' => $ticket,
-				'service' => $service,
-		));
-		$result = \SimpleSAML\Utils\HTTP::fetch($url);
-		$res = preg_split("/\r?\n/",$result);
-
-		if (strcmp($res[0], "yes") == 0) {
-			return array($res[1], array());
-		} else {
-			throw new Exception("Failed to validate CAS service ticket: $ticket");
-		}
-	}
-
-
-	/**
-	 * Uses the cas service validate, this provides additional attributes
-	 *
-	 * @param string $ticket
-	 * @param string $service
-	 * @return list username and attributes
-	 */
-	private function casServiceValidate($ticket, $service){
-		$url = \SimpleSAML\Utils\HTTP::addURLParameters($this->_casConfig['serviceValidate'], array(
-				'ticket' => $ticket,
-				'service' => $service,
-		));
-		$result = \SimpleSAML\Utils\HTTP::fetch($url);
-
-		$dom = \SAML2\DOMDocumentFactory::fromString($result);
-		$xPath = new DOMXpath($dom);
-		$xPath->registerNamespace("cas", 'http://www.yale.edu/tp/cas');
-		$success = $xPath->query("/cas:serviceResponse/cas:authenticationSuccess/cas:user");
-		if ($success->length == 0) {
-			$failure = $xPath->evaluate("/cas:serviceResponse/cas:authenticationFailure");
-			throw new Exception("Error when validating CAS service ticket: " . $failure->item(0)->textContent);
-		} else {
-
-			$attributes = array();
-			if ($casattributes = $this->_casConfig['attributes']) { # some has attributes in the xml - attributes is a list of XPath expressions to get them
-				foreach ($casattributes as $name => $query) {
-					$attrs = $xPath->query($query);
-					foreach ($attrs as $attrvalue) $attributes[$name][] = $attrvalue->textContent;
-				}
-			}
-			$casusername = $success->item(0)->textContent;
-
-			return array($casusername, $attributes);
-
-		}
-	}
-
-
-	/**
-	 * Main validation method, redirects to correct method
-	 * (keeps finalStep clean)
-	 *
-	 * @param string $ticket
-	 * @param string $service
-	 * @return list username and attributes
-	 */
-	protected function casValidation($ticket, $service){
-		switch($this->_validationMethod){
-			case 'validate':
-				return  $this->casValidate($ticket, $service);
-				break;
-			case 'serviceValidate':
-				return $this->casServiceValidate($ticket, $service);
-				break;
-			default:
-				throw new Exception("validate or serviceValidate not specified");
-		}
-	}
-
-
-	/**
-	 * Called by linkback, to finish validate/ finish logging in.
-	 * @param state $state
-	 * @return list username, casattributes/ldap attributes
-	 */
-	public function finalStep(&$state) {
-
-
-		$ticket = $state['cas:ticket'];
-		$stateID = SimpleSAML_Auth_State::saveState($state, self::STAGE_INIT);
-		$service =  SimpleSAML\Module::getModuleURL('cas/linkback.php', array('stateID' => $stateID));
-		list($username, $casattributes) = $this->casValidation($ticket, $service);
-		$ldapattributes = array();
-		if ($this->_ldapConfig['servers']) {
-			$ldap = new SimpleSAML_Auth_LDAP($this->_ldapConfig['servers'], $this->_ldapConfig['enable_tls']);
-			$ldapattributes = $ldap->validate($this->_ldapConfig, $username);
-		}
-		$attributes = array_merge_recursive($casattributes, $ldapattributes);
-		$state['Attributes'] = $attributes;
-
-		SimpleSAML_Auth_Source::completeAuth($state);
-	}
-
-
-	/**
-	 * Log-in using cas
-	 *
-	 * @param array &$state  Information about the current authentication.
-	 */
-	public function authenticate(&$state) {
-		assert(is_array($state));
-
-		// We are going to need the authId in order to retrieve this authentication source later
-		$state[self::AUTHID] = $this->authId;
-
-		$stateID = SimpleSAML_Auth_State::saveState($state, self::STAGE_INIT);
-
-
-
-		$serviceUrl = SimpleSAML\Module::getModuleURL('cas/linkback.php', array('stateID' => $stateID));
-
-		\SimpleSAML\Utils\HTTP::redirectTrustedURL($this->_loginMethod, array(
-			'service' => $serviceUrl));
-	}
-
-
-	/**
-	 * Log out from this authentication source.
-	 *
-	 * This function should be overridden if the authentication source requires special
-	 * steps to complete a logout operation.
-	 *
-	 * If the logout process requires a redirect, the state should be saved. Once the
-	 * logout operation is completed, the state should be restored, and completeLogout
-	 * should be called with the state. If this operation can be completed without
-	 * showing the user a page, or redirecting, this function should return.
-	 *
-	 * @param array &$state  Information about the current logout operation.
-	 */
-	public function logout(&$state) {
-		assert(is_array($state));
-		$logoutUrl = $this->_casConfig['logout'];
-
-		SimpleSAML_Auth_State::deleteState($state);
-		// we want cas to log us out
-		\SimpleSAML\Utils\HTTP::redirectTrustedURL($logoutUrl);
-	}
 
+class CAS extends \SimpleSAML\Auth\Source
+{
+    /**
+     * The string used to identify our states.
+     */
+    const STAGE_INIT = '\SimpleSAML\Module\cas\Auth\Source\CAS.state';
+
+    /**
+     * The key of the AuthId field in the state.
+     */
+    const AUTHID = '\SimpleSAML\Module\cas\Auth\Source\CAS.AuthId';
+
+    /**
+     * @var array with ldap configuration
+     */
+    private $_ldapConfig;
+
+    /**
+     * @var cas configuration
+     */
+    private $_casConfig;
+
+    /**
+     * @var string cas chosen validation method
+     */
+
+    private $_validationMethod;
+    /**
+     * @var string cas login method
+     */
+    private $_loginMethod;
+
+    /**
+     * Constructor for this authentication source.
+     *
+     * @param array $info  Information about this authentication source.
+     * @param array $config  Configuration.
+     */
+    public function __construct($info, $config)
+    {
+        assert(is_array($info));
+        assert(is_array($config));
+
+        // Call the parent constructor first, as required by the interface
+        parent::__construct($info, $config);
+
+        if (!array_key_exists('cas', $config)) {
+            throw new \Exception('cas authentication source is not properly configured: missing [cas]');
+        }
+
+        if (!array_key_exists('ldap', $config)) {
+            throw new \Exception('ldap authentication source is not properly configured: missing [ldap]');
+        }
+
+        $this->_casConfig = $config['cas'];
+        $this->_ldapConfig = $config['ldap'];
+
+        if (isset($this->_casConfig['serviceValidate'])) {
+            $this->_validationMethod = 'serviceValidate';
+        } elseif(isset($this->_casConfig['validate'])) {
+            $this->_validationMethod = 'validate';
+        } else {
+            throw new \Exception("validate or serviceValidate not specified");
+        }
+
+        if (isset($this->_casConfig['login'])) {
+            $this->_loginMethod =  $this->_casConfig['login'];
+        } else {
+            throw new \Exception("cas login URL not specified");
+        }
+    }
+
+
+    /**
+     * This the most simple version of validating, this provides only authentication validation
+     *
+     * @param string $ticket
+     * @param string $service
+     *
+     * @return array username and attributes
+     */
+    private function casValidate($ticket, $service)
+    {
+        $url = \SimpleSAML\Utils\HTTP::addURLParameters($this->_casConfig['validate'], array(
+            'ticket' => $ticket,
+            'service' => $service,
+        ));
+        $result = \SimpleSAML\Utils\HTTP::fetch($url);
+        $res = preg_split("/\r?\n/",$result);
+
+        if (strcmp($res[0], "yes") == 0) {
+            return array($res[1], array());
+        } else {
+            throw new \Exception("Failed to validate CAS service ticket: $ticket");
+        }
+    }
+
+
+    /**
+     * Uses the cas service validate, this provides additional attributes
+     *
+     * @param string $ticket
+     * @param string $service
+     *
+     * @return array username and attributes
+     */
+    private function casServiceValidate($ticket, $service)
+    {
+        $url = \SimpleSAML\Utils\HTTP::addURLParameters(
+            $this->_casConfig['serviceValidate'],
+            array(
+                'ticket' => $ticket,
+                'service' => $service,
+            )
+        );
+        $result = \SimpleSAML\Utils\HTTP::fetch($url);
+
+        $dom = \SAML2\DOMDocumentFactory::fromString($result);
+        $xPath = new \DOMXpath($dom);
+        $xPath->registerNamespace("cas", 'http://www.yale.edu/tp/cas');
+        $success = $xPath->query("/cas:serviceResponse/cas:authenticationSuccess/cas:user");
+        if ($success->length == 0) {
+            $failure = $xPath->evaluate("/cas:serviceResponse/cas:authenticationFailure");
+            throw new \Exception("Error when validating CAS service ticket: " . $failure->item(0)->textContent);
+        } else {
+            $attributes = array();
+            if ($casattributes = $this->_casConfig['attributes']) { # some has attributes in the xml - attributes is a list of XPath expressions to get them
+                foreach ($casattributes as $name => $query) {
+                    $attrs = $xPath->query($query);
+                    foreach ($attrs as $attrvalue) {
+                        $attributes[$name][] = $attrvalue->textContent;
+                    }
+                }
+            }
+            $casusername = $success->item(0)->textContent;
+
+            return array($casusername, $attributes);
+        }
+    }
+
+
+    /**
+     * Main validation method, redirects to correct method
+     * (keeps finalStep clean)
+     *
+     * @param string $ticket
+     * @param string $service
+     * @return array username and attributes
+     */
+    protected function casValidation($ticket, $service)
+    {
+        switch ($this->_validationMethod)
+        {
+            case 'validate':
+                return  $this->casValidate($ticket, $service);
+                break;
+            case 'serviceValidate':
+                return $this->casServiceValidate($ticket, $service);
+                break;
+            default:
+                throw new \Exception("validate or serviceValidate not specified");
+        }
+    }
+
+
+    /**
+     * Called by linkback, to finish validate/ finish logging in.
+     * @param array $state
+     * @return array username, casattributes/ldap attributes
+     */
+    public function finalStep(&$state)
+    {
+        $ticket = $state['cas:ticket'];
+        $stateID = \SimpleSAML\Auth\State::saveState($state, self::STAGE_INIT);
+        $service =  \SimpleSAML\Module::getModuleURL('cas/linkback.php', array('stateID' => $stateID));
+        list($username, $casattributes) = $this->casValidation($ticket, $service);
+        $ldapattributes = array();
+
+        $config = \SimpleSAML\Configuration::loadFromArray($this->_ldapConfig,
+            'Authentication source ' . var_export($this->authId, true));
+        if ($this->_ldapConfig['servers']) {
+            $ldap = new \SimpleSAML\Auth\LDAP(
+                $config->getString('servers'),
+                $config->getBoolean('enable_tls', false),
+                $config->getBoolean('debug', false),
+                $config->getInteger('timeout', 0),
+                $config->getInteger('port', 389),
+                $config->getBoolean('referrals', true)
+            );
+            $ldapattributes = $ldap->validate($this->_ldapConfig, $username);
+        }
+        $attributes = array_merge_recursive($casattributes, $ldapattributes);
+        $state['Attributes'] = $attributes;
+
+        \SimpleSAML\Auth\Source::completeAuth($state);
+    }
+
+
+    /**
+     * Log-in using cas
+     *
+     * @param array &$state  Information about the current authentication.
+     */
+    public function authenticate(&$state)
+    {
+        assert(is_array($state));
+
+        // We are going to need the authId in order to retrieve this authentication source later
+        $state[self::AUTHID] = $this->authId;
+
+        $stateID = \SimpleSAML\Auth\State::saveState($state, self::STAGE_INIT);
+
+        $serviceUrl = \SimpleSAML\Module::getModuleURL('cas/linkback.php', array('stateID' => $stateID));
+
+        \SimpleSAML\Utils\HTTP::redirectTrustedURL($this->_loginMethod, array('service' => $serviceUrl));
+    }
+
+
+    /**
+     * Log out from this authentication source.
+     *
+     * This function should be overridden if the authentication source requires special
+     * steps to complete a logout operation.
+     *
+     * If the logout process requires a redirect, the state should be saved. Once the
+     * logout operation is completed, the state should be restored, and completeLogout
+     * should be called with the state. If this operation can be completed without
+     * showing the user a page, or redirecting, this function should return.
+     *
+     * @param array &$state  Information about the current logout operation.
+     */
+    public function logout(&$state)
+    {
+        assert(is_array($state));
+        $logoutUrl = $this->_casConfig['logout'];
+
+        \SimpleSAML\Auth\State::deleteState($state);
+        // we want cas to log us out
+        \SimpleSAML\Utils\HTTP::redirectTrustedURL($logoutUrl);
+    }
 }
diff --git a/modules/cas/www/linkback.php b/modules/cas/www/linkback.php
index a6ffa4971e5c7f28685ccdf82e9825b622462b11..a429b9c8e7fed6111212fe6466f126c6c278ce76 100644
--- a/modules/cas/www/linkback.php
+++ b/modules/cas/www/linkback.php
@@ -5,22 +5,22 @@
  */
 
 if (!isset($_GET['stateID'])) {
-	throw new SimpleSAML_Error_BadRequest('Missing stateID parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing stateID parameter.');
 }
-$state = SimpleSAML_Auth_State::loadState($_GET['stateID'], sspmod_cas_Auth_Source_CAS::STAGE_INIT);
+$state = \SimpleSAML\Auth\State::loadState($_GET['stateID'], \SimpleSAML\Module\cas\Auth\Source\CAS::STAGE_INIT);
 
 if (!isset($_GET['ticket'])) {
-	throw new SimpleSAML_Error_BadRequest('Missing ticket parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing ticket parameter.');
 }
 $state['cas:ticket'] = (string)$_GET['ticket'];
 
 // Find authentication source
-assert(array_key_exists(sspmod_cas_Auth_Source_CAS::AUTHID, $state));
-$sourceId = $state[sspmod_cas_Auth_Source_CAS::AUTHID];
+assert(array_key_exists(\SimpleSAML\Module\cas\Auth\Source\CAS::AUTHID, $state));
+$sourceId = $state[\SimpleSAML\Module\cas\Auth\Source\CAS::AUTHID];
 
-$source = SimpleSAML_Auth_Source::getById($sourceId);
-if ($source === NULL) {
-	throw new Exception('Could not find authentication source with id ' . $sourceId);
+$source = \SimpleSAML\Auth\Source::getById($sourceId);
+if ($source === null) {
+    throw new \Exception('Could not find authentication source with id ' . $sourceId);
 }
 
 $source->finalStep($state);
diff --git a/modules/casserver/www/cas.php b/modules/casserver/www/cas.php
index 5b9d16baddc11f77522d13488225eba77a7fe574..712b4f08309f1a54b499c452524799ab9b53866c 100644
--- a/modules/casserver/www/cas.php
+++ b/modules/casserver/www/cas.php
@@ -15,20 +15,20 @@
  * Proxyed services (targetService) shall be present in the legal_service_urls config.
  * 
  */
- 
+
  
 $validFunctions = array(
-	'login' => 'login',
-	'proxy' => 'proxy',
-	'validate' => 'serviceValidate',
-	'serviceValidate' => 'serviceValidate',
-	'proxyValidate' => 'serviceValidate'
+    'login' => 'login',
+    'proxy' => 'proxy',
+    'validate' => 'serviceValidate',
+    'serviceValidate' => 'serviceValidate',
+    'proxyValidate' => 'serviceValidate'
 );
 
 $function = substr($_SERVER['PATH_INFO'], 1);
 
 if (!isset($validFunctions[$function])) {
-	throw new SimpleSAML_Error_NotFound('Not a valid function for cas.php.');
+    throw new \SimpleSAML\Error\NotFound('Not a valid function for cas.php.');
 }
 
 include($validFunctions[$function].".php");
diff --git a/modules/casserver/www/login.php b/modules/casserver/www/login.php
index fd55f05eb8a3b11dd845c8335ea2f3d11350d492..7b1d967fc8a3ae61369b66547007fd626c5ee379 100644
--- a/modules/casserver/www/login.php
+++ b/modules/casserver/www/login.php
@@ -17,8 +17,8 @@ $service = $_GET['service'];
 $forceAuthn =isset($_GET['renew']) && $_GET['renew'];
 $isPassive = isset($_GET['gateway']) && $_GET['gateway'];
 
-$config = SimpleSAML_Configuration::getInstance();
-$casconfig = SimpleSAML_Configuration::getConfig('module_casserver.php');
+$config = \SimpleSAML\Configuration::getInstance();
+$casconfig = \SimpleSAML\Configuration::getConfig('module_casserver.php');
 
 $legal_service_urls = $casconfig->getValue('legal_service_urls');
 if (!checkServiceURL($service, $legal_service_urls))
@@ -52,4 +52,4 @@ storeTicket($ticket, $path, array('service' => $service,
 	\SimpleSAML\Utils\HTTP::addURLParameters($service,
 		array('ticket' => $ticket)
 	)
-);
\ No newline at end of file
+);
diff --git a/modules/casserver/www/proxy.php b/modules/casserver/www/proxy.php
index 6fc14e4a31407db3d1adf22f0ec23b6684212336..4ae88113423f800493328ff238017ccd342d290e 100644
--- a/modules/casserver/www/proxy.php
+++ b/modules/casserver/www/proxy.php
@@ -15,7 +15,7 @@ if (array_key_exists('targetService', $_GET)) {
 	throw new Exception('Required URL query parameter [targetService] not provided. (CAS Server)');
 }
 
-$casconfig = SimpleSAML_Configuration::getConfig('module_casserver.php');
+$casconfig = \SimpleSAML\Configuration::getConfig('module_casserver.php');
 
 $legal_service_urls = $casconfig->getValue('legal_service_urls');
 
@@ -50,4 +50,4 @@ print <<<eox
     </cas:proxyFailure>
 </cas:serviceResponse>
 eox;
-}
\ No newline at end of file
+}
diff --git a/modules/casserver/www/serviceValidate.php b/modules/casserver/www/serviceValidate.php
index cf4bd0af22c7d00bf416c458369cfb2d32bf1ea4..9fd4fdf62dd67cd7d121eb4e25ae771dd1b44572 100644
--- a/modules/casserver/www/serviceValidate.php
+++ b/modules/casserver/www/serviceValidate.php
@@ -1,8 +1,10 @@
 <?php
-require 'tickets.php';
+require('tickets.php');
 
-# set manually if called directly - ie not included from validate.php or cas.php
-if (!$function) $function = 'serviceValidate';
+// set manually if called directly - ie not included from validate.php or cas.php
+if (!$function) {
+    $function = 'serviceValidate';
+}
 
 /*
  * Incoming parameters:
@@ -11,89 +13,95 @@ if (!$function) $function = 'serviceValidate';
  *  ticket
  *
  */
-
 if (array_key_exists('service', $_GET)) {
-	$service = $_GET['service'];
-	$ticket = $_GET['ticket'];
-	$forceAuthn = isset($_GET['renew']) && $_GET['renew'];
+    $service = $_GET['service'];
+    $ticket = $_GET['ticket'];
+    $forceAuthn = isset($_GET['renew']) && $_GET['renew'];
 } else { 
-	throw new Exception('Required URL query parameter [service] not provided. (CAS Server)');
+    throw new Exception('Required URL query parameter [service] not provided. (CAS Server)');
 }
 
 try {
-// Load SimpleSAMLphp, configuration and metadata
-	$casconfig = SimpleSAML_Configuration::getConfig('module_casserver.php');
-	
-	$path = $casconfig->resolvePath($casconfig->getValue('ticketcache', 'ticketcache'));
-	$ticketcontent = retrieveTicket($ticket, $path);
-	
-	$usernamefield = $casconfig->getValue('attrname', 'eduPersonPrincipalName');
-	$dosendattributes = $casconfig->getValue('attributes', FALSE);
-	
-	$attributes = $ticketcontent['attributes'];
+    // Load SimpleSAMLphp, configuration and metadata
+    $casconfig = \SimpleSAML\Configuration::getConfig('module_casserver.php');
+
+    $path = $casconfig->resolvePath($casconfig->getValue('ticketcache', 'ticketcache'));
+    $ticketcontent = retrieveTicket($ticket, $path);
+
+    $usernamefield = $casconfig->getValue('attrname', 'eduPersonPrincipalName');
+    $dosendattributes = $casconfig->getValue('attributes', false);
+
+    $attributes = $ticketcontent['attributes'];
+
+    $pgtiouxml = "";
 
-	$pgtiouxml = "";
+    if ($ticketcontent['service'] == $service
+            && $ticketcontent['forceAuthn'] == $forceAuthn
+            && array_key_exists($usernamefield, $attributes)
+            && $ticketcontent['validbefore'] > time()) {
 
-	if ($ticketcontent['service'] == $service
-			&& $ticketcontent['forceAuthn'] == $forceAuthn
-			&& array_key_exists($usernamefield, $attributes)
-			&& $ticketcontent['validbefore'] > time()) {
-					
-		if (isset($_GET['pgtUrl'])) {
-			$pgtUrl = $_GET['pgtUrl'];
-			$pgtiou = str_replace( '_', 'PGTIOU-', SimpleSAML\Utils\Random::generateID());
-			$pgt = str_replace( '_', 'PGT-', SimpleSAML\Utils\Random::generateID());
-			$content = array(
-				'attributes' => $attributes,
-				'forceAuthn' => false,
-				'proxies' => array_merge(array($service), $ticketcontent['proxies']),
-				'validbefore' => time() + 60);
-			\SimpleSAML\Utils\HTTP::fetch($pgtUrl . '?pgtIou=' . $pgtiou . '&pgtId=' . $pgt);
-			storeTicket($pgt, $path, $content);
-			$pgtiouxml = "\n<cas:proxyGrantingTicket>$pgtiou</cas:proxyGrantingTicket>\n";
-		}
-		
-		$proxiesxml = join("\n", array_map(create_function('$a', 'return "<cas:proxy>$a</cas:proxy>";'), $ticketcontent['proxies']));
-		if ($proxiesxml) $proxiesxml = "<cas:proxies>\n$proxiesxml\n</cas:proxies>\n";
-		returnResponse('YES', $function, $attributes[$usernamefield][0], $dosendattributes ? $attributes : array(), $pgtiouxml.$proxiesxml);
-	} else {
-		returnResponse('NO', $function);
+        if (isset($_GET['pgtUrl'])) {
+            $pgtUrl = $_GET['pgtUrl'];
+            $pgtiou = str_replace( '_', 'PGTIOU-', SimpleSAML\Utils\Random::generateID());
+            $pgt = str_replace( '_', 'PGT-', SimpleSAML\Utils\Random::generateID());
+            $content = array(
+                'attributes' => $attributes,
+                'forceAuthn' => false,
+                'proxies' => array_merge(array($service), $ticketcontent['proxies']),
+                'validbefore' => time() + 60);
+            \SimpleSAML\Utils\HTTP::fetch($pgtUrl . '?pgtIou=' . $pgtiou . '&pgtId=' . $pgt);
+            storeTicket($pgt, $path, $content);
+            $pgtiouxml = "\n<cas:proxyGrantingTicket>$pgtiou</cas:proxyGrantingTicket>\n";
+        }
+
+	$proxiesxml = join("\n", array_map(
+	    function($a) { return "<cas:proxy>$a</cas:proxy>"; },
+	    $ticketcontent['proxies']));
+	if ($proxiesxml) {
+	    $proxiesxml = "<cas:proxies>\n$proxiesxml\n</cas:proxies>\n";
 	}
 
+	returnResponse('YES', $function, $attributes[$usernamefield][0],
+            $dosendattributes ? $attributes : array(),
+            $pgtiouxml.$proxiesxml);
+    } else {
+        returnResponse('NO', $function);
+    }
+
 } catch (Exception $e) {
-	returnResponse('NO', $function, $e->getMessage());
+    returnResponse('NO', $function, $e->getMessage());
 }
 
-function returnResponse($value, $function, $usrname = '', $attributes = array(), $xtraxml = "") {
-	if ($value === 'YES') {	
-		if ($function != 'validate') {
-			$attributesxml = "";
-			foreach ($attributes as $attributename => $attributelist) {
-				$attr = htmlspecialchars($attributename);
-				foreach ($attributelist as $attributevalue) {
-					$attributesxml .= "<cas:$attr>" . htmlspecialchars($attributevalue) . "</cas:$attr>\n";
-				}
-			}
-			if (sizeof($attributes)) $attributesxml = "<cas:attributes>\n" . $attributesxml . "</cas:attributes>\n";
-			echo '<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">
+function returnResponse($value, $function, $usrname = '', $attributes = array(), $xtraxml = "")
+{
+    if ($value === 'YES') {
+        if ($function != 'validate') {
+            $attributesxml = "";
+            foreach ($attributes as $attributename => $attributelist) {
+                $attr = htmlspecialchars($attributename);
+                foreach ($attributelist as $attributevalue) {
+                    $attributesxml .= "<cas:$attr>" . htmlspecialchars($attributevalue) . "</cas:$attr>\n";
+                }
+            }
+            if (sizeof($attributes)) $attributesxml = "<cas:attributes>\n" . $attributesxml . "</cas:attributes>\n";
+            echo '<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">
 <cas:authenticationSuccess>
 <cas:user>' . htmlspecialchars($usrname) . '</cas:user>' .
-		$xtraxml .
-		$attributesxml .
-		'</cas:authenticationSuccess>
+        $xtraxml .
+        $attributesxml .
+        '</cas:authenticationSuccess>
 </cas:serviceResponse>';
-		} else {
-			echo 'yes' . "\n" . $usrname;
-		}
-	} else {
-		if ($function != 'validate') {
-			echo '<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">
+        } else {
+            echo 'yes' . "\n" . $usrname;
+        }
+    } else {
+        if ($function != 'validate') {
+            echo '<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">
 <cas:authenticationFailure code="">
 </cas:authenticationFailure>
 </cas:serviceResponse>';
-		} else {
-			echo 'no';
-
-		}
-	}
-}
\ No newline at end of file
+        } else {
+            echo 'no';
+        }
+    }
+}
diff --git a/modules/casserver/www/validate.php b/modules/casserver/www/validate.php
index b57c744693a9c4f34abacc5f91ae87153296a480..29e29a05f651c7465fb1b0cff3eb61e871ca4cb9 100644
--- a/modules/casserver/www/validate.php
+++ b/modules/casserver/www/validate.php
@@ -1,3 +1,4 @@
 <?php
+
 $function = 'validate';
 include("serviceValidate.php");
diff --git a/modules/cdc/config-templates/module_cdc.php b/modules/cdc/config-templates/module_cdc.php
index 77b83bdceceb63f8319440f810a8175e2d3daa7e..0e5013c87c5d5a489b1ebfec3e3264ac8baa5397 100644
--- a/modules/cdc/config-templates/module_cdc.php
+++ b/modules/cdc/config-templates/module_cdc.php
@@ -1,24 +1,22 @@
 <?php
 
 $config = array(
-	'example.org' => array(
+    'example.org' => array(
+        /*
+         * The shared key for this CDC server.
+         */
+        'key' => 'ExampleSharedKey',
 
-		/*
-		 * The shared key for this CDC server.
-		 */
-		'key' => 'ExampleSharedKey',
+        /*
+         * The URL to the server script.
+         */
+        'server' => 'https://my-cdc.example.org/simplesaml/module.php/cdc/server.php',
 
-		/*
-		 * The URL to the server script.
-		 */
-		'server' => 'https://my-cdc.example.org/simplesaml/module.php/cdc/server.php',
-
-		/*
-		 * The lifetime of our cookie, in seconds.
-		 *
-		 * If this is 0, the cookie will expire when the browser is closed.
-		 */
-		'cookie.lifetime' => 0,
-
-	),
+        /*
+         * The lifetime of our cookie, in seconds.
+         *
+         * If this is 0, the cookie will expire when the browser is closed.
+         */
+        'cookie.lifetime' => 0,
+    ),
 );
diff --git a/modules/cdc/lib/Auth/Process/CDC.php b/modules/cdc/lib/Auth/Process/CDC.php
index bdcf4b70633a98278d979d5aef64da0a339b2712..c616e7aeae0881b09b0bf0fd4f940cfe8a42e513 100644
--- a/modules/cdc/lib/Auth/Process/CDC.php
+++ b/modules/cdc/lib/Auth/Process/CDC.php
@@ -1,71 +1,74 @@
 <?php
 
+namespace SimpleSAML\module\cdc\Auth\Process;
+
 /**
  * Filter for setting the SAML 2 common domain cookie.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_cdc_Auth_Process_CDC extends SimpleSAML_Auth_ProcessingFilter {
-
-
-	/**
-	 * Our CDC domain.
-	 *
-	 * @var string
-	 */
-	private $domain;
-
-
-	/**
-	 * Our CDC client.
-	 *
-	 * @var sspmod_cdc_Client
-	 */
-	private $client;
-
-
-	/**
-	 * Initialize this filter.
-	 *
-	 * @param array $config  Configuration information about this filter.
-	 * @param mixed $reserved  For future use.
-	 */
-	public function __construct($config, $reserved) {
-		parent::__construct($config, $reserved);
-		assert(is_array($config));
-
-		if (!isset($config['domain'])) {
-			throw new SimpleSAML_Error_Exception('Missing domain option in cdc:CDC filter.');
-		}
-		$this->domain = (string)$config['domain'];
-
-		$this->client = new sspmod_cdc_Client($this->domain);
-	}
-
-
-	/**
-	 * Redirect to page setting CDC.
-	 *
-	 * @param array &$state  The request state.
-	 */
-	public function process(&$state) {
-		assert(is_array($state));
-
-		if (!isset($state['Source']['entityid'])) {
-			SimpleSAML\Logger::warning('saml:CDC: Could not find IdP entityID.');
-			return;
-		}
-
-		// Save state and build request
-		$id = SimpleSAML_Auth_State::saveState($state, 'cdc:resume');
-
-		$returnTo = SimpleSAML\Module::getModuleURL('cdc/resume.php', array('domain' => $this->domain));
-
-		$params = array(
-			'id' => $id,
-			'entityID' => $state['Source']['entityid'],
-		);
-		$this->client->sendRequest($returnTo, 'append', $params);
-	}
 
+class CDC extends \SimpleSAML\Auth\ProcessingFilter
+{
+    /**
+     * Our CDC domain.
+     *
+     * @var string
+     */
+    private $domain;
+
+
+    /**
+     * Our CDC client.
+     *
+     * @var \SimpleSAML\Module\cdc\Client
+     */
+    private $client;
+
+
+    /**
+     * Initialize this filter.
+     *
+     * @param array $config  Configuration information about this filter.
+     * @param mixed $reserved  For future use.
+     */
+    public function __construct($config, $reserved)
+    {
+        parent::__construct($config, $reserved);
+        assert(is_array($config));
+
+        if (!isset($config['domain'])) {
+            throw new \SimpleSAML\Error\Exception('Missing domain option in cdc:CDC filter.');
+        }
+        $this->domain = (string)$config['domain'];
+
+        $this->client = new \SimpleSAML\Module\cdc\Client($this->domain);
+    }
+
+
+    /**
+     * Redirect to page setting CDC.
+     *
+     * @param array &$state  The request state.
+     */
+    public function process(&$state)
+    {
+        assert(is_array($state));
+
+        if (!isset($state['Source']['entityid'])) {
+            \SimpleSAML\Logger::warning('saml:CDC: Could not find IdP entityID.');
+            return;
+        }
+
+        // Save state and build request
+        $id = \SimpleSAML\Auth\State::saveState($state, 'cdc:resume');
+
+        $returnTo = \SimpleSAML\Module::getModuleURL('cdc/resume.php', array('domain' => $this->domain));
+
+        $params = array(
+            'id' => $id,
+            'entityID' => $state['Source']['entityid'],
+        );
+        $this->client->sendRequest($returnTo, 'append', $params);
+    }
 }
diff --git a/modules/cdc/lib/Client.php b/modules/cdc/lib/Client.php
index 41c119a56a859f21795c9c9657cfa11d279846a5..6af90fa492f49f19d84eb23c2a730305a90e0ec4 100644
--- a/modules/cdc/lib/Client.php
+++ b/modules/cdc/lib/Client.php
@@ -1,66 +1,70 @@
 <?php
 
+namespace SimpleSAML\Module\cdc;
+
 /**
  * CDC client class.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_cdc_Client {
-
-	/**
-	 * Our CDC domain.
-	 *
-	 * @var string
-	 */
-	private $domain;
-
 
-	/**
-	 * The CDC server we send requests to.
-	 *
-	 * @var sspmod_cdc_Server|NULL
-	 */
-	private $server;
+class Client
+{
+    /**
+     * Our CDC domain.
+     *
+     * @var string
+     */
+    private $domain;
 
 
-	/**
-	 * Initialize a CDC client.
-	 *
-	 * @param string $domain  The domain we should query the server for.
-	 */
-	public function __construct($domain) {
-		assert(is_string($domain));
+    /**
+     * The CDC server we send requests to.
+     *
+     * @var Server|NULL
+     */
+    private $server;
 
-		$this->domain = $domain;
-		$this->server = new sspmod_cdc_Server($domain);
-	}
 
+    /**
+     * Initialize a CDC client.
+     *
+     * @param string $domain  The domain we should query the server for.
+     */
+    public function __construct($domain)
+    {
+        assert(is_string($domain));
 
-	/**
-	 * Receive a CDC response.
-	 *
-	 * @return array|NULL  The response, or NULL if no response is received.
-	 */
-	public function getResponse() {
+        $this->domain = $domain;
+        $this->server = new Server($domain);
+    }
 
-		return $this->server->getResponse();
-	}
 
+    /**
+     * Receive a CDC response.
+     *
+     * @return array|NULL  The response, or NULL if no response is received.
+     */
+    public function getResponse()
+    {
+        return $this->server->getResponse();
+    }
 
-	/**
-	 * Send a request.
-	 *
-	 * @param string $returnTo  The URL we should return to afterwards.
-	 * @param string $op  The operation we are performing.
-	 * @param array $params  Additional parameters.
-	 */
-	public function sendRequest($returnTo, $op, array $params = array()) {
-		assert(is_string($returnTo));
-		assert(is_string($op));
 
-		$params['op'] = $op;
-		$params['return'] = $returnTo;
-		$this->server->sendRequest($params);
-	}
+    /**
+     * Send a request.
+     *
+     * @param string $returnTo  The URL we should return to afterwards.
+     * @param string $op  The operation we are performing.
+     * @param array $params  Additional parameters.
+     */
+    public function sendRequest($returnTo, $op, array $params = array())
+    {
+        assert(is_string($returnTo));
+        assert(is_string($op));
 
+        $params['op'] = $op;
+        $params['return'] = $returnTo;
+        $this->server->sendRequest($params);
+    }
 }
diff --git a/modules/cdc/lib/Server.php b/modules/cdc/lib/Server.php
index 569a33d98ca0ea88a3e640b95ef8bf0320390f8b..b7afe261360de2d09deffa7aafe12107155202c3 100644
--- a/modules/cdc/lib/Server.php
+++ b/modules/cdc/lib/Server.php
@@ -1,413 +1,422 @@
 <?php
 
+namespace SimpleSAML\Module\cdc;
+
 /**
  * CDC server class.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_cdc_Server {
-
-	/**
-	 * The domain.
-	 *
-	 * @var string
-	 */
-	private $domain;
-
-
-	/**
-	 * The URL to the server.
-	 *
-	 * @var string
-	 */
-	private $server;
-
-
-	/**
-	 * Our shared key.
-	 *
-	 * @var string
-	 */
-	private $key;
-
-
-	/**
-	 * The lifetime of our cookie, in seconds.
-	 *
-	 * If this is 0, the cookie will expire when the browser is closed.
-	 *
-	 * @param int
-	 */
-	private $cookieLifetime;
-
-
-	/**
-	 * Initialize a CDC server.
-	 *
-	 * @param string $domain  The domain we are a server for.
-	 */
-	public function __construct($domain) {
-		assert(is_string($domain));
-
-		$cdcConfig = SimpleSAML_Configuration::getConfig('module_cdc.php');
-		$config = $cdcConfig->getConfigItem($domain, NULL);
-
-		if ($config === NULL) {
-			throw new SimpleSAML_Error_Exception('Unknown CDC domain: ' . var_export($domain, TRUE));
-		}
-
-		$this->domain = $domain;
-		$this->server = $config->getString('server');
-		$this->key = $config->getString('key');
-		$this->cookieLifetime = $config->getInteger('cookie.lifetime', 0);
-
-		if ($this->key === 'ExampleSharedKey') {
-			throw new SimpleSAML_Error_Exception('Key for CDC domain ' . var_export($domain, TRUE) . ' not changed from default.');
-		}
-	}
-
-
-	/**
-	 * Send a request to this CDC server.
-	 *
-	 * @param array $request  The CDC request.
-	 */
-	public function sendRequest(array $request) {
-		assert(isset($request['return']));
-		assert(isset($request['op']));
-
-		$request['domain'] = $this->domain;
-		$this->send($this->server, 'CDCRequest', $request);
-	}
-
-
-	/**
-	 * Parse and validate response received from a CDC server.
-	 *
-	 * @return array|NULL  The response, or NULL if no response is received.
-	 */
-	public function getResponse() {
-
-		$response = self::get('CDCResponse');
-		if ($response === NULL) {
-			return NULL;
-		}
-
-		if ($response['domain'] !== $this->domain) {
-			throw new SimpleSAML_Error_Exception('Response received from wrong domain.');
-		}
-
-		$this->validate('CDCResponse');
-
-		return $response;
-	}
-
-
-	/**
-	 * Parse and process a CDC request.
-	 */
-	public static function processRequest() {
-		$request = self::get('CDCRequest');
-		if ($request === NULL) {
-			throw new SimpleSAML_Error_BadRequest('Missing "CDCRequest" parameter.');
-		}
-
-		$domain = $request['domain'];
-		$server = new sspmod_cdc_Server($domain);
-
-		$server->validate('CDCRequest');
-
-		$server->handleRequest($request);
-	}
-
-
-	/**
-	 * Handle a parsed CDC requst.
-	 *
-	 * @param array $request
-	 */
-	private function handleRequest(array $request) {
-
-		if (!isset($request['op'])) {
-			throw new SimpleSAML_Error_BadRequest('Missing "op" in CDC request.');
-		}
-		$op = (string)$request['op'];
-
-		SimpleSAML\Logger::info('Received CDC request with "op": ' . var_export($op, TRUE));
-
-		if (!isset($request['return'])) {
-			throw new SimpleSAML_Error_BadRequest('Missing "return" in CDC request.');
-		}
-		$return = (string)$request['return'];
-
-		switch ($op) {
-		case 'append':
-			$response = $this->handleAppend($request);
-			break;
-		case 'delete':
-			$response = $this->handleDelete($request);
-			break;
-		case 'read':
-			$response = $this->handleRead($request);
-			break;
-		default:
-			$response = 'unknown-op';
-		}
-
-		if (is_string($response)) {
-			$response = array(
-				'status' => $response,
-			);
-		}
-
-		$response['op'] = $op;
-		if (isset($request['id'])) {
-			$response['id'] = (string)$request['id'];
-		}
-		$response['domain'] = $this->domain;
-
-		$this->send($return, 'CDCResponse', $response);
-	}
-
-
-	/**
-	 * Handle an append request.
-	 *
-	 * @param array $request  The request.
-	 * @return array  The response.
-	 */
-	private function handleAppend(array $request) {
-
-		if (!isset($request['entityID'])) {
-			throw new SimpleSAML_Error_BadRequest('Missing entityID in append request.');
-		}
-		$entityID = (string)$request['entityID'];
-
-		$list = $this->getCDC();
-
-		$prevIndex = array_search($entityID, $list, TRUE);
-		if ($prevIndex !== FALSE) {
-			unset($list[$prevIndex]);
-		}
-		$list[] = $entityID;
-
-		$this->setCDC($list);
-
-		return 'ok';
-	}
-
-
-	/**
-	 * Handle a delete request.
-	 *
-	 * @param array $request  The request.
-	 * @return array  The response.
-	 */
-	private function handleDelete(array $request) {
-		$params = array(
-			'path' => '/',
-			'domain' => '.' . $this->domain,
-			'secure' => TRUE,
-			'httponly' => FALSE,
-		);
-
-        \SimpleSAML\Utils\HTTP::setCookie('_saml_idp', NULL, $params, FALSE);
-		return 'ok';
-	}
-
-
-	/**
-	 * Handle a read request.
-	 *
-	 * @param array $request  The request.
-	 * @return array  The response.
-	 */
-	private function handleRead(array $request) {
-
-		$list = $this->getCDC();
-
-		return array(
-			'status' => 'ok',
-			'cdc' => $list,
-		);
-	}
-
-
-	/**
-	 * Helper function for parsing and validating a CDC message.
-	 *
-	 * @param string $parameter  The name of the query parameter.
-	 * @return array|NULL  The response, or NULL if no response is received.
-	 */
-	private static function get($parameter) {
-		assert(is_string($parameter));
-
-		if (!isset($_REQUEST[$parameter])) {
-			return NULL;
-		}
-		$message = (string)$_REQUEST[$parameter];
-
-		$message = @base64_decode($message);
-		if ($message === FALSE) {
-			throw new SimpleSAML_Error_BadRequest('Error base64-decoding CDC message.');
-		}
-
-		$message = @json_decode($message, TRUE);
-		if ($message === FALSE) {
-			throw new SimpleSAML_Error_BadRequest('Error json-decoding CDC message.');
-		}
-
-		if (!isset($message['timestamp'])) {
-			throw new SimpleSAML_Error_BadRequest('Missing timestamp in CDC message.');
-		}
-		$timestamp = (int)$message['timestamp'];
-
-		if ($timestamp + 60 < time()) {
-			throw new SimpleSAML_Error_BadRequest('CDC signature has expired.');
-		}
-		if ($timestamp - 60 > time()) {
-			throw new SimpleSAML_Error_BadRequest('CDC signature from the future.');
-		}
-
-		if (!isset($message['domain'])) {
-			throw new SimpleSAML_Error_BadRequest('Missing domain in CDC message.');
-		}
-
-		return $message;
-	}
-
-
-	/**
-	 * Helper function for validating the signature on a CDC message.
-	 *
-	 * Will throw an exception if the message is invalid.
-	 *
-	 * @param string $parameter  The name of the query parameter.
-	 */
-	private function validate($parameter) {
-		assert(is_string($parameter));
-		assert(isset($_REQUEST[$parameter]));
-
-		$message = (string)$_REQUEST[$parameter];
-
-		if (!isset($_REQUEST['Signature'])) {
-			throw new SimpleSAML_Error_BadRequest('Missing Signature on CDC message.');
-		}
-		$signature = (string)$_REQUEST['Signature'];
-
-		$cSignature = $this->calcSignature($message);
-		if ($signature !== $cSignature) {
-			throw new SimpleSAML_Error_BadRequest('Invalid signature on CDC message.');
-		}
-	}
-
-
-	/**
-	 * Helper function for sending CDC messages.
-	 *
-	 * @param string $to  The URL the message should be delivered to.
-	 * @param string $parameter  The query parameter the message should be sent in.
-	 * @param array $message  The CDC message.
-	 */
-	private function send($to, $parameter, array $message) {
-		assert(is_string($to));
-		assert(is_string($parameter));
-
-		$message['timestamp'] = time();
-		$message = json_encode($message);
-		$message = base64_encode($message);
-
-		$signature = $this->calcSignature($message);
-
-		$params = array(
-			$parameter => $message,
-			'Signature' => $signature,
-		);
-
-		$url = \SimpleSAML\Utils\HTTP::addURLParameters($to, $params);
-		if (strlen($url) < 2048) {
-			\SimpleSAML\Utils\HTTP::redirectTrustedURL($url);
-		} else {
-			\SimpleSAML\Utils\HTTP::submitPOSTData($to, $params);
-		}
-	}
-
-
-	/**
-	 * Calculate the signature on the given message.
-	 *
-	 * @param string $rawMessage  The base64-encoded message.
-	 * @return string  The signature.
-	 */
-	private function calcSignature($rawMessage) {
-		assert(is_string($rawMessage));
-
-		return sha1($this->key . $rawMessage . $this->key);
-	}
-
-
-	/**
-	 * Get the IdP entities saved in the common domain cookie.
-	 *
-	 * @return array  List of IdP entities.
-	 */
-	private function getCDC() {
-
-		if (!isset($_COOKIE['_saml_idp'])) {
-			return array();
-		}
-
-		$ret = (string)$_COOKIE['_saml_idp'];
-		$ret = explode(' ', $ret);
-		foreach ($ret as &$idp) {
-			$idp = base64_decode($idp);
-			if ($idp === FALSE) {
-				// Not properly base64 encoded
-				SimpleSAML\Logger::warning('CDC - Invalid base64-encoding of CDC entry.');
-				return array();
-			}
-		}
-
-		return $ret;
-	}
-
-
-	/**
-	 * Build a CDC cookie string.
-	 *
-	 * @param array $list  The list of IdPs.
-	 * @return string  The CDC cookie value.
-	 */
-	function setCDC(array $list) {
-
-		foreach ($list as &$value) {
-			$value = base64_encode($value);
-		}
-
-		$cookie = implode(' ', $list);
-
-		while (strlen($cookie) > 4000) {
-			// The cookie is too long. Remove the oldest elements until it is short enough
-			$tmp = explode(' ', $cookie, 2);
-			if (count($tmp) === 1) {
-				/*
-				 * We are left with a single entityID whose base64
-				 * representation is too long to fit in a cookie.
-				 */
-				break;
-			}
-			$cookie = $tmp[1];
-		}
-
-		$params = array(
-			'lifetime' => $this->cookieLifetime,
-			'path' => '/',
-			'domain' => '.' . $this->domain,
-			'secure' => TRUE,
-			'httponly' => FALSE,
-		);
-
-        \SimpleSAML\Utils\HTTP::setCookie('_saml_idp', $cookie, $params, FALSE);
-	}
 
+class Server
+{
+    /**
+     * The domain.
+     *
+     * @var string
+     */
+    private $domain;
+
+
+    /**
+     * The URL to the server.
+     *
+     * @var string
+     */
+    private $server;
+
+
+    /**
+     * Our shared key.
+     *
+     * @var string
+     */
+    private $key;
+
+
+    /**
+     * The lifetime of our cookie, in seconds.
+     *
+     * If this is 0, the cookie will expire when the browser is closed.
+     *
+     * @param int
+     */
+    private $cookieLifetime;
+
+
+    /**
+     * Initialize a CDC server.
+     *
+     * @param string $domain  The domain we are a server for.
+     */
+    public function __construct($domain)
+    {
+        assert(is_string($domain));
+
+        $cdcConfig = \SimpleSAML\Configuration::getConfig('module_cdc.php');
+        $config = $cdcConfig->getConfigItem($domain, null);
+
+        if ($config === null) {
+            throw new \SimpleSAML\Error\Exception('Unknown CDC domain: ' . var_export($domain, true));
+        }
+
+        $this->domain = $domain;
+        $this->server = $config->getString('server');
+        $this->key = $config->getString('key');
+        $this->cookieLifetime = $config->getInteger('cookie.lifetime', 0);
+
+        if ($this->key === 'ExampleSharedKey') {
+            throw new \SimpleSAML\Error\Exception('Key for CDC domain ' . var_export($domain, true) . ' not changed from default.');
+        }
+    }
+
+
+    /**
+     * Send a request to this CDC server.
+     *
+     * @param array $request  The CDC request.
+     */
+    public function sendRequest(array $request)
+    {
+        assert(isset($request['return']));
+        assert(isset($request['op']));
+
+        $request['domain'] = $this->domain;
+        $this->send($this->server, 'CDCRequest', $request);
+    }
+
+
+    /**
+     * Parse and validate response received from a CDC server.
+     *
+     * @return array|NULL  The response, or NULL if no response is received.
+     */
+    public function getResponse()
+    {
+        $response = self::get('CDCResponse');
+        if ($response === null) {
+            return null;
+        }
+
+        if ($response['domain'] !== $this->domain) {
+            throw new \SimpleSAML\Error\Exception('Response received from wrong domain.');
+        }
+
+        $this->validate('CDCResponse');
+
+        return $response;
+    }
+
+
+    /**
+     * Parse and process a CDC request.
+     */
+    public static function processRequest()
+    {
+        $request = self::get('CDCRequest');
+        if ($request === null) {
+            throw new \SimpleSAML\Error\BadRequest('Missing "CDCRequest" parameter.');
+        }
+
+        $domain = $request['domain'];
+        $server = new Server($domain);
+
+        $server->validate('CDCRequest');
+        $server->handleRequest($request);
+    }
+
+
+    /**
+     * Handle a parsed CDC requst.
+     *
+     * @param array $request
+     */
+    private function handleRequest(array $request)
+    {
+        if (!isset($request['op'])) {
+            throw new \SimpleSAML\Error\BadRequest('Missing "op" in CDC request.');
+        }
+        $op = (string)$request['op'];
+
+        \SimpleSAML\Logger::info('Received CDC request with "op": ' . var_export($op, true));
+
+        if (!isset($request['return'])) {
+            throw new \SimpleSAML\Error\BadRequest('Missing "return" in CDC request.');
+        }
+        $return = (string)$request['return'];
+
+        switch ($op) {
+            case 'append':
+                $response = $this->handleAppend($request);
+                break;
+            case 'delete':
+                $response = $this->handleDelete($request);
+                break;
+            case 'read':
+                $response = $this->handleRead($request);
+                break;
+            default:
+                $response = 'unknown-op';
+        }
+
+        if (is_string($response)) {
+            $response = array(
+                'status' => $response,
+            );
+        }
+
+        $response['op'] = $op;
+        if (isset($request['id'])) {
+            $response['id'] = (string)$request['id'];
+        }
+        $response['domain'] = $this->domain;
+
+        $this->send($return, 'CDCResponse', $response);
+    }
+
+
+    /**
+     * Handle an append request.
+     *
+     * @param array $request  The request.
+     * @return array  The response.
+     */
+    private function handleAppend(array $request)
+    {
+        if (!isset($request['entityID'])) {
+            throw new \SimpleSAML\Error\BadRequest('Missing entityID in append request.');
+        }
+        $entityID = (string)$request['entityID'];
+
+        $list = $this->getCDC();
+
+        $prevIndex = array_search($entityID, $list, true);
+        if ($prevIndex !== false) {
+            unset($list[$prevIndex]);
+        }
+        $list[] = $entityID;
+
+        $this->setCDC($list);
+
+        return 'ok';
+    }
+
+
+    /**
+     * Handle a delete request.
+     *
+     * @param array $request  The request.
+     * @return array  The response.
+     */
+    private function handleDelete(array $request)
+    {
+        $params = array(
+            'path' => '/',
+            'domain' => '.' . $this->domain,
+            'secure' => true,
+            'httponly' => false,
+        );
+
+        \SimpleSAML\Utils\HTTP::setCookie('_saml_idp', null, $params, false);
+        return 'ok';
+    }
+
+
+    /**
+     * Handle a read request.
+     *
+     * @param array $request  The request.
+     * @return array  The response.
+     */
+    private function handleRead(array $request)
+    {
+        $list = $this->getCDC();
+
+        return array(
+            'status' => 'ok',
+            'cdc' => $list,
+        );
+    }
+
+
+    /**
+     * Helper function for parsing and validating a CDC message.
+     *
+     * @param string $parameter  The name of the query parameter.
+     * @return array|NULL  The response, or NULL if no response is received.
+     */
+    private static function get($parameter)
+    {
+        assert(is_string($parameter));
+
+        if (!isset($_REQUEST[$parameter])) {
+            return null;
+        }
+        $message = (string)$_REQUEST[$parameter];
+
+        $message = @base64_decode($message);
+        if ($message === false) {
+            throw new \SimpleSAML\Error\BadRequest('Error base64-decoding CDC message.');
+        }
+
+        $message = @json_decode($message, true);
+        if ($message === false) {
+            throw new \SimpleSAML\Error\BadRequest('Error json-decoding CDC message.');
+        }
+
+        if (!isset($message['timestamp'])) {
+            throw new \SimpleSAML\Error\BadRequest('Missing timestamp in CDC message.');
+        }
+        $timestamp = (int)$message['timestamp'];
+
+        if ($timestamp + 60 < time()) {
+            throw new \SimpleSAML\Error\BadRequest('CDC signature has expired.');
+        }
+        if ($timestamp - 60 > time()) {
+            throw new \SimpleSAML\Error\BadRequest('CDC signature from the future.');
+        }
+
+        if (!isset($message['domain'])) {
+            throw new \SimpleSAML\Error\BadRequest('Missing domain in CDC message.');
+        }
+
+        return $message;
+    }
+
+
+    /**
+     * Helper function for validating the signature on a CDC message.
+     *
+     * Will throw an exception if the message is invalid.
+     *
+     * @param string $parameter  The name of the query parameter.
+     */
+    private function validate($parameter)
+    {
+        assert(is_string($parameter));
+        assert(isset($_REQUEST[$parameter]));
+
+        $message = (string)$_REQUEST[$parameter];
+
+        if (!isset($_REQUEST['Signature'])) {
+            throw new \SimpleSAML\Error\BadRequest('Missing Signature on CDC message.');
+        }
+        $signature = (string)$_REQUEST['Signature'];
+
+        $cSignature = $this->calcSignature($message);
+        if ($signature !== $cSignature) {
+            throw new \SimpleSAML\Error\BadRequest('Invalid signature on CDC message.');
+        }
+    }
+
+
+    /**
+     * Helper function for sending CDC messages.
+     *
+     * @param string $to  The URL the message should be delivered to.
+     * @param string $parameter  The query parameter the message should be sent in.
+     * @param array $message  The CDC message.
+     */
+    private function send($to, $parameter, array $message)
+    {
+        assert(is_string($to));
+        assert(is_string($parameter));
+
+        $message['timestamp'] = time();
+        $message = json_encode($message);
+        $message = base64_encode($message);
+
+        $signature = $this->calcSignature($message);
+
+        $params = array(
+            $parameter => $message,
+            'Signature' => $signature,
+        );
+
+        $url = \SimpleSAML\Utils\HTTP::addURLParameters($to, $params);
+        if (strlen($url) < 2048) {
+            \SimpleSAML\Utils\HTTP::redirectTrustedURL($url);
+        } else {
+            \SimpleSAML\Utils\HTTP::submitPOSTData($to, $params);
+        }
+    }
+
+
+    /**
+     * Calculate the signature on the given message.
+     *
+     * @param string $rawMessage  The base64-encoded message.
+     * @return string  The signature.
+     */
+    private function calcSignature($rawMessage)
+    {
+        assert(is_string($rawMessage));
+
+        return sha1($this->key . $rawMessage . $this->key);
+    }
+
+
+    /**
+     * Get the IdP entities saved in the common domain cookie.
+     *
+     * @return array  List of IdP entities.
+     */
+    private function getCDC()
+    {
+        if (!isset($_COOKIE['_saml_idp'])) {
+            return array();
+        }
+
+        $ret = (string)$_COOKIE['_saml_idp'];
+        $ret = explode(' ', $ret);
+        foreach ($ret as &$idp) {
+            $idp = base64_decode($idp);
+            if ($idp === false) {
+                // Not properly base64 encoded
+                \SimpleSAML\Logger::warning('CDC - Invalid base64-encoding of CDC entry.');
+                return array();
+            }
+        }
+
+        return $ret;
+    }
+
+
+    /**
+     * Build a CDC cookie string.
+     *
+     * @param array $list  The list of IdPs.
+     * @return string  The CDC cookie value.
+     */
+    private function setCDC(array $list)
+    {
+        foreach ($list as &$value) {
+            $value = base64_encode($value);
+        }
+
+        $cookie = implode(' ', $list);
+
+        while (strlen($cookie) > 4000) {
+            // The cookie is too long. Remove the oldest elements until it is short enough
+            $tmp = explode(' ', $cookie, 2);
+            if (count($tmp) === 1) {
+                /*
+                 * We are left with a single entityID whose base64
+                 * representation is too long to fit in a cookie.
+                 */
+                break;
+            }
+            $cookie = $tmp[1];
+        }
+
+        $params = array(
+            'lifetime' => $this->cookieLifetime,
+            'path' => '/',
+            'domain' => '.' . $this->domain,
+            'secure' => true,
+            'httponly' => false,
+        );
+
+        \SimpleSAML\Utils\HTTP::setCookie('_saml_idp', $cookie, $params, false);
+    }
 }
diff --git a/modules/cdc/www/resume.php b/modules/cdc/www/resume.php
index a7f821998c953ff4a290315cf839a8d2a03dd815..1e6f7910368478115c541e5f1c8ad3871e642c70 100644
--- a/modules/cdc/www/resume.php
+++ b/modules/cdc/www/resume.php
@@ -2,20 +2,20 @@
 
 
 if (!array_key_exists('domain', $_REQUEST)) {
-	throw new SimpleSAML_Error_BadRequest('Missing domain to CDC resume handler.');
+    throw new \SimpleSAML\Error\BadRequest('Missing domain to CDC resume handler.');
 }
 
 $domain = (string)$_REQUEST['domain'];
-$client = new sspmod_cdc_Client($domain);
+$client = new \SimpleSAML\Module\cdc\Client($domain);
 
 $response = $client->getResponse();
-if ($response === NULL) {
-	throw new SimpleSAML_Error_BadRequest('Missing CDC response to CDC resume handler.');
+if ($response === null) {
+    throw new \SimpleSAML\Error\BadRequest('Missing CDC response to CDC resume handler.');
 }
 
 if (!isset($response['id'])) {
-	throw new SimpleSAML_Error_BadRequest('CDCResponse without id.');
+    throw new \SimpleSAML\Error\BadRequest('CDCResponse without id.');
 }
-$state = SimpleSAML_Auth_State::loadState($response['id'], 'cdc:resume');
+$state = \SimpleSAML\Auth\State::loadState($response['id'], 'cdc:resume');
 
-SimpleSAML_Auth_ProcessingChain::resumeProcessing($state);
+\SimpleSAML\Auth\ProcessingChain::resumeProcessing($state);
diff --git a/modules/cdc/www/server.php b/modules/cdc/www/server.php
index f84b7a90614528eecf3b4f97930d8ceadc8011a1..d5cfd16ece5aecda1184fdb626e824ca56e2d6a3 100644
--- a/modules/cdc/www/server.php
+++ b/modules/cdc/www/server.php
@@ -1,3 +1,3 @@
 <?php
 
-sspmod_cdc_Server::processRequest();
\ No newline at end of file
+\SimpleSAML\Module\cdc\Server::processRequest();
diff --git a/modules/consent/docs/consent.md b/modules/consent/docs/consent.md
index c2632a28c0f9a6f876db8bf958a20f3b1d51458d..5959a3a36b7eb4c913657d9df9c963c476fac58d 100644
--- a/modules/consent/docs/consent.md
+++ b/modules/consent/docs/consent.md
@@ -72,8 +72,8 @@ database.
 Here is the initialization SQL script:
 
 	CREATE TABLE consent (
-		consent_date TIMESTAMP NOT NULL,
-		usage_date TIMESTAMP NOT NULL,
+		consent_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+		usage_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
 		hashed_user_id VARCHAR(80) NOT NULL,
 		service_id VARCHAR(255) NOT NULL,
 		attribute VARCHAR(80) NOT NULL,
@@ -149,7 +149,7 @@ The following options can be used when configuring the Consent module:
 `store`
 :   Configuration of the Consent storage backend. The store option is given in 
     the format <module>:<class> and refers to the class 
-    sspmod_<module>_Consent_Store_<class>. The consent module comes with two 
+    \SimpleSAML\Module\<module>\Consent\Store\<class>. The consent module comes with two 
     built in storage backends: 'consent:Cookie' and 'consent:Database'. See 
     the separate section on setting up consent using different storage methods. 
     This option is optional. If the option is not set, then the user is asked to 
@@ -160,9 +160,15 @@ The following options can be used when configuring the Consent module:
     the attributes that should have their value hidden. Default behaviour is that 
     all attribute values are shown.
 
+`attributes.exclude`
+:   Allows certain attributes to be excluded from the attribute hash when
+    `includeValues` is `true` (and as a side effect, to be hidden from display
+    as `hiddenAttributes` does). Set to an array of the attributes that should
+    be excluded. Default behaviour is to include all values in the hash.
+
 `showNoConsentAboutService`
 :   Whether we will show a link to more information about the service from the
-    no consent page. Defaults to `TRUE`.
+    no consent page. Defaults to `true`.
 
 External options
 ----------------
diff --git a/modules/consent/lib/Auth/Process/Consent.php b/modules/consent/lib/Auth/Process/Consent.php
index a904590bb2442390824e404357c13982a6cb1fe1..e2744aab1d370ed5a3339c842539ea77d9773c8a 100644
--- a/modules/consent/lib/Auth/Process/Consent.php
+++ b/modules/consent/lib/Auth/Process/Consent.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML\Module\consent\Auth\Process;
 
 /**
  * Consent Authentication Processing filter
@@ -9,7 +10,13 @@
  *
  * @package SimpleSAMLphp
  */
-class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilter
+
+use SimpleSAML\Logger;
+use SimpleSAML\Module;
+use SimpleSAML\Stats;
+use SimpleSAML\Utils;
+
+class Consent extends \SimpleSAML\Auth\ProcessingFilter
 {
     /**
      * Button to receive focus
@@ -35,7 +42,7 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
     /**
      * Consent backend storage configuration
      *
-     * @var array
+     * @var \SimpleSAML\Module\consent\Store|null
      */
     private $_store = null;
 
@@ -49,7 +56,7 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
     /**
      * Attributes which should not require consent
      *
-     * @var aray
+     * @var array
      */
     private $_noconsentattributes = array();
 
@@ -69,7 +76,7 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
      * @param array $config Configuration information.
      * @param mixed $reserved For future use.
      *
-     * @throws SimpleSAML_Error_Exception if the configuration is not valid.
+     * @throws \SimpleSAML\Error\Exception if the configuration is not valid.
      */
     public function __construct($config, $reserved)
     {
@@ -78,7 +85,7 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
 
         if (array_key_exists('includeValues', $config)) {
             if (!is_bool($config['includeValues'])) {
-                throw new SimpleSAML_Error_Exception(
+                throw new \SimpleSAML\Error\Exception(
                     'Consent: includeValues must be boolean. '.
                     var_export($config['includeValues'], true).' given.'
                 );
@@ -88,7 +95,7 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
 
         if (array_key_exists('checked', $config)) {
             if (!is_bool($config['checked'])) {
-                throw new SimpleSAML_Error_Exception(
+                throw new \SimpleSAML\Error\Exception(
                     'Consent: checked must be boolean. '.
                     var_export($config['checked'], true).' given.'
                 );
@@ -98,7 +105,7 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
 
         if (array_key_exists('focus', $config)) {
             if (!in_array($config['focus'], array('yes', 'no'), true)) {
-                throw new SimpleSAML_Error_Exception(
+                throw new \SimpleSAML\Error\Exception(
                     'Consent: focus must be a string with values `yes` or `no`. '.
                     var_export($config['focus'], true).' given.'
                 );
@@ -108,7 +115,7 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
 
         if (array_key_exists('hiddenAttributes', $config)) {
             if (!is_array($config['hiddenAttributes'])) {
-                throw new SimpleSAML_Error_Exception(
+                throw new \SimpleSAML\Error\Exception(
                     'Consent: hiddenAttributes must be an array. '.
                     var_export($config['hiddenAttributes'], true).' given.'
                 );
@@ -116,9 +123,18 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
             $this->_hiddenAttributes = $config['hiddenAttributes'];
         }
 
-        if (array_key_exists('noconsentattributes', $config)) {
+        if (array_key_exists('attributes.exclude', $config)) {
+            if (!is_array($config['attributes.exclude'])) {
+                throw new \SimpleSAML\Error\Exception(
+                    'Consent: attributes.exclude must be an array. '.
+                    var_export($config['attributes.exclude'], true).' given.'
+                );
+            }
+            $this->_noconsentattributes = $config['attributes.exclude'];
+        } elseif (array_key_exists('noconsentattributes', $config)) {
+            Logger::warning("The 'noconsentattributes' option has been deprecated in favour of 'attributes.exclude'.");
             if (!is_array($config['noconsentattributes'])) {
-                throw new SimpleSAML_Error_Exception(
+                throw new \SimpleSAML\Error\Exception(
                     'Consent: noconsentattributes must be an array. '.
                     var_export($config['noconsentattributes'], true).' given.'
                 );
@@ -128,9 +144,9 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
 
         if (array_key_exists('store', $config)) {
             try {
-                $this->_store = sspmod_consent_Store::parseStoreConfig($config['store']);
-            } catch (Exception $e) {
-                SimpleSAML\Logger::error(
+                $this->_store = \SimpleSAML\Module\consent\Store::parseStoreConfig($config['store']);
+            } catch (\Exception $e) {
+                Logger::error(
                     'Consent: Could not create consent storage: '.
                     $e->getMessage()
                 );
@@ -139,7 +155,7 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
 
         if (array_key_exists('showNoConsentAboutService', $config)) {
             if (!is_bool($config['showNoConsentAboutService'])) {
-                throw new SimpleSAML_Error_Exception('Consent: showNoConsentAboutService must be a boolean.');
+                throw new \SimpleSAML\Error\Exception('Consent: showNoConsentAboutService must be a boolean.');
             }
             $this->_showNoConsentAboutService = $config['showNoConsentAboutService'];
         }
@@ -213,7 +229,7 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
      *
      * @return void
      *
-     * @throws SimpleSAML_Error_NoPassive if the request was passive and consent is needed.
+     * @throws \SimpleSAML\Error\NoPassive if the request was passive and consent is needed.
      */
     public function process(&$state)
     {
@@ -228,7 +244,7 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
         $spEntityId = $state['Destination']['entityid'];
         $idpEntityId = $state['Source']['entityid'];
 
-        $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+        $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 
         /**
          * If the consent module is active on a bridge $state['saml:sp:IdP']
@@ -248,15 +264,15 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
         if (isset($state['Source']['consent.disable']) &&
             self::checkDisable($state['Source']['consent.disable'], $spEntityId)
         ) {
-            SimpleSAML\Logger::debug('Consent: Consent disabled for entity '.$spEntityId.' with IdP '.$idpEntityId);
-            SimpleSAML_Stats::log('consent:disabled', $statsData);
+            Logger::debug('Consent: Consent disabled for entity '.$spEntityId.' with IdP '.$idpEntityId);
+            Stats::log('consent:disabled', $statsData);
             return;
         }
         if (isset($state['Destination']['consent.disable']) &&
             self::checkDisable($state['Destination']['consent.disable'], $idpEntityId)
         ) {
-            SimpleSAML\Logger::debug('Consent: Consent disabled for entity '.$spEntityId.' with IdP '.$idpEntityId);
-            SimpleSAML_Stats::log('consent:disabled', $statsData);
+            Logger::debug('Consent: Consent disabled for entity '.$spEntityId.' with IdP '.$idpEntityId);
+            Stats::log('consent:disabled', $statsData);
             return;
         }
 
@@ -272,15 +288,15 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
                 }
             }
 
-            SimpleSAML\Logger::debug('Consent: userid: '.$state['UserID']);
-            SimpleSAML\Logger::debug('Consent: source: '.$source);
-            SimpleSAML\Logger::debug('Consent: destination: '.$destination);
+            Logger::debug('Consent: userid: '.$state['UserID']);
+            Logger::debug('Consent: source: '.$source);
+            Logger::debug('Consent: destination: '.$destination);
 
             $userId = self::getHashedUserID($state['UserID'], $source);
             $targetedId = self::getTargetedID($state['UserID'], $source, $destination);
             $attributeSet = self::getAttributeHash($attributes, $this->_includeValues);
 
-            SimpleSAML\Logger::debug(
+            Logger::debug(
                 'Consent: hasConsent() ['.$userId.'|'.$targetedId.'|'.
                 $attributeSet.']'
             );
@@ -288,26 +304,26 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
             try {
                 if ($this->_store->hasConsent($userId, $targetedId, $attributeSet)) {
                     // Consent already given
-                    SimpleSAML\Logger::stats('Consent: Consent found');
-                    SimpleSAML_Stats::log('consent:found', $statsData);
+                    Logger::stats('consent found');
+                    Stats::log('consent:found', $statsData);
                     return;
                 }
 
-                SimpleSAML\Logger::stats('Consent: Consent notfound');
-                SimpleSAML_Stats::log('consent:notfound', $statsData);
+                Logger::stats('consent notfound');
+                Stats::log('consent:notfound', $statsData);
 
                 $state['consent:store'] = $this->_store;
                 $state['consent:store.userId'] = $userId;
                 $state['consent:store.destination'] = $targetedId;
                 $state['consent:store.attributeSet'] = $attributeSet;
-            } catch (Exception $e) {
-                SimpleSAML\Logger::error('Consent: Error reading from storage: '.$e->getMessage());
-                SimpleSAML\Logger::stats('Consent: Failed');
-                SimpleSAML_Stats::log('consent:failed', $statsData);
+            } catch (\Exception $e) {
+                Logger::error('Consent: Error reading from storage: '.$e->getMessage());
+                Logger::stats('Ccnsent failed');
+                Stats::log('consent:failed', $statsData);
             }
         } else {
-            SimpleSAML\Logger::stats('Consent: No storage');
-            SimpleSAML_Stats::log('consent:nostorage', $statsData);
+            Logger::stats('consent nostorage');
+            Stats::log('consent:nostorage', $statsData);
         }
 
         $state['consent:focus'] = $this->_focus;
@@ -318,14 +334,17 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
 
         // user interaction necessary. Throw exception on isPassive request
         if (isset($state['isPassive']) && $state['isPassive'] === true) {
-            SimpleSAML_Stats::log('consent:nopassive', $statsData);
-            throw new SimpleSAML_Error_NoPassive('Unable to give consent on passive request.');
+            Stats::log('consent:nopassive', $statsData);
+            throw new Module\saml\Error\NoPassive(
+                    \SAML2\Constants::STATUS_REQUESTER,
+                    'Unable to give consent on passive request.'
+            );
         }
 
         // Save state and redirect
-        $id = SimpleSAML_Auth_State::saveState($state, 'consent:request');
-        $url = SimpleSAML\Module::getModuleURL('consent/getconsent.php');
-        \SimpleSAML\Utils\HTTP::redirectTrustedURL($url, array('StateId' => $id));
+        $id = \SimpleSAML\Auth\State::saveState($state, 'consent:request');
+        $url = Module::getModuleURL('consent/getconsent.php');
+        Utils\HTTP::redirectTrustedURL($url, array('StateId' => $id));
     }
 
 
@@ -339,7 +358,7 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
      */
     public static function getHashedUserID($userid, $source)
     {
-        return hash('sha1', $userid.'|'.SimpleSAML\Utils\Config::getSecretSalt().'|'.$source);
+        return hash('sha1', $userid.'|'.Utils\Config::getSecretSalt().'|'.$source);
     }
 
 
@@ -354,7 +373,7 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
      */
     public static function getTargetedID($userid, $source, $destination)
     {
-        return hash('sha1', $userid.'|'.SimpleSAML\Utils\Config::getSecretSalt().'|'.$source.'|'.$destination);
+        return hash('sha1', $userid.'|'.Utils\Config::getSecretSalt().'|'.$source.'|'.$destination);
     }
 
 
@@ -371,8 +390,10 @@ class sspmod_consent_Auth_Process_Consent extends SimpleSAML_Auth_ProcessingFilt
      */
     public static function getAttributeHash($attributes, $includeValues = false)
     {
-        $hashBase = null;
         if ($includeValues) {
+            foreach ($attributes as &$values) {
+                sort($values);
+            }
             ksort($attributes);
             $hashBase = serialize($attributes);
         } else {
diff --git a/modules/consent/lib/Consent/Store/Cookie.php b/modules/consent/lib/Consent/Store/Cookie.php
index d9b9d0a133db9eedefdc74e9f257e36b8fd967fe..ad448c799149215068942357ae4ed119ce0589af 100644
--- a/modules/consent/lib/Consent/Store/Cookie.php
+++ b/modules/consent/lib/Consent/Store/Cookie.php
@@ -1,4 +1,7 @@
 <?php
+
+namespace SimpleSAML\Module\consent\Consent\Store;
+
 /**
  * Cookie storage for consent
  *
@@ -18,7 +21,8 @@
  * @author  Olav Morken <olav.morken@uninett.no>
  * @package SimpleSAMLphp
  */
-class sspmod_consent_Consent_Store_Cookie extends sspmod_consent_Store
+
+class Cookie extends \SimpleSAML\Module\consent\Store
 {
     /**
      * Check for consent.
@@ -42,17 +46,17 @@ class sspmod_consent_Consent_Store_Cookie extends sspmod_consent_Store
 
         $data = $userId . ':' . $attributeSet . ':' . $destinationId;
 
-        SimpleSAML\Logger::debug('Consent cookie - Get [' . $data . ']');
+        \SimpleSAML\Logger::debug('Consent cookie - Get [' . $data . ']');
 
         if (!array_key_exists($cookieName, $_COOKIE)) {
-            SimpleSAML\Logger::debug(
+            \SimpleSAML\Logger::debug(
                 'Consent cookie - no cookie with name \'' .
                 $cookieName . '\'.'
             );
             return false;
         }
         if (!is_string($_COOKIE[$cookieName])) {
-            SimpleSAML\Logger::warning(
+            \SimpleSAML\Logger::warning(
                 'Value of consent cookie wasn\'t a string. Was: ' .
                 var_export($_COOKIE[$cookieName], true)
             );
@@ -62,13 +66,13 @@ class sspmod_consent_Consent_Store_Cookie extends sspmod_consent_Store
         $data = self::_sign($data);
 
         if ($_COOKIE[$cookieName] !== $data) {
-            SimpleSAML\Logger::info(
+            \SimpleSAML\Logger::info(
                 'Attribute set changed from the last time consent was given.'
             );
             return false;
         }
 
-        SimpleSAML\Logger::debug(
+        \SimpleSAML\Logger::debug(
             'Consent cookie - found cookie with correct name and value.'
         );
 
@@ -97,7 +101,7 @@ class sspmod_consent_Consent_Store_Cookie extends sspmod_consent_Store
         $name = self::_getCookieName($userId, $destinationId);
         $value = $userId . ':' . $attributeSet . ':' . $destinationId;
 
-        SimpleSAML\Logger::debug('Consent cookie - Set [' . $value . ']');
+        \SimpleSAML\Logger::debug('Consent cookie - Set [' . $value . ']');
 
         $value = self::_sign($value);
         $this->_setConsentCookie($name, $value);
@@ -131,14 +135,14 @@ class sspmod_consent_Consent_Store_Cookie extends sspmod_consent_Store
      *
      * @return void This method does not return.
      *
-     * @throws Exception This method always throws an exception indicating that it is not possible to delete all given
+     * @throws \Exception This method always throws an exception indicating that it is not possible to delete all given
      * consents with this handler.
      */
     public function deleteAllConsents($userId)
     {
         assert(is_string($userId));
 
-        throw new Exception(
+        throw new \Exception(
             'The cookie consent handler does not support delete of all consents...'
         );
     }
@@ -159,7 +163,7 @@ class sspmod_consent_Consent_Store_Cookie extends sspmod_consent_Store
 
         $ret = array();
 
-        $cookieNameStart = 'sspmod_consent:';
+        $cookieNameStart = '\SimpleSAML\Module\consent:';
         $cookieNameStartLen = strlen($cookieNameStart);
         foreach ($_COOKIE as $name => $value) {
             if (substr($name, 0, $cookieNameStartLen) !== $cookieNameStart) {
@@ -173,7 +177,7 @@ class sspmod_consent_Consent_Store_Cookie extends sspmod_consent_Store
 
             $tmp = explode(':', $value, 3);
             if (count($tmp) !== 3) {
-                SimpleSAML\Logger::warning(
+                \SimpleSAML\Logger::warning(
                     'Consent cookie with invalid value: ' . $value
                 );
                 continue;
@@ -205,7 +209,7 @@ class sspmod_consent_Consent_Store_Cookie extends sspmod_consent_Store
     {
         assert(is_string($data));
 
-        $secretSalt = SimpleSAML\Utils\Config::getSecretSalt();
+        $secretSalt = \SimpleSAML\Utils\Config::getSecretSalt();
 
         return sha1($secretSalt . $data . $secretSalt) . ':' . $data;
     }
@@ -226,14 +230,14 @@ class sspmod_consent_Consent_Store_Cookie extends sspmod_consent_Store
 
         $data = explode(':', $signedData, 2);
         if (count($data) !== 2) {
-            SimpleSAML\Logger::warning('Consent cookie: Missing signature.');
+            \SimpleSAML\Logger::warning('Consent cookie: Missing signature.');
             return false;
         }
         $data = $data[1];
 
         $newSignedData = self::_sign($data);
         if ($newSignedData !== $signedData) {
-            SimpleSAML\Logger::warning('Consent cookie: Invalid signature.');
+            \SimpleSAML\Logger::warning('Consent cookie: Invalid signature.');
             return false;
         }
 
@@ -256,7 +260,7 @@ class sspmod_consent_Consent_Store_Cookie extends sspmod_consent_Store
         assert(is_string($userId));
         assert(is_string($destinationId));
 
-        return 'sspmod_consent:' . sha1($userId . ':' . $destinationId);
+        return '\SimpleSAML\Module\consent:' . sha1($userId . ':' . $destinationId);
     }
 
 
@@ -273,7 +277,7 @@ class sspmod_consent_Consent_Store_Cookie extends sspmod_consent_Store
         assert(is_string($name));
         assert(is_string($value) || $value === null);
 
-        $globalConfig = SimpleSAML_Configuration::getInstance();
+        $globalConfig = \SimpleSAML\Configuration::getInstance();
         $params = array(
             'lifetime' => 7776000,    // (90*24*60*60)
             'path' => ($globalConfig->getBasePath()),
diff --git a/modules/consent/lib/Consent/Store/Database.php b/modules/consent/lib/Consent/Store/Database.php
index 3eb3577a4f33d30cdbec9cf8f5f85c25d78a4c1a..739edcff375dfbe327c42ca38bc1d28926fca79c 100644
--- a/modules/consent/lib/Consent/Store/Database.php
+++ b/modules/consent/lib/Consent/Store/Database.php
@@ -1,4 +1,7 @@
 <?php
+
+namespace SimpleSAML\Module\consent\Consent\Store;
+
 /**
  * Store consent in database.
  *
@@ -15,7 +18,8 @@
  * @author Olav Morken <olav.morken@uninett.no>
  * @package SimpleSAMLphp
  */
-class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
+
+class Database extends \SimpleSAML\Module\consent\Store
 {
     /**
      * DSN for the database.
@@ -37,6 +41,11 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
      */
     private $_password;
 
+    /**
+     * Options for the database;
+     */
+    private $_options;
+
     /**
      * Table with consent.
      */
@@ -45,7 +54,7 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
     /**
      * The timeout of the database connection.
      *
-     * @var int|NULL
+     * @var int|null
      */
     private $_timeout = null;
 
@@ -64,18 +73,17 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
      *
      * @param array $config Configuration for database consent store.
      *
-     * @throws Exception in case of a configuration error.
+     * @throws \Exception in case of a configuration error.
      */
     public function __construct($config)
     {
         parent::__construct($config);
 
-
         if (!array_key_exists('dsn', $config)) {
-            throw new Exception('consent:Database - Missing required option \'dsn\'.');
+            throw new \Exception('consent:Database - Missing required option \'dsn\'.');
         }
         if (!is_string($config['dsn'])) {
-            throw new Exception('consent:Database - \'dsn\' is supposed to be a string.');
+            throw new \Exception('consent:Database - \'dsn\' is supposed to be a string.');
         }
 
         $this->_dsn = $config['dsn'];
@@ -83,7 +91,7 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
 
         if (array_key_exists('username', $config)) {
             if (!is_string($config['username'])) {
-                throw new Exception('consent:Database - \'username\' is supposed to be a string.');
+                throw new \Exception('consent:Database - \'username\' is supposed to be a string.');
             }
             $this->_username = $config['username'];
         } else {
@@ -92,16 +100,24 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
 
         if (array_key_exists('password', $config)) {
             if (!is_string($config['password'])) {
-                throw new Exception('consent:Database - \'password\' is supposed to be a string.');
+                throw new \Exception('consent:Database - \'password\' is supposed to be a string.');
             }
             $this->_password = $config['password'];
         } else {
             $this->_password = null;
         }
 
+        if (array_key_exists('options', $config)) {
+            if (!is_array($config['options'])) {
+                throw new \Exception('consent:Database - \'options\' is supposed to be an array.');
+            }
+            $this->_options = $config['options'];
+        } else {
+            $this->_options = null;
+        }
         if (array_key_exists('table', $config)) {
             if (!is_string($config['table'])) {
-                throw new Exception('consent:Database - \'table\' is supposed to be a string.');
+                throw new \Exception('consent:Database - \'table\' is supposed to be a string.');
             }
             $this->_table = $config['table'];
         } else {
@@ -110,7 +126,7 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
 
         if (isset($config['timeout'])) {
             if (!is_int($config['timeout'])) {
-                throw new Exception('consent:Database - \'timeout\' is supposed to be an integer.');
+                throw new \Exception('consent:Database - \'timeout\' is supposed to be an integer.');
             }
             $this->_timeout = $config['timeout'];
         }
@@ -167,10 +183,10 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
 
         $rowCount = $st->rowCount();
         if ($rowCount === 0) {
-            SimpleSAML\Logger::debug('consent:Database - No consent found.');
+            \SimpleSAML\Logger::debug('consent:Database - No consent found.');
             return false;
         } else {
-            SimpleSAML\Logger::debug('consent:Database - Consent found.');
+            \SimpleSAML\Logger::debug('consent:Database - Consent found.');
             return true;
         }
     }
@@ -208,7 +224,7 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
 
         if ($st->rowCount() > 0) {
             // Consent has already been stored in the database
-            SimpleSAML\Logger::debug('consent:Database - Updated old consent.');
+            \SimpleSAML\Logger::debug('consent:Database - Updated old consent.');
             return;
         }
 
@@ -220,7 +236,7 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
         );
 
         if ($st !== false) {
-            SimpleSAML\Logger::debug('consent:Database - Saved new consent.');
+            \SimpleSAML\Logger::debug('consent:Database - Saved new consent.');
         }
         return true;
     }
@@ -251,10 +267,10 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
         }
 
         if ($st->rowCount() > 0) {
-            SimpleSAML\Logger::debug('consent:Database - Deleted consent.');
+            \SimpleSAML\Logger::debug('consent:Database - Deleted consent.');
             return $st->rowCount();
         } else {
-            SimpleSAML\Logger::warning(
+            \SimpleSAML\Logger::warning(
                 'consent:Database - Attempted to delete nonexistent consent'
             );
         }
@@ -282,10 +298,10 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
         }
 
         if ($st->rowCount() > 0) {
-            SimpleSAML\Logger::debug('consent:Database - Deleted (' . $st->rowCount() . ') consent(s).');
+            \SimpleSAML\Logger::debug('consent:Database - Deleted (' . $st->rowCount() . ') consent(s).');
             return $st->rowCount();
         } else {
-            SimpleSAML\Logger::warning('consent:Database - Attempted to delete nonexistent consent');
+            \SimpleSAML\Logger::warning('consent:Database - Attempted to delete nonexistent consent');
         }
     }
 
@@ -315,7 +331,7 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
             return array();
         }
 
-        while ($row = $st->fetch(PDO::FETCH_NUM)) {
+        while ($row = $st->fetch(\PDO::FETCH_NUM)) {
             $ret[] = $row;
         }
 
@@ -332,7 +348,7 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
      * @param string $statement  The statement which should be executed.
      * @param array  $parameters Parameters for the statement.
      *
-     * @return PDOStatement|false  The statement, or false if execution failed.
+     * @return \PDOStatement|false  The statement, or false if execution failed.
      */
     private function _execute($statement, $parameters)
     {
@@ -346,7 +362,7 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
 
         $st = $db->prepare($statement);
         if ($st === false) {
-            SimpleSAML\Logger::error(
+            \SimpleSAML\Logger::error(
                 'consent:Database - Error preparing statement \'' .
                 $statement . '\': ' . self::_formatError($db->errorInfo())
             );
@@ -354,7 +370,7 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
         }
 
         if ($st->execute($parameters) !== true) {
-            SimpleSAML\Logger::error(
+            \SimpleSAML\Logger::error(
                 'consent:Database - Error executing statement \'' .
                 $statement . '\': ' . self::_formatError($st->errorInfo())
             );
@@ -374,49 +390,48 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
      * ' services: Total number of services that has been given consent to
      *
      * @return array Array containing the statistics
-     * @TODO Change fixed table name to config option
      */
     public function getStatistics()
     {
         $ret = array();
 
         // Get total number of consents
-        $st = $this->_execute('SELECT COUNT(*) AS no FROM consent', array());
-        
+        $st = $this->_execute('SELECT COUNT(*) AS no FROM '.$this->_table, array());
+
         if ($st === false) {
             return array();
         }
 
-        if ($row = $st->fetch(PDO::FETCH_NUM)) {
+        if ($row = $st->fetch(\PDO::FETCH_NUM)) {
             $ret['total'] = $row[0];
         }
 
         // Get total number of users that has given consent
         $st = $this->_execute(
             'SELECT COUNT(*) AS no ' .
-            'FROM (SELECT DISTINCT hashed_user_id FROM consent ) AS foo',
+            'FROM (SELECT DISTINCT hashed_user_id FROM '.$this->_table.' ) AS foo',
             array()
         );
-        
+
         if ($st === false) {
             return array();
         }
 
-        if ($row = $st->fetch(PDO::FETCH_NUM)) {
+        if ($row = $st->fetch(\PDO::FETCH_NUM)) {
             $ret['users'] = $row[0];
         }
 
         // Get total number of services that has been given consent to
         $st = $this->_execute(
-            'SELECT COUNT(*) AS no FROM (SELECT DISTINCT service_id FROM consent) AS foo',
+            'SELECT COUNT(*) AS no FROM (SELECT DISTINCT service_id FROM '.$this->_table.') AS foo',
             array()
         );
-        
+
         if ($st === false) {
             return array();
         }
 
-        if ($row = $st->fetch(PDO::FETCH_NUM)) {
+        if ($row = $st->fetch(\PDO::FETCH_NUM)) {
             $ret['services'] = $row[0];
         }
 
@@ -424,40 +439,10 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
     }
 
 
-    /**
-     * Create consent table.
-     *
-     * This function creates the table with consent data.
-     *
-     * @return True if successful, false if not.
-     *
-     * @TODO Remove this function since it is not used
-     */
-    private function _createTable()
-    {
-        $db = $this->_getDB();
-        if ($db === false) {
-            return false;
-        }
-
-        $res = $this->db->exec(
-            'CREATE TABLE ' . $this->_table . ' (consent_date TIMESTAMP NOT null, usage_date TIMESTAMP NOT null,' .
-            'hashed_user_id VARCHAR(80) NOT null, service_id VARCHAR(255) NOT null, attribute VARCHAR(80) NOT null,' .
-            'UNIQUE (hashed_user_id, service_id)'
-        );
-        if ($res === false) {
-            SimpleSAML\Logger::error('consent:Database - Failed to create table \'' . $this->_table . '\'.');
-            return false;
-        }
-
-        return true;
-    }
-
-
     /**
      * Get database handle.
      *
-     * @return PDO|false Database handle, or false if we fail to connect.
+     * @return \PDO|false Database handle, or false if we fail to connect.
      */
     private function _getDB()
     {
@@ -467,10 +452,15 @@ class sspmod_consent_Consent_Store_Database extends sspmod_consent_Store
 
         $driver_options = array();
         if (isset($this->_timeout)) {
-            $driver_options[PDO::ATTR_TIMEOUT] = $this->_timeout;
+            $driver_options[\PDO::ATTR_TIMEOUT] = $this->_timeout;
+        }
+        if (isset($this->_options)) {
+            $this->_options = array_merge($driver_options, $this->_options);
+        } else {
+            $this->_options = $driver_options;
         }
 
-        $this->_db = new PDO($this->_dsn, $this->_username, $this->_password, $driver_options);
+        $this->_db = new \PDO($this->_dsn, $this->_username, $this->_password, $this->_options);
 
         return $this->_db;
     }
diff --git a/modules/consent/lib/Logout.php b/modules/consent/lib/Logout.php
index dbaa071e88b23dcf4ae32de9f440c42315727fe2..f82961ee3d487f34ca42225d7f400157f1f57894 100644
--- a/modules/consent/lib/Logout.php
+++ b/modules/consent/lib/Logout.php
@@ -1,16 +1,18 @@
 <?php
 
+namespace SimpleSAML\Module\consent;
 
 /**
  * Class defining the logout completed handler for the consent page.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_consent_Logout
+
+class Logout
 {
-    public static function postLogout(SimpleSAML_IdP $idp, array $state)
+    public static function postLogout(\SimpleSAML\IdP $idp, array $state)
     {
-        $url = SimpleSAML\Module::getModuleURL('consent/logout_completed.php');
+        $url = \SimpleSAML\Module::getModuleURL('consent/logout_completed.php');
         \SimpleSAML\Utils\HTTP::redirectTrustedURL($url);
     }
 }
diff --git a/modules/consent/lib/Store.php b/modules/consent/lib/Store.php
index b9f9ae3cebaa6428b2e32944f36968497105a8fb..528f2ca16f66ee5e90a950952b52d65d52cd15bf 100644
--- a/modules/consent/lib/Store.php
+++ b/modules/consent/lib/Store.php
@@ -1,4 +1,7 @@
 <?php
+
+namespace SimpleSAML\Module\consent;
+
 /**
  * Base class for consent storage handlers.
  *
@@ -6,7 +9,8 @@
  * @author Olav Morken <olav.morken@uninett.no>
  * @author JAcob Christiansen <jach@wayf.dk>
  */
-abstract class sspmod_consent_Store
+
+abstract class Store
 {
     /**
      * Constructor for the base class.
@@ -74,11 +78,11 @@ abstract class sspmod_consent_Store
      *
      * @return mixed Should be the number of consent removed
      *
-     * @throws Exception
+     * @throws \Exception
      */
     public function deleteAllConsents($userId)
     {
-        throw new Exception('Not implemented: deleteAllConsents()');
+        throw new \Exception('Not implemented: deleteAllConsents()');
     }
 
 
@@ -87,11 +91,11 @@ abstract class sspmod_consent_Store
      *
      * @return mixed Statistics from the consent store
      *
-     * @throws Exception
+     * @throws \Exception
      */
     public function getStatistics()
     {
-        throw new Exception('Not implemented: getStatistics()');
+        throw new \Exception('Not implemented: getStatistics()');
     }
 
 
@@ -115,9 +119,9 @@ abstract class sspmod_consent_Store
      *
      * @param mixed $config The configuration.
      *
-     * @return sspmod_consent_Store An object which implements the sspmod_consent_Store class.
+     * @return \SimpleSAML\Module\consent\Store An object which implements the \SimpleSAML\Module\consent\Store class.
      *
-     * @throws Exception if the configuration is invalid.
+     * @throws \Exception if the configuration is invalid.
      */
     public static function parseStoreConfig($config)
     {
@@ -126,17 +130,17 @@ abstract class sspmod_consent_Store
         }
 
         if (!is_array($config)) {
-            throw new Exception('Invalid configuration for consent store option: '.var_export($config, true));
+            throw new \Exception('Invalid configuration for consent store option: '.var_export($config, true));
         }
 
         if (!array_key_exists(0, $config)) {
-            throw new Exception('Consent store without name given.');
+            throw new \Exception('Consent store without name given.');
         }
 
-        $className = SimpleSAML\Module::resolveClass(
+        $className = \SimpleSAML\Module::resolveClass(
             $config[0],
             'Consent_Store',
-            'sspmod_consent_Store'
+            '\SimpleSAML\Module\consent\Store'
         );
 
         unset($config[0]);
diff --git a/modules/consent/templates/consentform.php b/modules/consent/templates/consentform.php
index 738276b0b68ce11fd58e54152e59182882c27b5e..957775034187df9210c232222890678eaf0a43fe 100644
--- a/modules/consent/templates/consentform.php
+++ b/modules/consent/templates/consentform.php
@@ -58,7 +58,108 @@ if ($this->data['sppp'] !== false) {
     echo "</p>";
 }
 
-echo '<h3 id="attributeheader">' . $this->data['consent_attributes_header'] . '</h3>';
-echo $this->data['attributes_html'];
+/**
+ * Recursive attribute array listing function
+ *
+ * @param \SimpleSAML\XHTML\Template $t          Template object
+ * @param array                      $attributes Attributes to be presented
+ * @param string                     $nameParent Name of parent element
+ *
+ * @return string HTML representation of the attributes 
+ */
+function present_attributes($t, $attributes, $nameParent)
+{
+    $translator = $t->getTranslator();
+
+    $alternate = array('odd', 'even');
+    $i = 0;
+    $summary = 'summary="' . $t->t('{consent:consent:table_summary}') . '"';
+
+    if (strlen($nameParent) > 0) {
+        $parentStr = strtolower($nameParent) . '_';
+        $str = '<table class="attributes" ' . $summary . '>';
+    } else {
+        $parentStr = '';
+        $str = '<table id="table_with_attributes"  class="attributes" '. $summary .'>';
+        $str .= "\n" . '<caption>' . $t->t('{consent:consent:table_caption}') .
+            '</caption>';
+    }
+
+    foreach ($attributes as $name => $value) {
+        $nameraw = $name;
+        $name = $translator->getAttributeTranslation($parentStr . $nameraw);
+
+        if (preg_match('/^child_/', $nameraw)) {
+            // insert child table
+            $parentName = preg_replace('/^child_/', '', $nameraw);
+            foreach ($value as $child) {
+                $str .= "\n" . '<tr class="odd"><td style="padding: 2em">' .
+                    present_attributes($t, $child, $parentName) . '</td></tr>';
+            }
+        } else {
+            // insert values directly
+
+            $str .= "\n" . '<tr class="' . $alternate[($i++ % 2)] .
+                '"><td><span class="attrname">' . htmlspecialchars($name) . '</span>';
+
+            $isHidden = in_array($nameraw, $t->data['hiddenAttributes'], true);
+            if ($isHidden) {
+                $hiddenId = SimpleSAML\Utils\Random::generateID();
+
+                $str .= '<div class="attrvalue" style="display: none;" id="hidden_' . $hiddenId . '">';
+            } else {
+                $str .= '<div class="attrvalue">';
+            }
+
+            if (sizeof($value) > 1) {
+                // we hawe several values
+                $str .= '<ul>';
+                foreach ($value as $listitem) {
+                    if ($nameraw === 'jpegPhoto') {
+                        $str .= '<li><img src="data:image/jpeg;base64,' .
+                            htmlspecialchars($listitem) .
+                            '" alt="User photo" /></li>';
+                    } else {
+                        $str .= '<li>' . htmlspecialchars($listitem) . '</li>';
+                    }
+                }
+                $str .= '</ul>';
+            } elseif (isset($value[0])) {
+                // we hawe only one value
+                if ($nameraw === 'jpegPhoto') {
+                    $str .= '<img src="data:image/jpeg;base64,' .
+                        htmlspecialchars($value[0]) .
+                        '" alt="User photo" />';
+                } else {
+                    $str .= htmlspecialchars($value[0]);
+                }
+            } // end of if multivalue
+            $str .= '</div>';
+
+            if ($isHidden) {
+                $str .= '<div class="attrvalue consent_showattribute" id="visible_' . $hiddenId . '">';
+                $str .= '... ';
+                $str .= '<a class="consent_showattributelink" href="javascript:SimpleSAML_show(\'hidden_' . $hiddenId;
+                $str .= '\'); SimpleSAML_hide(\'visible_' . $hiddenId . '\');">';
+                $str .= $t->t('{consent:consent:show_attribute}');
+                $str .= '</a>';
+                $str .= '</div>';
+            }
+
+            $str .= '</td></tr>';
+        }	// end else: not child table
+    }	// end foreach
+    $str .= isset($attributes)? '</table>':'';
+    return $str;
+}
+
+echo '<h3 id="attributeheader">' .
+    $this->t(
+        '{consent:consent:consent_attributes_header}',
+        array( 'SPNAME' => $dstName, 'IDPNAME' => $srcName)
+    ) .
+    '</h3>';
+
+echo present_attributes($this, $attributes, '');
 
 $this->includeAtTemplateBase('includes/footer.php');
diff --git a/modules/consent/www/getconsent.php b/modules/consent/www/getconsent.php
index cf649904edfaf54c00419816cea0230f85aadb9a..658e4ee822e7f14665e8312ea029846dddd0f99b 100644
--- a/modules/consent/www/getconsent.php
+++ b/modules/consent/www/getconsent.php
@@ -19,17 +19,18 @@
  */
 session_cache_limiter('nocache');
 
-$globalConfig = SimpleSAML_Configuration::getInstance();
+$globalConfig = \SimpleSAML\Configuration::getInstance();
 
 SimpleSAML\Logger::info('Consent - getconsent: Accessing consent interface');
 
 if (!array_key_exists('StateId', $_REQUEST)) {
-    throw new SimpleSAML_Error_BadRequest(
+    throw new \SimpleSAML\Error\BadRequest(
         'Missing required StateId query parameter.'
     );
 }
 
-$state = SimpleSAML_Auth_State::loadState($_REQUEST['StateId'], 'consent:request');
+$id = $_REQUEST['StateId'];
+$state = \SimpleSAML\Auth\State::loadState($id, 'consent:request');
 
 if (array_key_exists('core:SP', $state)) {
     $spentityid = $state['core:SP'];
@@ -54,7 +55,7 @@ if (array_key_exists('yes', $_REQUEST)) {
     if (isset($state['Destination']['entityid'])) {
         $statsInfo['spEntityID'] = $state['Destination']['entityid'];
     }
-    SimpleSAML_Stats::log('consent:accept', $statsInfo);
+    \SimpleSAML\Stats::log('consent:accept', $statsInfo);
 
     if (   array_key_exists('consent:store', $state) 
         && array_key_exists('saveconsent', $_REQUEST)
@@ -66,7 +67,7 @@ if (array_key_exists('yes', $_REQUEST)) {
         $targetedId = $state['consent:store.destination'];
         $attributeSet = $state['consent:store.attributeSet'];
 
-        SimpleSAML\Logger::debug(
+        \SimpleSAML\Logger::debug(
             'Consent - saveConsent() : [' . $userId . '|' .
             $targetedId . '|' .  $attributeSet . ']'
         );	
@@ -77,7 +78,7 @@ if (array_key_exists('yes', $_REQUEST)) {
         }
     }
 
-    SimpleSAML_Auth_ProcessingChain::resumeProcessing($state);
+    \SimpleSAML\Auth\ProcessingChain::resumeProcessing($state);
 }
 
 // Prepare attributes for presentation
@@ -115,10 +116,14 @@ if (array_key_exists('name', $state['Destination'])) {
 }
 
 // Make, populate and layout consent form
-$t = new SimpleSAML_XHTML_Template($globalConfig, 'consent:consentform.php');
-$t->data['yesTarget'] = SimpleSAML\Module::getModuleURL('consent/getconsent.php');
-$t->data['noTarget'] = SimpleSAML\Module::getModuleURL('consent/noconsent.php');
-$t->data['stateId'] = $_REQUEST['StateId'];
+$t = new \SimpleSAML\XHTML\Template($globalConfig, 'consent:consentform.php');
+$t->data['srcMetadata'] = $state['Source'];
+$t->data['dstMetadata'] = $state['Destination'];
+$t->data['yesTarget'] = \SimpleSAML\Module::getModuleURL('consent/getconsent.php');
+$t->data['yesData'] = array('StateId' => $id);
+$t->data['noTarget'] = \SimpleSAML\Module::getModuleURL('consent/noconsent.php');
+$t->data['noData'] = array('StateId' => $id);
+$t->data['attributes'] = $attributes;
 $t->data['checked'] = $state['consent:checked'];
 
 $srcName = htmlspecialchars(is_array($srcName) ? $t->t($srcName) : $srcName);
diff --git a/modules/consent/www/logout.php b/modules/consent/www/logout.php
index 2d46540df73b23eb61cf54aeed83ac02c590e27a..0065cbea172eb3c2625e454e8d1fd339995033a0 100644
--- a/modules/consent/www/logout.php
+++ b/modules/consent/www/logout.php
@@ -6,12 +6,12 @@
  */
 
 if (!array_key_exists('StateId', $_GET)) {
-    throw new SimpleSAML_Error_BadRequest('Missing required StateId query parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing required StateId query parameter.');
 }
-$state = SimpleSAML_Auth_State::loadState($_GET['StateId'], 'consent:request');
+$state = \SimpleSAML\Auth\State::loadState($_GET['StateId'], 'consent:request');
 
-$state['Responder'] = array('sspmod_consent_Logout', 'postLogout');
+$state['Responder'] = array('\SimpleSAML\Module\consent\Logout', 'postLogout');
 
-$idp = SimpleSAML_IdP::getByState($state);
+$idp = \SimpleSAML\IdP::getByState($state);
 $idp->handleLogoutRequest($state, null);
 assert(false);
diff --git a/modules/consent/www/logout_completed.php b/modules/consent/www/logout_completed.php
index a543c30574e1725c831435c5fe2dca00f7057fa1..a5124704f3a192dc6c9fd106ced8d69fc3961785 100644
--- a/modules/consent/www/logout_completed.php
+++ b/modules/consent/www/logout_completed.php
@@ -5,6 +5,6 @@
  * @package SimpleSAMLphp
  */
 
-$globalConfig = SimpleSAML_Configuration::getInstance();
-$t = new SimpleSAML_XHTML_Template($globalConfig, 'consent:logout_completed.php');
+$globalConfig = \SimpleSAML\Configuration::getInstance();
+$t = new \SimpleSAML\XHTML\Template($globalConfig, 'consent:logout_completed.php');
 $t->show();
diff --git a/modules/consent/www/noconsent.php b/modules/consent/www/noconsent.php
index 5aee2625b2a390381355240ea4e907ff46b70bea..4ac9f5e8f5f3fb29c3faa253a6673ebd25a06d14 100644
--- a/modules/consent/www/noconsent.php
+++ b/modules/consent/www/noconsent.php
@@ -1,24 +1,26 @@
 <?php
+
 /**
  * This is the page the user lands on when choosing "no" in the consent form.
  *
  * @package SimpleSAMLphp
  */
+
 if (!array_key_exists('StateId', $_REQUEST)) {
-    throw new SimpleSAML_Error_BadRequest(
+    throw new \SimpleSAML\Error\BadRequest(
         'Missing required StateId query parameter.'
     );
 }
 
 $id = $_REQUEST['StateId'];
-$state = SimpleSAML_Auth_State::loadState($id, 'consent:request');
+$state = \SimpleSAML\Auth\State::loadState($id, 'consent:request');
 
-$resumeFrom = SimpleSAML\Module::getModuleURL(
+$resumeFrom = \SimpleSAML\Module::getModuleURL(
     'consent/getconsent.php',
     array('StateId' => $id)
 );
 
-$logoutLink = SimpleSAML\Module::getModuleURL(
+$logoutLink = \SimpleSAML\Module::getModuleURL(
     'consent/logout.php',
     array('StateId' => $id)
 );
@@ -34,7 +36,7 @@ $statsInfo = array();
 if (isset($state['Destination']['entityid'])) {
     $statsInfo['spEntityID'] = $state['Destination']['entityid'];
 }
-SimpleSAML_Stats::log('consent:reject', $statsInfo);
+\SimpleSAML\Stats::log('consent:reject', $statsInfo);
 
 if (array_key_exists('name', $state['Destination'])) {
     $dstName = $state['Destination']['name'];
@@ -44,9 +46,10 @@ if (array_key_exists('name', $state['Destination'])) {
     $dstName = $state['Destination']['entityid'];
 }
 
-$globalConfig = SimpleSAML_Configuration::getInstance();
+$globalConfig = \SimpleSAML\Configuration::getInstance();
 
-$t = new SimpleSAML_XHTML_Template($globalConfig, 'consent:noconsent.php');
+$t = new \SimpleSAML\XHTML\Template($globalConfig, 'consent:noconsent.php');
+$t->data['dstMetadata'] = $state['Destination'];
 $t->data['resumeFrom'] = $resumeFrom;
 $t->data['aboutService'] = $aboutService;
 $t->data['logoutLink'] = $logoutLink;
diff --git a/modules/consentAdmin/config-templates/module_consentAdmin.php b/modules/consentAdmin/config-templates/module_consentAdmin.php
index 418065c14ec2ddb421cc9809a0ce39a8156693da..02fdf8d42009d69a9128b9e068353b7e02715e8d 100644
--- a/modules/consentAdmin/config-templates/module_consentAdmin.php
+++ b/modules/consentAdmin/config-templates/module_consentAdmin.php
@@ -6,23 +6,26 @@
  * @package SimpleSAMLphp
  */
 $config = array(
-	/*
-	 * Configuration for the database connection.
-	 */
-	'consentadmin'  => array(
-		'consent:Database',
-		'dsn'		=>	'mysql:host=DBHOST;dbname=DBNAME',
-		'username'	=>	'USERNAME', 
-		'password'	=>	'PASSWORD',
-	),
-	
-	// Hash attributes including values or not
-	'attributes.hash' => TRUE,
+    /*
+     * Configuration for the database connection.
+     */
+    'consentadmin'  => array(
+        'consent:Database',
+        'dsn'       =>  'mysql:host=DBHOST;dbname=DBNAME',
+        'username'  =>  'USERNAME',
+        'password'  =>  'PASSWORD',
+    ),
 
-	// Where to direct the user after logout
-    // REMEMBER to prefix with http:// otherwise the relaystate is only appended 
+    // Hash attributes including values or not
+    'attributes.hash' => true,
+
+    // If you set attributes.exclude in the consent module, this must match
+    // 'attributes.exclude' => array(),
+
+    // Where to direct the user after logout
+    // REMEMBER to prefix with http:// otherwise the relaystate is only appended
     // to saml2 logout URL
-	'returnURL' => 'http://www.wayf.dk',
+    'returnURL' => 'http://www.wayf.dk',
 
     // Shows description of the services if set to true (defaults to true)
     'showDescription' => true,
diff --git a/modules/consentAdmin/docs/consentAdmin.md b/modules/consentAdmin/docs/consentAdmin.md
index 454cd5f47825899530c4128efd1e2a8f0c84c5c9..1dc342e7f917930674a92ef66908e95cd0fafa99 100644
--- a/modules/consentAdmin/docs/consentAdmin.md
+++ b/modules/consentAdmin/docs/consentAdmin.md
@@ -44,7 +44,9 @@ Setting optional parameters
 In order to make the consentAdmin module work together with the consent
 module correctly, you need to set the configuration 'attributes.hash'
 according to the value of 'includeValues' configuration in the consent
-module.
+module. Likewise, if you've used the 'attributes.exclude' configuration
+option in the consent module, you should also set the 'attributes.exclude'
+configuration option here to match.
 
 You should also set the 'returnURL' configuration in order to pass on your
 users when the press the 'Logout' link.
diff --git a/modules/consentAdmin/www/consentAdmin.php b/modules/consentAdmin/www/consentAdmin.php
index f3760a64805c2e49e5365a86de6e9c2c110e6280..57b22db43203ced353af576657ed0ebc46cae399 100644
--- a/modules/consentAdmin/www/consentAdmin.php
+++ b/modules/consentAdmin/www/consentAdmin.php
@@ -22,13 +22,14 @@ function driveProcessingChain(
     $sp_entityid,
     $attributes,
     $userid,
-    $hashAttributes = false
+    $hashAttributes = false,
+    $excludeAttributes = array()
 ) {
 
     /*
      * Create a new processing chain
      */
-    $pc = new SimpleSAML_Auth_ProcessingChain($idp_metadata, $sp_metadata, 'idp');
+    $pc = new \SimpleSAML\Auth\ProcessingChain($idp_metadata, $sp_metadata, 'idp');
 
     /*
      * Construct the state.
@@ -37,9 +38,15 @@ function driveProcessingChain(
     $authProcState = array(
         'Attributes'  => $attributes,
         'Destination' => $sp_metadata,
+        'SPMetadata'  => $sp_metadata,
         'Source'      => $idp_metadata,
+        'IdPMetadata' => $idp_metadata,
         'isPassive'   => true,
     );
+    /* we're being bridged, so add that info to the state */
+    if (strpos($source, '-idp-remote|') !== false) {
+        $authProcState['saml:sp:IdP'] = substr($source, strpos($source, '|') + 1);
+    }
 
     /*
      * Call processStatePAssive.
@@ -48,26 +55,32 @@ function driveProcessingChain(
     $pc->processStatePassive($authProcState);
 
     $attributes = $authProcState['Attributes'];
+    // Remove attributes that do not require consent/should be excluded
+    foreach ($attributes as $attrkey => $attrval) {
+        if (in_array($attrkey, $excludeAttributes)) {
+            unset($attributes[$attrkey]);
+        }
+    }
 
     /*
      * Generate identifiers and hashes
      */
     $destination = $sp_metadata['metadata-set'].'|'.$sp_entityid;
 
-    $targeted_id = sspmod_consent_Auth_Process_Consent::getTargetedID($userid, $source, $destination);
-    $attribute_hash = sspmod_consent_Auth_Process_Consent::getAttributeHash($attributes, $hashAttributes);
+    $targeted_id = \SimpleSAML\Module\consent\Auth\Process\Consent::getTargetedID($userid, $source, $destination);
+    $attribute_hash = \SimpleSAML\Module\consent\Auth\Process\Consent::getAttributeHash($attributes, $hashAttributes);
 
-    SimpleSAML\Logger::info('consentAdmin: user: '.$userid);
-    SimpleSAML\Logger::info('consentAdmin: target: '.$targeted_id);
-    SimpleSAML\Logger::info('consentAdmin: attribute: '.$attribute_hash);
+    \SimpleSAML\Logger::info('consentAdmin: user: '.$userid);
+    \SimpleSAML\Logger::info('consentAdmin: target: '.$targeted_id);
+    \SimpleSAML\Logger::info('consentAdmin: attribute: '.$attribute_hash);
 
     // Return values
     return array($targeted_id, $attribute_hash, $attributes);
 }
 
 // Get config object
-$config = SimpleSAML_Configuration::getInstance();
-$cA_config = SimpleSAML_Configuration::getConfig('module_consentAdmin.php');
+$config = \SimpleSAML\Configuration::getInstance();
+$cA_config = \SimpleSAML\Configuration::getConfig('module_consentAdmin.php');
 $authority = $cA_config->getValue('authority');
 
 $as = new \SimpleSAML\Auth\Simple($authority);
@@ -80,6 +93,8 @@ if (array_key_exists('logout', $_REQUEST)) {
 
 $hashAttributes = $cA_config->getValue('attributes.hash');
 
+$excludeAttributes = $cA_config->getValue('attributes.exclude', array());
+
 // Check if valid local session exists
 $as->requireAuth();
 
@@ -87,33 +102,32 @@ $as->requireAuth();
 $attributes = $as->getAttributes();
 
 // Get metadata storage handler
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 
 /*
  * Get IdP id and metadata
  */
 
 
-$local_idp_entityid = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
-$local_idp_metadata = $metadata->getMetaData($local_idp_entityid, 'saml20-idp-hosted');
+$idp_entityid = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
+$idp_metadata = $metadata->getMetaData($idp_entityid, 'saml20-idp-hosted');
 
+// Calc correct source
 if ($as->getAuthData('saml:sp:IdP') !== null) {
     // from a remote idp (as bridge)
-    $idp_entityid = $as->getAuthData('saml:sp:IdP');
-    $idp_metadata = $metadata->getMetaData($idp_entityid, 'saml20-idp-remote');
+    $source = 'saml20-idp-remote|'.$as->getAuthData('saml:sp:IdP');
 } else {
     // from the local idp
-    $idp_entityid = $local_idp_entityid;
-    $idp_metadata = $local_idp_metadata;
+    $source = $idp_metadata['metadata-set'].'|'.$idp_entityid;
 }
 
 // Get user ID
-$userid_attributename = (isset($local_idp_metadata['userid.attribute']) && is_string($local_idp_metadata['userid.attribute'])) ? $local_idp_metadata['userid.attribute'] : 'eduPersonPrincipalName';
+$userid_attributename = (isset($idp_metadata['userid.attribute']) && is_string($idp_metadata['userid.attribute'])) ? $idp_metadata['userid.attribute'] : 'eduPersonPrincipalName';
 
 $userids = $attributes[$userid_attributename];
 
 if (empty($userids)) {
-    throw new Exception('Could not generate useridentifier for storing consent. Attribute ['.
+    throw new \Exception('Could not generate useridentifier for storing consent. Attribute ['.
         $userid_attributename.'] was not available.');
 }
 
@@ -132,7 +146,7 @@ if (!empty($_GET['action'])) {
     $action = $_GET["action"];
 }
 
-SimpleSAML\Logger::critical('consentAdmin: sp: '.$sp_entityid.' action: '.$action);
+\SimpleSAML\Logger::critical('consentAdmin: sp: '.$sp_entityid.' action: '.$action);
 
 // Remove services, whitch have consent disabled
 if (isset($idp_metadata['consent.disable'])) {
@@ -143,16 +157,13 @@ if (isset($idp_metadata['consent.disable'])) {
     }
 }
 
-SimpleSAML\Logger::info('consentAdmin: '.$idp_entityid);
-
-// Calc correct source
-$source = $idp_metadata['metadata-set'].'|'.$idp_entityid;
+\SimpleSAML\Logger::info('consentAdmin: '.$idp_entityid);
 
 // Parse consent config
-$consent_storage = sspmod_consent_Store::parseStoreConfig($cA_config->getValue('consentadmin'));
+$consent_storage = \SimpleSAML\Module\consent\Store::parseStoreConfig($cA_config->getValue('consentadmin'));
 
 // Calc correct user ID hash
-$hashed_user_id = sspmod_consent_Auth_Process_Consent::getHashedUserID($userid, $source);
+$hashed_user_id = \SimpleSAML\Module\consent\Auth\Process\Consent::getHashedUserID($userid, $source);
 
 // If a checkbox have been clicked
 if ($action !== null && $sp_entityid !== null) {
@@ -161,7 +172,7 @@ if ($action !== null && $sp_entityid !== null) {
 
     // Run AuthProc filters
     list($targeted_id, $attribute_hash, $attributes_new) = driveProcessingChain($idp_metadata, $source, $sp_metadata,
-        $sp_entityid, $attributes, $userid, $hashAttributes);
+        $sp_entityid, $attributes, $userid, $hashAttributes, $excludeAttributes);
 
     // Add a consent (or update if attributes have changed and old consent for SP and IdP exists)
     if ($action == 'true') {
@@ -175,18 +186,18 @@ if ($action !== null && $sp_entityid !== null) {
     } else {
         if ($action == 'false') {
             // Got consent, so this is a request to remove it
-            $rowcount = $consent_storage->deleteConsent($hashed_user_id, $targeted_id, $attribute_hash);
+            $rowcount = $consent_storage->deleteConsent($hashed_user_id, $targeted_id);
             if ($rowcount > 0) {
                 $res = "removed";
             }
             // Unknown action (should not happen)
         } else {
-            SimpleSAML\Logger::info('consentAdmin: unknown action');
+            \SimpleSAML\Logger::info('consentAdmin: unknown action');
             $res = "unknown";
         }
     }
     // init template to enable translation of status messages
-    $template = new SimpleSAML_XHTML_Template($config, 'consentAdmin:consentadminajax.php', 'consentAdmin:consentadmin');
+    $template = new \SimpleSAML\XHTML\Template($config, 'consentAdmin:consentadminajax.php', 'consentAdmin:consentadmin');
     $template->data['res'] = $res;
     $template->show();
     exit;
@@ -204,7 +215,7 @@ foreach ($user_consent_list as $c) {
 $template_sp_content = array();
 
 // Init template
-$template = new SimpleSAML_XHTML_Template($config, 'consentAdmin:consentadmin.php', 'consentAdmin:consentadmin');
+$template = new \SimpleSAML\XHTML\Template($config, 'consentAdmin:consentadmin.php', 'consentAdmin:consentadmin');
 $translator = $template->getTranslator();
 $translator->includeLanguageFile('attributes.php'); // attribute listings translated by this dictionary
 $sp_empty_name = $translator->getTag('sp_empty_name');
@@ -217,15 +228,15 @@ foreach ($all_sp_metadata as $sp_entityid => $sp_values) {
 
     // Run attribute filters
     list($targeted_id, $attribute_hash, $attributes_new) = driveProcessingChain($idp_metadata, $source, $sp_metadata,
-        $sp_entityid, $attributes, $userid, $hashAttributes);
+        $sp_entityid, $attributes, $userid, $hashAttributes, $excludeAttributes);
 
     // Check if consent exists
     if (array_key_exists($targeted_id, $user_consent)) {
         $sp_status = "changed";
-        SimpleSAML\Logger::info('consentAdmin: changed');
+        \SimpleSAML\Logger::info('consentAdmin: changed');
         // Check if consent is valid. (Possible that attributes has changed)
         if ($user_consent[$targeted_id] == $attribute_hash) {
-            SimpleSAML\Logger::info('consentAdmin: ok');
+            \SimpleSAML\Logger::info('consentAdmin: ok');
             $sp_status = "ok";
         }
         // Consent does not exists
diff --git a/modules/core/dictionaries/cardinality.definition.json b/modules/core/dictionaries/cardinality.definition.json
new file mode 100644
index 0000000000000000000000000000000000000000..b9059cb93a389ad4422be193ae8b17371ed426cf
--- /dev/null
+++ b/modules/core/dictionaries/cardinality.definition.json
@@ -0,0 +1,14 @@
+{
+    "cardinality_header": {
+        "en": "Incorrect Attributes"
+    },
+    "cardinality_text": {
+        "en": "One or more of the attributes supplied by your identity provider did not contain the expected number of values."
+    },
+    "problematic_attributes": {
+        "en": "The problematic attribute(s) are:"
+    },
+    "got_want": {
+        "en": "got %GOT% values, want %WANT%"
+    }
+}
diff --git a/modules/core/dictionaries/cardinality.translation.json b/modules/core/dictionaries/cardinality.translation.json
new file mode 100644
index 0000000000000000000000000000000000000000..9f479dc0fb9c19f913e12cf6f2177b447214ad4b
--- /dev/null
+++ b/modules/core/dictionaries/cardinality.translation.json
@@ -0,0 +1,27 @@
+{
+  "cardinality_header": {
+    "af": "Verkeerde Eienskappe",
+    "nl": "Niet de juiste attributen",
+    "es": "Atributos inválidos",
+    "no": "Ugyldige atributter"
+
+  },
+  "cardinality_text": {
+    "af": "Een of meer van die eienskappe wat deur u identiteits-verskaffer voorsien was, bevat nie die verwagte aantal waardes nie.",
+    "nl": "Één of meer door de Identity Provider geleverde attributen bevat niet het vereiste aantal attributen.",
+    "es": "Uno o más atributos proporcionados por su proveedor de identidad no contiene la cantidad de valores esperada.",
+    "no": "Én eller flere atributter levert av din identitetsleverandør har ikke så mange verdier som forventes."
+  },
+  "problematic_attributes": {
+    "af": "Die problematiese eienskap(pe) is:",
+    "nl": "De onjuiste attributen zijn:",
+    "es": "Los atributos problemáticos son:",
+    "no": "De ugyldige atributter er:"
+  },
+  "got_want": {
+    "af": "%GOT% waarde ontvang, %WANT% nodig",
+    "nl": "%GOT% ontvangen waarden, %WANT% vereist",
+    "es": "contiene %GOT% valores, se esperaban %WANT%",
+    "no": "har %GOT% verdier, forventer %WANT%"
+  }
+}
diff --git a/modules/core/docs/authproc_attributelimit.md b/modules/core/docs/authproc_attributelimit.md
index 5b640fd82144a100b41688dc0c545e22ad0b40c6..73c4406efd4875c5c72ea8503ea32adcc3036c45 100644
--- a/modules/core/docs/authproc_attributelimit.md
+++ b/modules/core/docs/authproc_attributelimit.md
@@ -32,6 +32,41 @@ Allow `eduPersonTargetedID` and `eduPersonAffiliation` by default, but allow the
         ),
     ),
 
+Only allow specific values for an attribute.
+
+    'authproc' => array(
+        50 => array(
+            'class' => 'core:AttributeLimit',
+            'eduPersonEntitlement' => array('urn:x-surfnet:surf.nl:surfdrive:quota:100')
+        ),
+    ),
+
+Only allow specific values for an attribute ignoring case.
+
+    'authproc' => array(
+        50 => array(
+            'class' => 'core:AttributeLimit',
+            'eduPersonEntitlement' => array(
+                'ignoreCase' => true,
+                'URN:x-surfnet:surf.nl:SURFDRIVE:quota:100'
+             )
+        ),
+    ),
+    
+Only allow specific values for an attribute that match a regex pattern
+
+    'authproc' => array(
+        50 => array(
+            'class' => 'core:AttributeLimit',
+            'eduPersonEntitlement' => array(
+                'regex' => true,
+                '/^urn:x-surfnet:surf/',
+                '/^urn:x-IGNORE_Case/i',
+            )
+        ),
+    ),
+    
+    
 Don't allow any attributes by default, but allow the metadata to override it.
 
     'authproc' => array(
diff --git a/modules/core/docs/authproc_cardinality.md b/modules/core/docs/authproc_cardinality.md
new file mode 100644
index 0000000000000000000000000000000000000000..0902bf27863dad94991aacb54d15a7a407750f63
--- /dev/null
+++ b/modules/core/docs/authproc_cardinality.md
@@ -0,0 +1,47 @@
+`core:Cardinality`
+==================
+
+Ensure the number of attribute values is within the specified multiplicity.
+
+This filter should contain a set of attribute name => rule pairs describing the multiplicity rules for an attribute.
+
+The special parameter `%ignoreEntities` can be used to give an array of entity IDs that should be ignored for testing, etc purposes.
+
+Specifying Rules
+----------------
+
+Multiplicity rules are specified as an associative array containing one or more of the following parameters:
+
+`min`
+:   The minimum number of values (participation) this attribute should have. Defaults to `zero`.
+
+`max`
+:   The maximum number of values (cardinality) this attribute should have. Defaults to no upper bound.
+
+`warn`
+:   Log a warning rather than generating an error. Defaults to `false`.
+
+For convenience, minimum and maximum values can also be specified using a shorthand list notation.
+
+Examples
+--------
+
+Require at least one `givenName`, no more than two email addresses, and between two and four values for `eduPersonScopedAffiliation`.
+
+    'authproc' => array(
+        50 => array(
+            'class' => 'core:Cardinality',
+            'givenName' => array('min' => 1),
+            'mail' => array('max' => 2),
+            'eduPersonScopedAffiliation' => array('min' => 2, 'max' => 4),
+        ),
+    ),
+
+Use the shorthand notation for min, max:
+
+    'authproc' => array(
+        50 => array(
+            'class' => 'core:Cardinality',
+            'mail' => array(0, 2),
+        ),
+    ),
diff --git a/modules/core/docs/authproc_cardinalitysingle.md b/modules/core/docs/authproc_cardinalitysingle.md
new file mode 100644
index 0000000000000000000000000000000000000000..4a61bdbc5aaca4579729fc0bafec6b6976a2efea
--- /dev/null
+++ b/modules/core/docs/authproc_cardinalitysingle.md
@@ -0,0 +1,88 @@
+`core:CardinalitySingle`
+========================
+
+Ensure the correct cardinality of single-valued attributes. This filter is a special case
+of the more generic [core:Cardinality] filter that allows for optional corrective measures
+when multi-valued attributes are received where single-valued ones are expected.
+
+Parameters
+----------
+
+This filter implements a number of optional parameters:
+
+`singleValued`
+:   array of attribute names that *must* be single-valued, or a 403 error is generated.
+
+`firstValue`
+:   array of attribute names where only the first value of a multi-valued assertion should be returned.
+
+`flatten`
+:   array of attribute names where a multi-valued assertion is flattened into a single delimited string.
+
+`flattenWith`
+:   the delimiter for `flatten`. Defaults to ";".
+
+`ignoreEntities`
+:   array of entity IDs that should be ignored for testing, etc purposes.
+
+When the same attribute name appears in multiple stanzas, they are processed in the order above.
+
+Examples
+--------
+
+Abort with an error if any attribute defined as single-valued in the eduPerson or SCHAC schemas exists and has more than one value:
+
+    'authproc' => array(
+        50 => array(
+            'class' => 'core:CardinalitySingle',
+            'singleValued' => array(
+                /* from eduPerson (internet2-mace-dir-eduperson-201602) */
+                'eduPersonOrgDN', 'eduPersonPrimaryAffiliation', 'eduPersonPrimaryOrgUnitDN',
+                'eduPersonPrincipalName', 'eduPersonUniqueId',
+                /* from inetOrgPerson (RFC2798), referenced by internet2-mace-dir-eduperson-201602 */
+                'displayName', 'preferredLanguage',
+                /* from SCHAC-IAD Version 1.3.0 */
+                'schacMotherTongue', 'schacGender', 'schacDateOfBirth', 'schacPlaceOfBirth',
+                'schacPersonalTitle', 'schacHomeOrganization', 'schacHomeOrganizationType',
+                'schacExpiryDate',
+            ),
+        ),
+    ),
+
+Abort if multiple values are received for `eduPersonPrincipalName`, but take the first value for `eduPersonPrimaryAffiliation`:
+
+    'authproc' => array(
+        50 => array(
+            'class' => 'core:CardinalitySingle',
+            'singleValued' => array('eduPersonPrincipalName'),
+            'firstValue' => array('eduPersonPrimaryAffiliation'),
+            ),
+        ),
+    ),
+
+Construct `eduPersonPrimaryAffiliation` using the first value in `eduPersonAffiliation`:
+
+    'authproc' => array(
+        50 => array(
+            'class' => 'core:AttributeCopy',
+            'eduPersonAffiliation' => 'eduPersonPrimaryAffiliation',
+        ),
+        51 => array(
+            'class' => 'core:CardinalitySingle',
+            'firstValue' => array('eduPersonPrimaryAffiliation'),
+        ),
+    ),
+
+Construct a single, comma-separated value version of `eduPersonAffiliation`:
+
+    'authproc' => array(
+        50 => array(
+            'class' => 'core:AttributeCopy',
+            'eduPersonAffiliation' => 'eduPersonAffiliationWithCommas',
+        ),
+        51 => array(
+            'class' => 'core:CardinalitySingle',
+            'flatten' => array('eduPersonAffiliationWithCommas'),
+			'flattenWith' => ',',
+        ),
+    ),
diff --git a/modules/core/docs/authproc_scopefromattribute.md b/modules/core/docs/authproc_scopefromattribute.md
index 0b7f92b9882897918cc1fd66fd4566140aa3659c..5eba851b9f8702fbbb322bf6c28ee48d0bbf895b 100644
--- a/modules/core/docs/authproc_scopefromattribute.md
+++ b/modules/core/docs/authproc_scopefromattribute.md
@@ -25,7 +25,7 @@ Set the `scope` attribute to the scope from the `eduPersonPrincipalName` attribu
     'authproc' => array(
         50 => array(
             'class' => 'core:ScopeFromAttribute',
-            'sourceAttribute' => 'eduPersonPrincipal'
-            'targetAttribute' => 'scope'
+            'sourceAttribute' => 'eduPersonPrincipalName',
+            'targetAttribute' => 'scope',
         ),
     ),
diff --git a/modules/core/docs/authproc_statisticswithattribute.md b/modules/core/docs/authproc_statisticswithattribute.md
index 53753f9dbce44e23a60ae7336ca75909aa55b254..4607c059ea5da12c6324c6130e7396aa10d34a27 100644
--- a/modules/core/docs/authproc_statisticswithattribute.md
+++ b/modules/core/docs/authproc_statisticswithattribute.md
@@ -12,6 +12,9 @@ Parameters
 `type`
 :   The type of the statistics entry.
 
+`skipPassive`
+:   A boolean indicating whether passive requests should be skipped. Defaults to `FALSE`, in which case the type tag is prefixed with 'passive-'.
+
 
 Example
 -------
diff --git a/modules/core/hooks/hook_sanitycheck.php b/modules/core/hooks/hook_sanitycheck.php
index 237a295caab09d56f89fd9dbd2a8f752a0a83ad0..d3683a3698dd77402841767edeef9b122b205ebf 100644
--- a/modules/core/hooks/hook_sanitycheck.php
+++ b/modules/core/hooks/hook_sanitycheck.php
@@ -9,7 +9,7 @@ function core_hook_sanitycheck(&$hookinfo) {
 	assert(array_key_exists('errors', $hookinfo));
 	assert(array_key_exists('info', $hookinfo));
 
-	$config = SimpleSAML_Configuration::getInstance();
+	$config = \SimpleSAML\Configuration::getInstance();
 	
 	if($config->getString('auth.adminpassword', '123') === '123') {
 		$hookinfo['errors'][] = '[core] Password in config.php is not set properly';
diff --git a/modules/core/lib/ACL.php b/modules/core/lib/ACL.php
index 175c6c2620fc7037400d8daea103916c3f797d9c..b99483b745a0f30b43284d7bad9dbce7116a1a5a 100644
--- a/modules/core/lib/ACL.php
+++ b/modules/core/lib/ACL.php
@@ -1,11 +1,14 @@
 <?php
 
+namespace SimpleSAML\Module\core;
+
 /**
  * Generic library for access control lists.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_core_ACL {
+
+class ACL {
 
 	/**
 	 * The access control list, as an array.
@@ -29,15 +32,15 @@ class sspmod_core_ACL {
 
 		foreach ($acl as $rule) {
 			if (!is_array($rule)) {
-				throw new SimpleSAML_Error_Exception('Invalid rule in access control list: ' . var_export($rule, TRUE));
+				throw new \SimpleSAML\Error\Exception('Invalid rule in access control list: ' . var_export($rule, TRUE));
 			}
 			if (count($rule) === 0) {
-				throw new SimpleSAML_Error_Exception('Empty rule in access control list.');
+				throw new \SimpleSAML\Error\Exception('Empty rule in access control list.');
 			}
 
 			$action = array_shift($rule);
 			if ($action !== 'allow' && $action !== 'deny') {
-				throw new SimpleSAML_Error_Exception('Invalid action in rule in access control list: ' . var_export($action, TRUE));
+				throw new \SimpleSAML\Error\Exception('Invalid action in rule in access control list: ' . var_export($action, TRUE));
 			}
 
 		}
@@ -55,9 +58,9 @@ class sspmod_core_ACL {
 	private static function getById($id) {
 		assert(is_string($id));
 
-		$config = SimpleSAML_Configuration::getOptionalConfig('acl.php');
+		$config = \SimpleSAML\Configuration::getOptionalConfig('acl.php');
 		if (!$config->hasValue($id)) {
-			throw new SimpleSAML_Error_Exception('No ACL with id ' . var_export($id, TRUE) . ' in config/acl.php.');
+			throw new \SimpleSAML\Error\Exception('No ACL with id ' . var_export($id, TRUE) . ' in config/acl.php.');
 		}
 
 		return $config->getArray($id);
@@ -119,7 +122,7 @@ class sspmod_core_ACL {
 		case 'or':
 			return self::opOr($attributes, $rule);
 		default:
-			throw new SimpleSAML_Error_Exception('Invalid ACL operation: ' . var_export($op, TRUE));
+			throw new \SimpleSAML\Error\Exception('Invalid ACL operation: ' . var_export($op, TRUE));
 		}
 	}
 
diff --git a/modules/core/lib/Auth/Process/AttributeAdd.php b/modules/core/lib/Auth/Process/AttributeAdd.php
index 63aa03fb2becf34654b18b7f95b7a307c912c7b9..e83a54f05573171c638f0b5540d343e524d04a5b 100644
--- a/modules/core/lib/Auth/Process/AttributeAdd.php
+++ b/modules/core/lib/Auth/Process/AttributeAdd.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\core\Auth\Process;
+
 /**
  * Filter to add attributes.
  *
@@ -8,8 +10,9 @@
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class sspmod_core_Auth_Process_AttributeAdd extends SimpleSAML_Auth_ProcessingFilter {
 
+class AttributeAdd extends \SimpleSAML\Auth\ProcessingFilter
+{
 	/**
 	 * Flag which indicates wheter this filter should append new values or replace old values.
 	 */
@@ -40,7 +43,7 @@ class sspmod_core_Auth_Process_AttributeAdd extends SimpleSAML_Auth_ProcessingFi
 				if($values === '%replace') {
 					$this->replace = TRUE;
 				} else {
-					throw new Exception('Unknown flag: ' . var_export($values, TRUE));
+					throw new \Exception('Unknown flag: ' . var_export($values, TRUE));
 				}
 				continue;
 			}
@@ -50,7 +53,7 @@ class sspmod_core_Auth_Process_AttributeAdd extends SimpleSAML_Auth_ProcessingFi
 			}
 			foreach($values as $value) {
 				if(!is_string($value)) {
-					throw new Exception('Invalid value for attribute ' . $name . ': ' .
+					throw new \Exception('Invalid value for attribute ' . $name . ': ' .
 						var_export($values, TRUE));
 				}
 			}
@@ -81,5 +84,4 @@ class sspmod_core_Auth_Process_AttributeAdd extends SimpleSAML_Auth_ProcessingFi
 			}
 		}
 	}
-
 }
diff --git a/modules/core/lib/Auth/Process/AttributeAlter.php b/modules/core/lib/Auth/Process/AttributeAlter.php
index 984bae118d04d3f29fa8c19314b620161ed83dec..da0546e9b640d91d5ca5a9c2fe28c93f75f21ce9 100644
--- a/modules/core/lib/Auth/Process/AttributeAlter.php
+++ b/modules/core/lib/Auth/Process/AttributeAlter.php
@@ -1,4 +1,7 @@
 <?php
+
+namespace SimpleSAML\Module\core\Auth\Process;
+
 /**
  * Filter to modify attributes using regular expressions
  *
@@ -7,17 +10,18 @@
  * @author Jacob Christiansen, WAYF
  * @package SimpleSAMLphp
  */
-class sspmod_core_Auth_Process_AttributeAlter extends SimpleSAML_Auth_ProcessingFilter {
 
+class AttributeAlter extends \SimpleSAML\Auth\ProcessingFilter
+{
     /**
      * Should the pattern found be replaced?
      */
-    private $replace = FALSE;
+    private $replace = false;
 
     /**
      * Should the value found be removed?
      */
-    private $remove = FALSE;
+    private $remove = false;
 
     /**
      * Pattern to search for.
@@ -27,7 +31,7 @@ class sspmod_core_Auth_Process_AttributeAlter extends SimpleSAML_Auth_Processing
     /**
      * String to replace the pattern found with.
      */
-    private $replacement = FALSE;
+    private $replacement = false;
 
     /**
      * Attribute to search in
@@ -44,9 +48,10 @@ class sspmod_core_Auth_Process_AttributeAlter extends SimpleSAML_Auth_Processing
      *
      * @param array $config  Configuration information about this filter.
      * @param mixed $reserved  For future use.
-     * @throws SimpleSAML_Error_Exception In case of invalid configuration.
+     * @throws \SimpleSAML\Error\Exception In case of invalid configuration.
      */
-    public function __construct($config, $reserved) {
+    public function __construct($config, $reserved)
+    {
         parent::__construct($config, $reserved);
 
         assert(is_array($config));
@@ -55,33 +60,25 @@ class sspmod_core_Auth_Process_AttributeAlter extends SimpleSAML_Auth_Processing
         foreach ($config as $name => $value) {
             if (is_int($name)) {
                 // check if this is an option
-                if($value === '%replace') {
-                    $this->replace = TRUE;
+                if ($value === '%replace') {
+                    $this->replace = true;
                 } elseif ($value === '%remove') {
-                    $this->remove = TRUE;
+                    $this->remove = true;
                 } else {
-                    throw new SimpleSAML_Error_Exception('Unknown flag : ' . var_export($value, TRUE));
+                    throw new \SimpleSAML\Error\Exception('Unknown flag : ' . var_export($value, true));
                 }
                 continue;
-            }
-
-            // Set pattern
-            if ($name === 'pattern') {
+            } elseif ($name === 'pattern') {
+                // Set pattern
                 $this->pattern = $value;
-            }
-
-            // Set replacement
-            if ($name === 'replacement') {
+            } elseif ($name === 'replacement') {
+                // Set replacement
                 $this->replacement = $value;
-            }
-
-            // Set subject
-            if ($name === 'subject') {
+            } elseif ($name === 'subject') {
+                // Set subject
                 $this->subject = $value;
-            }
-
-            // Set target
-            if ($name === 'target') {
+            } elseif ($name === 'target') {
+                // Set target
                 $this->target = $value;
             }
         }
@@ -93,7 +90,7 @@ class sspmod_core_Auth_Process_AttributeAlter extends SimpleSAML_Auth_Processing
      * Modify existing attributes with the configured values.
      *
      * @param array &$request The current request.
-     * @throws SimpleSAML_Error_Exception In case of invalid configuration.
+     * @throws \SimpleSAML\Error\Exception In case of invalid configuration.
      */
     public function process(&$request) {
         assert(is_array($request));
@@ -104,20 +101,20 @@ class sspmod_core_Auth_Process_AttributeAlter extends SimpleSAML_Auth_Processing
 
         // check that all required params are set in config
         if (empty($this->pattern) || empty($this->subject)) {
-            throw new SimpleSAML_Error_Exception("Not all params set in config.");
+            throw new \SimpleSAML\Error\Exception("Not all params set in config.");
         }
 
         if (!$this->replace && !$this->remove && $this->replacement === false) {
-            throw new SimpleSAML_Error_Exception("'replacement' must be set if neither '%replace' nor ".
+            throw new \SimpleSAML\Error\Exception("'replacement' must be set if neither '%replace' nor ".
                 "'%remove' are set.");
         }
 
         if (!$this->replace && $this->replacement === null) {
-            throw new SimpleSAML_Error_Exception("'%replace' must be set if 'replacement' is null.");
+            throw new \SimpleSAML\Error\Exception("'%replace' must be set if 'replacement' is null.");
         }
 
         if ($this->replace && $this->remove) {
-            throw new SimpleSAML_Error_Exception("'%replace' and '%remove' cannot be used together.");
+            throw new \SimpleSAML\Error\Exception("'%replace' and '%remove' cannot be used together.");
         }
 
         if (empty($this->target)) {
@@ -126,7 +123,7 @@ class sspmod_core_Auth_Process_AttributeAlter extends SimpleSAML_Auth_Processing
         }
 
         if ($this->subject !== $this->target && $this->remove) {
-            throw new SimpleSAML_Error_Exception("Cannot use '%remove' when 'target' is different than 'subject'.");
+            throw new \SimpleSAML\Error\Exception("Cannot use '%remove' when 'target' is different than 'subject'.");
         }
 
         if (!array_key_exists($this->subject, $attributes)) {
@@ -166,12 +163,19 @@ class sspmod_core_Auth_Process_AttributeAlter extends SimpleSAML_Auth_Processing
             }
         } else { // replace only the part that matches
             if ($this->subject === $this->target) {
-                $attributes[$this->target] = preg_replace($this->pattern, $this->replacement,
-                                                          $attributes[$this->subject]);
+                $attributes[$this->target] = preg_replace(
+                    $this->pattern, $this->replacement,
+                    $attributes[$this->subject]
+                );
             } else {
-                $attributes[$this->target] = array_diff(preg_replace($this->pattern, $this->replacement,
-                                                                     $attributes[$this->subject]),
-                                                        $attributes[$this->subject]);
+                $attributes[$this->target] = array_diff(
+                    preg_replace(
+                        $this->pattern,
+                        $this->replacement,
+                        $attributes[$this->subject]
+                    ),
+                    $attributes[$this->subject]
+                );
             }
         }
     }
diff --git a/modules/core/lib/Auth/Process/AttributeCopy.php b/modules/core/lib/Auth/Process/AttributeCopy.php
index e2412a45c8d0ff36e41bf9cfc2e51a89d12ec48c..0e156d956fb40b42d055453316b7bd23e1e3b22c 100644
--- a/modules/core/lib/Auth/Process/AttributeCopy.php
+++ b/modules/core/lib/Auth/Process/AttributeCopy.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\core\Auth\Process;
+
 /**
  * Attribute filter for renaming attributes.
  *
@@ -15,8 +17,9 @@
  *         ),
  *
  */
-class sspmod_core_Auth_Process_AttributeCopy extends SimpleSAML_Auth_ProcessingFilter {
 
+class AttributeCopy extends \SimpleSAML\Auth\ProcessingFilter
+{
 	/**
 	 * Assosiative array with the mappings of attribute names.
 	 */
@@ -37,11 +40,11 @@ class sspmod_core_Auth_Process_AttributeCopy extends SimpleSAML_Auth_ProcessingF
 		foreach($config as $source => $destination) {
 
 			if(!is_string($source)) {
-				throw new Exception('Invalid source attribute name: ' . var_export($source, TRUE));
+				throw new \Exception('Invalid source attribute name: ' . var_export($source, TRUE));
 			}
 
 			if(!is_string($destination) && !is_array($destination)) {
-				throw new Exception('Invalid destination attribute name: ' . var_export($destination, TRUE));
+				throw new \Exception('Invalid destination attribute name: ' . var_export($destination, TRUE));
 			}
 
 			$this->map[$source] = $destination;
diff --git a/modules/core/lib/Auth/Process/AttributeLimit.php b/modules/core/lib/Auth/Process/AttributeLimit.php
index d74d60355c1fd103caa9945cd7e75fbb3f3093db..70e991590b4899847ac0468c3968050820d1d176 100644
--- a/modules/core/lib/Auth/Process/AttributeLimit.php
+++ b/modules/core/lib/Auth/Process/AttributeLimit.php
@@ -1,13 +1,16 @@
 <?php
 
+namespace SimpleSAML\Module\core\Auth\Process;
+
 /**
  * A filter for limiting which attributes are passed on.
  *
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class sspmod_core_Auth_Process_AttributeLimit extends SimpleSAML_Auth_ProcessingFilter {
 
+class AttributeLimit extends \SimpleSAML\Auth\ProcessingFilter
+{
 	/**
 	 * List of attributes which this filter will allow through.
 	 */
@@ -19,7 +22,7 @@ class sspmod_core_Auth_Process_AttributeLimit extends SimpleSAML_Auth_Processing
 	 *
 	 * @var bool
 	 */
-	private $isDefault = FALSE;
+	private $isDefault = false;
 
 
 	/**
@@ -27,7 +30,7 @@ class sspmod_core_Auth_Process_AttributeLimit extends SimpleSAML_Auth_Processing
 	 *
 	 * @param array $config  Configuration information about this filter.
 	 * @param mixed $reserved  For future use
-     * @throws SimpleSAML_Error_Exception If invalid configuration is found.
+	 * @throws \SimpleSAML\Error\Exception If invalid configuration is found.
 	 */
 	public function __construct($config, $reserved) {
 		parent::__construct($config, $reserved);
@@ -39,18 +42,18 @@ class sspmod_core_Auth_Process_AttributeLimit extends SimpleSAML_Auth_Processing
 				$this->isDefault = (bool)$value;
 			} elseif (is_int($index)) {
 				if (!is_string($value)) {
-					throw new SimpleSAML_Error_Exception('AttributeLimit: Invalid attribute name: ' .
+					throw new \SimpleSAML\Error\Exception('AttributeLimit: Invalid attribute name: ' .
                         var_export($value, TRUE));
 				}
 				$this->allowedAttributes[] = $value;
             } elseif (is_string($index)) {
                 if (!is_array($value)) {
-                    throw new SimpleSAML_Error_Exception('AttributeLimit: Values for ' . var_export($index, TRUE) .
+                    throw new \SimpleSAML\Error\Exception('AttributeLimit: Values for ' . var_export($index, TRUE) .
                         ' must be specified in an array.');
                 }
                 $this->allowedAttributes[$index] = $value;
 			} else {
-				throw new SimpleSAML_Error_Exception('AttributeLimit: Invalid option: ' . var_export($index, TRUE));
+				throw new \SimpleSAML\Error\Exception('AttributeLimit: Invalid option: ' . var_export($index, TRUE));
 			}
 		}
 	}
@@ -82,7 +85,7 @@ class sspmod_core_Auth_Process_AttributeLimit extends SimpleSAML_Auth_Processing
 	 * Removes all attributes which aren't one of the allowed attributes.
 	 *
 	 * @param array &$request  The current request
-     * @throws SimpleSAML_Error_Exception If invalid configuration is found.
+	 * @throws \SimpleSAML\Error\Exception If invalid configuration is found.
 	 */
 	public function process(&$request) {
 		assert(is_array($request));
@@ -110,10 +113,10 @@ class sspmod_core_Auth_Process_AttributeLimit extends SimpleSAML_Auth_Processing
                 if (array_key_exists($name, $allowedAttributes)) {
                     // but it is an index of the array
                     if (!is_array($allowedAttributes[$name])) {
-                        throw new SimpleSAML_Error_Exception('AttributeLimit: Values for ' . var_export($name, TRUE) .
+                        throw new \SimpleSAML\Error\Exception('AttributeLimit: Values for ' . var_export($name, TRUE) .
                             ' must be specified in an array.');
                     }
-                    $attributes[$name] = array_intersect($attributes[$name], $allowedAttributes[$name]);
+                    $attributes[$name] = $this->filterAttributeValues($attributes[$name], $allowedAttributes[$name]);
                     if (!empty($attributes[$name])) {
                         continue;
                     }
@@ -124,4 +127,45 @@ class sspmod_core_Auth_Process_AttributeLimit extends SimpleSAML_Auth_Processing
 
 	}
 
+    /**
+     * Perform the filtering of attributes
+     * @param array $values The current values for a given attribute
+     * @param array $allowedConfigValues The allowed values, and possibly configuration options.
+     * @return array The filtered values
+     */
+    private function filterAttributeValues(array $values, array $allowedConfigValues)
+    {
+        if (array_key_exists('regex', $allowedConfigValues) && $allowedConfigValues['regex'] === true) {
+            $matchedValues = array();
+            foreach ($allowedConfigValues as $option => $pattern) {
+                if (!is_int($option)) {
+                    // Ignore any configuration options in $allowedConfig. e.g. regex=>true
+                    continue;
+                }
+                foreach ($values as $index => $attributeValue) {
+                    /* Suppress errors in preg_match since phpunit is set to fail on warnings, which
+                       prevents us from testing with invalid regex.
+                    */
+                    $regexResult = @preg_match($pattern, $attributeValue);
+                    if ($regexResult === false) {
+                        \SimpleSAML\Logger::warning("Error processing regex '$pattern' on value '$attributeValue'");
+                        break;
+                    } elseif ($regexResult === 1) {
+                        $matchedValues[] = $attributeValue;
+                        // Remove matched value incase a subsequent regex also matches it.
+                        unset($values[$index]);
+                    }
+                }
+            }
+            return $matchedValues;
+        } elseif (array_key_exists('ignoreCase', $allowedConfigValues) && $allowedConfigValues['ignoreCase'] === true) {
+            unset($allowedConfigValues['ignoreCase']);
+            return array_uintersect($values, $allowedConfigValues, "strcasecmp");
+        }
+        // The not true values for these options shouldn't leak through to array_intersect
+        unset($allowedConfigValues['ignoreCase']);
+        unset($allowedConfigValues['regex']);
+
+        return array_intersect($values, $allowedConfigValues);
+    }
 }
diff --git a/modules/core/lib/Auth/Process/AttributeMap.php b/modules/core/lib/Auth/Process/AttributeMap.php
index 5de07cb24b229f8503adfe6c8150db31423bdbed..6eb229cd40b9819fa42a643bfb38fc835ceb5efa 100644
--- a/modules/core/lib/Auth/Process/AttributeMap.php
+++ b/modules/core/lib/Auth/Process/AttributeMap.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML\Module\core\Auth\Process;
 
 /**
  * Attribute filter for renaming attributes.
@@ -7,9 +8,9 @@
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class sspmod_core_Auth_Process_AttributeMap extends SimpleSAML_Auth_ProcessingFilter
-{
 
+class AttributeMap extends \SimpleSAML\Auth\ProcessingFilter
+{
     /**
      * Associative array with the mappings of attribute names.
      */
@@ -48,11 +49,11 @@ class sspmod_core_Auth_Process_AttributeMap extends SimpleSAML_Auth_ProcessingFi
             }
 
             if (!is_string($origName)) {
-                throw new Exception('Invalid attribute name: '.var_export($origName, true));
+                throw new \Exception('Invalid attribute name: '.var_export($origName, true));
             }
 
             if (!is_string($newName) && !is_array($newName)) {
-                throw new Exception('Invalid attribute name: '.var_export($newName, true));
+                throw new \Exception('Invalid attribute name: '.var_export($newName, true));
             }
 
             $this->map[$origName] = $newName;
@@ -75,26 +76,26 @@ class sspmod_core_Auth_Process_AttributeMap extends SimpleSAML_Auth_ProcessingFi
      */
     private function loadMapFile($fileName)
     {
-        $config = SimpleSAML_Configuration::getInstance();
+        $config = \SimpleSAML\Configuration::getInstance();
 
         $m = explode(':', $fileName);
         if (count($m) === 2) { // we are asked for a file in a module
-            if (!SimpleSAML\Module::isModuleEnabled($m[0])) {
-                throw new Exception("Module '$m[0]' is not enabled.");
+            if (!\SimpleSAML\Module::isModuleEnabled($m[0])) {
+                throw new \Exception("Module '$m[0]' is not enabled.");
             }
-            $filePath = SimpleSAML\Module::getModuleDir($m[0]).'/attributemap/'.$m[1].'.php';
+            $filePath = \SimpleSAML\Module::getModuleDir($m[0]).'/attributemap/'.$m[1].'.php';
         } else {
             $filePath = $config->getPathValue('attributenamemapdir', 'attributemap/').$fileName.'.php';
         }
 
         if (!file_exists($filePath)) {
-            throw new Exception('Could not find attribute map file: '.$filePath);
+            throw new \Exception('Could not find attribute map file: '.$filePath);
         }
 
         $attributemap = null;
         include($filePath);
         if (!is_array($attributemap)) {
-            throw new Exception('Attribute map file "'.$filePath.'" didn\'t define an attribute map.');
+            throw new \Exception('Attribute map file "'.$filePath.'" didn\'t define an attribute map.');
         }
 
         if ($this->duplicate) {
@@ -115,24 +116,28 @@ class sspmod_core_Auth_Process_AttributeMap extends SimpleSAML_Auth_ProcessingFi
         assert(is_array($request));
         assert(array_key_exists('Attributes', $request));
 
-        $attributes =& $request['Attributes'];
+        $mapped_attributes = array();
 
-        foreach ($attributes as $name => $values) {
+        foreach ($request['Attributes'] as $name => $values) {
             if (array_key_exists($name, $this->map)) {
                 if (!is_array($this->map[$name])) {
-                    if (!$this->duplicate) {
-                        unset($attributes[$name]);
+                    if ($this->duplicate) {
+                        $mapped_attributes[$name] = $values;
                     }
-                    $attributes[$this->map[$name]] = $values;
+                    $mapped_attributes[$this->map[$name]] = $values;
                 } else {
                     foreach ($this->map[$name] as $to_map) {
-                        $attributes[$to_map] = $values;
+                        $mapped_attributes[$to_map] = $values;
                     }
-                    if (!$this->duplicate && !in_array($name, $this->map[$name], true)) {
-                        unset($attributes[$name]);
+                    if ($this->duplicate && !in_array($name, $this->map[$name], true)) {
+                        $mapped_attributes[$name] = $values;
                     }
                 }
+            } else {
+                $mapped_attributes[$name] = $values;
             }
         }
+
+        $request['Attributes'] = $mapped_attributes;
     }
 }
diff --git a/modules/core/lib/Auth/Process/AttributeRealm.php b/modules/core/lib/Auth/Process/AttributeRealm.php
index 86c8be1b2f10e25b04873213d573f681e504a0d5..c32543d8b4b31a0c7295a566562b6b502d9c492e 100644
--- a/modules/core/lib/Auth/Process/AttributeRealm.php
+++ b/modules/core/lib/Auth/Process/AttributeRealm.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\core\Auth\Process;
+
 /**
  * Filter that will take the user ID on the format 'andreas@uninett.no'
  * and create a new attribute 'realm' that includes the value after the '@' sign.
@@ -8,8 +10,9 @@
  * @package SimpleSAMLphp
  * @deprecated Use ScopeFromAttribute instead.
  */
-class sspmod_core_Auth_Process_AttributeRealm extends SimpleSAML_Auth_ProcessingFilter {
 
+class AttributeRealm extends \SimpleSAML\Auth\ProcessingFilter
+{
     private $attributename = 'realm';
 
     /**
@@ -41,7 +44,7 @@ class sspmod_core_Auth_Process_AttributeRealm extends SimpleSAML_Auth_Processing
         $attributes =& $request['Attributes'];
 
         if (!array_key_exists('UserID', $request)) {
-            throw new Exception('core:AttributeRealm: Missing UserID for this user. Please' .
+            throw new \Exception('core:AttributeRealm: Missing UserID for this user. Please' .
                 ' check the \'userid.attribute\' option in the metadata against the' .
                 ' attributes provided by the authentication source.');
         }
diff --git a/modules/core/lib/Auth/Process/AttributeValueMap.php b/modules/core/lib/Auth/Process/AttributeValueMap.php
index 5c69048f69d97ba59fc97c57190f1f7c44582745..293bc9b13fbbf232206e8350b5197ff5472debd9 100644
--- a/modules/core/lib/Auth/Process/AttributeValueMap.php
+++ b/modules/core/lib/Auth/Process/AttributeValueMap.php
@@ -8,9 +8,9 @@ namespace SimpleSAML\Module\core\Auth\Process;
  * @author Martin van Es, m7
  * @package SimpleSAMLphp
  */
-class AttributeValueMap extends \SimpleSAML_Auth_ProcessingFilter
-{
 
+class AttributeValueMap extends \SimpleSAML\Auth\ProcessingFilter
+{
     /**
     * The name of the attribute we should assign values to (ie: the target attribute).
     */
@@ -41,7 +41,7 @@ class AttributeValueMap extends \SimpleSAML_Auth_ProcessingFilter
      *
      * @param array $config Configuration information about this filter.
      * @param mixed $reserved For future use.
-     * @throws \SimpleSAML_Error_Exception If the configuration is not valid.
+     * @throws \SimpleSAML\Error\Exception If the configuration is not valid.
     */
     public function __construct($config, $reserved)
     {
@@ -84,13 +84,13 @@ class AttributeValueMap extends \SimpleSAML_Auth_ProcessingFilter
 
         // now validate it
         if (!is_string($this->sourceattribute)) {
-            throw new \SimpleSAML_Error_Exception("AttributeValueMap: 'sourceattribute' configuration option not set.");
+            throw new \SimpleSAML\Error\Exception("AttributeValueMap: 'sourceattribute' configuration option not set.");
         }
         if (!is_string($this->targetattribute)) {
-            throw new \SimpleSAML_Error_Exception("AttributeValueMap: 'targetattribute' configuration option not set.");
+            throw new \SimpleSAML\Error\Exception("AttributeValueMap: 'targetattribute' configuration option not set.");
         }
         if (!is_array($this->values)) {
-            throw new \SimpleSAML_Error_Exception("AttributeValueMap: 'values' configuration option is not an array.");
+            throw new \SimpleSAML\Error\Exception("AttributeValueMap: 'values' configuration option is not an array.");
         }
     }
 
diff --git a/modules/core/lib/Auth/Process/Cardinality.php b/modules/core/lib/Auth/Process/Cardinality.php
new file mode 100644
index 0000000000000000000000000000000000000000..983431fce775c88a20b4c1ed2720d1c94245e80f
--- /dev/null
+++ b/modules/core/lib/Auth/Process/Cardinality.php
@@ -0,0 +1,175 @@
+<?php
+
+namespace SimpleSAML\Module\core\Auth\Process;
+
+use SimpleSAML\Utils\HTTPAdapter;
+
+/**
+ * Filter to ensure correct cardinality of attributes
+ *
+ * @author Guy Halse, http://orcid.org/0000-0002-9388-8592
+ * @package SimpleSAMLphp
+ */
+
+class Cardinality extends \SimpleSAML\Auth\ProcessingFilter
+{
+    /** @var array Associative array with the mappings of attribute names. */
+    private $cardinality = array();
+
+    /** @var array Entities that should be ignored */
+    private $ignoreEntities = array();
+
+    /** @var HTTPAdapter */
+    private $http;
+
+    /**
+     * Initialize this filter, parse configuration.
+     *
+     * @param array $config  Configuration information about this filter.
+     * @param mixed $reserved  For future use.
+     * @param HTTPAdapter $http  HTTP utility service (handles redirects).
+     * @throws \SimpleSAML\Error\Exception
+     */
+    public function __construct($config, $reserved, HTTPAdapter $http = null)
+    {
+        parent::__construct($config, $reserved);
+        assert(is_array($config));
+
+        $this->http = $http ?: new HTTPAdapter();
+
+        foreach ($config as $attribute => $rules) {
+            if ($attribute === '%ignoreEntities') {
+                $this->ignoreEntities = $config['%ignoreEntities'];
+                continue;
+            }
+
+            if (!is_string($attribute)) {
+                throw new \SimpleSAML\Error\Exception('Invalid attribute name: '.var_export($attribute, true));
+            }
+            $this->cardinality[$attribute] = array('warn' => false);
+
+            /* allow either positional or name-based parameters */
+            if (isset($rules[0])) {
+                $this->cardinality[$attribute]['min'] = $rules[0];
+            } elseif (isset($rules['min'])) {
+                $this->cardinality[$attribute]['min'] = $rules['min'];
+            }
+            if (isset($rules[1])) {
+                $this->cardinality[$attribute]['max'] = $rules[1];
+            } elseif (isset($rules['max'])) {
+                $this->cardinality[$attribute]['max'] = $rules['max'];
+            }
+            if (array_key_exists('warn', $rules)) {
+                $this->cardinality[$attribute]['warn'] = (bool) $rules['warn'];
+            }
+
+            /* sanity check the rules */
+            if (!array_key_exists('min', $this->cardinality[$attribute])) {
+                $this->cardinality[$attribute]['min'] = 0;
+            } elseif (!is_int($this->cardinality[$attribute]['min']) ||
+                $this->cardinality[$attribute]['min'] < 0
+            ) {
+                throw new \SimpleSAML\Error\Exception('Minimum cardinality must be a positive integer: '.
+                    var_export($attribute, true));
+            }
+            if (array_key_exists('max', $this->cardinality[$attribute]) &&
+                !is_int($this->cardinality[$attribute]['max'])
+            ) {
+                throw new \SimpleSAML\Error\Exception('Maximum cardinality must be a positive integer: '.
+                    var_export($attribute, true));
+            }
+            if (array_key_exists('min', $this->cardinality[$attribute]) &&
+                array_key_exists('max', $this->cardinality[$attribute]) &&
+                $this->cardinality[$attribute]['min'] > $this->cardinality[$attribute]['max']
+            ) {
+                throw new \SimpleSAML\Error\Exception('Minimum cardinality must be less than maximium: '.
+                    var_export($attribute, true));
+            }
+
+            /* generate a display expression */
+            $this->cardinality[$attribute]['_expr'] = sprintf('%d ≤ n', $this->cardinality[$attribute]['min']);
+            if (array_key_exists('max', $this->cardinality[$attribute])) {
+                $this->cardinality[$attribute]['_expr'] .= sprintf(' ≤ %d', $this->cardinality[$attribute]['max']);
+            }
+        }
+    }
+
+    /**
+     * Process this filter
+     *
+     * @param array &$request  The current request
+     */
+    public function process(&$request)
+    {
+        assert(is_array($request));
+        assert(array_key_exists("Attributes", $request));
+
+        $entityid = false;
+        if (array_key_exists('Source', $request) && array_key_exists('entityid', $request['Source'])) {
+            $entityid = $request['Source']['entityid'];
+        }
+        if (in_array($entityid, $this->ignoreEntities, true)) {
+            \SimpleSAML\Logger::debug('Cardinality: Ignoring assertions from '.$entityid);
+            return;
+        }
+
+        foreach ($request['Attributes'] as $k => $v) {
+
+            if (!array_key_exists($k, $this->cardinality)) {
+                continue;
+            }
+            if (!is_array($v)) {
+                $v = array($v);
+            }
+
+            /* minimum cardinality */
+            if (count($v) < $this->cardinality[$k]['min']) {
+                if ($this->cardinality[$k]['warn']) {
+                    \SimpleSAML\Logger::warning(sprintf(
+                        'Cardinality: attribute %s from %s does not meet minimum cardinality of %d (%d)',
+                        $k, $entityid, $this->cardinality[$k]['min'], count($v)
+                    ));
+                } else {
+                    $request['core:cardinality:errorAttributes'][$k] = array(count($v), $this->cardinality[$k]['_expr']);
+                }
+                continue;
+            }
+
+            /* maximum cardinality */
+            if (array_key_exists('max', $this->cardinality[$k]) && count($v) > $this->cardinality[$k]['max']) {
+                if ($this->cardinality[$k]['warn']) {
+                    \SimpleSAML\Logger::warning(sprintf(
+                        'Cardinality: attribute %s from %s does not meet maximum cardinality of %d (%d)',
+                        $k, $entityid, $this->cardinality[$k]['max'], count($v)
+                    ));
+                } else {
+                    $request['core:cardinality:errorAttributes'][$k] = array(count($v), $this->cardinality[$k]['_expr']);
+                }
+                continue;
+            }
+        }
+
+        /* check for missing attributes with a minimum cardinality */
+        foreach ($this->cardinality as $k => $v) {
+            if (!$this->cardinality[$k]['min'] || array_key_exists($k, $request['Attributes'])) {
+                continue;
+            }
+            if ($this->cardinality[$k]['warn']) {
+                \SimpleSAML\Logger::warning(sprintf(
+                    'Cardinality: attribute %s from %s is missing',
+                    $k, $entityid
+                ));
+            } else {
+                $request['core:cardinality:errorAttributes'][$k] = array(0, $this->cardinality[$k]['_expr']);
+            }
+        }
+
+        /* abort if we found a problematic attribute */
+        if (array_key_exists('core:cardinality:errorAttributes', $request)) {
+            $id = \SimpleSAML\Auth\State::saveState($request, 'core:cardinality');
+            $url = \SimpleSAML\Module::getModuleURL('core/cardinality_error.php');
+            $this->http->redirectTrustedURL($url, array('StateId' => $id));
+            return;
+        }
+    }
+}
diff --git a/modules/core/lib/Auth/Process/CardinalitySingle.php b/modules/core/lib/Auth/Process/CardinalitySingle.php
new file mode 100644
index 0000000000000000000000000000000000000000..0d4b180f378881c08c6607d69e64c6a02c05a3dd
--- /dev/null
+++ b/modules/core/lib/Auth/Process/CardinalitySingle.php
@@ -0,0 +1,120 @@
+<?php
+
+namespace SimpleSAML\Module\core\Auth\Process;
+
+use SimpleSAML\Utils\HttpAdapter;
+
+/**
+ * Filter to ensure correct cardinality of single-valued attributes
+ *
+ * This filter implements a special case of the core:Cardinality filter, and
+ * allows for optional corrections to be made when cardinality errors are encountered.
+ *
+ * @author Guy Halse, http://orcid.org/0000-0002-9388-8592
+ * @package SimpleSAMLphp
+ */
+
+class CardinalitySingle extends \SimpleSAML\Auth\ProcessingFilter
+{
+    /** @var array Attributes that should be single-valued or we generate an error */
+    private $singleValued = array();
+
+    /** @var array Attributes for which the first value should be taken */
+    private $firstValue = array();
+
+    /** @var array Attributes that can be flattened to a single value */
+    private $flatten = array();
+
+    /** @var string Separator for flattened value */
+    private $flattenWith = ';';
+
+    /** @var array Entities that should be ignored */
+    private $ignoreEntities = array();
+
+    /** @var HTTPAdapter */
+    private $http;
+
+    /**
+     * Initialize this filter, parse configuration.
+     *
+     * @param array $config  Configuration information about this filter.
+     * @param mixed $reserved  For future use.
+     * @param HTTPAdapter $http  HTTP utility service (handles redirects).
+     */
+    public function __construct($config, $reserved, HTTPAdapter $http = null)
+    {
+        parent::__construct($config, $reserved);
+        assert(is_array($config));
+
+        $this->http = $http ?: new HTTPAdapter();
+
+        if (array_key_exists('singleValued', $config)) {
+            $this->singleValued = $config['singleValued'];
+        }
+        if (array_key_exists('firstValue', $config)) {
+            $this->firstValue = $config['firstValue'];
+        }
+        if (array_key_exists('flattenWith', $config)) {
+            $this->flattenWith = is_array($config['flattenWith']) ? array_shift($config['flattenWith']) : $config['flattenWith'];
+        }
+        if (array_key_exists('flatten', $config)) {
+            $this->flatten = $config['flatten'];
+        }
+        if (array_key_exists('ignoreEntities', $config)) {
+            $this->ignoreEntities = $config['ignoreEntities'];
+        }
+        /* for consistency with core:Cardinality */
+        if (array_key_exists('%ignoreEntities', $config)) {
+            $this->ignoreEntities = $config['%ignoreEntities'];
+        }
+    }
+
+    /**
+     * Process this filter
+     *
+     * @param array &$request  The current request
+     */
+    public function process(&$request)
+    {
+        assert(is_array($request));
+        assert(array_key_exists("Attributes", $request));
+
+        if (array_key_exists('Source', $request) &&
+            array_key_exists('entityid', $request['Source']) &&
+            in_array($request['Source']['entityid'], $this->ignoreEntities, true)
+        ) {
+            \SimpleSAML\Logger::debug('CardinalitySingle: Ignoring assertions from '.$request['Source']['entityid']);
+            return;
+        }
+
+        foreach ($request['Attributes'] as $k => $v) {
+            if (!is_array($v)) {
+                continue;
+            }
+            if (count($v) <= 1) {
+                continue;
+            }
+
+            if (in_array($k, $this->singleValued)) {
+                $request['core:cardinality:errorAttributes'][$k] = array(count($v), '0 ≤ n ≤ 1');
+                continue;
+            }
+            if (in_array($k, $this->firstValue)) {
+                $request['Attributes'][$k] = array(array_shift($v));
+                continue;
+            }
+            if (in_array($k, $this->flatten)) {
+                $request['Attributes'][$k] = array(implode($this->flattenWith, $v));
+                continue;
+            }
+        }
+
+        /* abort if we found a problematic attribute */
+        if (array_key_exists('core:cardinality:errorAttributes', $request)) {
+            $id = \SimpleSAML\Auth\State::saveState($request, 'core:cardinality');
+            $url = \SimpleSAML\Module::getModuleURL('core/cardinality_error.php');
+            $this->http->redirectTrustedURL($url, array('StateId' => $id));
+            return;
+        }
+    }
+}
diff --git a/modules/core/lib/Auth/Process/ExtendIdPSession.php b/modules/core/lib/Auth/Process/ExtendIdPSession.php
index faca137a8a80ec1e84ae609d7cb9da09fa38ca6e..4a4bd5ae51b777415fbc7ad2e5c4b28c7f2746bf 100644
--- a/modules/core/lib/Auth/Process/ExtendIdPSession.php
+++ b/modules/core/lib/Auth/Process/ExtendIdPSession.php
@@ -1,10 +1,13 @@
 <?php
 
+namespace SimpleSAML\Module\core\Auth\Process;
+
 /**
  * Extend IdP session and cookies.
 */
-class sspmod_core_Auth_Process_ExtendIdPSession extends SimpleSAML_Auth_ProcessingFilter {
 
+class ExtendIdPSession extends \SimpleSAML\Auth\ProcessingFilter
+{
 	public function process(&$state) {
 		assert(is_array($state));
 
@@ -15,7 +18,7 @@ class sspmod_core_Auth_Process_ExtendIdPSession extends SimpleSAML_Auth_Processi
 		$now = time();
 		$delta = $state['Expire'] - $now;
 
-		$globalConfig = SimpleSAML_Configuration::getInstance();
+		$globalConfig = \SimpleSAML\Configuration::getInstance();
 		$sessionDuration = $globalConfig->getInteger('session.duration', 8*60*60);
 
 		// Extend only if half of session duration already passed
@@ -24,7 +27,7 @@ class sspmod_core_Auth_Process_ExtendIdPSession extends SimpleSAML_Auth_Processi
 		}
 
 		// Update authority expire time
-		$session = SimpleSAML_Session::getSessionFromRequest();
+		$session = \SimpleSAML\Session::getSessionFromRequest();
 		$session->setAuthorityExpire($state['Authority']);
 
 		/* Update session cookies duration */
diff --git a/modules/core/lib/Auth/Process/GenerateGroups.php b/modules/core/lib/Auth/Process/GenerateGroups.php
index 17b896e5f28e17f2221f4a9791833cd383d21e3c..f2bdf41b82b5c091fd51cec05f52b30f27b99997 100644
--- a/modules/core/lib/Auth/Process/GenerateGroups.php
+++ b/modules/core/lib/Auth/Process/GenerateGroups.php
@@ -1,14 +1,16 @@
 <?php
 
+namespace SimpleSAML\Module\core\Auth\Process;
+
 /**
  * Filter to generate a groups attribute based on many of the attributes of the user.
  *
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class sspmod_core_Auth_Process_GenerateGroups extends SimpleSAML_Auth_ProcessingFilter {
-
 
+class GenerateGroups extends \SimpleSAML\Auth\ProcessingFilter
+{
 	/**
 	 * The attributes we should generate groups from.
 	 */
@@ -38,7 +40,7 @@ class sspmod_core_Auth_Process_GenerateGroups extends SimpleSAML_Auth_Processing
 			// Validate configuration
 			foreach ($config as $attributeName) {
 				if (!is_string($attributeName)) {
-					throw new Exception('Invalid attribute name for core:GenerateGroups filter: ' .
+					throw new \Exception('Invalid attribute name for core:GenerateGroups filter: ' .
 						var_export($attributeName, TRUE));
 				}
 			}
@@ -68,7 +70,7 @@ class sspmod_core_Auth_Process_GenerateGroups extends SimpleSAML_Auth_Processing
 
 		foreach ($this->generateGroupsFrom as $name) {
 			if (!array_key_exists($name, $attributes)) {
-				SimpleSAML\Logger::debug('GenerateGroups - attribute \'' . $name . '\' not found.');
+				\SimpleSAML\Logger::debug('GenerateGroups - attribute \'' . $name . '\' not found.');
 				/* Attribute not present. */
 				continue;
 			}
diff --git a/modules/core/lib/Auth/Process/LanguageAdaptor.php b/modules/core/lib/Auth/Process/LanguageAdaptor.php
index 4a1b381405255b2f441089e95f5595db24243326..eb120e29af782af277531cf947fb2c5e0c34408c 100644
--- a/modules/core/lib/Auth/Process/LanguageAdaptor.php
+++ b/modules/core/lib/Auth/Process/LanguageAdaptor.php
@@ -1,13 +1,16 @@
 <?php
 
+namespace SimpleSAML\Module\core\Auth\Process;
+
 /**
  * Filter to set and get language settings from attributes.
  *
  * @author Andreas Ă…kre Solberg, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class sspmod_core_Auth_Process_LanguageAdaptor extends SimpleSAML_Auth_ProcessingFilter {
 
+class LanguageAdaptor extends \SimpleSAML\Auth\ProcessingFilter
+{
 	private $langattr = 'preferredLanguage';
 
 
@@ -44,18 +47,18 @@ class sspmod_core_Auth_Process_LanguageAdaptor extends SimpleSAML_Auth_Processin
 		if (array_key_exists($this->langattr, $attributes))
 			$attrlang = $attributes[$this->langattr][0];
 
-		$lang = SimpleSAML\Locale\Language::getLanguageCookie();
+		$lang = \SimpleSAML\Locale\Language::getLanguageCookie();
 
 
 		if (isset($attrlang))
-			SimpleSAML\Logger::debug('LanguageAdaptor: Language in attribute was set [' . $attrlang . ']');
+			\SimpleSAML\Logger::debug('LanguageAdaptor: Language in attribute was set [' . $attrlang . ']');
 		if (isset($lang))
-			SimpleSAML\Logger::debug('LanguageAdaptor: Language in session   was set [' . $lang . ']');
+			\SimpleSAML\Logger::debug('LanguageAdaptor: Language in session   was set [' . $lang . ']');
 
 
 		if (isset($attrlang) && !isset($lang)) {
 			// Language set in attribute but not in cookie - update cookie
-			SimpleSAML\Locale\Language::setLanguageCookie($attrlang);
+			\SimpleSAML\Locale\Language::setLanguageCookie($attrlang);
 		} elseif (!isset($attrlang) && isset($lang)) {
 			// Language set in cookie, but not in attribute. Update attribute
 			$request['Attributes'][$this->langattr] = array($lang);
diff --git a/modules/core/lib/Auth/Process/PHP.php b/modules/core/lib/Auth/Process/PHP.php
index 48d668c4ee62f99d6d911055cadc3b31ee0a4521..386a5991927cdd74d5a5776b89f3c7b51bdba85e 100644
--- a/modules/core/lib/Auth/Process/PHP.php
+++ b/modules/core/lib/Auth/Process/PHP.php
@@ -1,14 +1,15 @@
 <?php
 
+namespace SimpleSAML\Module\core\Auth\Process;
 
 /**
  * Attribute filter for running arbitrary PHP code.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_core_Auth_Process_PHP extends SimpleSAML_Auth_ProcessingFilter
-{
 
+class PHP extends \SimpleSAML\Auth\ProcessingFilter
+{
     /**
      * The PHP code that should be run.
      *
@@ -23,7 +24,7 @@ class sspmod_core_Auth_Process_PHP extends SimpleSAML_Auth_ProcessingFilter
      * @param array $config Configuration information about this filter.
      * @param mixed $reserved For future use.
      *
-     * @throws SimpleSAML_Error_Exception if the 'code' option is not defined.
+     * @throws \SimpleSAML\Error\Exception if the 'code' option is not defined.
      */
     public function __construct($config, $reserved)
     {
@@ -32,7 +33,7 @@ class sspmod_core_Auth_Process_PHP extends SimpleSAML_Auth_ProcessingFilter
         assert(is_array($config));
 
         if (!isset($config['code'])) {
-            throw new SimpleSAML_Error_Exception("core:PHP: missing mandatory configuration option 'code'.");
+            throw new \SimpleSAML\Error\Exception("core:PHP: missing mandatory configuration option 'code'.");
         }
         $this->code = (string) $config['code'];
     }
@@ -48,7 +49,7 @@ class sspmod_core_Auth_Process_PHP extends SimpleSAML_Auth_ProcessingFilter
         assert(is_array($request));
         assert(array_key_exists('Attributes', $request));
 
-        $function = create_function('&$attributes', $this->code);
+        $function = function(&$attributes) { eval($this->code); };
         $function($request['Attributes']);
     }
 }
diff --git a/modules/core/lib/Auth/Process/ScopeAttribute.php b/modules/core/lib/Auth/Process/ScopeAttribute.php
index 21b6a0553d17703e45233ed7515fb9697dc47035..ee7eb0409ceff20ba275ad0f33b1e33888be70b5 100644
--- a/modules/core/lib/Auth/Process/ScopeAttribute.php
+++ b/modules/core/lib/Auth/Process/ScopeAttribute.php
@@ -1,12 +1,15 @@
 <?php
 
+namespace SimpleSAML\Module\core\Auth\Process;
+
 /**
  * Add a scoped variant of an attribute.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_core_Auth_Process_ScopeAttribute extends SimpleSAML_Auth_ProcessingFilter {
 
+class ScopeAttribute extends \SimpleSAML\Auth\ProcessingFilter
+{
 	/**
 	 * The attribute we extract the scope from.
 	 *
@@ -44,11 +47,12 @@ class sspmod_core_Auth_Process_ScopeAttribute extends SimpleSAML_Auth_Processing
 	 * @param array $config  Configuration information about this filter.
 	 * @param mixed $reserved  For future use.
 	 */
-	public function __construct($config, $reserved) {
+	public function __construct($config, $reserved)
+    {
 		parent::__construct($config, $reserved);
 		assert(is_array($config));
 
-		$config = SimpleSAML_Configuration::loadFromArray($config, 'ScopeAttribute');
+		$config = \SimpleSAML\Configuration::loadFromArray($config, 'ScopeAttribute');
 
 		$this->scopeAttribute = $config->getString('scopeAttribute');
 		$this->sourceAttribute = $config->getString('sourceAttribute');
@@ -62,7 +66,8 @@ class sspmod_core_Auth_Process_ScopeAttribute extends SimpleSAML_Auth_Processing
 	 *
 	 * @param array &$request  The current request
 	 */
-	public function process(&$request) {
+	public function process(&$request)
+    {
 		assert(is_array($request));
 		assert(array_key_exists('Attributes', $request));
 
@@ -80,13 +85,12 @@ class sspmod_core_Auth_Process_ScopeAttribute extends SimpleSAML_Auth_Processing
 			$attributes[$this->targetAttribute] = array();
 		}
 
-		if ($this->onlyIfEmpty and count($attributes[$this->targetAttribute]) > 0) {
+		if ($this->onlyIfEmpty && count($attributes[$this->targetAttribute]) > 0) {
 			return;
 		}
 
 		foreach ($attributes[$this->scopeAttribute] as $scope) {
-
-			if (strpos($scope, '@') !== FALSE) {
+			if (strpos($scope, '@') !== false) {
 				$scope = explode('@', $scope, 2);
 				$scope = $scope[1];
 			}
@@ -94,7 +98,7 @@ class sspmod_core_Auth_Process_ScopeAttribute extends SimpleSAML_Auth_Processing
 			foreach ($attributes[$this->sourceAttribute] as $value) {
 				$value = $value . '@' . $scope;
 
-				if (in_array($value, $attributes[$this->targetAttribute], TRUE)) {
+				if (in_array($value, $attributes[$this->targetAttribute], true)) {
 					// Already present
 					continue;
 				}
@@ -102,7 +106,5 @@ class sspmod_core_Auth_Process_ScopeAttribute extends SimpleSAML_Auth_Processing
 				$attributes[$this->targetAttribute][] = $value;
 			}
 		}
-
 	}
-
 }
diff --git a/modules/core/lib/Auth/Process/ScopeFromAttribute.php b/modules/core/lib/Auth/Process/ScopeFromAttribute.php
index 818a24f7657bfcfb77e5bba86ce54790f0056db8..da41e9ab022d8baaeb21d31249588a801a741bfe 100644
--- a/modules/core/lib/Auth/Process/ScopeFromAttribute.php
+++ b/modules/core/lib/Auth/Process/ScopeFromAttribute.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\core\Auth\Process;
+
 /**
  * Retrieve a scope from a source attribute and add it as a virtual target
  * attribute.
@@ -16,7 +18,9 @@
  * to add a virtual 'scope' attribute from the eduPersonPrincipalName
  * attribute.
  */
-class sspmod_core_Auth_Process_ScopeFromAttribute extends SimpleSAML_Auth_ProcessingFilter {
+
+class ScopeFromAttribute extends \SimpleSAML\Auth\ProcessingFilter
+{
 	/**
 	 * The attribute where the scope is taken from
 	 *
@@ -40,7 +44,7 @@ class sspmod_core_Auth_Process_ScopeFromAttribute extends SimpleSAML_Auth_Proces
 		parent::__construct($config, $reserved);
 		assert(is_array($config));
 
-		$config = SimpleSAML_Configuration::loadFromArray($config, 'ScopeFromAttribute');
+		$config = \SimpleSAML\Configuration::loadFromArray($config, 'ScopeFromAttribute');
 		$this->targetAttribute = $config->getString('targetAttribute');
 		$this->sourceAttribute = $config->getString('sourceAttribute');
 	} // end constructor
@@ -76,11 +80,11 @@ class sspmod_core_Auth_Process_ScopeFromAttribute extends SimpleSAML_Auth_Proces
 			$attributes[$this->targetAttribute] = array();
 			$scope = substr($sourceAttrVal, $scopeIndex+1);
 			$attributes[$this->targetAttribute][] = $scope;
-			SimpleSAML\Logger::debug('ScopeFromAttribute: Inserted new attribute ' .
+			\SimpleSAML\Logger::debug('ScopeFromAttribute: Inserted new attribute ' .
 			                         $this->targetAttribute . ', with scope ' .
 			                         $scope);
 		} else {
-			SimpleSAML\Logger::warning('ScopeFromAttribute: The configured source attribute ' .
+			\SimpleSAML\Logger::warning('ScopeFromAttribute: The configured source attribute ' .
 			                           $this->sourceAttribute .
 			                           ' does not have a scope. Did not add attribute ' .
 			                           $this->targetAttribute . '.');
diff --git a/modules/core/lib/Auth/Process/StatisticsWithAttribute.php b/modules/core/lib/Auth/Process/StatisticsWithAttribute.php
index eedf3a5903c4de8836559f6c18da7425a9d362b9..35848be87d9ecdfd73689ca9bd7de80895f47b1d 100644
--- a/modules/core/lib/Auth/Process/StatisticsWithAttribute.php
+++ b/modules/core/lib/Auth/Process/StatisticsWithAttribute.php
@@ -1,85 +1,116 @@
 <?php
 
+namespace SimpleSAML\Module\core\Auth\Process;
+
 /**
  * Log a line in the STAT log with one attribute.
  *
  * @author Andreas Ă…kre Solberg, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class sspmod_core_Auth_Process_StatisticsWithAttribute extends SimpleSAML_Auth_ProcessingFilter {
-
-
-	/**
-	 * The attribute to log
-	 */
-	private $attribute = NULL;
-	
-	private $typeTag = 'saml20-idp-SSO';
-
-
-	/**
-	 * Initialize this filter.
-	 *
-	 * @param array $config  Configuration information about this filter.
-	 * @param mixed $reserved  For future use.
-	 */
-	public function __construct($config, $reserved) {
-		parent::__construct($config, $reserved);
-
-		assert(is_array($config));
-
-		if (array_key_exists('attributename', $config)) {
-			$this->attribute = $config['attributename'];
-			if (!is_string($this->attribute)) {
-				throw new Exception('Invalid attribute name given to core:StatisticsWithAttribute filter.');
-			}
-		}
-		
-		if (array_key_exists('type', $config)) {
-			$this->typeTag = $config['type'];
-			if (!is_string($this->typeTag)) {
-				throw new Exception('Invalid typeTag given to core:StatisticsWithAttribute filter.');
-			}
-		}
-	}
 
+class StatisticsWithAttribute extends \SimpleSAML\Auth\ProcessingFilter
+{
+    /**
+     * The attribute to log
+     * @var string|null
+     */
+    private $attribute = null;
+
+    /**
+     * @var string
+     */
+    private $typeTag = 'saml20-idp-SSO';
+
+    /**
+     * @var bool
+     */
+    private $skipPassive = false;
+
+
+    /**
+     * Initialize this filter.
+     *
+     * @param array $config  Configuration information about this filter.
+     * @param mixed $reserved  For future use.
+     */
+    public function __construct($config, $reserved)
+    {
+        parent::__construct($config, $reserved);
+
+        assert(is_array($config));
+
+        if (array_key_exists('attributename', $config)) {
+            $this->attribute = $config['attributename'];
+            if (!is_string($this->attribute)) {
+                throw new \Exception('Invalid attribute name given to core:StatisticsWithAttribute filter.');
+            }
+        }
+
+        if (array_key_exists('type', $config)) {
+            $this->typeTag = $config['type'];
+            if (!is_string($this->typeTag)) {
+                throw new \Exception('Invalid typeTag given to core:StatisticsWithAttribute filter.');
+            }
+        }
+
+        if (array_key_exists('skipPassive', $config)) {
+            $this->skipPassive = (bool) $config['skipPassive'];
+        }
+    }
+
+
+    /**
+     * Log line.
+     *
+     * @param array &$state  The current state.
+     */
+    public function process(&$state)
+    {
+        assert(is_array($state));
+        assert(array_key_exists('Attributes', $state));
+
+        $logAttribute = 'NA';
+        $isPassive = '';
+
+        if (array_key_exists('isPassive', $state) && $state['isPassive'] === true) {
+            if ($this->skipPassive === true) {
+                // We have a passive request. Skip logging statistics
+                return;
+            }
+            $isPassive = 'passive-';
+        }
+
+        if (array_key_exists($this->attribute, $state['Attributes'])) {
+            $logAttribute = $state['Attributes'][$this->attribute][0];
+        }
+
+        $source = $this->setIdentifier('Source', $state);
+        $dest = $this->setIdentifier('Destination', $state);
+
+        if (!array_key_exists('PreviousSSOTimestamp', $state)) {
+            // The user hasn't authenticated with this SP earlier in this session
+            \SimpleSAML\Logger::stats($isPassive.$this->typeTag.'-first '.$dest.' '.$source.' '. $logAttribute);
+        }
 
-	/**
-	 * Log line.
-	 *
-	 * @param array &$state  The current state.
-	 */
-	public function process(&$state) {
-		assert(is_array($state));
-		assert(array_key_exists('Attributes', $state));
-
-		$logAttribute = 'NA';
-		$source = 'NA';
-		$dest = 'NA';
-
-		if (array_key_exists($this->attribute, $state['Attributes'])) $logAttribute = $state['Attributes'][$this->attribute][0];		
-		if (array_key_exists('Source', $state)) {
-			if (isset($state['Source']['core:statistics-id'])) {
-				$source = $state['Source']['core:statistics-id'];
-			} else {
-				$source = $state['Source']['entityid'];
-			}
-		}
-
-		if (array_key_exists('Destination', $state)) {
-			if (isset($state['Destination']['core:statistics-id'])) {
-				$dest = $state['Destination']['core:statistics-id'];
-			} else {
-				$dest = $state['Destination']['entityid'];
-			}
-		}
-
-		if (!array_key_exists('PreviousSSOTimestamp', $state)) {
-			// The user hasn't authenticated with this SP earlier in this session
-			SimpleSAML\Logger::stats($this->typeTag . '-first ' . $dest . ' ' . $source . ' ' . $logAttribute);
-		}
-
-		SimpleSAML\Logger::stats($this->typeTag . ' ' . $dest . ' ' . $source . ' ' . $logAttribute);
+        \SimpleSAML\Logger::stats($isPassive.$this->typeTag.' '.$dest.' '.$source.' '.$logAttribute);
 	}
 
+    /**
+     * @param string &$direction  Either 'Source' or 'Destination'.
+     * @param array $state  The current state.
+     *
+     * @return string
+     */
+    private function setIdentifier($direction, $state)
+    {
+        if (array_key_exists($direction, $state)) {
+            if (isset($state[$direction]['core:statistics-id'])) {
+                return $state[$direction]['core:statistics-id'];
+            } else {
+                return $state[$direction]['entityid'];
+            }
+        }
+        return 'NA';
+    }
 }
diff --git a/modules/core/lib/Auth/Process/TargetedID.php b/modules/core/lib/Auth/Process/TargetedID.php
index 3b70f02aa4ad20a7468862fa6c3ff89be8ec236a..538d8138f7827345294545250e97b84887867edc 100644
--- a/modules/core/lib/Auth/Process/TargetedID.php
+++ b/modules/core/lib/Auth/Process/TargetedID.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\core\Auth\Process;
+
 /**
  * Filter to generate the eduPersonTargetedID attribute.
  *
@@ -28,9 +30,9 @@
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class sspmod_core_Auth_Process_TargetedID extends SimpleSAML_Auth_ProcessingFilter {
-
 
+class TargetedID extends \SimpleSAML\Auth\ProcessingFilter
+{
 	/**
 	 * The attribute we should generate the targeted id from, or NULL if we should use the
 	 * UserID.
@@ -60,14 +62,14 @@ class sspmod_core_Auth_Process_TargetedID extends SimpleSAML_Auth_ProcessingFilt
 		if (array_key_exists('attributename', $config)) {
 			$this->attribute = $config['attributename'];
 			if (!is_string($this->attribute)) {
-				throw new Exception('Invalid attribute name given to core:TargetedID filter.');
+				throw new \Exception('Invalid attribute name given to core:TargetedID filter.');
 			}
 		}
 
 		if (array_key_exists('nameId', $config)) {
 			$this->generateNameId = $config['nameId'];
 			if (!is_bool($this->generateNameId)) {
-				throw new Exception('Invalid value of \'nameId\'-option to core:TargetedID filter.');
+				throw new \Exception('Invalid value of \'nameId\'-option to core:TargetedID filter.');
 			}
 		}
 	}
@@ -84,7 +86,7 @@ class sspmod_core_Auth_Process_TargetedID extends SimpleSAML_Auth_ProcessingFilt
 
 		if ($this->attribute === NULL) {
 			if (!array_key_exists('UserID', $state)) {
-				throw new Exception('core:TargetedID: Missing UserID for this user. Please' .
+				throw new \Exception('core:TargetedID: Missing UserID for this user. Please' .
 					' check the \'userid.attribute\' option in the metadata against the' .
 					' attributes provided by the authentication source.');
 			}
@@ -92,7 +94,7 @@ class sspmod_core_Auth_Process_TargetedID extends SimpleSAML_Auth_ProcessingFilt
 			$userID = $state['UserID'];
 		} else {
 			if (!array_key_exists($this->attribute, $state['Attributes'])) {
-				throw new Exception('core:TargetedID: Missing attribute \'' . $this->attribute .
+				throw new \Exception('core:TargetedID: Missing attribute \'' . $this->attribute .
 					'\', which is needed to generate the targeted ID.');
 			}
 
@@ -100,7 +102,7 @@ class sspmod_core_Auth_Process_TargetedID extends SimpleSAML_Auth_ProcessingFilt
 		}
 
 
-		$secretSalt = SimpleSAML\Utils\Config::getSecretSalt();
+		$secretSalt = \SimpleSAML\Utils\Config::getSecretSalt();
 
 		if (array_key_exists('Source', $state)) {
 			$srcID = self::getEntityId($state['Source']);
diff --git a/modules/core/lib/Auth/Process/WarnShortSSOInterval.php b/modules/core/lib/Auth/Process/WarnShortSSOInterval.php
index d8ae6fa0a6e9bda49d7d493aaa00997216296b72..b51180f5c335b845716bac28740bac28e570198f 100644
--- a/modules/core/lib/Auth/Process/WarnShortSSOInterval.php
+++ b/modules/core/lib/Auth/Process/WarnShortSSOInterval.php
@@ -1,12 +1,15 @@
 <?php
 
+namespace SimpleSAML\Module\core\Auth\Process;
+
 /**
  * Give a warning to the user if we receive multiple requests in a short time.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_core_Auth_Process_WarnShortSSOInterval extends SimpleSAML_Auth_ProcessingFilter {
 
+class WarnShortSSOInterval extends \SimpleSAML\Auth\ProcessingFilter
+{
 	/**
 	 * Process a authentication response.
 	 *
@@ -39,13 +42,13 @@ class sspmod_core_Auth_Process_WarnShortSSOInterval extends SimpleSAML_Auth_Proc
 			$entityId = 'UNKNOWN';
 		}
 
-		SimpleSAML\Logger::warning('WarnShortSSOInterval: Only ' . $timeDelta .
+		\SimpleSAML\Logger::warning('WarnShortSSOInterval: Only ' . $timeDelta .
 			' seconds since last SSO for this user from the SP ' .
 			var_export($entityId, TRUE));
 
 		// Save state and redirect
-		$id = SimpleSAML_Auth_State::saveState($state, 'core:short_sso_interval');
-		$url = SimpleSAML\Module::getModuleURL('core/short_sso_interval.php');
+		$id = \SimpleSAML\Auth\State::saveState($state, 'core:short_sso_interval');
+		$url = \SimpleSAML\Module::getModuleURL('core/short_sso_interval.php');
 		\SimpleSAML\Utils\HTTP::redirectTrustedURL($url, array('StateId' => $id));
 	}
 
diff --git a/modules/core/lib/Auth/Source/AdminPassword.php b/modules/core/lib/Auth/Source/AdminPassword.php
index 3ba1a821086d5e290b0149445c323562973429df..13afe27f0fecb4242eafc899020e5e7fbe14c8f9 100644
--- a/modules/core/lib/Auth/Source/AdminPassword.php
+++ b/modules/core/lib/Auth/Source/AdminPassword.php
@@ -1,14 +1,16 @@
 <?php
 
+namespace SimpleSAML\Module\core\Auth\Source;
+
 /**
  * Authentication source which verifies the password against
  * the 'auth.adminpassword' configuration option.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_core_Auth_Source_AdminPassword extends sspmod_core_Auth_UserPassBase {
-
 
+class AdminPassword extends \SimpleSAML\Module\core\Auth\UserPassBase
+{
 	/**
 	 * Constructor for this authentication source.
 	 *
@@ -31,7 +33,7 @@ class sspmod_core_Auth_Source_AdminPassword extends sspmod_core_Auth_UserPassBas
 	 *
 	 * On a successful login, this function should return the users attributes. On failure,
 	 * it should throw an exception. If the error was caused by the user entering the wrong
-	 * username or password, a SimpleSAML_Error_Error('WRONGUSERPASS') should be thrown.
+	 * username or password, a \SimpleSAML\Error\Error('WRONGUSERPASS') should be thrown.
 	 *
 	 * Note that both the username and the password are UTF-8 encoded.
 	 *
@@ -43,22 +45,21 @@ class sspmod_core_Auth_Source_AdminPassword extends sspmod_core_Auth_UserPassBas
 		assert(is_string($username));
 		assert(is_string($password));
 
-		$config = SimpleSAML_Configuration::getInstance();
+		$config = \SimpleSAML\Configuration::getInstance();
 		$adminPassword = $config->getString('auth.adminpassword', '123');
 		if ($adminPassword === '123') {
 			// We require that the user changes the password
-			throw new SimpleSAML_Error_Error('NOTSET');
+			throw new \SimpleSAML\Error\Error('NOTSET');
 		}
 
 		if ($username !== "admin") {
-			throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+			throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
 		}
 
-		if (!SimpleSAML\Utils\Crypto::pwValid($adminPassword, $password)) {
-			throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+		if (!\SimpleSAML\Utils\Crypto::pwValid($adminPassword, $password)) {
+			throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
 		}
 
 		return array('user' => array('admin'));
 	}
-
 }
diff --git a/modules/core/lib/Auth/UserPassBase.php b/modules/core/lib/Auth/UserPassBase.php
index a8c7e5445003f27cc175aa3edf9c4e9417930b35..324a5fc2ca6c944ad16b79a6c7761192cd15ca7d 100644
--- a/modules/core/lib/Auth/UserPassBase.php
+++ b/modules/core/lib/Auth/UserPassBase.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\core\Auth;
+
 /**
  * Helper class for username/password authentication.
  *
@@ -9,19 +11,19 @@
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-abstract class sspmod_core_Auth_UserPassBase extends SimpleSAML_Auth_Source {
-
 
+abstract class UserPassBase extends \SimpleSAML\Auth\Source
+{
 	/**
 	 * The string used to identify our states.
 	 */
-	const STAGEID = 'sspmod_core_Auth_UserPassBase.state';
+	const STAGEID = '\SimpleSAML\Module\core\Auth\UserPassBase.state';
 
 
 	/**
 	 * The key of the AuthId field in the state.
 	 */
-	const AUTHID = 'sspmod_core_Auth_UserPassBase.AuthId';
+	const AUTHID = '\SimpleSAML\Module\core\Auth\UserPassBase.AuthId';
 
 
 	/**
@@ -31,9 +33,9 @@ abstract class sspmod_core_Auth_UserPassBase extends SimpleSAML_Auth_Source {
 	 * If this is NULL, we won't force any username.
 	 */
 	private $forcedUsername;
-	
+
 	/**
-	 * Links to pages from login page. 
+	 * Links to pages from login page.
 	 * From configuration
 	 */
 	protected $loginLinks;
@@ -103,7 +105,7 @@ abstract class sspmod_core_Auth_UserPassBase extends SimpleSAML_Auth_Source {
 		}
 
         // get the "remember me" config options
-        $sspcnf = SimpleSAML_Configuration::getInstance();
+        $sspcnf = \SimpleSAML\Configuration::getInstance();
         $this->rememberMeEnabled = $sspcnf->getBoolean('session.rememberme.enable', FALSE);
         $this->rememberMeChecked = $sspcnf->getBoolean('session.rememberme.checked', FALSE);
 	}
@@ -183,16 +185,33 @@ abstract class sspmod_core_Auth_UserPassBase extends SimpleSAML_Auth_Source {
 			 * is allowed to change the username.
 			 */
 			$state['forcedUsername'] = $this->forcedUsername;
-		}
+	    }
+
+	  // ECP requests supply authentication credentials with the AUthnRequest
+	  // so we validate them now rather than redirecting
+	  if (isset($state['core:auth:username']) && isset($state['core:auth:password'])) {
+	      $username = $state['core:auth:username'];
+	      $password = $state['core:auth:password'];
+
+	      if (isset($state['forcedUsername'])) {
+	          $username = $state['forcedUsername'];
+	      }
+
+	      $attributes = $this->login($username, $password);
+	      assert(is_array($attributes));
+	      $state['Attributes'] = $attributes;
+
+	      return;
+	  }
 
 		/* Save the $state-array, so that we can restore it after a redirect. */
-		$id = SimpleSAML_Auth_State::saveState($state, self::STAGEID);
+		$id = \SimpleSAML\Auth\State::saveState($state, self::STAGEID);
 
 		/*
 		 * Redirect to the login form. We include the identifier of the saved
 		 * state array as a parameter to the login form.
 		 */
-		$url = SimpleSAML\Module::getModuleURL('core/loginuserpass.php');
+		$url = \SimpleSAML\Module::getModuleURL('core/loginuserpass.php');
 		$params = array('AuthState' => $id);
 		\SimpleSAML\Utils\HTTP::redirectTrustedURL($url, $params);
 
@@ -206,7 +225,7 @@ abstract class sspmod_core_Auth_UserPassBase extends SimpleSAML_Auth_Source {
 	 *
 	 * On a successful login, this function should return the users attributes. On failure,
 	 * it should throw an exception/error. If the error was caused by the user entering the wrong
-	 * username or password, a SimpleSAML_Error_Error('WRONGUSERPASS') should be thrown.
+	 * username or password, a \SimpleSAML\Error\Error('WRONGUSERPASS') should be thrown.
 	 *
 	 * Note that both the username and the password are UTF-8 encoded.
 	 *
@@ -234,13 +253,13 @@ abstract class sspmod_core_Auth_UserPassBase extends SimpleSAML_Auth_Source {
 		assert(is_string($password));
 
 		/* Here we retrieve the state array we saved in the authenticate-function. */
-		$state = SimpleSAML_Auth_State::loadState($authStateId, self::STAGEID);
+		$state = \SimpleSAML\Auth\State::loadState($authStateId, self::STAGEID);
 
 		/* Retrieve the authentication source we are executing. */
 		assert(array_key_exists(self::AUTHID, $state));
-		$source = SimpleSAML_Auth_Source::getById($state[self::AUTHID]);
+		$source = \SimpleSAML\Auth\Source::getById($state[self::AUTHID]);
 		if ($source === NULL) {
-			throw new Exception('Could not find authentication source with id ' . $state[self::AUTHID]);
+			throw new \Exception('Could not find authentication source with id ' . $state[self::AUTHID]);
 		}
 
 		/*
@@ -251,19 +270,19 @@ abstract class sspmod_core_Auth_UserPassBase extends SimpleSAML_Auth_Source {
 		/* Attempt to log in. */
 		try {
 			$attributes = $source->login($username, $password);
-		} catch (Exception $e) {
-			SimpleSAML\Logger::stats('Unsuccessful login attempt from '.$_SERVER['REMOTE_ADDR'].'.');
+		} catch (\Exception $e) {
+			\SimpleSAML\Logger::stats('Unsuccessful login attempt from '.$_SERVER['REMOTE_ADDR'].'.');
 			throw $e;
 		}
 
-		SimpleSAML\Logger::stats('User \''.$username.'\' successfully authenticated from '.$_SERVER['REMOTE_ADDR']);
+		\SimpleSAML\Logger::stats('User \''.$username.'\' successfully authenticated from '.$_SERVER['REMOTE_ADDR']);
 
 		/* Save the attributes we received from the login-function in the $state-array. */
 		assert(is_array($attributes));
 		$state['Attributes'] = $attributes;
 
 		/* Return control to SimpleSAMLphp after successful authentication. */
-		SimpleSAML_Auth_Source::completeAuth($state);
+		\SimpleSAML\Auth\Source::completeAuth($state);
 	}
 
 }
diff --git a/modules/core/lib/Auth/UserPassOrgBase.php b/modules/core/lib/Auth/UserPassOrgBase.php
index 8c22372268200a6925101731c13eacd372785f42..08f9b8f00cd18d294ced3ccf194c19cde7454d74 100644
--- a/modules/core/lib/Auth/UserPassOrgBase.php
+++ b/modules/core/lib/Auth/UserPassOrgBase.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\core\Auth;
+
 /**
  * Helper class for username/password/organization authentication.
  *
@@ -11,25 +13,25 @@
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-abstract class sspmod_core_Auth_UserPassOrgBase extends SimpleSAML_Auth_Source {
-
 
+abstract class UserPassOrgBase extends \SimpleSAML\Auth\Source
+{
 	/**
 	 * The string used to identify our states.
 	 */
-	const STAGEID = 'sspmod_core_Auth_UserPassOrgBase.state';
+	const STAGEID = '\SimpleSAML\Module\core\Auth\UserPassOrgBase.state';
 
 
 	/**
 	 * The key of the AuthId field in the state.
 	 */
-	const AUTHID = 'sspmod_core_Auth_UserPassOrgBase.AuthId';
+	const AUTHID = '\SimpleSAML\Module\core\Auth\UserPassOrgBase.AuthId';
 
 
 	/**
 	 * The key of the OrgId field in the state, identifies which org was selected.
 	 */
-	const ORGID = 'sspmod_core_Auth_UserPassOrgBase.SelectedOrg';
+	const ORGID = '\SimpleSAML\Module\core\Auth\UserPassOrgBase.SelectedOrg';
 
 
 	/**
@@ -194,9 +196,9 @@ abstract class sspmod_core_Auth_UserPassOrgBase extends SimpleSAML_Auth_Source {
 		// We are going to need the authId in order to retrieve this authentication source later
 		$state[self::AUTHID] = $this->authId;
 
-		$id = SimpleSAML_Auth_State::saveState($state, self::STAGEID);
+		$id = \SimpleSAML\Auth\State::saveState($state, self::STAGEID);
 
-		$url = SimpleSAML\Module::getModuleURL('core/loginuserpassorg.php');
+		$url = \SimpleSAML\Module::getModuleURL('core/loginuserpassorg.php');
 		$params = array('AuthState' => $id);
 		\SimpleSAML\Utils\HTTP::redirectTrustedURL($url, $params);
 	}
@@ -207,7 +209,7 @@ abstract class sspmod_core_Auth_UserPassOrgBase extends SimpleSAML_Auth_Source {
 	 *
 	 * On a successful login, this function should return the users attributes. On failure,
 	 * it should throw an exception/error. If the error was caused by the user entering the wrong
-	 * username or password, a SimpleSAML_Error_Error('WRONGUSERPASS') should be thrown.
+	 * username or password, a \SimpleSAML\Error\Error('WRONGUSERPASS') should be thrown.
 	 *
 	 * Note that both the username and the password are UTF-8 encoded.
 	 *
@@ -251,13 +253,13 @@ abstract class sspmod_core_Auth_UserPassOrgBase extends SimpleSAML_Auth_Source {
 		assert(is_string($organization));
 
 		/* Retrieve the authentication state. */
-		$state = SimpleSAML_Auth_State::loadState($authStateId, self::STAGEID);
+		$state = \SimpleSAML\Auth\State::loadState($authStateId, self::STAGEID);
 
 		/* Find authentication source. */
 		assert(array_key_exists(self::AUTHID, $state));
-		$source = SimpleSAML_Auth_Source::getById($state[self::AUTHID]);
+		$source = \SimpleSAML\Auth\Source::getById($state[self::AUTHID]);
 		if ($source === NULL) {
-			throw new Exception('Could not find authentication source with id ' . $state[self::AUTHID]);
+			throw new \Exception('Could not find authentication source with id ' . $state[self::AUTHID]);
 		}
 
 		$orgMethod = $source->getUsernameOrgMethod();
@@ -269,7 +271,7 @@ abstract class sspmod_core_Auth_UserPassOrgBase extends SimpleSAML_Auth_Source {
 			} else {
 				if ($orgMethod === 'force') {
 					/* The organization should be a part of the username, but isn't. */
-					throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+					throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
 				}
 			}
 		}
@@ -282,7 +284,7 @@ abstract class sspmod_core_Auth_UserPassOrgBase extends SimpleSAML_Auth_Source {
 		$state['PersistentAuthData'][] = self::ORGID;
 
 		$state['Attributes'] = $attributes;
-		SimpleSAML_Auth_Source::completeAuth($state);
+		\SimpleSAML\Auth\Source::completeAuth($state);
 	}
 
 
@@ -299,13 +301,13 @@ abstract class sspmod_core_Auth_UserPassOrgBase extends SimpleSAML_Auth_Source {
 		assert(is_string($authStateId));
 
 		/* Retrieve the authentication state. */
-		$state = SimpleSAML_Auth_State::loadState($authStateId, self::STAGEID);
+		$state = \SimpleSAML\Auth\State::loadState($authStateId, self::STAGEID);
 
 		/* Find authentication source. */
 		assert(array_key_exists(self::AUTHID, $state));
-		$source = SimpleSAML_Auth_Source::getById($state[self::AUTHID]);
+		$source = \SimpleSAML\Auth\Source::getById($state[self::AUTHID]);
 		if ($source === NULL) {
-			throw new Exception('Could not find authentication source with id ' . $state[self::AUTHID]);
+			throw new \Exception('Could not find authentication source with id ' . $state[self::AUTHID]);
 		}
 
 		$orgMethod = $source->getUsernameOrgMethod();
diff --git a/modules/core/lib/Stats/Output/File.php b/modules/core/lib/Stats/Output/File.php
index 0642bcda23ae138c532c2b000f2546967003de94..fe0dc3fddd67a8ec63392e8697f5ebc22048cb77 100644
--- a/modules/core/lib/Stats/Output/File.php
+++ b/modules/core/lib/Stats/Output/File.php
@@ -1,12 +1,15 @@
 <?php
 
+namespace SimpleSAML\Module\core\Stats\Output;
+
 /**
  * Statistics logger that writes to a set of log files
  *
  * @package SimpleSAMLphp
  */
-class sspmod_core_Stats_Output_File extends SimpleSAML_Stats_Output {
 
+class File extends \SimpleSAML\Stats\Output
+{
 	/**
 	 * The log directory.
 	 * @var string
@@ -30,16 +33,16 @@ class sspmod_core_Stats_Output_File extends SimpleSAML_Stats_Output {
 	/**
 	 * Initialize the output.
 	 *
-	 * @param SimpleSAML_Configuration $config  The configuration for this output.
+	 * @param \SimpleSAML\Configuration $config  The configuration for this output.
 	 */
-	public function __construct(SimpleSAML_Configuration $config) {
+	public function __construct(\SimpleSAML\Configuration $config) {
 
 		$this->logDir = $config->getPathValue('directory');
 		if ($this->logDir === NULL) {
-			throw new Exception('Missing "directory" option for core:File');
+			throw new \Exception('Missing "directory" option for core:File');
 		}
 		if (!is_dir($this->logDir)) {
-			throw new Exception('Could not find log directory: ' . var_export($this->logDir, TRUE));
+			throw new \Exception('Could not find log directory: ' . var_export($this->logDir, TRUE));
 		}
 
 	}
@@ -61,7 +64,7 @@ class sspmod_core_Stats_Output_File extends SimpleSAML_Stats_Output {
 		$fileName = $this->logDir . '/' . $date . '.log';
 		$this->file = @fopen($fileName, 'a');
 		if ($this->file === FALSE) {
-			throw new SimpleSAML_Error_Exception('Error opening log file: ' . var_export($fileName, TRUE));
+			throw new \SimpleSAML\Error\Exception('Error opening log file: ' . var_export($fileName, TRUE));
 		}
 
 		// Disable output buffering
diff --git a/modules/core/lib/Stats/Output/Log.php b/modules/core/lib/Stats/Output/Log.php
index 70e914e4bb4316cb4d2b83a1a4370e6b68175f29..b4872bd5bead6089b51f2ae872586af128a6e478 100644
--- a/modules/core/lib/Stats/Output/Log.php
+++ b/modules/core/lib/Stats/Output/Log.php
@@ -1,12 +1,15 @@
 <?php
 
+namespace SimpleSAML\Module\core\Stats\Output;
+
 /**
  * Statistics logger that writes to the default logging handler.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_core_Stats_Output_Log extends SimpleSAML_Stats_Output {
 
+class Log extends \SimpleSAML\Stats\Output
+{
 	/**
 	 * The logging function we should call.
 	 * @var callback
@@ -17,14 +20,13 @@ class sspmod_core_Stats_Output_Log extends SimpleSAML_Stats_Output {
 	/**
 	 * Initialize the output.
 	 *
-	 * @param SimpleSAML_Configuration $config  The configuration for this output.
+	 * @param \SimpleSAML\Configuration $config  The configuration for this output.
 	 */
-	public function __construct(SimpleSAML_Configuration $config) {
-
+	public function __construct(\SimpleSAML\Configuration $config) {
 		$logLevel = $config->getString('level', 'notice');
-		$this->logger = array('SimpleSAML\Logger', $logLevel);
+		$this->logger = array('\SimpleSAML\Logger', $logLevel);
 		if (!is_callable($this->logger)) {
-			throw new Exception('Invalid log level: ' . var_export($logLevel, TRUE));
+			throw new \Exception('Invalid log level: ' . var_export($logLevel, TRUE));
 		}
 	}
 
@@ -38,5 +40,4 @@ class sspmod_core_Stats_Output_Log extends SimpleSAML_Stats_Output {
 		$str_data = json_encode($data);
 		call_user_func($this->logger, 'EVENT ' . $str_data);
 	}
-
 }
diff --git a/modules/core/lib/Storage/SQLPermanentStorage.php b/modules/core/lib/Storage/SQLPermanentStorage.php
index 54bb5642bf1b59201b850164f1ac343489d4b64a..8db457f66e6b6778247c9ebf6c8e39096127b77e 100644
--- a/modules/core/lib/Storage/SQLPermanentStorage.php
+++ b/modules/core/lib/Storage/SQLPermanentStorage.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\core\Storage;
+
 /**
  * SQLPermanentStorage
  * 
@@ -9,198 +11,209 @@
  * @author Andreas Ă…kre Solberg <andreas@uninett.no>, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class sspmod_core_Storage_SQLPermanentStorage {
-	
-	private $db;
-	
-	function __construct($name, $config = NULL) {
-		if (is_null($config))
-			$config = SimpleSAML_Configuration::getInstance();
-		
-		$datadir = $config->getPathValue('datadir', 'data/');
-		
-		if (!is_dir($datadir))
-			throw new Exception('Data directory [' . $datadir. '] does not exist');
-		if (!is_writable($datadir))
-			throw new Exception('Data directory [' . $datadir. '] is not writable');
-		
-		$sqllitedir = $datadir . 'sqllite/';
-		if (!is_dir($sqllitedir)) {
-			mkdir($sqllitedir);
-		}
-		
-		$dbfile = $sqllitedir . $name . '.sqllite';
-		
-		if ($this->db = new SQLiteDatabase($dbfile)) {
-			$q = @$this->db->query('SELECT key1 FROM data LIMIT 1');
-			if ($q === false) {
-				$this->db->queryExec('
-		CREATE TABLE data (
-			key1 text, 
-			key2 text,
-			type text,
-			value text,
-			created timestamp,
-			updated timestamp,
-			expire timestamp,
-			PRIMARY KEY (key1,key2,type)
-		);
-		');
-			} 
-		} else {
-		    throw new Exception('Error creating SQL lite database [' . $dbfile . '].');
-		}
-	}
-
-	public function set($type, $key1, $key2, $value, $duration = NULL) {
-		if ($this->exists($type, $key1, $key2)) {
-			$this->update($type, $key1, $key2, $value, $duration);
-		} else {
-			$this->insert($type, $key1, $key2, $value, $duration);
-		}
-	}
-
-	private function insert($type, $key1, $key2, $value, $duration = NULL) {
-		
-		$setDuration = '';
-		if (is_null($duration)) {
-			$setDuration = 'NULL';
-		} else {
-			$setDuration = "'" . sqlite_escape_string(time() + $duration) . "'";
-		}
-		
-		$query = "INSERT INTO data (key1,key2,type,created,updated,expire,value) VALUES (" . 
-			"'" . sqlite_escape_string($key1) . "'," . 
-			"'" . sqlite_escape_string($key2) . "'," . 
-			"'" . sqlite_escape_string($type) . "'," . 
-			"'" . sqlite_escape_string(time()) . "'," . 
-			"'" . sqlite_escape_string(time()) . "'," . 
-			$setDuration . "," .
-			"'" . sqlite_escape_string(serialize($value)) . "')";
-		$results = $this->db->queryExec($query);
-		return $results;
-	}
-	
-	private function update($type, $key1, $key2, $value, $duration = NULL) {
-		
-		$setDuration = '';
-		if (is_null($duration)) {
-			$setDuration = ", expire = NULL ";
-		} else {
-			$setDuration = ", expire = '" . sqlite_escape_string(time() + $duration) . "' ";
-		}
-		
-		$query = "UPDATE data SET " . 
-			"updated = '" . sqlite_escape_string(time()) . "'," . 
-			"value = '" . sqlite_escape_string(serialize($value)) . "'" .
-			$setDuration .
-			"WHERE " . 
-			"key1 = '" . sqlite_escape_string($key1) . "' AND " . 
-			"key2 = '" . sqlite_escape_string($key2) . "' AND " . 
-			"type = '" . sqlite_escape_string($type) . "'";
-		$results = $this->db->queryExec($query);
-		return $results;
-	}
-
-	public function get($type = NULL, $key1 = NULL, $key2 = NULL) {
-		
-		$condition = self::getCondition($type, $key1, $key2);
-		$query = "SELECT * FROM data WHERE " . $condition;
-		$results = $this->db->arrayQuery($query, SQLITE_ASSOC);
-
-		if (count($results) !== 1) return NULL;
-		
-		$res = $results[0];
-		$res['value'] = unserialize($res['value']);
-		return $res;
-	}
-	
-	/*
-	 * Return the value directly (not in a container)
-	 */
-	public function getValue($type = NULL, $key1 = NULL, $key2 = NULL) {
-		$res = $this->get($type, $key1, $key2);
-		if ($res === NULL) return NULL;
-		return $res['value'];
-	}
-	
-	public function exists($type, $key1, $key2) {
-		$query = "SELECT * FROM data WHERE " . 
-			"key1 = '" . sqlite_escape_string($key1) . "' AND " . 
-			"key2 = '" . sqlite_escape_string($key2) . "' AND " . 
-			"type = '" . sqlite_escape_string($type) . "' LIMIT 1";
-		$results = $this->db->arrayQuery($query, SQLITE_ASSOC);
-		return (count($results) == 1);
-	}
-		
-	public function getList($type = NULL, $key1 = NULL, $key2 = NULL) {
-		
-		$condition = self::getCondition($type, $key1, $key2);
-		$query = "SELECT * FROM data WHERE " . $condition;
-		$results = $this->db->arrayQuery($query, SQLITE_ASSOC);
-		if (count($results) == 0) return NULL;
-		
-		foreach($results AS $key => $value) {
-			$results[$key]['value'] = unserialize($results[$key]['value']);
-		}
-		return $results;
-	}
-	
-	public function getKeys($type = NULL, $key1 = NULL, $key2 = NULL, $whichKey = 'type') {
-
-		if (!in_array($whichKey, array('key1', 'key2', 'type'), true))
-			throw new Exception('Invalid key type');
-			
-		$condition = self::getCondition($type, $key1, $key2);
-		
-		$query = "SELECT DISTINCT " . $whichKey . " FROM data WHERE " . $condition;
-		$results = $this->db->arrayQuery($query, SQLITE_ASSOC);
-
-		if (count($results) == 0) return NULL;
-		
-		$resarray = array();
-		foreach($results AS $key => $value) {
-			$resarray[] = $value[$whichKey];
-		}
-		
-		return $resarray;
-	}
-	
-	
-	public function remove($type, $key1, $key2) {
-		$query = "DELETE FROM data WHERE " . 
-			"key1 = '" . sqlite_escape_string($key1) . "' AND " . 
-			"key2 = '" . sqlite_escape_string($key2) . "' AND " . 
-			"type = '" . sqlite_escape_string($type) . "'";
-		$results = $this->db->arrayQuery($query, SQLITE_ASSOC);
-		return (count($results) == 1);
-	}
-	
-	public function removeExpired() {
-		$query = "DELETE FROM data WHERE expire NOT NULL AND expire < " . time();
-		$this->db->arrayQuery($query, SQLITE_ASSOC);
-		$changes = $this->db->changes();
-		return $changes;
-	}
-	
-	
-	/**
-	 * Create a SQL condition statement based on parameters
-	 */
-	private static function getCondition($type = NULL, $key1 = NULL, $key2 = NULL) {
-		$conditions = array();
-		
-		if (!is_null($type)) $conditions[] = "type = '" . sqlite_escape_string($type) . "'";
-		if (!is_null($key1)) $conditions[] = "key1 = '" . sqlite_escape_string($key1) . "'";
-		if (!is_null($key2)) $conditions[] = "key2 = '" . sqlite_escape_string($key2) . "'";
-		
-		if (count($conditions) === 0) return '1';
-		
-		$condition = join(' AND ', $conditions);
-		
-		return $condition;
-	}
-	
-	
+
+class SQLPermanentStorage
+{
+    private $db;
+
+    public function __construct($name, $config = null)
+    {
+        if (is_null($config)) {
+            $config = \SimpleSAML\Configuration::getInstance();
+        }
+
+        $datadir = $config->getPathValue('datadir', 'data/');
+
+        if (!is_dir($datadir)) {
+            throw new \Exception('Data directory ['.$datadir.'] does not exist');
+        } else if (!is_writable($datadir)) {
+            throw new \Exception('Data directory ['.$datadir.'] is not writable');
+        }
+
+        $sqllitedir = $datadir.'sqllite/';
+        if (!is_dir($sqllitedir)) {
+            mkdir($sqllitedir);
+        }
+
+        $dbfile = 'sqlite:'.$sqllitedir.$name.'.sqlite';
+        if ($this->db = new \PDO($dbfile)) {
+            $q = @$this->db->query('SELECT key1 FROM data LIMIT 1');
+            if ($q === false) {
+                $this->db->exec('
+		    CREATE TABLE data (
+                        key1 text, 
+                        key2 text,
+                        type text,
+                        value text,
+                        created timestamp,
+                        updated timestamp,
+                        expire timestamp,
+                        PRIMARY KEY (key1,key2,type)
+                    );
+                ');
+            } 
+        } else {
+            throw new \Exception('Error creating SQL lite database ['.$dbfile.'].');
+        }
+    }
+
+    public function set($type, $key1, $key2, $value, $duration = null)
+    {
+        if ($this->exists($type, $key1, $key2)) {
+            $this->update($type, $key1, $key2, $value, $duration);
+        } else {
+            $this->insert($type, $key1, $key2, $value, $duration);
+        }
+    }
+
+    private function insert($type, $key1, $key2, $value, $duration = null)
+    {
+        $expire = is_null($duration) ? null : (time() + $duration);
+
+        $query = "INSERT INTO data (key1, key2, type, created, updated, expire, value)".
+            " VALUES(:key1, :key2, :type, :created, :updated, :expire, :value)";
+        $prepared = $this->db->prepare($query);
+        $data = array(':key1' => $key1, ':key2' => $key2,
+            ':type' => $type, ':created' => time(),
+            ':updated' => time(), ':expire' => $expire,
+            ':value' => serialize($value));
+        $prepared->execute($data);
+        $results = $prepared->fetchAll(\PDO::FETCH_ASSOC);
+        return $results;
+    }
+
+    private function update($type, $key1, $key2, $value, $duration = null)
+    {
+        $expire = is_null($duration) ? null : (time() + $duration);
+
+        $query = "UPDATE data SET updated = :updated, value = :value, expire = :expire WHERE key1 = :key1 AND key2 = :key2 AND type = :type";
+        $prepared = $this->db->prepare($query);
+        $data = array(':key1' => $key1, ':key2' => $key2,
+            ':type' => $type, ':updated' => time(),
+            ':expire' => $expire, ':value' => serialize($value));
+        $prepared->execute($data);
+        $results = $prepared->fetchAll(\PDO::FETCH_ASSOC);
+        return $results;
+    }
+
+    public function get($type = null, $key1 = null, $key2 = null)
+    {
+        $conditions = self::getCondition($type, $key1, $key2);
+        $query = 'SELECT * FROM data WHERE '.$conditions;
+
+        $prepared = $this->db->prepare($query);
+        $prepared->execute();
+        $results = $prepared->fetchAll(\PDO::FETCH_ASSOC);
+        if (count($results) !== 1) {
+            return null;
+        }
+
+        $res = $results[0];
+        $res['value'] = unserialize($res['value']);
+        return $res;
+    }
+
+    /*
+     * Return the value directly (not in a container)
+     */
+    public function getValue($type = null, $key1 = null, $key2 = null)
+    {
+        $res = $this->get($type, $key1, $key2);
+        if ($res === null) {
+            return null;
+        }
+        return $res['value'];
+    }
+
+    public function exists($type, $key1, $key2)
+    {
+        $query = 'SELECT * FROM data WHERE type = :type AND key1 = :key1 AND key2 = :key2 LIMIT 1';
+        $prepared = $this->db->prepare($query);
+        $data = array(':type' => $type, ':key1' => $key1, ':key2' => $key2);
+        $prepared->execute($data);
+        $results = $prepared->fetchAll(\PDO::FETCH_ASSOC);
+        return (count($results) == 1);
+    }
+
+    public function getList($type = null, $key1 = null, $key2 = null)
+    {
+        $conditions = self::getCondition($type, $key1, $key2);
+        $query = 'SELECT * FROM data WHERE '.$conditions;
+        $prepared = $this->db->prepare($query);
+        $prepared->execute();
+
+        $results = $prepared->fetchAll(\PDO::FETCH_ASSOC);
+        if (count($results) == 0) {
+            return null;
+        }
+
+        foreach ($results as $key => $value) {
+            $results[$key]['value'] = unserialize($results[$key]['value']);
+        }
+        return $results;
+    }
+
+    public function getKeys($type = null, $key1 = null, $key2 = null, $whichKey = 'type')
+    {
+        if (!in_array($whichKey, array('key1', 'key2', 'type'), true)) {
+            throw new \Exception('Invalid key type');
+        }
+
+        $conditions = self::getCondition($type, $key1, $key2);
+        $query = 'SELECT DISTINCT :whichKey FROM data WHERE '.$conditions;
+        $prepared = $this->db->prepare($query);
+        $data = array('whichKey' => $whichKey);
+        $prepared->execute($data);
+        $results = $prepared->fetchAll(\PDO::FETCH_ASSOC);
+
+        if (count($results) == 0) {
+            return null;
+        }
+
+        $resarray = array();
+        foreach ($results as $key => $value) {
+            $resarray[] = $value[$whichKey];
+        }
+        return $resarray;
+    }
+
+    public function remove($type, $key1, $key2)
+    {
+        $query = 'DELETE FROM data WHERE type = :type AND key1 = :key1 AND key2 = :key2';
+        $prepared = $this->db->prepare($query);
+        $data = array(':type' => $type, ':key1' => $key1, ':key2' => $key2);
+        $prepared->execute($data);
+        $results = $prepared->fetchAll(\PDO::FETCH_ASSOC);
+        return (count($results) == 1);
+    }
+
+    public function removeExpired()
+    {
+        $query = "DELETE FROM data WHERE expire IS NOT NULL AND expire < :expire";
+        $prepared = $this->db->prepare($query);
+        $data = array(':expire' => time());
+        $prepared->execute($data);
+        return $prepared->rowCount();
+    }
+
+    /**
+     * Create a SQL condition statement based on parameters
+     */
+    private function getCondition($type = null, $key1 = null, $key2 = null)
+    {
+        $conditions = array();
+        if (!is_null($type)) {
+            $conditions[] = "type = ".$this->db->quote($type);
+        }
+        if (!is_null($key1)) {
+            $conditions[] = "key1 = ".$this->db->quote($key1);
+        }
+        if (!is_null($key2)) {
+            $conditions[] = "key2 = ".$this->db->quote($key2);
+        }
+
+        $conditions[] = "(expire IS NULL OR expire >= ".time().")";
+		    return join(' AND ', $conditions);
+    }
 }
 
diff --git a/modules/core/templates/cardinality_error.tpl.php b/modules/core/templates/cardinality_error.tpl.php
new file mode 100644
index 0000000000000000000000000000000000000000..dc75c540afc9b7f71a167a5d397188eca3cb3e47
--- /dev/null
+++ b/modules/core/templates/cardinality_error.tpl.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Template which is shown when when an attribute violates a cardinality rule
+ *
+ * Parameters:
+ * - 'target': Target URL.
+ * - 'params': Parameters which should be included in the request.
+ *
+ * @package SimpleSAMLphp
+ */
+
+
+$this->data['cardinality_header'] = $this->t('{core:cardinality:cardinality_header}');
+$this->data['cardinality_text'] = $this->t('{core:cardinality:cardinality_text}');
+$this->data['problematic_attributes'] = $this->t('{core:cardinality:problematic_attributes}');
+
+$this->includeAtTemplateBase('includes/header.php');
+?>
+<h1><?php echo $this->data['cardinality_header']; ?></h1>
+<p><?php echo $this->data['cardinality_text']; ?></p>
+<h3><?php echo $this->data['problematic_attributes']; ?></h3>
+<dl class="cardinalityErrorAttributes">
+<?php foreach ($this->data['cardinalityErrorAttributes'] as $attr => $v) { ?>
+        <dt><?php echo $attr ?></td>
+        <dd><?php echo $this->t('{core:cardinality:got_want}', array('%GOT%' => $v[0], '%WANT%' => htmlspecialchars($v[1]))) ?></dd>
+    </tr>
+<?php } ?>
+</dl>
+<?php
+if (isset($this->data['LogoutURL'])) {
+?>
+<p><a href="<?php echo htmlspecialchars($this->data['LogoutURL']); ?>"><?php echo $this->t('{status:logout}'); ?></a></p>
+<?php
+}
+?>
+<?php
+$this->includeAtTemplateBase('includes/footer.php');
diff --git a/modules/core/www/as_login.php b/modules/core/www/as_login.php
index e43a77898b7d7faa6d17279003fddad88aee2279..14d8b1dc9f5dd7db009607bf417b78517fde0181 100644
--- a/modules/core/www/as_login.php
+++ b/modules/core/www/as_login.php
@@ -7,18 +7,18 @@
  */
 
 if (!isset($_REQUEST['ReturnTo'])) {
-	throw new SimpleSAML_Error_BadRequest('Missing ReturnTo parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing ReturnTo parameter.');
 }
 
 if (!isset($_REQUEST['AuthId'])) {
-	throw new SimpleSAML_Error_BadRequest('Missing AuthId parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing AuthId parameter.');
 }
 
 /*
  * Setting up the options for the requireAuth() call later..
  */
 $options = array(
-	'ReturnTo' => \SimpleSAML\Utils\HTTP::checkURLAllowed($_REQUEST['ReturnTo']),
+    'ReturnTo' => \SimpleSAML\Utils\HTTP::checkURLAllowed($_REQUEST['ReturnTo']),
 );
 
 /*
@@ -26,7 +26,7 @@ $options = array(
  * as used by the DiscoJuice embedded client.
  */
 if (!empty($_REQUEST['saml:idp'])) {
-	$options['saml:idp'] = $_REQUEST['saml:idp'];
+    $options['saml:idp'] = $_REQUEST['saml:idp'];
 }
 
 $as = new \SimpleSAML\Auth\Simple($_REQUEST['AuthId']);
diff --git a/modules/core/www/as_logout.php b/modules/core/www/as_logout.php
index bfd92341534a75c243bc33a76944c2f9b564d9e3..6fe7c95adad5ca27aa481781ffc329fa1bb97694 100644
--- a/modules/core/www/as_logout.php
+++ b/modules/core/www/as_logout.php
@@ -7,11 +7,11 @@
  */
 
 if (!isset($_REQUEST['ReturnTo']) || !is_string($_REQUEST['ReturnTo'])) {
-	throw new SimpleSAML_Error_BadRequest('Missing ReturnTo parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing ReturnTo parameter.');
 }
 
 if (!isset($_REQUEST['AuthId']) || !is_string($_REQUEST['AuthId'])) {
-	throw new SimpleSAML_Error_BadRequest('Missing AuthId parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing AuthId parameter.');
 }
 
 $as = new \SimpleSAML\Auth\Simple($_REQUEST['AuthId']);
diff --git a/modules/core/www/authenticate.php b/modules/core/www/authenticate.php
index d09947b364d0c88853c6dd981d6626be1abde339..df978a8f1eea7955153cfd41a4c067c92debc3f3 100644
--- a/modules/core/www/authenticate.php
+++ b/modules/core/www/authenticate.php
@@ -1,12 +1,11 @@
 <?php
 
-$config = SimpleSAML_Configuration::getInstance();
+$config = \SimpleSAML\Configuration::getInstance();
 
 if (!array_key_exists('as', $_REQUEST)) {
-    $t = new SimpleSAML_XHTML_Template($config, 'core:authsource_list.tpl.php');
+    $t = new \SimpleSAML\XHTML\Template($config, 'core:authsource_list.tpl.php');
 
-    $t->data['header'] = 'Test authentication sources';
-    $t->data['sources'] = SimpleSAML_Auth_Source::getSources();
+    $t->data['sources'] = \SimpleSAML\Auth\Source::getSources();
     $t->show();
     exit();
 }
@@ -18,18 +17,18 @@ if (array_key_exists('logout', $_REQUEST)) {
     $as->logout($config->getBasePath().'logout.php');
 }
 
-if (array_key_exists(SimpleSAML_Auth_State::EXCEPTION_PARAM, $_REQUEST)) {
+if (array_key_exists(\SimpleSAML\Auth\State::EXCEPTION_PARAM, $_REQUEST)) {
     // This is just a simple example of an error
 
-    $state = SimpleSAML_Auth_State::loadExceptionState();
-    assert(array_key_exists(SimpleSAML_Auth_State::EXCEPTION_DATA, $state));
-    $e = $state[SimpleSAML_Auth_State::EXCEPTION_DATA];
+    $state = \SimpleSAML\Auth\State::loadExceptionState();
+    assert(array_key_exists(\SimpleSAML\Auth\State::EXCEPTION_DATA, $state));
+    $e = $state[\SimpleSAML\Auth\State::EXCEPTION_DATA];
 
     throw $e;
 }
 
 if (!$as->isAuthenticated()) {
-    $url = SimpleSAML\Module::getModuleURL('core/authenticate.php', array('as' => $asId));
+    $url = \SimpleSAML\Module::getModuleURL('core/authenticate.php', array('as' => $asId));
     $params = array(
         'ErrorURL' => $url,
         'ReturnTo' => $url,
@@ -38,11 +37,13 @@ if (!$as->isAuthenticated()) {
 }
 
 $attributes = $as->getAttributes();
+$authData = $as->getAuthDataArray();
 
-$t = new SimpleSAML_XHTML_Template($config, 'status.php', 'attributes');
+$t = new \SimpleSAML\XHTML\Template($config, 'status.php', 'attributes');
 
 $t->data['header'] = '{status:header_saml20_sp}';
 $t->data['attributes'] = $attributes;
+$t->data['authData'] = $authData;
 $t->data['nameid'] = !is_null($as->getAuthData('saml:sp:NameID')) ? $as->getAuthData('saml:sp:NameID') : false;
 $t->data['logouturl'] = \SimpleSAML\Utils\HTTP::getSelfURLNoQuery().'?as='.urlencode($asId).'&logout';
 $t->show();
diff --git a/modules/core/www/cardinality_error.php b/modules/core/www/cardinality_error.php
new file mode 100644
index 0000000000000000000000000000000000000000..c73a4fee6da9746252c3a3b6b749c60ad6cef971
--- /dev/null
+++ b/modules/core/www/cardinality_error.php
@@ -0,0 +1,26 @@
+<?php
+
+/**
+ * Show a 403 Forbidden page when an attribute violates a cardinality rule
+ *
+ * @package SimpleSAMLphp
+ */
+
+if (!array_key_exists('StateId', $_REQUEST)) {
+    throw new \SimpleSAML\Error\BadRequest('Missing required StateId query parameter.');
+}
+$id = $_REQUEST['StateId'];
+$state = \SimpleSAML\Auth\State::loadState($id, 'core:cardinality');
+$session = \SimpleSAML\Session::getSessionFromRequest();
+
+\SimpleSAML\Logger::stats('core:cardinality:error '.$state['Destination']['entityid'].' '.$state['saml:sp:IdP'].
+    ' '.implode(',', array_keys($state['core:cardinality:errorAttributes'])));
+
+$globalConfig = \SimpleSAML\Configuration::getInstance();
+$t = new \SimpleSAML\XHTML\Template($globalConfig, 'core:cardinality_error.tpl.php');
+$t->data['cardinalityErrorAttributes'] = $state['core:cardinality:errorAttributes'];
+if (isset($state['Source']['auth'])) {
+    $t->data['LogoutURL'] = \SimpleSAML\Module::getModuleURL('core/authenticate.php', array('as' => $state['Source']['auth']))."&logout";
+}
+header('HTTP/1.0 403 Forbidden');
+$t->show();
diff --git a/modules/core/www/cleardiscochoices.php b/modules/core/www/cleardiscochoices.php
index 3628a45315554190036520efccf551a8726480e8..96c19d8418c883c2fa4b4fdc28d99c5a9b357ee4 100644
--- a/modules/core/www/cleardiscochoices.php
+++ b/modules/core/www/cleardiscochoices.php
@@ -7,7 +7,7 @@ require_once('_include.php');
  */
 
 // The base path for cookies. This should be the installation directory for SimpleSAMLphp.
-$config = SimpleSAML_Configuration::getInstance();
+$config = \SimpleSAML\Configuration::getInstance();
 $cookiePath = $config->getBasePath();
 
 // We delete all cookies which starts with 'idpdisco_'
@@ -23,7 +23,6 @@ foreach($_COOKIE as $cookieName => $value) {
     \SimpleSAML\Utils\HTTP::setCookie($cookieName, NULL, array('path' => $cookiePath, 'httponly' => FALSE), FALSE);
 }
 
-
 /* Find where we should go now. */
 if(array_key_exists('ReturnTo', $_REQUEST)) {
 	$returnTo = \SimpleSAML\Utils\HTTP::checkURLAllowed($_REQUEST['ReturnTo']);
diff --git a/modules/core/www/frontpage_auth.php b/modules/core/www/frontpage_auth.php
index fde6b460772feb0aa484be2d2f4c853357adc9bd..5ed037ceaaec24a72dae4bf3be75f96fd998038f 100644
--- a/modules/core/www/frontpage_auth.php
+++ b/modules/core/www/frontpage_auth.php
@@ -1,28 +1,22 @@
 <?php
 
-
-// Load SimpleSAMLphp, configuration
-$config = SimpleSAML_Configuration::getInstance();
-$session = SimpleSAML_Session::getSessionFromRequest();
+// Load SimpleSAMLphp configuration
+$config = \SimpleSAML\Configuration::getInstance();
+$session = \SimpleSAML\Session::getSessionFromRequest();
 
 // Check if valid local session exists
 if ($config->getBoolean('admin.protectindexpage', false)) {
-    SimpleSAML\Utils\Auth::requireAdmin();
+    \SimpleSAML\Utils\Auth::requireAdmin();
 }
-$loginurl = SimpleSAML\Utils\Auth::getAdminLoginURL();
-$isadmin = SimpleSAML\Utils\Auth::isAdmin();
-
-
-
+$loginurl = \SimpleSAML\Utils\Auth::getAdminLoginURL();
+$isadmin = \SimpleSAML\Utils\Auth::isAdmin();
 
-	
 $links = array();
 $links_welcome = array();
 $links_config = array();
 $links_auth = array();
 $links_federation = array();
 
-
 $links_auth[] = array(
 	'href' => 'login.php',
 	'text' => '{core:frontpage:authtest}',
@@ -35,11 +29,9 @@ $allLinks = array(
 	'auth'       => &$links_auth,
 	'federation' => &$links_federation,
 );
-SimpleSAML\Module::callHooks('frontpage', $allLinks);
-
-
+\SimpleSAML\Module::callHooks('frontpage', $allLinks);
 
-$t = new SimpleSAML_XHTML_Template($config, 'core:frontpage_auth.tpl.php');
+$t = new \SimpleSAML\XHTML\Template($config, 'core:frontpage_auth.tpl.php');
 $t->data['pageid'] = 'frontpage_auth';
 $t->data['isadmin'] = $isadmin;
 $t->data['loginurl'] = $loginurl;
diff --git a/modules/core/www/frontpage_config.php b/modules/core/www/frontpage_config.php
index 42a468a24c92e28715a6e9429b2d5268adac1978..3566cf613c36cae4e5134c18eecd80415bb4fd86 100644
--- a/modules/core/www/frontpage_config.php
+++ b/modules/core/www/frontpage_config.php
@@ -1,17 +1,15 @@
 <?php
 
-
-
-// Load SimpleSAMLphp, configuration
-$config = SimpleSAML_Configuration::getInstance();
-$session = SimpleSAML_Session::getSessionFromRequest();
+// Load SimpleSAMLphp configuration
+$config = \SimpleSAML\Configuration::getInstance();
+$session = \SimpleSAML\Session::getSessionFromRequest();
 
 // Check if valid local session exists.
 if ($config->getBoolean('admin.protectindexpage', false)) {
-    SimpleSAML\Utils\Auth::requireAdmin();
+    \SimpleSAML\Utils\Auth::requireAdmin();
 }
-$loginurl = SimpleSAML\Utils\Auth::getAdminLoginURL();
-$isadmin = SimpleSAML\Utils\Auth::isAdmin();
+$loginurl = \SimpleSAML\Utils\Auth::getAdminLoginURL();
+$isadmin = \SimpleSAML\Utils\Auth::isAdmin();
 
 
 $warnings = array();
@@ -54,7 +52,7 @@ $allLinks = array(
     'auth'       => &$links_auth,
     'federation' => &$links_federation,
 );
-SimpleSAML\Module::callHooks('frontpage', $allLinks);
+\SimpleSAML\Module::callHooks('frontpage', $allLinks);
 
 // Check for updates. Store the remote result in the session so we
 // don't need to fetch it on every access to this page.
@@ -89,8 +87,8 @@ if ($config->getBoolean('admin.checkforupdates', true) && $current !== 'master')
 }
 
 $enablematrix = array(
-    'saml20idp' => $config->getBoolean('enable.saml20-idp', false),
-    'shib13idp' => $config->getBoolean('enable.shib13-idp', false),
+    'saml20-idp' => $config->getBoolean('enable.saml20-idp', false),
+    'shib13-idp' => $config->getBoolean('enable.shib13-idp', false),
 );
 
 
@@ -108,10 +106,10 @@ $functionchecks = array(
     'session_start'  => array('optional', 'Session Extension (required if PHP sessions are used)'),
     'pdo_drivers'    => array('optional', 'PDO Extension (required if a database backend is used)'),
 );
-if (SimpleSAML\Module::isModuleEnabled('ldap')) {
+if (\SimpleSAML\Module::isModuleEnabled('ldap')) {
     $functionchecks['ldap_bind'] = array('optional', 'LDAP Extension (required if an LDAP backend is used)');
 }
-if (SimpleSAML\Module::isModuleEnabled('radius')) {
+if (\SimpleSAML\Module::isModuleEnabled('radius')) {
     $functionchecks['radius_auth_open'] = array('optional', 'Radius Extension (required if a Radius backend is used)');
 }
 
@@ -160,8 +158,7 @@ $funcmatrix[] = array(
     'enabled' => $password_ok
 );
 
-
-$t = new SimpleSAML_XHTML_Template($config, 'core:frontpage_config.tpl.php');
+$t = new \SimpleSAML\XHTML\Template($config, 'core:frontpage_config.tpl.php');
 $t->data['pageid'] = 'frontpage_config';
 $t->data['header'] = $t->t('{core:frontpage:page_title}');
 $t->data['isadmin'] = $isadmin;
@@ -176,7 +173,6 @@ $t->data['links_auth'] = $links_auth;
 $t->data['links_federation'] = $links_federation;
 
 
-
 $t->data['enablematrix'] = $enablematrix;
 $t->data['funcmatrix'] = $funcmatrix;
 $t->data['requiredmap'] = array(
@@ -188,5 +184,3 @@ $t->data['version'] = $config->getVersion();
 $t->data['directory'] = dirname(dirname(dirname(dirname(__FILE__))));
 
 $t->show();
-
-
diff --git a/modules/core/www/frontpage_federation.php b/modules/core/www/frontpage_federation.php
index 9b19d911713586dc699eedb4280b21617b4f16a1..b3e2602c1aa81e3ecb73ddc1237145fcfeba1d74 100644
--- a/modules/core/www/frontpage_federation.php
+++ b/modules/core/www/frontpage_federation.php
@@ -1,33 +1,22 @@
 <?php
 
-
-
-// Load SimpleSAMLphp, configuration
-$config = SimpleSAML_Configuration::getInstance();
-$session = SimpleSAML_Session::getSessionFromRequest();
+// Load SimpleSAMLphp configuration
+$config = \SimpleSAML\Configuration::getInstance();
+$session = \SimpleSAML\Session::getSessionFromRequest();
 
 // Check if valid local session exists.
 if ($config->getBoolean('admin.protectindexpage', false)) {
-    SimpleSAML\Utils\Auth::requireAdmin();
+    \SimpleSAML\Utils\Auth::requireAdmin();
 }
-$loginurl = SimpleSAML\Utils\Auth::getAdminLoginURL();
-$isadmin = SimpleSAML\Utils\Auth::isAdmin();
-
-
-
+$loginurl = \SimpleSAML\Utils\Auth::getAdminLoginURL();
+$isadmin = \SimpleSAML\Utils\Auth::isAdmin();
 
-	
-	
-	
 $links = array();
 $links_welcome = array();
 $links_config = array();
 $links_auth = array();
 $links_federation = array();
 
-
-
-
 if($config->getBoolean('idpdisco.enableremember', FALSE)) {
 	$links_federation[] = array(
 		'href' => 'cleardiscochoices.php',
@@ -41,9 +30,6 @@ $links_federation[] = array(
 	'text' => '{core:frontpage:link_xmlconvert}',
 );
 
-
-
-
 $allLinks = array(
 	'links'      => &$links,
 	'welcome'    => &$links_welcome,
@@ -51,21 +37,14 @@ $allLinks = array(
 	'auth'       => &$links_auth,
 	'federation' => &$links_federation,
 );
-SimpleSAML\Module::callHooks('frontpage', $allLinks);
+\SimpleSAML\Module::callHooks('frontpage', $allLinks);
 
 
 $metadataHosted = array();
-SimpleSAML\Module::callHooks('metadata_hosted', $metadataHosted);
-
-
-
-
-
-
-
+\SimpleSAML\Module::callHooks('metadata_hosted', $metadataHosted);
 
 
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 
 $metaentries = array('hosted' => $metadataHosted, 'remote' => array() );
 
@@ -83,7 +62,7 @@ if ($config->getBoolean('enable.saml20-idp', FALSE) === true) {
 		if ($isadmin)
 			$metaentries['remote']['saml20-sp-remote'] = $metadata->getList('saml20-sp-remote');
 	} catch(Exception $e) {
-        SimpleSAML_Logger::error('Federation: Error loading saml20-idp: ' . $e->getMessage());
+        \SimpleSAML\Logger::error('Federation: Error loading saml20-idp: ' . $e->getMessage());
     }
 }
 if ($config->getBoolean('enable.shib13-idp', FALSE) === true) {
@@ -94,18 +73,18 @@ if ($config->getBoolean('enable.shib13-idp', FALSE) === true) {
 		if ($isadmin)
 			$metaentries['remote']['shib13-sp-remote'] = $metadata->getList('shib13-sp-remote');
 	} catch(Exception $e) {
-        SimpleSAML_Logger::error('Federation: Error loading shib13-idp: ' . $e->getMessage());
+        \SimpleSAML\Logger::error('Federation: Error loading shib13-idp: ' . $e->getMessage());
     }
 }
 if ($config->getBoolean('enable.adfs-idp', FALSE) === true) {
     try {
         $metaentries['hosted']['adfs-idp'] = $metadata->getMetaDataCurrent('adfs-idp-hosted');
-        $metaentries['hosted']['adfs-idp']['metadata-url'] = SimpleSAML\Module::getModuleURL('adfs/idp/metadata.php',
+        $metaentries['hosted']['adfs-idp']['metadata-url'] = \SimpleSAML\Module::getModuleURL('adfs/idp/metadata.php',
                                                                                              array('output' => 'xhtml'));
         if ($isadmin)
             $metaentries['remote']['adfs-sp-remote'] = $metadata->getList('adfs-sp-remote');
     } catch(Exception $e) {
-        SimpleSAML_Logger::error('Federation: Error loading adfs-idp: ' . $e->getMessage());
+        \SimpleSAML\Logger::error('Federation: Error loading adfs-idp: ' . $e->getMessage());
     }
 }
 
@@ -115,7 +94,7 @@ foreach ($metaentries['remote'] as $key => $value) {
 	}
 }
 
-$t = new SimpleSAML_XHTML_Template($config, 'core:frontpage_federation.tpl.php');
+$t = new \SimpleSAML\XHTML\Template($config, 'core:frontpage_federation.tpl.php');
 
 $language = $t->getLanguage();
 $defaultLanguage = $config->getString('language.default', 'en');
diff --git a/modules/core/www/frontpage_welcome.php b/modules/core/www/frontpage_welcome.php
index aa79756cd463d56ee6adaa0c2c9113aa8ff1fdfb..6ec1517492fd2e438d8d375d47c0fbd901d8f407 100644
--- a/modules/core/www/frontpage_welcome.php
+++ b/modules/core/www/frontpage_welcome.php
@@ -1,20 +1,15 @@
 <?php
 
-
-// Load SimpleSAMLphp, configuration
-$config = SimpleSAML_Configuration::getInstance();
-$session = SimpleSAML_Session::getSessionFromRequest();
+// Load SimpleSAMLphp configuration
+$config = \SimpleSAML\Configuration::getInstance();
+$session = \SimpleSAML\Session::getSessionFromRequest();
 
 // Check if valid local session exists.
 if ($config->getBoolean('admin.protectindexpage', false)) {
     SimpleSAML\Utils\Auth::requireAdmin();
 }
-$loginurl = SimpleSAML\Utils\Auth::getAdminLoginURL();
-$isadmin = SimpleSAML\Utils\Auth::isAdmin();
-
-
-
-
+$loginurl = \SimpleSAML\Utils\Auth::getAdminLoginURL();
+$isadmin = \SimpleSAML\Utils\Auth::isAdmin();
 
 $links = array();
 $links_welcome = array();
@@ -22,8 +17,6 @@ $links_config = array();
 $links_auth = array();
 $links_federation = array();
 
-
-
 $allLinks = array(
 	'links'      => &$links,
 	'welcome'    => &$links_welcome,
@@ -37,17 +30,9 @@ $links_welcome[] = array(
 	'text' => '{core:frontpage:doc_header}',
 );
 
-SimpleSAML\Module::callHooks('frontpage', $allLinks);
-
-
-
-
-
-
-
-
+\SimpleSAML\Module::callHooks('frontpage', $allLinks);
 
-$t = new SimpleSAML_XHTML_Template($config, 'core:frontpage_welcome.tpl.php');
+$t = new \SimpleSAML\XHTML\Template($config, 'core:frontpage_welcome.tpl.php');
 $t->data['pageid'] = 'frontpage_welcome';
 $t->data['isadmin'] = $isadmin;
 $t->data['loginurl'] = $loginurl;
diff --git a/modules/core/www/idp/logout-iframe-done.php b/modules/core/www/idp/logout-iframe-done.php
index 6b00621b842b3f334939797f93ea2c78172cb88c..a01665a646fe8b83f3185aceaac5654454031c91 100644
--- a/modules/core/www/idp/logout-iframe-done.php
+++ b/modules/core/www/idp/logout-iframe-done.php
@@ -1,21 +1,21 @@
 <?php
 
 if (!isset($_REQUEST['id'])) {
-    throw new SimpleSAML_Error_BadRequest('Missing required parameter: id');
+    throw new \SimpleSAML\Error\BadRequest('Missing required parameter: id');
 }
-$state = SimpleSAML_Auth_State::loadState($_REQUEST['id'], 'core:Logout-IFrame');
-$idp = SimpleSAML_IdP::getByState($state);
+$state = \SimpleSAML\Auth\State::loadState($_REQUEST['id'], 'core:Logout-IFrame');
+$idp = \SimpleSAML\IdP::getByState($state);
 
 $associations = $idp->getAssociations();
 
 if (!isset($_REQUEST['cancel'])) {
-    SimpleSAML\Logger::stats('slo-iframe done');
-    SimpleSAML_Stats::log('core:idp:logout-iframe:page', array('type' => 'done'));
+    \SimpleSAML\Logger::stats('slo-iframe done');
+    \SimpleSAML\Stats::log('core:idp:logout-iframe:page', array('type' => 'done'));
     $SPs = $state['core:Logout-IFrame:Associations'];
 } else {
     // user skipped global logout
-    SimpleSAML\Logger::stats('slo-iframe skip');
-    SimpleSAML_Stats::log('core:idp:logout-iframe:page', array('type' => 'skip'));
+    \SimpleSAML\Logger::stats('slo-iframe skip');
+    \SimpleSAML\Stats::log('core:idp:logout-iframe:page', array('type' => 'skip'));
     $SPs = array(); // no SPs should have been logged out
     $state['core:Failed'] = true; // mark as partial logout
 }
@@ -42,14 +42,14 @@ foreach ($SPs as $assocId => $sp) {
     if ($sp['core:Logout-IFrame:State'] === 'completed') {
         $idp->terminateAssociation($assocId);
     } else {
-        SimpleSAML\Logger::warning('Unable to terminate association with '.var_export($assocId, true).'.');
+        \SimpleSAML\Logger::warning('Unable to terminate association with '.var_export($assocId, true).'.');
         if (isset($sp['saml:entityID'])) {
             $spId = $sp['saml:entityID'];
         } else {
             $spId = $assocId;
         }
-        SimpleSAML\Logger::stats('slo-iframe-fail '.$spId);
-        SimpleSAML_Stats::log('core:idp:logout-iframe:spfail', array('sp' => $spId));
+        \SimpleSAML\Logger::stats('slo-iframe-fail '.$spId);
+        \SimpleSAML\Stats::log('core:idp:logout-iframe:spfail', array('sp' => $spId));
         $state['core:Failed'] = true;
     }
 }
diff --git a/modules/core/www/idp/logout-iframe-post.php b/modules/core/www/idp/logout-iframe-post.php
index 7079e19aa6b63be297bf5031e43141b3b30c92e6..603cb1fb5c33cf630572c7fc4cd14cd15878e360 100644
--- a/modules/core/www/idp/logout-iframe-post.php
+++ b/modules/core/www/idp/logout-iframe-post.php
@@ -1,13 +1,13 @@
 <?php
 
 if (!isset($_REQUEST['idp'])) {
-    throw new SimpleSAML_Error_BadRequest('Missing "idp" parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing "idp" parameter.');
 }
 $idp = (string) $_REQUEST['idp'];
-$idp = SimpleSAML_IdP::getById($idp);
+$idp = \SimpleSAML\IdP::getById($idp);
 
 if (!isset($_REQUEST['association'])) {
-    throw new SimpleSAML_Error_BadRequest('Missing "association" parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing "association" parameter.');
 }
 $assocId = urldecode($_REQUEST['association']);
 
@@ -18,15 +18,15 @@ if (isset($_REQUEST['RelayState'])) {
 
 $associations = $idp->getAssociations();
 if (!isset($associations[$assocId])) {
-    throw new SimpleSAML_Error_BadRequest('Invalid association id.');
+    throw new \SimpleSAML\Error\BadRequest('Invalid association id.');
 }
 $association = $associations[$assocId];
 
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 $idpMetadata = $idp->getConfig();
 $spMetadata = $metadata->getMetaDataConfig($association['saml:entityID'], 'saml20-sp-remote');
 
-$lr = sspmod_saml_Message::buildLogoutRequest($idpMetadata, $spMetadata);
+$lr = \SimpleSAML\Module\saml\Message::buildLogoutRequest($idpMetadata, $spMetadata);
 $lr->setSessionIndex($association['saml:SessionIndex']);
 $lr->setNameId($association['saml:NameID']);
 
@@ -41,10 +41,10 @@ if ($encryptNameId === null) {
     $encryptNameId = $idpMetadata->getBoolean('nameid.encryption', false);
 }
 if ($encryptNameId) {
-    $lr->encryptNameId(sspmod_saml_Message::getEncryptionKey($spMetadata));
+    $lr->encryptNameId(\SimpleSAML\Module\saml\Message::getEncryptionKey($spMetadata));
 }
 
-SimpleSAML_Stats::log('saml:idp:LogoutRequest:sent', array(
+\SimpleSAML\Stats::log('saml:idp:LogoutRequest:sent', array(
     'spEntityID'  => $association['saml:entityID'],
     'idpEntityID' => $idpMetadata->getString('entityid'),
 ));
diff --git a/modules/core/www/idp/logout-iframe.php b/modules/core/www/idp/logout-iframe.php
index f5e8e4e6a98e3c5ac432589079021be4e5682385..e2be5bd7905fb937468bf586a60bf638b6971904 100644
--- a/modules/core/www/idp/logout-iframe.php
+++ b/modules/core/www/idp/logout-iframe.php
@@ -1,26 +1,26 @@
 <?php
 
 if (!isset($_REQUEST['id'])) {
-    throw new SimpleSAML_Error_BadRequest('Missing required parameter: id');
+    throw new \SimpleSAML\Error\BadRequest('Missing required parameter: id');
 }
 
 if (isset($_REQUEST['type'])) {
     $type = (string) $_REQUEST['type'];
     if (!in_array($type, array('init', 'js', 'nojs', 'embed'), true)) {
-        throw new SimpleSAML_Error_BadRequest('Invalid value for type.');
+        throw new \SimpleSAML\Error\BadRequest('Invalid value for type.');
     }
 } else {
     $type = 'init';
 }
 
 if ($type !== 'embed') {
-    SimpleSAML\Logger::stats('slo-iframe '.$type);
-    SimpleSAML_Stats::log('core:idp:logout-iframe:page', array('type' => $type));
+    \SimpleSAML\Logger::stats('slo-iframe '.$type);
+    \SimpleSAML\Stats::log('core:idp:logout-iframe:page', array('type' => $type));
 }
 
-$state = SimpleSAML_Auth_State::loadState($_REQUEST['id'], 'core:Logout-IFrame');
-$idp = SimpleSAML_IdP::getByState($state);
-$mdh = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$state = \SimpleSAML\Auth\State::loadState($_REQUEST['id'], 'core:Logout-IFrame');
+$idp = \SimpleSAML\IdP::getByState($state);
+$mdh = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 
 if ($type !== 'init') { // update association state
     foreach ($state['core:Logout-IFrame:Associations'] as $assocId => &$sp) {
@@ -53,7 +53,7 @@ if ($type !== 'init') { // update association state
 
         if (!isset($sp['core:Logout-IFrame:Timeout'])) {
             if (method_exists($sp['Handler'], 'getAssociationConfig')) {
-                $assocIdP = SimpleSAML_IdP::getByState($sp);
+                $assocIdP = \SimpleSAML\IdP::getByState($sp);
                 $assocConfig = call_user_func(array($sp['Handler'], 'getAssociationConfig'), $assocIdP, $sp);
                 $sp['core:Logout-IFrame:Timeout'] = $assocConfig->getInteger('core:logout-timeout', 5) + time();
             } else {
@@ -71,10 +71,10 @@ foreach ($state['core:Logout-IFrame:Associations'] as $assocId => &$sp) {
     }
 
     try {
-        $assocIdP = SimpleSAML_IdP::getByState($sp);
+        $assocIdP = \SimpleSAML\IdP::getByState($sp);
         $url = call_user_func(array($sp['Handler'], 'getLogoutURL'), $assocIdP, $sp, null);
         $sp['core:Logout-IFrame:URL'] = $url;
-    } catch (Exception $e) {
+    } catch (\Exception $e) {
         $sp['core:Logout-IFrame:State'] = 'failed';
     }
 }
@@ -112,15 +112,15 @@ foreach ($state['core:Logout-IFrame:Associations'] as $association) {
     }
 }
 
-$id = SimpleSAML_Auth_State::saveState($state, 'core:Logout-IFrame');
-$globalConfig = SimpleSAML_Configuration::getInstance();
+$id = \SimpleSAML\Auth\State::saveState($state, 'core:Logout-IFrame');
+$globalConfig = \SimpleSAML\Configuration::getInstance();
 
 $template_id = 'core:logout-iframe.php';
 if ($type === 'nojs') {
     $template_id = 'core:logout-iframe-wrapper.php';
 }
 
-$t = new SimpleSAML_XHTML_Template($globalConfig, $template_id);
+$t = new \SimpleSAML\XHTML\Template($globalConfig, $template_id);
 $t->data['auth_state'] = $id;
 $t->data['header'] = $t->t('{logout:progress}');
 
diff --git a/modules/core/www/idp/resumelogout.php b/modules/core/www/idp/resumelogout.php
index 199dad3b6f33515cf24ea1c944d89bfa1eb9b252..3e84b3a4e2a8b78c001ef8db9b810dc221e556c5 100644
--- a/modules/core/www/idp/resumelogout.php
+++ b/modules/core/www/idp/resumelogout.php
@@ -1,10 +1,10 @@
 <?php
 
 if (!isset($_REQUEST['id'])) {
-    throw new SimpleSAML_Error_BadRequest('Missing id-parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing id-parameter.');
 }
-$state = SimpleSAML_Auth_State::loadState($_REQUEST['id'], 'core:Logout:afterbridge');
-$idp = SimpleSAML_IdP::getByState($state);
+$state = \SimpleSAML\Auth\State::loadState($_REQUEST['id'], 'core:Logout:afterbridge');
+$idp = \SimpleSAML\IdP::getByState($state);
 
 $assocId = $state['core:TerminatedAssocId'];
 
diff --git a/modules/core/www/login-admin.php b/modules/core/www/login-admin.php
index 22bc7854aed50348332d85f3cc0aabd8cb9a7ff8..2fc0c6623944c783c63b974caba1f38ecc96d597 100644
--- a/modules/core/www/login-admin.php
+++ b/modules/core/www/login-admin.php
@@ -1,13 +1,14 @@
 <?php
+
 /*
  * Helper page for starting a admin login. Can be used as a target for links.
  */
 
 if (!array_key_exists('ReturnTo', $_REQUEST)) {
-	throw new SimpleSAML_Error_BadRequest('Missing ReturnTo parameter.');
+	throw new \SimpleSAML\Error\BadRequest('Missing ReturnTo parameter.');
 }
 
-SimpleSAML\Utils\Auth::requireAdmin();
+\SimpleSAML\Utils\Auth::requireAdmin();
 
 \SimpleSAML\Utils\HTTP::redirectUntrustedURL($_REQUEST['ReturnTo']);
 
diff --git a/modules/core/www/loginuserpass.php b/modules/core/www/loginuserpass.php
index 99be03f979fd5537d9d15480635d44229ce2f5d6..ff5955e58f5c35de9c071533209e7d73a5f9047e 100644
--- a/modules/core/www/loginuserpass.php
+++ b/modules/core/www/loginuserpass.php
@@ -2,7 +2,7 @@
 
 /**
  * This page shows a username/password login form, and passes information from it
- * to the sspmod_core_Auth_UserPassBase class, which is a generic class for
+ * to the \SimpleSAML\Module\core\Auth\UserPassBase class, which is a generic class for
  * username/password authentication.
  *
  * @author Olav Morken, UNINETT AS.
@@ -11,14 +11,14 @@
 
 // Retrieve the authentication state
 if (!array_key_exists('AuthState', $_REQUEST)) {
-	throw new SimpleSAML_Error_BadRequest('Missing AuthState parameter.');
+	throw new \SimpleSAML\Error\BadRequest('Missing AuthState parameter.');
 }
 $authStateId = $_REQUEST['AuthState'];
-$state = SimpleSAML_Auth_State::loadState($authStateId, sspmod_core_Auth_UserPassBase::STAGEID);
+$state = \SimpleSAML\Auth\State::loadState($authStateId, \SimpleSAML\Module\core\Auth\UserPassBase::STAGEID);
 
-$source = SimpleSAML_Auth_Source::getById($state[sspmod_core_Auth_UserPassBase::AUTHID]);
+$source = \SimpleSAML\Auth\Source::getById($state[\SimpleSAML\Module\core\Auth\UserPassBase::AUTHID]);
 if ($source === NULL) {
-	throw new Exception('Could not find authentication source with id ' . $state[sspmod_core_Auth_UserPassBase::AUTHID]);
+	throw new \Exception('Could not find authentication source with id ' . $state[\SimpleSAML\Module\core\Auth\UserPassBase::AUTHID]);
 }
 
 
@@ -66,13 +66,13 @@ if (!empty($_REQUEST['username']) || !empty($password)) {
     if ($source->isRememberMeEnabled()) {
         if (array_key_exists('remember_me', $_REQUEST) && $_REQUEST['remember_me'] === 'Yes') {
             $state['RememberMe'] = TRUE;
-            $authStateId = SimpleSAML_Auth_State::saveState($state, sspmod_core_Auth_UserPassBase::STAGEID);
+            $authStateId = \SimpleSAML\Auth\State::saveState($state, \SimpleSAML\Module\core\Auth\UserPassBase::STAGEID);
         }
     }
 
 	try {
-		sspmod_core_Auth_UserPassBase::handleLogin($authStateId, $username, $password);
-	} catch (SimpleSAML_Error_Error $e) {
+		\SimpleSAML\Module\core\Auth\UserPassBase::handleLogin($authStateId, $username, $password);
+	} catch (\SimpleSAML\Error\Error $e) {
 		/* Login failed. Extract error code and parameters, to display the error. */
 		$errorCode = $e->getErrorCode();
 		$errorParams = $e->getParameters();
@@ -88,8 +88,8 @@ if (!empty($_REQUEST['username']) || !empty($password)) {
     }
 }
 
-$globalConfig = SimpleSAML_Configuration::getInstance();
-$t = new SimpleSAML_XHTML_Template($globalConfig, 'core:loginuserpass.php');
+$globalConfig = \SimpleSAML\Configuration::getInstance();
+$t = new \SimpleSAML\XHTML\Template($globalConfig, 'core:loginuserpass.php');
 $t->data['stateparams'] = array('AuthState' => $authStateId);
 if (array_key_exists('forcedUsername', $state)) {
 	$t->data['username'] = $state['forcedUsername'];
diff --git a/modules/core/www/loginuserpassorg.php b/modules/core/www/loginuserpassorg.php
index be1dc21fa5749a0f2adbcc4b1f4dc89c3c5d1347..5051dbb29c1032aa4961ad6c176aa856970db4c4 100644
--- a/modules/core/www/loginuserpassorg.php
+++ b/modules/core/www/loginuserpassorg.php
@@ -2,7 +2,7 @@
 
 /**
  * This page shows a username/password/organization login form, and passes information from
- * itto the sspmod_core_Auth_UserPassBase class, which is a generic class for
+ * into the \SimpleSAML\Module\core\Auth\UserPassBase class, which is a generic class for
  * username/password/organization authentication.
  *
  * @author Olav Morken, UNINETT AS.
@@ -11,17 +11,17 @@
 
 // Retrieve the authentication state
 if (!array_key_exists('AuthState', $_REQUEST)) {
-	throw new SimpleSAML_Error_BadRequest('Missing AuthState parameter.');
+	throw new \SimpleSAML\Error\BadRequest('Missing AuthState parameter.');
 }
 $authStateId = $_REQUEST['AuthState'];
-$state = SimpleSAML_Auth_State::loadState($authStateId, sspmod_core_Auth_UserPassOrgBase::STAGEID);
+$state = \SimpleSAML\Auth\State::loadState($authStateId, \SimpleSAML\Module\core\Auth\UserPassOrgBase::STAGEID);
 
-$source = SimpleSAML_Auth_Source::getById($state[sspmod_core_Auth_UserPassOrgBase::AUTHID]);
+$source = \SimpleSAML\Auth\Source::getById($state[\SimpleSAML\Module\core\Auth\UserPassOrgBase::AUTHID]);
 if ($source === NULL) {
-	throw new Exception('Could not find authentication source with id ' . $state[sspmod_core_Auth_UserPassOrgBase::AUTHID]);
+	throw new \Exception('Could not find authentication source with id ' . $state[\SimpleSAML\Module\core\Auth\UserPassOrgBase::AUTHID]);
 }
 
-$organizations = sspmod_core_Auth_UserPassOrgBase::listOrganizations($authStateId);
+$organizations = \SimpleSAML\Module\core\Auth\UserPassOrgBase::listOrganizations($authStateId);
 
 if (array_key_exists('username', $_REQUEST)) {
 	$username = $_REQUEST['username'];
@@ -79,8 +79,8 @@ if ($organizations === NULL || !empty($organization)) {
         }
 
 		try {
-			sspmod_core_Auth_UserPassOrgBase::handleLogin($authStateId, $username, $password, $organization);
-		} catch (SimpleSAML_Error_Error $e) {
+			\SimpleSAML\Module\core\Auth\UserPassOrgBase::handleLogin($authStateId, $username, $password, $organization);
+		} catch (\SimpleSAML\Error\Error $e) {
 			// Login failed. Extract error code and parameters, to display the error
 			$errorCode = $e->getErrorCode();
 			$errorParams = $e->getParameters();
@@ -97,8 +97,8 @@ if ($organizations === NULL || !empty($organization)) {
 	}
 }
 
-$globalConfig = SimpleSAML_Configuration::getInstance();
-$t = new SimpleSAML_XHTML_Template($globalConfig, 'core:loginuserpass.php');
+$globalConfig = \SimpleSAML\Configuration::getInstance();
+$t = new \SimpleSAML\XHTML\Template($globalConfig, 'core:loginuserpass.php');
 $t->data['stateparams'] = array('AuthState' => $authStateId);
 $t->data['username'] = $username;
 $t->data['forceUsername'] = FALSE;
@@ -111,7 +111,7 @@ $t->data['rememberOrganizationEnabled'] = $source->getRememberOrganizationEnable
 $t->data['rememberOrganizationChecked'] = $source->getRememberOrganizationChecked();
 if (isset($_COOKIE[$source->getAuthId() . '-organization'])) $t->data['rememberOrganizationChecked'] = true;
 $t->data['errorcode'] = $errorCode;
-$t->data['errorcodes'] = SimpleSAML\Error\ErrorCodes::getAllErrorCodeMessages();
+$t->data['errorcodes'] = \SimpleSAML\Error\ErrorCodes::getAllErrorCodeMessages();
 $t->data['errorparams'] = $errorParams;
 
 if (!empty($queryParams)) {
diff --git a/modules/core/www/no_cookie.php b/modules/core/www/no_cookie.php
index ec330500fb525ba2a3911e0db0ff27991a5c53d6..24d6b3e8868e7d9ec3d3d3515699dde3eea384ae 100644
--- a/modules/core/www/no_cookie.php
+++ b/modules/core/www/no_cookie.php
@@ -7,8 +7,8 @@ if (isset($_REQUEST['retryURL'])) {
     $retryURL = null;
 }
 
-$globalConfig = SimpleSAML_Configuration::getInstance();
-$t = new SimpleSAML_XHTML_Template($globalConfig, 'core:no_cookie.tpl.php');
+$globalConfig = \SimpleSAML\Configuration::getInstance();
+$t = new \SimpleSAML\XHTML\Template($globalConfig, 'core:no_cookie.tpl.php');
 
 $t->data['header'] = htmlspecialchars($t->t('{core:no_cookie:header}'));
 $t->data['description'] = htmlspecialchars($t->t('{core:no_cookie:description}'));
diff --git a/modules/core/www/postredirect.php b/modules/core/www/postredirect.php
index 2f3cb131c4f5bb3afc05f2279d84425d7623051c..40441f1980e2c451a8e93505b815bcd48f51b9ee 100644
--- a/modules/core/www/postredirect.php
+++ b/modules/core/www/postredirect.php
@@ -8,23 +8,23 @@
 
 if (array_key_exists('RedirId', $_REQUEST)) {
 	$postId = $_REQUEST['RedirId'];
-	$session = SimpleSAML_Session::getSessionFromRequest();
+	$session = \SimpleSAML\Session::getSessionFromRequest();
 } elseif (array_key_exists('RedirInfo', $_REQUEST)) {
 	$encData = base64_decode($_REQUEST['RedirInfo']);
 
 	if (empty($encData)) {
-		throw new SimpleSAML_Error_BadRequest('Invalid RedirInfo data.');
+		throw new \SimpleSAML\Error\BadRequest('Invalid RedirInfo data.');
 	}
 
-	list($sessionId, $postId) = explode(':', SimpleSAML\Utils\Crypto::aesDecrypt($encData));
+	list($sessionId, $postId) = explode(':', \SimpleSAML\Utils\Crypto::aesDecrypt($encData));
 
 	if (empty($sessionId) || empty($postId)) {
-		throw new SimpleSAML_Error_BadRequest('Invalid session info data.');
+		throw new \SimpleSAML\Error\BadRequest('Invalid session info data.');
 	}
 
-	$session = SimpleSAML_Session::getSession($sessionId);
+	$session = \SimpleSAML\Session::getSession($sessionId);
 } else {
-	throw new SimpleSAML_Error_BadRequest('Missing redirection info parameter.');
+	throw new \SimpleSAML\Error\BadRequest('Missing redirection info parameter.');
 }
 
 if ($session === NULL) {
@@ -44,8 +44,8 @@ assert(is_array($postData));
 assert(array_key_exists('url', $postData));
 assert(array_key_exists('post', $postData));
 
-$config = SimpleSAML_Configuration::getInstance();
-$template = new SimpleSAML_XHTML_Template($config, 'post.php');
+$config = \SimpleSAML\Configuration::getInstance();
+$template = new \SimpleSAML\XHTML\Template($config, 'post.php');
 $template->data['destination'] = $postData['url'];
 $template->data['post'] = $postData['post'];
 $template->show();
diff --git a/modules/core/www/short_sso_interval.php b/modules/core/www/short_sso_interval.php
index 1c598c4832b8c2896f1cdfc642bc7e8a42a8bf65..d1f5ae32dd5dfec1fa3b38d08f83163411c98c81 100644
--- a/modules/core/www/short_sso_interval.php
+++ b/modules/core/www/short_sso_interval.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Show a warning to an user about the SP requesting SSO a short time after
  * doing it previously.
@@ -7,20 +8,20 @@
  */
 
 if (!array_key_exists('StateId', $_REQUEST)) {
-	throw new SimpleSAML_Error_BadRequest('Missing required StateId query parameter.');
+	throw new \SimpleSAML\Error\BadRequest('Missing required StateId query parameter.');
 }
 $id = $_REQUEST['StateId'];
-$state = SimpleSAML_Auth_State::loadState($id, 'core:short_sso_interval');
-$session = SimpleSAML_Session::getSessionFromRequest();
+$state = \SimpleSAML\Auth\State::loadState($id, 'core:short_sso_interval');
+$session = \SimpleSAML\Session::getSessionFromRequest();
 
 if (array_key_exists('continue', $_REQUEST)) {
 	// The user has pressed the continue/retry-button
-	SimpleSAML_Auth_ProcessingChain::resumeProcessing($state);
+	\SimpleSAML\Auth\ProcessingChain::resumeProcessing($state);
 }
 
-$globalConfig = SimpleSAML_Configuration::getInstance();
-$t = new SimpleSAML_XHTML_Template($globalConfig, 'core:short_sso_interval.php');
-$t->data['target'] = SimpleSAML\Module::getModuleURL('core/short_sso_interval.php');
+$globalConfig = \SimpleSAML\Configuration::getInstance();
+$t = new \SimpleSAML\XHTML\Template($globalConfig, 'core:short_sso_interval.php');
+$t->data['target'] = \SimpleSAML\Module::getModuleURL('core/short_sso_interval.php');
 $t->data['params'] = array('StateId' => $id);
 $t->data['trackId'] = $session->getTrackID();
 $this->data['header'] = $this->t('{core:short_sso_interval:warning_header}');
diff --git a/modules/core/www/show_metadata.php b/modules/core/www/show_metadata.php
index 102f1033f2feb862dbcd35fb7eb244eaeea0ce1d..389d12a3309d5818a154b8ced1a79b6ca357f5e2 100644
--- a/modules/core/www/show_metadata.php
+++ b/modules/core/www/show_metadata.php
@@ -1,10 +1,10 @@
 <?php
 
 // load configuration
-$config = SimpleSAML_Configuration::getInstance();
-$session = SimpleSAML_Session::getSessionFromRequest();
+$config = \SimpleSAML\Configuration::getInstance();
+$session = \SimpleSAML\Session::getSessionFromRequest();
 
-SimpleSAML\Utils\Auth::requireAdmin();
+\SimpleSAML\Utils\Auth::requireAdmin();
 
 if (!array_key_exists('entityid', $_REQUEST)) {
     throw new Exception('required parameter [entityid] missing');
@@ -20,18 +20,15 @@ if (!in_array(
     throw new Exception('Invalid set');
 }
 
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 
 $m = $metadata->getMetadata($_REQUEST['entityid'], $_REQUEST['set']);
 
-$t = new SimpleSAML_XHTML_Template($config, 'core:show_metadata.tpl.php');
+$t = new \SimpleSAML\XHTML\Template($config, 'core:show_metadata.tpl.php');
 $t->data['clipboard.js'] = true;
 $t->data['pageid'] = 'show_metadata';
 $t->data['header'] = 'SimpleSAMLphp Show Metadata';
-$t->data['backlink'] = SimpleSAML\Module::getModuleURL('core/frontpage_federation.php');
-/**
- * @todo Remove "m" from the data array once we remove the old PHP templates.
- */
+$t->data['backlink'] = \SimpleSAML\Module::getModuleURL('core/frontpage_federation.php');
 $t->data['m'] = $m;
 $t->data['entityid'] = $m['metadata-index'];
 unset($m['metadata-index']);
diff --git a/modules/cron/hooks/hook_cron.php b/modules/cron/hooks/hook_cron.php
index ba175b4eb2ebb4c6224309fff310007a7556ad4c..6d2cd290ca96092420a91afd7b5c0d2c038cea94 100644
--- a/modules/cron/hooks/hook_cron.php
+++ b/modules/cron/hooks/hook_cron.php
@@ -9,7 +9,7 @@ function cron_hook_cron(&$croninfo) {
 	assert(array_key_exists('summary', $croninfo));
 	assert(array_key_exists('tag', $croninfo));
 
-	$cronconfig = SimpleSAML_Configuration::getConfig('module_cron.php');
+	$cronconfig = \SimpleSAML\Configuration::getConfig('module_cron.php');
 	
 	if ($cronconfig->getValue('debug_message', TRUE)) {
 
diff --git a/modules/cron/lib/Cron.php b/modules/cron/lib/Cron.php
index bba782afaca5d768b123c5667fa6d9577600aa95..0df16e375f4ab725b1db4ac37a1a341f05063e8b 100644
--- a/modules/cron/lib/Cron.php
+++ b/modules/cron/lib/Cron.php
@@ -9,18 +9,18 @@ class Cron
 {
     /**
      * The configuration for the Cron module
-     * @var \SimpleSAML_Configuration
+     * @var \SimpleSAML\Configuration
      */
     private $cronconfig;
 
     /*
-     * @param \SimpleSAML_Configuration $cronconfig The cron configuration to use. If not specified defaults
+     * @param \SimpleSAML\Configuration $cronconfig The cron configuration to use. If not specified defaults
      * to `config/module_cron.php`
      */
-    public function __construct(\SimpleSAML_Configuration $cronconfig = null)
+    public function __construct(\SimpleSAML\Configuration $cronconfig = null)
     {
         if ($cronconfig == null) {
-            $cronconfig = \SimpleSAML_Configuration::getConfig('module_cron.php');
+            $cronconfig = \SimpleSAML\Configuration::getConfig('module_cron.php');
         }
         $this->cronconfig = $cronconfig;
     }
diff --git a/modules/cron/www/cron.php b/modules/cron/www/cron.php
index 4f22fc5df0b111403d9fd6e119264a8d083b04f2..69329b977a6018af9b73fec1b2e57e169b43b0e9 100644
--- a/modules/cron/www/cron.php
+++ b/modules/cron/www/cron.php
@@ -1,22 +1,21 @@
 <?php
 
-$config = SimpleSAML_Configuration::getInstance();
-$cronconfig = SimpleSAML_Configuration::getConfig('module_cron.php');
+$config = \SimpleSAML\Configuration::getInstance();
+$cronconfig = \SimpleSAML\Configuration::getConfig('module_cron.php');
 
 if (!is_null($cronconfig->getValue('key'))) {
 	if ($_REQUEST['key'] !== $cronconfig->getValue('key')) {
-		SimpleSAML\Logger::error('Cron - Wrong key provided. Cron will not run.');
+		\SimpleSAML\Logger::error('Cron - Wrong key provided. Cron will not run.');
 		exit;
 	}
 }
 
-$cron = new SimpleSAML\Module\cron\Cron();
+$cron = new \SimpleSAML\Module\cron\Cron();
 if (!$cron->isValidTag($_REQUEST['tag'])) {
     SimpleSAML\Logger::error('Cron - Illegal tag [' . $_REQUEST['tag'] . '].');
     exit;
 }
 
-
 $url = \SimpleSAML\Utils\HTTP::getSelfURL();
 $time = date(DATE_RFC822);
 
@@ -24,7 +23,6 @@ $croninfo = $cron->runTag($_REQUEST['tag']);
 $summary = $croninfo['summary'];
 
 if ($cronconfig->getValue('sendemail', TRUE) && count($summary) > 0) {
-
 	$message = '<h1>Cron report</h1><p>Cron ran at ' . $time . '</p>' .
 		'<p>URL: <tt>' . $url . '</tt></p>' .
 		'<p>Tag: ' . $croninfo['tag'] . "</p>\n\n" .
@@ -32,18 +30,17 @@ if ($cronconfig->getValue('sendemail', TRUE) && count($summary) > 0) {
 
 	$toaddress = $config->getString('technicalcontact_email', 'na@example.org');
 	if($toaddress == 'na@example.org') {
-		SimpleSAML\Logger::error('Cron - Could not send email. [technicalcontact_email] not set in config.');
+		\SimpleSAML\Logger::error('Cron - Could not send email. [technicalcontact_email] not set in config.');
 	} else {
 		// Use $toaddress for both TO and FROM
-		$email = new SimpleSAML_XHTML_EMail($toaddress, 'SimpleSAMLphp cron report', $toaddress);
+		$email = new \SimpleSAML\XHTML\EMail($toaddress, 'SimpleSAMLphp cron report', $toaddress);
 		$email->setBody($message);
 		$email->send();
 	}
-	
 }
 
 if (isset($_REQUEST['output']) && $_REQUEST['output'] == "xhtml") {
-	$t = new SimpleSAML_XHTML_Template($config, 'cron:croninfo-result.php','cron:cron');
+	$t = new \SimpleSAML\XHTML\Template($config, 'cron:croninfo-result.php','cron:cron');
 	$t->data['tag'] = $croninfo['tag'];
 	$t->data['time'] = $time;
 	$t->data['url'] = $url;
diff --git a/modules/cron/www/croninfo.php b/modules/cron/www/croninfo.php
index 93b7acb5b15bc25898aaab4d587d12fbb05b791e..3e646cc6ccca52d6b14e545aa2c624c9685aa20e 100644
--- a/modules/cron/www/croninfo.php
+++ b/modules/cron/www/croninfo.php
@@ -4,16 +4,16 @@
  * The _include script registers a autoloader for the SimpleSAMLphp libraries. It also
  * initializes the SimpleSAMLphp config class with the correct path.
  */
-require_once('_include.php');
 
+require_once('_include.php');
 
-// Load SimpleSAMLphp, configuration and metadata
-$config = SimpleSAML_Configuration::getInstance();
-$session = SimpleSAML_Session::getSessionFromRequest();
+// Load SimpleSAMLphp configuration and metadata
+$config = \SimpleSAML\Configuration::getInstance();
+$session = \SimpleSAML\Session::getSessionFromRequest();
 
-SimpleSAML\Utils\Auth::requireAdmin();
+\SimpleSAML\Utils\Auth::requireAdmin();
 
-$cronconfig = SimpleSAML_Configuration::getConfig('module_cron.php');
+$cronconfig = \SimpleSAML\Configuration::getConfig('module_cron.php');
 
 $key = $cronconfig->getValue('key', '');
 $tags = $cronconfig->getValue('allowed_tags');
@@ -28,14 +28,12 @@ $def = array(
 $urls = array();
 foreach ($tags AS $tag) {
 	$urls[] = array(
-		'href' => SimpleSAML\Module::getModuleURL('cron/cron.php', array('key' => $key, 'tag' => $tag)),
+		'href' => \SimpleSAML\Module::getModuleURL('cron/cron.php', array('key' => $key, 'tag' => $tag)),
 		'tag' => $tag,
 		'int' => (array_key_exists($tag, $def) ? $def[$tag] : $def['default']),
 	);
 }
 
-
-
-$t = new SimpleSAML_XHTML_Template($config, 'cron:croninfo.tpl.php', 'cron:cron');
+$t = new \SimpleSAML\XHTML\Template($config, 'cron:croninfo.tpl.php', 'cron:cron');
 $t->data['urls'] = $urls;
 $t->show();
diff --git a/modules/discopower/lib/PowerIdPDisco.php b/modules/discopower/lib/PowerIdPDisco.php
index e70bc83d6c90b182140a27729d145ee6ccc43809..487b3f14b56a265ce6dbc4c59818bfa16029374b 100644
--- a/modules/discopower/lib/PowerIdPDisco.php
+++ b/modules/discopower/lib/PowerIdPDisco.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML\Module\discopower;
 
 /**
  * This class implements a generic IdP discovery service, for use in various IdP discovery service pages. This should
@@ -10,12 +11,13 @@
  * @author Andreas Ă…kre Solberg <andreas@uninett.no>, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class sspmod_discopower_PowerIdPDisco extends SimpleSAML_XHTML_IdPDisco
+
+class PowerIdPDisco extends \SimpleSAML\XHTML\IdPDisco
 {
     /**
      * The configuration for this instance.
      *
-     * @var SimpleSAML_Configuration
+     * @var \SimpleSAML\Configuration
      */
     private $discoconfig;
 
@@ -49,7 +51,7 @@ class sspmod_discopower_PowerIdPDisco extends SimpleSAML_XHTML_IdPDisco
     {
         parent::__construct($metadataSets, $instance);
 
-        $this->discoconfig = SimpleSAML_Configuration::getConfig('module_discopower.php');
+        $this->discoconfig = \SimpleSAML\Configuration::getConfig('module_discopower.php');
 
         $this->cdcDomain = $this->discoconfig->getString('cdc.domain', null);
         if ($this->cdcDomain !== null && $this->cdcDomain[0] !== '.') {
@@ -70,7 +72,7 @@ class sspmod_discopower_PowerIdPDisco extends SimpleSAML_XHTML_IdPDisco
      */
     protected function log($message)
     {
-        SimpleSAML\Logger::info('PowerIdPDisco.'.$this->instance.': '.$message);
+        \SimpleSAML\Logger::info('PowerIdPDisco.'.$this->instance.': '.$message);
     }
 
 
@@ -133,7 +135,7 @@ class sspmod_discopower_PowerIdPDisco extends SimpleSAML_XHTML_IdPDisco
         }
 
         foreach ($slist as $tab => $tbslist) {
-            uasort($slist[$tab], array('sspmod_discopower_PowerIdPDisco', 'mcmp'));
+            uasort($slist[$tab], array('\SimpleSAML\Module\discopower\PowerIdPDisco', 'mcmp'));
         }
 
         return $slist;
@@ -188,7 +190,7 @@ class sspmod_discopower_PowerIdPDisco extends SimpleSAML_XHTML_IdPDisco
 
         try {
             $spmd = $this->metadata->getMetaData($this->spEntityId, 'saml20-sp-remote');
-        } catch (Exception $e) {
+        } catch (\Exception $e) {
             return $list;
         }
 
@@ -245,7 +247,14 @@ class sspmod_discopower_PowerIdPDisco extends SimpleSAML_XHTML_IdPDisco
         $idpList = $this->idplistStructured($this->filterList($idpList));
         $preferredIdP = $this->getRecommendedIdP();
 
-        $t = new SimpleSAML_XHTML_Template($this->config, 'discopower:disco.tpl.php', 'disco');
+        $faventry = null;
+        foreach ($idpList AS $tab => $slist) {
+            if (!empty($preferredIdP) && array_key_exists($preferredIdP, $slist)) {
+                $faventry = $slist[$preferredIdP];
+            }
+        }
+
+        $t = new \SimpleSAML\XHTML\Template($this->config, 'discopower:disco.tpl.php', 'disco');
         $discoPowerTabs = array(
             'denmark' => $t->noop('{discopower:tabs:denmark}'),
             'edugain' => $t->noop('{discopower:tabs:edugain}'),
diff --git a/modules/discopower/www/disco.php b/modules/discopower/www/disco.php
index bfadb7c986dd9b5bb342d0b33cdd629b8d94cb99..29d4343f6d54aaec29939496c3b6e50631e609b8 100644
--- a/modules/discopower/www/disco.php
+++ b/modules/discopower/www/disco.php
@@ -1,15 +1,15 @@
 <?php
 
 try {
-	$discoHandler = new sspmod_discopower_PowerIdPDisco(array('saml20-idp-remote', 'shib13-idp-remote'), 'poweridpdisco');
-} catch (Exception $exception) {
-	// An error here should be caused by invalid query parameters
-	throw new SimpleSAML_Error_Error('DISCOPARAMS', $exception);
+    $discoHandler = new \SimpleSAML\Module\discopower\PowerIdPDisco(array('saml20-idp-remote', 'shib13-idp-remote'), 'poweridpdisco');
+} catch (\Exception $exception) {
+    // An error here should be caused by invalid query parameters
+    throw new \SimpleSAML\Error\Error('DISCOPARAMS', $exception);
 }
 
 try {
-	$discoHandler->handleRequest();
-} catch(Exception $exception) {
-	// An error here should be caused by metadata
-	throw new SimpleSAML_Error_Error('METADATA', $exception);
+    $discoHandler->handleRequest();
+} catch (\Exception $exception) {
+    // An error here should be caused by metadata
+    throw new \SimpleSAML\Error\Error('METADATA', $exception);
 }
diff --git a/modules/exampleattributeserver/www/attributeserver.php b/modules/exampleattributeserver/www/attributeserver.php
index 8f257c2a427bf9fb8564cbe8ceeba1a8a744a4ad..9978b0bbc274ae41d6e80a8fc5ce9a7e15002e83 100644
--- a/modules/exampleattributeserver/www/attributeserver.php
+++ b/modules/exampleattributeserver/www/attributeserver.php
@@ -1,11 +1,11 @@
 <?php
 
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 
 $binding = \SAML2\Binding::getCurrentBinding();
 $query = $binding->receive();
 if (!($query instanceof \SAML2\AttributeQuery)) {
-	throw new SimpleSAML_Error_BadRequest('Invalid message received to AttributeQuery endpoint.');
+	throw new \SimpleSAML\Error\BadRequest('Invalid message received to AttributeQuery endpoint.');
 }
 
 $idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
@@ -13,7 +13,7 @@ $idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
 
 $spEntityId = $query->getIssuer();
 if ($spEntityId === NULL) {
-	throw new SimpleSAML_Error_BadRequest('Missing <saml:Issuer> in <samlp:AttributeQuery>.');
+	throw new \SimpleSAML\Error\BadRequest('Missing <saml:Issuer> in <samlp:AttributeQuery>.');
 }
 
 $idpMetadata = $metadata->getMetadataConfig($idpEntityId, 'saml20-idp-hosted');
@@ -79,7 +79,7 @@ $sc->SubjectConfirmationData->Recipient = $endpoint;
 $sc->SubjectConfirmationData->InResponseTo = $query->getId();
 $assertion->setSubjectConfirmation(array($sc));
 
-sspmod_saml_Message::addSign($idpMetadata, $spMetadata, $assertion);
+\SimpleSAML\Module\saml\Message::addSign($idpMetadata, $spMetadata, $assertion);
 
 $response = new \SAML2\Response();
 $response->setRelayState($query->getRelayState());
@@ -87,7 +87,7 @@ $response->setDestination($endpoint);
 $response->setIssuer($idpEntityId);
 $response->setInResponseTo($query->getId());
 $response->setAssertions(array($assertion));
-sspmod_saml_Message::addSign($idpMetadata, $spMetadata, $response);
+\SimpleSAML\Module\saml\Message::addSign($idpMetadata, $spMetadata, $response);
 
 $binding = new \SAML2\HTTPPost();
 $binding->send($response);
diff --git a/modules/exampleauth/lib/Auth/Process/RedirectTest.php b/modules/exampleauth/lib/Auth/Process/RedirectTest.php
index 7e3e93ee03fae8c09354a4af286c8b4ac52ccc7a..1499769594f123c5f50673e945d55b00963f64f8 100644
--- a/modules/exampleauth/lib/Auth/Process/RedirectTest.php
+++ b/modules/exampleauth/lib/Auth/Process/RedirectTest.php
@@ -1,12 +1,14 @@
 <?php
 
+namespace SimpleSAML\Module\exampleautth\Auth\Process;
+
 /**
  * A simple processing filter for testing that redirection works as it should.
  *
  */
-class sspmod_exampleauth_Auth_Process_RedirectTest extends SimpleSAML_Auth_ProcessingFilter {
-
 
+class RedirectTest extends \SimpleSAML\Auth\ProcessingFilter
+{
 	/**
 	 * Initialize processing of the redirect test.
 	 *
@@ -20,9 +22,8 @@ class sspmod_exampleauth_Auth_Process_RedirectTest extends SimpleSAML_Auth_Proce
 		$state['Attributes']['RedirectTest1'] = array('OK');
 
 		// Save state and redirect
-		$id = SimpleSAML_Auth_State::saveState($state, 'exampleauth:redirectfilter-test');
-		$url = SimpleSAML\Module::getModuleURL('exampleauth/redirecttest.php');
+		$id = \SimpleSAML\Auth\State::saveState($state, 'exampleauth:redirectfilter-test');
+		$url = \SimpleSAML\Module::getModuleURL('exampleauth/redirecttest.php');
 		\SimpleSAML\Utils\HTTP::redirectTrustedURL($url, array('StateId' => $id));
 	}
-
 }
diff --git a/modules/exampleauth/lib/Auth/Source/External.php b/modules/exampleauth/lib/Auth/Source/External.php
index 6b37a541a54a569627074c034959d0d2e2f41fd9..453d0da3a17f2f943daf46732c2dc9149030bb28 100644
--- a/modules/exampleauth/lib/Auth/Source/External.php
+++ b/modules/exampleauth/lib/Auth/Source/External.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\exampleauth\Auth\Source;
+
 /**
  * Example external authentication source.
  *
@@ -20,7 +22,13 @@
  *
  * @package SimpleSAMLphp
  */
-class sspmod_exampleauth_Auth_Source_External extends SimpleSAML_Auth_Source {
+
+class External extends \SimpleSAML\Auth\Source
+{
+        /**
+         * The key of the AuthId field in the state.
+         */
+        const AUTHID = 'SimpleSAML\Module\exampleautth\Auth\Sourc\External.AuthId';
 
 	/**
 	 * Constructor for this authentication source.
@@ -113,7 +121,7 @@ class sspmod_exampleauth_Auth_Source_External extends SimpleSAML_Auth_Source {
 		 * First we add the identifier of this authentication source
 		 * to the state array, so that we know where to resume.
 		 */
-		$state['exampleauth:AuthID'] = $this->authId;
+		$state['exampleauth:AuthID'] = self::AUTHID;
 
 
 		/*
@@ -129,14 +137,14 @@ class sspmod_exampleauth_Auth_Source_External extends SimpleSAML_Auth_Source {
 		 * and restores it in another location, and thus bypasses steps in
 		 * the authentication process.
 		 */
-		$stateId = SimpleSAML_Auth_State::saveState($state, 'exampleauth:External');
+		$stateId = \SimpleSAML\Auth\State::saveState($state, 'exampleauth:External');
 
 		/*
 		 * Now we generate a URL the user should return to after authentication.
 		 * We assume that whatever authentication page we send the user to has an
 		 * option to return the user to a specific page afterwards.
 		 */
-		$returnTo = SimpleSAML\Module::getModuleURL('exampleauth/resume.php', array(
+		$returnTo = \SimpleSAML\Module::getModuleURL('exampleauth/resume.php', array(
 			'State' => $stateId,
 		));
 
@@ -147,7 +155,7 @@ class sspmod_exampleauth_Auth_Source_External extends SimpleSAML_Auth_Source {
 		 * is also part of this module, but in a real example, this would likely be
 		 * the absolute URL of the login page for the site.
 		 */
-		$authPage = SimpleSAML\Module::getModuleURL('exampleauth/authpage.php');
+		$authPage = \SimpleSAML\Module::getModuleURL('exampleauth/authpage.php');
 
 		/*
 		 * The redirect to the authentication page.
@@ -181,26 +189,26 @@ class sspmod_exampleauth_Auth_Source_External extends SimpleSAML_Auth_Source {
 		 * it in the 'State' request parameter.
 		 */
 		if (!isset($_REQUEST['State'])) {
-			throw new SimpleSAML_Error_BadRequest('Missing "State" parameter.');
+			throw new \SimpleSAML\Error\BadRequest('Missing "State" parameter.');
 		}
 
 		/*
 		 * Once again, note the second parameter to the loadState function. This must
 		 * match the string we used in the saveState-call above.
 		 */
-		$state = SimpleSAML_Auth_State::loadState($_REQUEST['State'], 'exampleauth:External');
+		$state = \SimpleSAML\Auth\State::loadState($_REQUEST['State'], 'exampleauth:External');
 
 		/*
 		 * Now we have the $state-array, and can use it to locate the authentication
 		 * source.
 		 */
-		$source = SimpleSAML_Auth_Source::getById($state['exampleauth:AuthID']);
+		$source = \SimpleSAML\Auth\Source::getById($state['exampleauth:AuthID']);
 		if ($source === NULL) {
 			/*
 			 * The only way this should fail is if we remove or rename the authentication source
 			 * while the user is at the login page.
 			 */
-			throw new SimpleSAML_Error_Exception('Could not find authentication source with id ' . $state[self::AUTHID]);
+			throw new \SimpleSAML\Error\Exception('Could not find authentication source with id ' . $state[self::AUTHID]);
 		}
 
 		/*
@@ -209,7 +217,7 @@ class sspmod_exampleauth_Auth_Source_External extends SimpleSAML_Auth_Source {
 		 * change config/authsources.php while an user is logging in.
 		 */
 		if (! ($source instanceof self)) {
-			throw new SimpleSAML_Error_Exception('Authentication source type changed.');
+			throw new \SimpleSAML\Error\Exception('Authentication source type changed.');
 		}
 
 
@@ -226,7 +234,7 @@ class sspmod_exampleauth_Auth_Source_External extends SimpleSAML_Auth_Source {
 			 * Here we simply throw an exception, but we could also redirect the user back to the
 			 * login page.
 			 */
-			throw new SimpleSAML_Error_Exception('User not authenticated after login page.');
+			throw new \SimpleSAML\Error\Exception('User not authenticated after login page.');
 		}
 
 		/*
@@ -235,7 +243,7 @@ class sspmod_exampleauth_Auth_Source_External extends SimpleSAML_Auth_Source {
 		 */
 
 		$state['Attributes'] = $attributes;
-		SimpleSAML_Auth_Source::completeAuth($state);
+		\SimpleSAML\Auth\Source::completeAuth($state);
 
 		/*
 		 * The completeAuth-function never returns, so we never get this far.
diff --git a/modules/exampleauth/lib/Auth/Source/Static.php b/modules/exampleauth/lib/Auth/Source/Static.php
index 8c5eba05715bceea091c129b8ec79e56f8d722dd..ca17a378cc36f1fb41b2d25b556d1491a626480b 100644
--- a/modules/exampleauth/lib/Auth/Source/Static.php
+++ b/modules/exampleauth/lib/Auth/Source/Static.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\exampleauth\Auth\Source;
+
 /**
  * Example authentication source.
  *
@@ -9,9 +11,9 @@
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class sspmod_exampleauth_Auth_Source_Static extends SimpleSAML_Auth_Source {
-
 
+class StaticSource extends \SimpleSAML\Auth\Source
+{
 	/**
 	 * The attributes we return.
 	 */
@@ -34,9 +36,9 @@ class sspmod_exampleauth_Auth_Source_Static extends SimpleSAML_Auth_Source {
 
 		// Parse attributes
 		try {
-			$this->attributes = SimpleSAML\Utils\Attributes::normalizeAttributesArray($config);
-		} catch(Exception $e) {
-			throw new Exception('Invalid attributes for authentication source ' .
+			$this->attributes = \SimpleSAML\Utils\Attributes::normalizeAttributesArray($config);
+		} catch (\Exception $e) {
+			throw new \Exception('Invalid attributes for authentication source ' .
 				$this->authId . ': ' . $e->getMessage());
 		}
 
diff --git a/modules/exampleauth/lib/Auth/Source/UserPass.php b/modules/exampleauth/lib/Auth/Source/UserPass.php
index 8582d1c7c989a28af3f233d18cb72c806f39d0b8..8a5ef6215bbcffc97edd20405cb7f59b37874e93 100644
--- a/modules/exampleauth/lib/Auth/Source/UserPass.php
+++ b/modules/exampleauth/lib/Auth/Source/UserPass.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\exampleauth\Auth\Source;
+
 /**
  * Example authentication source - username & password.
  *
@@ -9,9 +11,9 @@
  * @author Olav Morken, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class sspmod_exampleauth_Auth_Source_UserPass extends sspmod_core_Auth_UserPassBase {
-
 
+class UserPass extends \SimpleSAML\Module\core\Auth\UserPassBase
+{
 	/**
 	 * Our users, stored in an associative array. The key of the array is "<username>:<password>",
 	 * while the value of each element is a new array with the attributes for each user.
@@ -37,22 +39,22 @@ class sspmod_exampleauth_Auth_Source_UserPass extends sspmod_core_Auth_UserPassB
 		// Validate and parse our configuration
 		foreach ($config as $userpass => $attributes) {
 			if (!is_string($userpass)) {
-				throw new Exception('Invalid <username>:<password> for authentication source ' .
+				throw new \Exception('Invalid <username>:<password> for authentication source ' .
 					$this->authId . ': ' . $userpass);
 			}
 
 			$userpass = explode(':', $userpass, 2);
 			if (count($userpass) !== 2) {
-				throw new Exception('Invalid <username>:<password> for authentication source ' .
+				throw new \Exception('Invalid <username>:<password> for authentication source ' .
 					$this->authId . ': ' . $userpass[0]);
 			}
 			$username = $userpass[0];
 			$password = $userpass[1];
 
 			try {
-				$attributes = SimpleSAML\Utils\Attributes::normalizeAttributesArray($attributes);
-			} catch(Exception $e) {
-				throw new Exception('Invalid attributes for user ' . $username .
+				$attributes = \SimpleSAML\Utils\Attributes::normalizeAttributesArray($attributes);
+			} catch(\Exception $e) {
+				throw new \Exception('Invalid attributes for user ' . $username .
 					' in authentication source ' . $this->authId . ': ' .
 					$e->getMessage());
 			}
@@ -67,7 +69,7 @@ class sspmod_exampleauth_Auth_Source_UserPass extends sspmod_core_Auth_UserPassB
 	 *
 	 * On a successful login, this function should return the users attributes. On failure,
 	 * it should throw an exception. If the error was caused by the user entering the wrong
-	 * username or password, a SimpleSAML_Error_Error('WRONGUSERPASS') should be thrown.
+	 * username or password, a \SimpleSAML\Error\Error('WRONGUSERPASS') should be thrown.
 	 *
 	 * Note that both the username and the password are UTF-8 encoded.
 	 *
@@ -81,10 +83,9 @@ class sspmod_exampleauth_Auth_Source_UserPass extends sspmod_core_Auth_UserPassB
 
 		$userpass = $username . ':' . $password;
 		if (!array_key_exists($userpass, $this->users)) {
-			throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+			throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
 		}
 
 		return $this->users[$userpass];
 	}
-
 }
diff --git a/modules/exampleauth/www/authpage.php b/modules/exampleauth/www/authpage.php
index 73fcb131ecd9df5ce0bd4b82a41ad5502e0e95a1..5f176ec4ff8d6283271651907a51b32a1b40efbe 100644
--- a/modules/exampleauth/www/authpage.php
+++ b/modules/exampleauth/www/authpage.php
@@ -29,7 +29,7 @@ $returnTo = \SimpleSAML\Utils\HTTP::checkURLAllowed($_REQUEST['ReturnTo']);
 if (!preg_match('@State=(.*)@', $returnTo, $matches)) {
 	die('Invalid ReturnTo URL for this example.');
 }
-SimpleSAML_Auth_State::loadState(urldecode($matches[1]), 'exampleauth:External');
+\SimpleSAML\Auth\State::loadState(urldecode($matches[1]), 'exampleauth:External');
 
 /*
  * The loadState-function will not return if the second parameter does not
diff --git a/modules/exampleauth/www/redirecttest.php b/modules/exampleauth/www/redirecttest.php
index 96ff9a50f7bd3d229d9a32ca5f0fd48b9ed14ed0..103d262af775f8ff590b6e10233185e51402fc45 100644
--- a/modules/exampleauth/www/redirecttest.php
+++ b/modules/exampleauth/www/redirecttest.php
@@ -8,10 +8,10 @@
  */
 
 if (!array_key_exists('StateId', $_REQUEST)) {
-	throw new SimpleSAML_Error_BadRequest('Missing required StateId query parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing required StateId query parameter.');
 }
-$state = SimpleSAML_Auth_State::loadState($_REQUEST['StateId'], 'exampleauth:redirectfilter-test');
+$state = \SimpleSAML\Auth\State::loadState($_REQUEST['StateId'], 'exampleauth:redirectfilter-test');
 
 $state['Attributes']['RedirectTest2'] = array('OK');
 
-SimpleSAML_Auth_ProcessingChain::resumeProcessing($state);
+\SimpleSAML\Auth\ProcessingChain::resumeProcessing($state);
diff --git a/modules/exampleauth/www/resume.php b/modules/exampleauth/www/resume.php
index 08d66dd3f490d198e5467665d21204d8c6afd64b..192c13a20dceb45230de0044c7cf34a982f0864c 100644
--- a/modules/exampleauth/www/resume.php
+++ b/modules/exampleauth/www/resume.php
@@ -8,4 +8,7 @@
  *
  * @package SimpleSAMLphp
  */
-sspmod_exampleauth_Auth_Source_External::resume();
+
+namespace SimpleSAML\Module\exampleauth\Auth\Source;
+
+External::resume();
diff --git a/modules/expirycheck/lib/Auth/Process/ExpiryDate.php b/modules/expirycheck/lib/Auth/Process/ExpiryDate.php
index 27f32626ba259969b384bc99ed8af1ee1f55a12a..b6e0b3fcb552d8b9110ad3aa3b42bd64400bfeb8 100644
--- a/modules/expirycheck/lib/Auth/Process/ExpiryDate.php
+++ b/modules/expirycheck/lib/Auth/Process/ExpiryDate.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\expirycheck\Auth\Process;
+
 /**
  * Filter which show "about to expire" warning or deny access if netid is expired.
  *
@@ -20,8 +22,8 @@
  * @package SimpleSAMLphp
  */
 
-class sspmod_expirycheck_Auth_Process_ExpiryDate extends SimpleSAML_Auth_ProcessingFilter {
-
+class ExpiryDate extends \SimpleSAML\Auth\ProcessingFilter
+{
 	private $warndaysbefore = 0;
 	private $netid_attr = NULL;
 	private $expirydate_attr = NULL;
@@ -42,28 +44,28 @@ class sspmod_expirycheck_Auth_Process_ExpiryDate extends SimpleSAML_Auth_Process
 		if (array_key_exists('warndaysbefore', $config)) {
 			$this->warndaysbefore = $config['warndaysbefore'];
 			if (!is_string($this->warndaysbefore)) {
-				throw new Exception('Invalid value for number of days given to expirycheck::ExpiryDate filter.');
+				throw new \Exception('Invalid value for number of days given to expirycheck::ExpiryDate filter.');
 			}
 		}
 
 		if (array_key_exists('netid_attr', $config)) {
 			$this->netid_attr = $config['netid_attr'];
 			if (!is_string($this->netid_attr)) {
-				throw new Exception('Invalid attribute name given as eduPersonPrincipalName to expirycheck::ExpiryDate filter.');
+				throw new \Exception('Invalid attribute name given as eduPersonPrincipalName to expirycheck::ExpiryDate filter.');
 			}
 		}
 
 		if (array_key_exists('expirydate_attr', $config)) {
 			$this->expirydate_attr = $config['expirydate_attr'];
 			if (!is_string($this->expirydate_attr)) {
-				throw new Exception('Invalid attribute name given as schacExpiryDate to expirycheck::ExpiryDate filter.');
+				throw new \Exception('Invalid attribute name given as schacExpiryDate to expirycheck::ExpiryDate filter.');
 			}
 		}
 
 		if (array_key_exists('date_format', $config)) {
 			$this->date_format = $config['date_format'];
 			if (!is_string($this->date_format)) {
-				throw new Exception('Invalid date format given to expirycheck::ExpiryDate filter.');
+				throw new \Exception('Invalid date format given to expirycheck::ExpiryDate filter.');
 			}
 		}
 	}
@@ -126,27 +128,26 @@ class sspmod_expirycheck_Auth_Process_ExpiryDate extends SimpleSAML_Auth_Process
 				return;
 			}
 
-			SimpleSAML\Logger::warning('expirycheck: NetID ' . $netId .
+			\SimpleSAML\Logger::warning('expirycheck: NetID ' . $netId .
 			                           ' is about to expire!');
 
 			// Save state and redirect
 			$state['expireOnDate'] = date($this->date_format, $expireOnDate);
 			$state['netId'] = $netId;
-			$id = SimpleSAML_Auth_State::saveState($state, 'expirywarning:about2expire');
-			$url = SimpleSAML\Module::getModuleURL('expirycheck/about2expire.php');
+			$id = \SimpleSAML\Auth\State::saveState($state, 'expirywarning:about2expire');
+			$url = \SimpleSAML\Module::getModuleURL('expirycheck/about2expire.php');
 			\SimpleSAML\Utils\HTTP::redirectTrustedURL($url, array('StateId' => $id));
 		}
 
 		if (!self::checkDate($expireOnDate)) {
-			SimpleSAML\Logger::error('expirycheck: NetID ' . $netId .
+			\SimpleSAML\Logger::error('expirycheck: NetID ' . $netId .
 				' has expired [' . date($this->date_format, $expireOnDate) . ']. Access denied!');
-			$globalConfig = SimpleSAML_Configuration::getInstance();
 
 			/* Save state and redirect. */
 			$state['expireOnDate'] = date($this->date_format, $expireOnDate);
 			$state['netId'] = $netId;
-			$id = SimpleSAML_Auth_State::saveState($state, 'expirywarning:expired');
-			$url = SimpleSAML\Module::getModuleURL('expirycheck/expired.php');
+			$id = \SimpleSAML\Auth\State::saveState($state, 'expirywarning:expired');
+			$url = \SimpleSAML\Module::getModuleURL('expirycheck/expired.php');
 			\SimpleSAML\Utils\HTTP::redirectTrustedURL($url, array('StateId' => $id));
 
 		}
diff --git a/modules/expirycheck/www/about2expire.php b/modules/expirycheck/www/about2expire.php
index ddb438b17d133ea33007e5eb6c441a9e6a376d1a..fa502121e5699db9df40972157ea2d3cb91a307f 100644
--- a/modules/expirycheck/www/about2expire.php
+++ b/modules/expirycheck/www/about2expire.php
@@ -6,26 +6,26 @@
  * @package SimpleSAMLphp
  */
 
-SimpleSAML\Logger::info('expirycheck - User has been warned that NetID is near to expirational date.');
+\SimpleSAML\Logger::info('expirycheck - User has been warned that NetID is near to expirational date.');
 
 if (!array_key_exists('StateId', $_REQUEST)) {
-    throw new SimpleSAML_Error_BadRequest('Missing required StateId query parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing required StateId query parameter.');
 }
 $id = $_REQUEST['StateId'];
-$state = SimpleSAML_Auth_State::loadState($id, 'expirywarning:about2expire');
+$state = \SimpleSAML\Auth\State::loadState($id, 'expirywarning:about2expire');
 
 if (array_key_exists('yes', $_REQUEST)) {
     // The user has pressed the yes-button
-    SimpleSAML_Auth_ProcessingChain::resumeProcessing($state);
+    \SimpleSAML\Auth\ProcessingChain::resumeProcessing($state);
 }
 
-$globalConfig = SimpleSAML_Configuration::getInstance();
+$globalConfig = \SimpleSAML\Configuration::getInstance();
 
 $daysleft = $state['daysleft'];
 
-$t = new SimpleSAML_XHTML_Template($globalConfig, 'expirycheck:about2expire.php');
+$t = new \SimpleSAML\XHTML\Template($globalConfig, 'expirycheck:about2expire.php');
 $t->data['autofocus'] = 'yesbutton';
-$t->data['yesTarget'] = SimpleSAML\Module::getModuleURL('expirycheck/about2expire.php');
+$t->data['yesTarget'] = \SimpleSAML\Module::getModuleURL('expirycheck/about2expire.php');
 $t->data['yesData'] = array('StateId' => $id);
 $t->data['warning'] = $warning;
 $t->data['expireOnDate'] = $state['expireOnDate'];
diff --git a/modules/expirycheck/www/expired.php b/modules/expirycheck/www/expired.php
index 47fbd21164f975bd45481ff27de0e677a790852c..2d3d3b3e8d2d1f63dd164b11349183cccf999dbc 100644
--- a/modules/expirycheck/www/expired.php
+++ b/modules/expirycheck/www/expired.php
@@ -6,17 +6,16 @@
  * @package SimpleSAMLphp
  */
 
-SimpleSAML\Logger::info('expirycheck - User has been warned that NetID is near to expirational date.');
+\SimpleSAML\Logger::info('expirycheck - User has been warned that NetID is near to expirational date.');
 
 if (!array_key_exists('StateId', $_REQUEST)) {
-    throw new SimpleSAML_Error_BadRequest('Missing required StateId query parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing required StateId query parameter.');
 }
-$state = SimpleSAML_Auth_State::loadState($_REQUEST['StateId'], 'expirywarning:expired');
+$state = \SimpleSAML\Auth\State::loadState($_REQUEST['StateId'], 'expirywarning:expired');
 
-$globalConfig = SimpleSAML_Configuration::getInstance();
+$globalConfig = \SimpleSAML\Configuration::getInstance();
 
-$t = new SimpleSAML_XHTML_Template($globalConfig, 'expirycheck:expired.php');
-$t->data['header'] = $this->t('{expirycheck:expwarning:access_denied}');
-$t->data['expireOnDate'] = htmlspecialchars($state['expireOnDate']);
-$t->data['netId'] = htmlspecialchars($state['netId']);
+$t = new \SimpleSAML\XHTML\Template($globalConfig, 'expirycheck:expired.php');
+$t->data['expireOnDate'] = $state['expireOnDate'];
+$t->data['netId'] = $state['netId'];
 $t->show();
diff --git a/modules/ldap/docs/ldap.md b/modules/ldap/docs/ldap.md
index fae1ca1c6ae30d51f946d48a3a8ba4088b38c510..1bad69582b69d30162c4b1b1a7aff9bba7a74919 100644
--- a/modules/ldap/docs/ldap.md
+++ b/modules/ldap/docs/ldap.md
@@ -63,6 +63,12 @@ authentication source:
 		 */
 		'search.base' => 'ou=people,dc=example,dc=org',
 
+                /*
+                 * The scope of the search. Valid values are 'subtree' and 'onelevel' and 'base',
+                 * first one being the default if no value is set.
+                 */
+                'search.scope' => 'subtree',
+
 		/*
 		 * The attribute(s) the username should match against.
 		 *
@@ -94,7 +100,7 @@ You also need to update the `hostname` and `dnpattern` options. The
 `hostname` should be the hostname of your LDAP server, and the
 `dnpattern` should be a pattern which can be used to generate the `dn`
 of a user with a given username.
-
+-
 All other options have default values, and are not required.
 
 ### Searching for a user ###
diff --git a/modules/ldap/lib/Auth/Process/AttributeAddFromLDAP.php b/modules/ldap/lib/Auth/Process/AttributeAddFromLDAP.php
index 516e2630d762e31bcc46a75400575df0e142d45b..3aced463831844ef14e375869619a4ed07146ec1 100644
--- a/modules/ldap/lib/Auth/Process/AttributeAddFromLDAP.php
+++ b/modules/ldap/lib/Auth/Process/AttributeAddFromLDAP.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\ldap\Auth\Process;
+
 /**
  * Filter to add attributes to the identity by executing a query against an LDAP directory
  *
@@ -32,13 +34,13 @@
  * @author Remy Blom <remy.blom@hku.nl>
  * @package SimpleSAMLphp
  */
-class sspmod_ldap_Auth_Process_AttributeAddFromLDAP extends sspmod_ldap_Auth_Process_BaseFilter
-{
 
+class AttributeAddFromLDAP extends BaseFilter
+{
     /**
-     * LDAP attribute to add to the request attributes
+     * LDAP attributes to add to the request attributes
      *
-     * @var string
+     * @var array
      */
     protected $search_attributes;
 
@@ -143,13 +145,14 @@ class sspmod_ldap_Auth_Process_AttributeAddFromLDAP extends sspmod_ldap_Auth_Pro
         $attributes =& $request['Attributes'];
 
         // perform a merge on the ldap_search_filter
-
         // loop over the attributes and build the search and replace arrays
+        $arrSearch = array();
+        $arrReplace = array();
         foreach ($attributes as $attr => $val) {
             $arrSearch[] = '%'.$attr.'%';
 
             if (strlen($val[0]) > 0) {
-                $arrReplace[] = SimpleSAML_Auth_LDAP::escape_filter_value($val[0]);
+                $arrReplace[] = \SimpleSAML\Auth\LDAP::escape_filter_value($val[0]);
             } else {
                 $arrReplace[] = '';
             }
@@ -159,13 +162,13 @@ class sspmod_ldap_Auth_Process_AttributeAddFromLDAP extends sspmod_ldap_Auth_Pro
         $filter = str_replace($arrSearch, $arrReplace, $this->search_filter);
 
         if (strpos($filter, '%') !== false) {
-            SimpleSAML\Logger::info('AttributeAddFromLDAP: There are non-existing attributes in the search filter. ('.
+            \SimpleSAML\Logger::info('AttributeAddFromLDAP: There are non-existing attributes in the search filter. ('.
                                     $this->search_filter.')');
             return;
         }
 
         if (!in_array($this->attr_policy, array('merge', 'replace', 'add'), true)) {
-            SimpleSAML\Logger::warning("AttributeAddFromLDAP: 'attribute.policy' must be one of 'merge',".
+            \SimpleSAML\Logger::warning("AttributeAddFromLDAP: 'attribute.policy' must be one of 'merge',".
                                        "'replace' or 'add'.");
             return;
         }
@@ -173,9 +176,9 @@ class sspmod_ldap_Auth_Process_AttributeAddFromLDAP extends sspmod_ldap_Auth_Pro
         // getLdap
         try {
             $ldap = $this->getLdap();
-        } catch (Exception $e) {
+        } catch (\Exception $e) {
             // Added this warning in case $this->getLdap() fails
-            SimpleSAML\Logger::warning("AttributeAddFromLDAP: exception = " . $e);
+            \SimpleSAML\Logger::warning("AttributeAddFromLDAP: exception = " . $e);
             return;
         }
         // search for matching entries
@@ -187,7 +190,7 @@ class sspmod_ldap_Auth_Process_AttributeAddFromLDAP extends sspmod_ldap_Auth_Pro
                 true,
                 false
             );
-        } catch (Exception $e) {
+        } catch (\Exception $e) {
             return; // silent fail, error is still logged by LDAP search
         }
 
diff --git a/modules/ldap/lib/Auth/Process/AttributeAddUsersGroups.php b/modules/ldap/lib/Auth/Process/AttributeAddUsersGroups.php
index ab42a2ba360e56925cf519a9d63d3eb594599afc..c9b0a17dc37995c754cbc1ee5d085987fcb38bef 100644
--- a/modules/ldap/lib/Auth/Process/AttributeAddUsersGroups.php
+++ b/modules/ldap/lib/Auth/Process/AttributeAddUsersGroups.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\ldap\Auth\Process;
+
 /**
  * Does a reverse membership lookup on the logged in user,
  * looking for groups it is a member of and adds them to
@@ -8,7 +10,8 @@
  * @author Ryan Panning <panman@traileyes.com>
  * @package SimpleSAMLphp
  */
-class sspmod_ldap_Auth_Process_AttributeAddUsersGroups extends sspmod_ldap_Auth_Process_BaseFilter
+
+class AttributeAddUsersGroups extends BaseFilter
 {
     /**
      * This is run when the filter is processed by SimpleSAML.
@@ -16,7 +19,7 @@ class sspmod_ldap_Auth_Process_AttributeAddUsersGroups extends sspmod_ldap_Auth_
      * the best method possible for the LDAP product. The groups
      * are then added to the request attributes.
      *
-     * @throws SimpleSAML_Error_Exception
+     * @throws \SimpleSAML\Error\Exception
      * @param $request
      */
     public function process(&$request)
@@ -25,7 +28,7 @@ class sspmod_ldap_Auth_Process_AttributeAddUsersGroups extends sspmod_ldap_Auth_
         assert(array_key_exists('Attributes', $request));
 
         // Log the process
-        SimpleSAML\Logger::debug(
+        \SimpleSAML\Logger::debug(
             $this->title . 'Attempting to get the users groups...'
         );
 
@@ -43,7 +46,7 @@ class sspmod_ldap_Auth_Process_AttributeAddUsersGroups extends sspmod_ldap_Auth_
 
         // Must be an array, else cannot merge groups
         if (!is_array($attributes[$map['groups']])) {
-            throw new SimpleSAML_Error_Exception(
+            throw new \SimpleSAML\Error\Exception(
                 $this->title . 'The group attribute [' . $map['groups'] .
                 '] is not an array of group DNs. ' . $this->var_export($attributes[$map['groups']])
             );
@@ -55,7 +58,7 @@ class sspmod_ldap_Auth_Process_AttributeAddUsersGroups extends sspmod_ldap_Auth_
         $group_attribute = array_unique($group_attribute);
 
         // All done
-        SimpleSAML\Logger::debug(
+        \SimpleSAML\Logger::debug(
             $this->title . 'Added users groups to the group attribute [' .
             $map['groups'] . ']: ' . implode('; ', $groups)
         );
@@ -69,92 +72,45 @@ class sspmod_ldap_Auth_Process_AttributeAddUsersGroups extends sspmod_ldap_Auth_
      * using the required attribute values from the user to
      * get their group membership, recursively.
      *
-     * @throws SimpleSAML_Error_Exception
+     * @throws \SimpleSAML\Error\Exception
      * @param array $attributes
      * @return array
      */
-    protected function getGroups(array $attributes)
+    protected function getGroups($attributes)
     {
-        // Reference the map, just to make the name shorter
-        $map =& $this->attribute_map;
-
         // Log the request
-        SimpleSAML\Logger::debug(
+        \SimpleSAML\Logger::debug(
             $this->title . 'Checking for groups based on the best method for the LDAP product.'
         );
 
         // Based on the directory service, search LDAP for groups
         // If any attributes are needed, prepare them before calling search method
         switch ($this->product) {
-
             case 'ACTIVEDIRECTORY':
-
-                // Log the AD specific search
-                SimpleSAML\Logger::debug(
-                    $this->title . 'Searching LDAP using ActiveDirectory specific method.'
-                );
-
-                // Make sure the defined dn attribute exists
-                if (!isset($attributes[$map['dn']])) {
-                    throw new SimpleSAML_Error_Exception(
-                        $this->title . 'The DN attribute [' . $map['dn'] .
-                        '] is not defined in the users Attributes: ' . implode(', ', array_keys($attributes))
-                    );
-                }
-
-                // DN attribute must have a value
-                if (!isset($attributes[$map['dn']][0]) || !$attributes[$map['dn']][0]) {
-                    throw new SimpleSAML_Error_Exception(
-                        $this->title . 'The DN attribute [' . $map['dn'] .
-                        '] does not have a [0] value defined. ' . $this->var_export($attributes[$map['dn']])
-                    );
-                }
-
-                // Pass to the AD specific search
-                $groups = $this->searchActiveDirectory($attributes[$map['dn']][0]);
+                $groups = $this->getGroupsActiveDirectory($attributes);
                 break;
-                
             case 'OPENLDAP':
-                // Log the OpenLDAP specific search
-                SimpleSAML\Logger::debug(
-                    $this->title . 'Searching LDAP using OpenLDAP specific method.'
-                );
-                // Print group search string and search for all group names
-                $openldap_base = $this->config->getString('ldap.basedn','ou=groups,dc=example,dc=com');
-                SimpleSAML\Logger::debug(
-                    $this->title . "Searching for groups in ldap.basedn ".$openldap_base." with filter (".$map['memberof']."=".$attributes[$map['username']][0].") and attributes ".$map['member']
-                );
-                $groups = array();
-                try {
-                    // Intention is to filter in 'ou=groups,dc=example,dc=com' for '(memberUid = <value of attribute.username>)' and take only the attributes 'cn' (=name of the group)
-                    $all_groups = $this->getLdap()->searchformultiple( $openldap_base, array($map['memberof'] => $attributes[$map['username']][0]) , array($map['member']));
-                } catch (SimpleSAML_Error_UserNotFound $e) {
-                    break; // if no groups found return with empty (still just initialized) groups array
-                }
-                // run through all groups and add each to our groups array
-                foreach ($all_groups as $group_entry) {
-                    $groups[] .= $group_entry[$map['member']][0];
-                }
+                $groups = $this->getGroupsOpenLdap($attributes);
                 break;
-                                
             default:
+                // Reference the map, just to make the name shorter
+                $map =& $this->attribute_map;
 
                 // Log the general search
-                SimpleSAML\Logger::debug(
+                \SimpleSAML\Logger::debug(
                     $this->title . 'Searching LDAP using the default search method.'
                 );
 
                 // Make sure the defined memberOf attribute exists
                 if (!isset($attributes[$map['memberof']])) {
-                    throw new SimpleSAML_Error_Exception(
+                    throw new \SimpleSAML\Error\Exception(
                         $this->title . 'The memberof attribute [' . $map['memberof'] .
-                        '] is not defined in the users Attributes: ' . implode(', ', array_keys($attributes))
-                    );
+                        '] is not defined in the user\'s Attributes: ' . implode(', ', array_keys($attributes)));
                 }
 
                 // MemberOf must be an array of group DN's
                 if (!is_array($attributes[$map['memberof']])) {
-                    throw new SimpleSAML_Error_Exception(
+                    throw new \SimpleSAML\Error\Exception(
                         $this->title . 'The memberof attribute [' . $map['memberof'] .
                         '] is not an array of group DNs. ' . $this->var_export($attributes[$map['memberof']])
                     );
@@ -165,13 +121,93 @@ class sspmod_ldap_Auth_Process_AttributeAddUsersGroups extends sspmod_ldap_Auth_
         }
 
         // All done
-        SimpleSAML\Logger::debug(
+        \SimpleSAML\Logger::debug(
             $this->title . 'User found to be a member of the groups:' . implode('; ', $groups)
         );
         return $groups;
     }
 
 
+    /**
+     * OpenLDAP optimized search
+     * using the required attribute values from the user to
+     * get their group membership, recursively.
+     *
+     * @throws \SimpleSAML\Error\Exception
+     * @param array $attributes
+     * @return array
+     */
+    protected function getGroupsOpenLdap($attributes)
+    {
+        // Log the OpenLDAP specific search
+        \SimpleSAML\Logger::debug(
+            $this->title . 'Searching LDAP using OpenLDAP specific method.'
+        );
+
+        // Reference the map, just to make the name shorter
+        $map =& $this->attribute_map;
+
+        // Print group search string and search for all group names
+        $openldap_base = $this->config->getString('ldap.basedn','ou=groups,dc=example,dc=com');
+        \SimpleSAML\Logger::debug(
+            $this->title . "Searching for groups in ldap.basedn ".$openldap_base." with filter (".$map['memberof']."=".$attributes[$map['username']][0].") and attributes ".$map['member']
+        );
+
+        $groups = array();
+        try {
+            // Intention is to filter in 'ou=groups,dc=example,dc=com' for '(memberUid = <value of attribute.username>)' and take only the attributes 'cn' (=name of the group)
+            $all_groups = $this->getLdap()->searchformultiple($openldap_base, array($map['memberof'] => $attributes[$map['username']][0]) , array($map['member']));
+        } catch (\SimpleSAML\Error\UserNotFound $e) {
+            return $groups; // if no groups found return with empty (still just initialized) groups array
+        }
+
+        // run through all groups and add each to our groups array
+        foreach ($all_groups as $group_entry) {
+            $groups[] .= $group_entry[$map['member']][0];
+        }
+
+        return $groups;
+    }
+
+
+    /**
+     * Active Directory optimized search
+     * using the required attribute values from the user to
+     * get their group membership, recursively.
+     *
+     * @throws \SimpleSAML\Error\Exception
+     * @param array $attributes
+     * @return array
+     */
+    protected function getGroupsActiveDirectory($attributes)
+    {
+        // Log the AD specific search
+        \SimpleSAML\Logger::debug(
+            $this->title . 'Searching LDAP using ActiveDirectory specific method.'
+        );
+
+        // Reference the map, just to make the name shorter
+        $map =& $this->attribute_map;
+
+        // Make sure the defined dn attribute exists
+        if (!isset($attributes[$map['dn']])) {
+            throw new \SimpleSAML\Error\Exception(
+                $this->title . 'The DN attribute [' . $map['dn'] .
+                '] is not defined in the user\'s Attributes: ' . implode(', ', array_keys($attributes)));
+        }
+
+        // DN attribute must have a value
+        if (!isset($attributes[$map['dn']][0]) || !$attributes[$map['dn']][0]) {
+            throw new \SimpleSAML\Error\Exception(
+                $this->title . 'The DN attribute [' . $map['dn'] .
+                '] does not have a [0] value defined. ' . $this->var_export($attributes[$map['dn']])
+            );
+        }
+
+        // Pass to the AD specific search
+        return $this->searchActiveDirectory($attributes[$map['dn']][0]);
+    }
+
     /**
      * Looks for groups from the list of DN's passed. Also
      * recursively searches groups for further membership.
@@ -195,13 +231,21 @@ class sspmod_ldap_Auth_Process_AttributeAddUsersGroups extends sspmod_ldap_Auth_
         $map =& $this->attribute_map;
 
         // Log the search
-        SimpleSAML\Logger::debug(
+        \SimpleSAML\Logger::debug(
             $this->title . 'Checking DNs for groups.' .
             ' DNs: '. implode('; ', $memberof) .
             ' Attributes: ' . $map['memberof'] . ', ' . $map['type'] .
             ' Group Type: ' . $this->type_map['group']
         );
 
+        // Work out what attributes to get for a group
+        $use_group_name = FALSE;
+        $get_attributes = array($map['memberof'], $map['type']);
+        if (isset($map['name']) && $map['name']) {
+            $get_attributes[] = $map['name'];
+            $use_group_name = TRUE;
+        }
+
         // Check each DN of the passed memberOf
         foreach ($memberof as $dn) {
 
@@ -216,8 +260,8 @@ class sspmod_ldap_Auth_Process_AttributeAddUsersGroups extends sspmod_ldap_Auth_
 
             // Query LDAP for the attribute values for the DN
             try {
-                $attributes = $this->getLdap()->getAttributes($dn, array($map['memberof'], $map['type']));
-            } catch (SimpleSAML_Error_AuthSource $e) {
+                $attributes = $this->getLdap()->getAttributes($dn, $get_attributes);
+            } catch (\SimpleSAML\Error\AuthSource $e) {
                 continue; // DN must not exist, just continue. Logged by the LDAP object
             }
 
@@ -227,10 +271,16 @@ class sspmod_ldap_Auth_Process_AttributeAddUsersGroups extends sspmod_ldap_Auth_
             }
 
             // Add to found groups array
-            $groups[] = $dn;
+            if ($use_group_name && isset($attributes[$map['name']]) && is_array($attributes[$map['name']])) {
+                $groups[] = $attributes[$map['name']][0];
+            } else {
+                $groups[] = $dn;
+            }
 
             // Recursively search "sub" groups
-            $groups = array_merge($groups, $this->search($attributes[$map['memberof']]));
+            if (!empty($attributes[$map['memberof']])) {
+                $groups = array_merge($groups, $this->search($attributes[$map['memberof']]));
+            }
         }
 
         // Return only the unique group names
@@ -254,7 +304,7 @@ class sspmod_ldap_Auth_Process_AttributeAddUsersGroups extends sspmod_ldap_Auth_
         $map =& $this->attribute_map;
 
         // Log the search
-        SimpleSAML\Logger::debug(
+        \SimpleSAML\Logger::debug(
             $this->title . 'Searching ActiveDirectory group membership.' .
             ' DN: ' . $dn .
             ' DN Attribute: ' . $map['dn'] .
@@ -277,7 +327,7 @@ class sspmod_ldap_Auth_Process_AttributeAddUsersGroups extends sspmod_ldap_Auth_
 
         // The search may throw an exception if no entries
         // are found, unlikely but possible.
-        } catch (SimpleSAML_Error_UserNotFound $e) {
+        } catch (\SimpleSAML\Error\UserNotFound $e) {
             return array();
         }
 
@@ -286,7 +336,6 @@ class sspmod_ldap_Auth_Process_AttributeAddUsersGroups extends sspmod_ldap_Auth_
 
         // Check each entry..
         foreach ($entries as $entry) {
-
             // Check for the DN using the original attribute name
             if (isset($entry[$map['dn']][0])) {
                 $groups[] = $entry[$map['dn']][0];
@@ -306,7 +355,7 @@ class sspmod_ldap_Auth_Process_AttributeAddUsersGroups extends sspmod_ldap_Auth_
             }
 
             // Could not find DN, log and continue
-            SimpleSAML\Logger::notice(
+            \SimpleSAML\Logger::notice(
                 $this->title . 'The DN attribute [' .
                 implode(', ', array($map['dn'], strtolower($map['dn']), 'dn')) .
                 '] could not be found in the entry. ' . $this->var_export($entry)
diff --git a/modules/ldap/lib/Auth/Process/BaseFilter.php b/modules/ldap/lib/Auth/Process/BaseFilter.php
index 19f3f661f336b70976184985b59c2f602fc50b89..60e9b70d9572fcd1a653387f88e79c0f8ad95116 100644
--- a/modules/ldap/lib/Auth/Process/BaseFilter.php
+++ b/modules/ldap/lib/Auth/Process/BaseFilter.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\ldap\Auth\Process;
+
 /**
  * This base LDAP filter class can be extended to enable real
  * filter classes direct access to the authsource ldap config
@@ -12,9 +14,9 @@
  * @author Remy Blom <remy.blom@hku.nl>
  * @package SimpleSAMLphp
  */
-abstract class sspmod_ldap_Auth_Process_BaseFilter extends SimpleSAML_Auth_ProcessingFilter
-{
 
+abstract class BaseFilter extends \SimpleSAML\Auth\ProcessingFilter
+{
     /**
      * List of attribute "alias's" linked to the real attribute
      * name. Used for abstraction / configuration of the LDAP
@@ -36,10 +38,10 @@ abstract class sspmod_ldap_Auth_Process_BaseFilter extends SimpleSAML_Auth_Proce
 
     /**
      * The construct method will change the filter config into
-     * a SimpleSAML_Configuration object and store it here for
+     * a \SimpleSAML\Configuration object and store it here for
      * later use, if needed.
      *
-     * @var SimpleSAML_Configuration
+     * @var \SimpleSAML\Configuration
      */
     protected $config;
 
@@ -48,7 +50,7 @@ abstract class sspmod_ldap_Auth_Process_BaseFilter extends SimpleSAML_Auth_Proce
      * Instance, object of the ldap connection. Stored here to
      * be access later during processing.
      *
-     * @var sspmod_ldap_LdapConnection
+     * @var \SimpleSAML\Auth\Ldap
      */
     private $ldap;
 
@@ -87,7 +89,7 @@ abstract class sspmod_ldap_Auth_Process_BaseFilter extends SimpleSAML_Auth_Proce
      * to the LDAP server. Then sets up the LDAP connection for the
      * instance/object and stores everything in class members.
      *
-     * @throws SimpleSAML_Error_Exception
+     * @throws \SimpleSAML\Error\Exception
      * @param array $config
      * @param $reserved
      */
@@ -99,29 +101,29 @@ abstract class sspmod_ldap_Auth_Process_BaseFilter extends SimpleSAML_Auth_Proce
         // This way if the class is extended the proper name is used
         $classname = get_class($this);
         $classname = explode('_', $classname);
-        $this->title = 'ldap:' . end($classname) . ' : ';
+        $this->title = 'ldap:'.end($classname).' : ';
 
         // Log the construction
-        SimpleSAML\Logger::debug(
-            $this->title . 'Creating and configuring the filter.'
+        \SimpleSAML\Logger::debug(
+            $this->title.'Creating and configuring the filter.'
         );
 
         // If an authsource was defined (an not empty string)...
         if (isset($config['authsource']) && $config['authsource']) {
 
             // Log the authsource request
-            SimpleSAML\Logger::debug(
-                $this->title . 'Attempting to get configuration values from authsource [' .
-                $config['authsource'] . ']'
+            \SimpleSAML\Logger::debug(
+                $this->title.'Attempting to get configuration values from authsource ['.
+                $config['authsource'].']'
             );
 
             // Get the authsources file, which should contain the config
-            $authsource = SimpleSAML_Configuration::getConfig('authsources.php');
+            $authsource = \SimpleSAML\Configuration::getConfig('authsources.php');
 
             // Verify that the authsource config exists
             if (!$authsource->hasValue($config['authsource'])) {
-                throw new SimpleSAML_Error_Exception(
-                    $this->title . 'Authsource [' . $config['authsource'] .
+                throw new \SimpleSAML\Error\Exception(
+                    $this->title.'Authsource ['.$config['authsource'].
                     '] defined in filter parameters not found in authsources.php'
                 );
             }
@@ -133,8 +135,8 @@ abstract class sspmod_ldap_Auth_Process_BaseFilter extends SimpleSAML_Auth_Proce
             // Make sure it is an ldap source
             // TODO: Support ldap:LDAPMulti, if possible
             if (@$authsource[0] != 'ldap:LDAP') {
-                throw new SimpleSAML_Error_Exception(
-                    $this->title . 'Authsource [' . $config['authsource'] .
+                throw new \SimpleSAML\Error\Exception(
+                    $this->title.'Authsource ['.$config['authsource'].
                     '] specified in filter parameters is not an ldap:LDAP type'
                 );
             }
@@ -162,7 +164,10 @@ abstract class sspmod_ldap_Auth_Process_BaseFilter extends SimpleSAML_Auth_Proce
             // only set when search.enabled = true
             if (isset($authsource['search.enable']) && $authsource['search.enable']) {
                 if (isset($authsource['search.base'])) {
-                    $authconfig['ldap.basedn']     = $authsource['search.base'];
+                    $authconfig['ldap.basedn'] = $authsource['search.base'];
+                }
+                if (isset($authsource['search.scope'])) {
+                    $authconfig['ldap.scope'] = $authsource['search.scope'];
                 }
                 if (isset($authsource['search.username'])) {
                     $authconfig['ldap.username']   = $authsource['search.username'];
@@ -191,16 +196,16 @@ abstract class sspmod_ldap_Auth_Process_BaseFilter extends SimpleSAML_Auth_Proce
             $config = array_merge($authconfig, $config);
 
             // Authsource complete
-            SimpleSAML\Logger::debug(
-                $this->title . 'Retrieved authsource [' . $config['authsource'] .
-                '] configuration values: ' . $this->var_export($authconfig)
+            \SimpleSAML\Logger::debug(
+                $this->title.'Retrieved authsource ['.$config['authsource'].
+                '] configuration values: '.$this->var_export($authconfig)
             );
         }
 
         // Convert the config array to a config class,
         // that way we can verify type and define defaults.
         // Store in the instance in-case needed later, by a child class.
-        $this->config = SimpleSAML_Configuration::loadFromArray($config, 'ldap:AuthProcess');
+        $this->config = \SimpleSAML\Configuration::loadFromArray($config, 'ldap:AuthProcess');
 
         // Set all the filter values, setting defaults if needed
         $this->base_dn = $this->config->getArrayizeString('ldap.basedn', '');
@@ -212,10 +217,10 @@ abstract class sspmod_ldap_Auth_Process_BaseFilter extends SimpleSAML_Auth_Proce
         $this->product = strtoupper($this->product);
 
         // Log the member values retrieved above
-        SimpleSAML\Logger::debug(
-            $this->title . 'Configuration values retrieved;' .
-            ' BaseDN: ' . $this->var_export($this->base_dn) .
-            ' Product: ' . $this->var_export($this->product)
+        \SimpleSAML\Logger::debug(
+            $this->title.'Configuration values retrieved;'.
+            ' BaseDN: '.$this->var_export($this->base_dn).
+            ' Product: '.$this->var_export($this->product)
         );
 
         // Setup the attribute map which will be used to search LDAP
@@ -230,8 +235,8 @@ abstract class sspmod_ldap_Auth_Process_BaseFilter extends SimpleSAML_Auth_Proce
         );
 
         // Log the attribute map
-        SimpleSAML\Logger::debug(
-            $this->title . 'Attribute map created: ' . $this->var_export($this->attribute_map)
+        \SimpleSAML\Logger::debug(
+            $this->title.'Attribute map created: '.$this->var_export($this->attribute_map)
         );
 
         // Setup the object type map which is used to determine a DNs' type
@@ -241,8 +246,8 @@ abstract class sspmod_ldap_Auth_Process_BaseFilter extends SimpleSAML_Auth_Proce
         );
 
         // Log the type map
-        SimpleSAML\Logger::debug(
-            $this->title . 'Type map created: ' . $this->var_export($this->type_map)
+        \SimpleSAML\Logger::debug(
+            $this->title.'Type map created: '.$this->var_export($this->type_map)
         );
     }
 
@@ -251,7 +256,7 @@ abstract class sspmod_ldap_Auth_Process_BaseFilter extends SimpleSAML_Auth_Proce
      * rather than setting in the constructor to avoid unnecessarily
      * connecting to LDAP when it might not be needed.
      *
-     * @return sspmod_ldap_LdapConnection
+     * @return \SimpleSAML\Auth\Ldap
      */
     protected function getLdap()
     {
@@ -265,26 +270,26 @@ abstract class sspmod_ldap_Auth_Process_BaseFilter extends SimpleSAML_Auth_Proce
         $port       = $this->config->getInteger('ldap.port', 389);
         $enable_tls = $this->config->getBoolean('ldap.enable_tls', false);
         $debug      = $this->config->getBoolean('ldap.debug', false);
-        $referrals   = $this->config->getBoolean('ldap.referrals', true);
+        $referrals  = $this->config->getBoolean('ldap.referrals', true);
         $timeout    = $this->config->getInteger('ldap.timeout', 0);
         $username   = $this->config->getString('ldap.username', null);
         $password   = $this->config->getString('ldap.password', null);
 
         // Log the LDAP connection
-        SimpleSAML\Logger::debug(
-            $this->title . 'Connecting to LDAP server;' .
-            ' Hostname: ' . $hostname .
-            ' Port: ' . $port .
-            ' Enable TLS: ' . ($enable_tls ? 'Yes' : 'No') .
-            ' Debug: ' . ($debug ? 'Yes' : 'No') .
-            ' Referrals: ' . ($referrals ? 'Yes' : 'No') .
-            ' Timeout: ' . $timeout .
-            ' Username: ' . $username .
-            ' Password: ' . (empty($password) ? '' : '********')
+        \SimpleSAML\Logger::debug(
+            $this->title.'Connecting to LDAP server;'.
+            ' Hostname: '.$hostname.
+            ' Port: '.$port.
+            ' Enable TLS: '.($enable_tls ? 'Yes' : 'No').
+            ' Debug: '.($debug ? 'Yes' : 'No').
+            ' Referrals: '.($referrals ? 'Yes' : 'No').
+            ' Timeout: '.$timeout.
+            ' Username: '.$username.
+            ' Password: '.(empty($password) ? '' : '********')
         );
 
         // Connect to the LDAP server to be queried during processing
-        $this->ldap = new SimpleSAML_Auth_LDAP($hostname, $enable_tls, $debug, $timeout, $port, $referrals);
+        $this->ldap = new \SimpleSAML\Auth\LDAP($hostname, $enable_tls, $debug, $timeout, $port, $referrals);
         $this->ldap->bind($username, $password);
 
         // All done
diff --git a/modules/ldap/lib/Auth/Source/LDAP.php b/modules/ldap/lib/Auth/Source/LDAP.php
index 2e2144b8f54351dc56585460db44c528cb8beef6..38101cce72eb184674c7bba02960bae922583b3f 100644
--- a/modules/ldap/lib/Auth/Source/LDAP.php
+++ b/modules/ldap/lib/Auth/Source/LDAP.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\ldap\Auth\Source;
+
 /**
  * LDAP authentication source.
  *
@@ -10,9 +12,9 @@
  *
  * @package SimpleSAMLphp
  */
-class sspmod_ldap_Auth_Source_LDAP extends sspmod_core_Auth_UserPassBase
-{
 
+class LDAP extends \SimpleSAML\Module\core\Auth\UserPassBase
+{
     /**
      * A LDAP configuration object.
      */
@@ -33,7 +35,7 @@ class sspmod_ldap_Auth_Source_LDAP extends sspmod_core_Auth_UserPassBase
         // Call the parent constructor first, as required by the interface
         parent::__construct($info, $config);
 
-        $this->ldapConfig = new sspmod_ldap_ConfigHelper($config,
+        $this->ldapConfig = new \SimpleSAML\Module\ldap\ConfigHelper($config,
             'Authentication source ' . var_export($this->authId, true));
     }
 
@@ -53,5 +55,4 @@ class sspmod_ldap_Auth_Source_LDAP extends sspmod_core_Auth_UserPassBase
 
         return $this->ldapConfig->login($username, $password, $sasl_args);
     }
-
 }
diff --git a/modules/ldap/lib/Auth/Source/LDAPMulti.php b/modules/ldap/lib/Auth/Source/LDAPMulti.php
index c11a43e469f0b9145d02051361a7e29618a6e7fd..ff6e3e42b94b527ebfc30c5eff2b73a887047c29 100644
--- a/modules/ldap/lib/Auth/Source/LDAPMulti.php
+++ b/modules/ldap/lib/Auth/Source/LDAPMulti.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\ldap\Auth\Source;
+
 /**
  * LDAP authentication source.
  *
@@ -10,9 +12,9 @@
  *
  * @package SimpleSAMLphp
  */
-class sspmod_ldap_Auth_Source_LDAPMulti extends sspmod_core_Auth_UserPassOrgBase
-{
 
+class LDAPMulti extends \SimpleSAML\Module\core\Auth\UserPassOrgBase
+{
     /**
      * An array with descriptions for organizations.
      */
@@ -43,7 +45,7 @@ class sspmod_ldap_Auth_Source_LDAPMulti extends sspmod_core_Auth_UserPassOrgBase
         // Call the parent constructor first, as required by the interface
         parent::__construct($info, $config);
 
-        $cfgHelper = SimpleSAML_Configuration::loadFromArray($config,
+        $cfgHelper = \SimpleSAML\Configuration::loadFromArray($config,
             'Authentication source ' . var_export($this->authId, true));
 
 
@@ -74,7 +76,7 @@ class sspmod_ldap_Auth_Source_LDAPMulti extends sspmod_core_Auth_UserPassOrgBase
                 $this->orgs[$orgId] = $orgId;
             }
 
-            $orgCfg = new sspmod_ldap_ConfigHelper($orgCfg,
+            $orgCfg = new \SimpleSAML\Module\ldap\ConfigHelper($orgCfg,
                 'Authentication source ' . var_export($this->authId, true) .
                 ', organization ' . var_export($orgId, true));
             $this->ldapOrgs[$orgId] = $orgCfg;
@@ -98,10 +100,10 @@ class sspmod_ldap_Auth_Source_LDAPMulti extends sspmod_core_Auth_UserPassOrgBase
 
         if (!array_key_exists($org, $this->ldapOrgs)) {
             // The user has selected an organization which doesn't exist anymore.
-            SimpleSAML\Logger::warning('Authentication source ' . var_export($this->authId, true) .
+            \SimpleSAML\Logger::warning('Authentication source ' . var_export($this->authId, true) .
                 ': Organization seems to have disappeared while the user logged in.' .
                 ' Organization was ' . var_export($org, true));
-            throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+            throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
         }
 
         if ($this->includeOrgInUsername) {
diff --git a/modules/ldap/lib/ConfigHelper.php b/modules/ldap/lib/ConfigHelper.php
index d76684bb8026d7721891f8409d527dbbff53595e..3b03a0826512413e6c888c3ae5de4e19331dcbff 100644
--- a/modules/ldap/lib/ConfigHelper.php
+++ b/modules/ldap/lib/ConfigHelper.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\ldap;
+
 /**
  * LDAP authentication source configuration parser.
  *
@@ -8,7 +10,8 @@
  *
  * @package SimpleSAMLphp
  */
-class sspmod_ldap_ConfigHelper
+
+class ConfigHelper
 {
     /**
      * String with the location of this configuration.
@@ -16,19 +19,16 @@ class sspmod_ldap_ConfigHelper
      */
     private $location;
 
-
     /**
      * The hostname of the LDAP server.
      */
     private $hostname;
 
-
     /**
      * Whether we should use TLS/SSL when contacting the LDAP server.
      */
     private $enableTLS;
 
-
     /**
      * Whether debug output is enabled.
      *
@@ -36,7 +36,6 @@ class sspmod_ldap_ConfigHelper
      */
     private $debug;
 
-
     /**
      * The timeout for accessing the LDAP server.
      *
@@ -56,30 +55,31 @@ class sspmod_ldap_ConfigHelper
      */
     private $referrals;
 
-
     /**
      * Whether we need to search for the users DN.
      */
     private $searchEnable;
 
-
     /**
      * The username we should bind with before we can search for the user.
      */
     private $searchUsername;
 
-
     /**
      * The password we should bind with before we can search for the user.
      */
     private $searchPassword;
 
-
     /**
      * Array with the base DN(s) for the search.
      */
     private $searchBase;
 
+    /**
+     * The scope of the search.
+     */
+    private $searchScope;
+
     /**
      * Additional LDAP filter fields for the search
      */
@@ -90,31 +90,26 @@ class sspmod_ldap_ConfigHelper
      */
     private $searchAttributes;
 
-
     /**
      * The DN pattern we should use to create the DN from the username.
      */
     private $dnPattern;
 
-
     /**
      * The attributes we should fetch. Can be NULL in which case we will fetch all attributes.
      */
     private $attributes;
 
-
     /**
      * The user cannot get all attributes, privileged reader required
      */
     private $privRead;
 
-
     /**
      * The DN we should bind with before we can get the attributes.
      */
     private $privUsername;
 
-
     /**
      * The password we should bind with before we can get the attributes.
      */
@@ -135,7 +130,7 @@ class sspmod_ldap_ConfigHelper
         $this->location = $location;
 
         // Parse configuration
-        $config = SimpleSAML_Configuration::loadFromArray($config, $location);
+        $config = \SimpleSAML\Configuration::loadFromArray($config, $location);
 
         $this->hostname = $config->getString('hostname');
         $this->enableTLS = $config->getBoolean('enable_tls', false);
@@ -153,6 +148,7 @@ class sspmod_ldap_ConfigHelper
             }
 
             $this->searchBase = $config->getArrayizeString('search.base');
+            $this->searchScope = $config->getString('search.scope', 'subtree');
             $this->searchFilter = $config->getString('search.filter', null);
             $this->searchAttributes = $config->getArray('search.attributes');
 
@@ -173,12 +169,12 @@ class sspmod_ldap_ConfigHelper
     /**
      * Attempt to log in using the given username and password.
      *
-     * Will throw a SimpleSAML_Error_Error('WRONGUSERPASS') if the username or password is wrong.
+     * Will throw a \SimpleSAML\Error\Error('WRONGUSERPASS') if the username or password is wrong.
      * If there is a configuration problem, an Exception will be thrown.
      *
      * @param string $username  The username the user wrote.
      * @param string $password  The password the user wrote.
-     * @param arrray $sasl_args  Array of SASL options for LDAP bind.
+     * @param array $sasl_args  Array of SASL options for LDAP bind.
      * @return array  Associative array with the users attributes.
      */
     public function login($username, $password, array $sasl_args = null)
@@ -187,11 +183,11 @@ class sspmod_ldap_ConfigHelper
         assert(is_string($password));
 
         if (empty($password)) {
-            SimpleSAML\Logger::info($this->location . ': Login with empty password disallowed.');
-            throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+            \SimpleSAML\Logger::info($this->location.': Login with empty password disallowed.');
+            throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
         }
 
-        $ldap = new SimpleSAML_Auth_LDAP($this->hostname, $this->enableTLS, $this->debug, $this->timeout, $this->port, $this->referrals);
+        $ldap = new \SimpleSAML\Auth\LDAP($this->hostname, $this->enableTLS, $this->debug, $this->timeout, $this->port, $this->referrals);
 
         if (!$this->searchEnable) {
             $ldapusername = addcslashes($username, ',+"\\<>;*');
@@ -199,21 +195,21 @@ class sspmod_ldap_ConfigHelper
         } else {
             if ($this->searchUsername !== null) {
                 if (!$ldap->bind($this->searchUsername, $this->searchPassword)) {
-                    throw new Exception('Error authenticating using search username & password.');
+                    throw new \Exception('Error authenticating using search username & password.');
                 }
             }
 
-            $dn = $ldap->searchfordn($this->searchBase, $this->searchAttributes, $username, true, $this->searchFilter);
+            $dn = $ldap->searchfordn($this->searchBase, $this->searchAttributes, $username, true, $this->searchFilter, $this->searchScope);
             if ($dn === null) {
                 /* User not found with search. */
-                SimpleSAML\Logger::info($this->location . ': Unable to find users DN. username=\'' . $username . '\'');
-                throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+                \SimpleSAML\Logger::info($this->location.': Unable to find users DN. username=\''.$username.'\'');
+                throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
             }
         }
 
         if (!$ldap->bind($dn, $password, $sasl_args)) {
-            SimpleSAML\Logger::info($this->location . ': '. $username . ' failed to authenticate. DN=' . $dn);
-            throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+            \SimpleSAML\Logger::info($this->location.': '.$username.' failed to authenticate. DN='.$dn);
+            throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
         }
 
         /* In case of SASL bind, authenticated and authorized DN may differ */
@@ -225,7 +221,7 @@ class sspmod_ldap_ConfigHelper
         if ($this->privRead) {
             /* Yes, rebind with privs */
             if (!$ldap->bind($this->privUsername, $this->privPassword)) {
-                throw new Exception('Error authenticating using privileged DN & password.');
+                throw new \Exception('Error authenticating using privileged DN & password.');
             }
         }
 
@@ -248,16 +244,16 @@ class sspmod_ldap_ConfigHelper
      * The DN of the matching element, if found. If no element was
      * found and $allowZeroHits is set to FALSE, an exception will
      * be thrown; otherwise NULL will be returned.
-     * @throws SimpleSAML_Error_AuthSource if:
+     * @throws \SimpleSAML\Error\AuthSource if:
      * - LDAP search encounter some problems when searching cataloge
      * - Not able to connect to LDAP server
-     * @throws SimpleSAML_Error_UserNotFound if:
+     * @throws \SimpleSAML\Error\UserNotFound if:
      * - $allowZeroHits is FALSE and no result is found
      *
      */
     public function searchfordn($attribute, $value, $allowZeroHits)
     {
-        $ldap = new SimpleSAML_Auth_LDAP($this->hostname,
+        $ldap = new \SimpleSAML\Auth\LDAP($this->hostname,
             $this->enableTLS,
             $this->debug,
             $this->timeout,
@@ -270,12 +266,12 @@ class sspmod_ldap_ConfigHelper
 
         if ($this->searchUsername !== null) {
             if (!$ldap->bind($this->searchUsername, $this->searchPassword)) {
-                throw new Exception('Error authenticating using search username & password.');
+                throw new \Exception('Error authenticating using search username & password.');
             }
         }
 
         return $ldap->searchfordn($this->searchBase, $attribute,
-            $value, $allowZeroHits, $this->searchFilter);
+            $value, $allowZeroHits, $this->searchFilter, $this->searchScope);
     }
 
     public function getAttributes($dn, $attributes = null)
@@ -284,7 +280,7 @@ class sspmod_ldap_ConfigHelper
             $attributes = $this->attributes;
         }
 
-        $ldap = new SimpleSAML_Auth_LDAP($this->hostname,
+        $ldap = new \SimpleSAML\Auth\LDAP($this->hostname,
             $this->enableTLS,
             $this->debug,
             $this->timeout,
@@ -295,10 +291,9 @@ class sspmod_ldap_ConfigHelper
         if ($this->privRead) {
             /* Yes, rebind with privs */
             if (!$ldap->bind($this->privUsername, $this->privPassword)) {
-                throw new Exception('Error authenticating using privileged DN & password.');
+                throw new \Exception('Error authenticating using privileged DN & password.');
             }
         }
         return $ldap->getAttributes($dn, $attributes);
     }
-
 }
diff --git a/modules/memcacheMonitor/dictionaries/memcachestat.definition.json b/modules/memcacheMonitor/dictionaries/memcachestat.definition.json
index be9187165db19f388606c385016864c26a606b3c..885b475085a28683868385d48391bb66e755f4f3 100644
--- a/modules/memcacheMonitor/dictionaries/memcachestat.definition.json
+++ b/modules/memcacheMonitor/dictionaries/memcachestat.definition.json
@@ -41,9 +41,9 @@
 	"cmd_set": {
 		"en": "Total SET commands"
 	},
-    "cmd_flush": {
-        "en": "Total FLUSH commands"
-    },
+	"cmd_flush": {
+		"en": "Total FLUSH commands"
+	},
 	"get_hits": {
 		"en": "Total GET commands (success)"
 	},
@@ -60,54 +60,87 @@
 		"en": "Total storage avail"
 	},
 	"pointer_size": {
-	    "en": "Pointer size (bits)"
+		"en": "Pointer size (bits)"
 	},
 	"delete_misses": {
-	    "en": "Total DELETE commands (failed)"
+		"en": "Total DELETE commands (failed)"
 	},
 	"delete_hits": {
-	    "en": "Total DELETE commands (success)"
+		"en": "Total DELETE commands (success)"
 	},
 	"incr_misses": {
-	    "en": "Total INCR commands (failed)"
+		"en": "Total INCR commands (failed)"
 	},
 	"incr_hits": {
-	    "en": "Total INCR commands (success)"
+		"en": "Total INCR commands (success)"
 	},
 	"decr_misses": {
-	    "en": "Total DECR commands (failed)"
+		"en": "Total DECR commands (failed)"
 	},
 	"decr_hits": {
-	    "en": "Total DECR commands (success)"
-    },
+		"en": "Total DECR commands (success)"
+	},
 	"cas_misses": {
-	    "en": "Total CAS commands (failed)"
+		"en": "Total CAS commands (failed)"
 	},
 	"cas_hits": {
-	    "en": "Total CAS commands (success)"
+		"en": "Total CAS commands (success)"
 	},
 	"cas_badval": {
-	    "en": "Total bad CAS identifiers"
+		"en": "Total bad CAS identifiers"
 	},
 	"auth_cmds": {
-	    "en": "Total authentication commands processed"
+		"en": "Total authentication commands processed"
 	},
 	"auth_errors": {
-	    "en": "Total authentication commands failed"
+		"en": "Total authentication commands failed"
 	},
 	"accepting_conns": {
-	    "en": "Currently accepting new connections"
+		"en": "Currently accepting new connections"
 	},
 	"listen_disabled_num": {
-	    "en": "Total number of denied connections (connection limit)"
+		"en": "Total number of denied connections (connection limit)"
 	},
 	"threads": {
-	    "en": "Number of available threads"
+		"en": "Number of available threads"
 	},
 	"conn_yields": {
-	    "en": "Number of times the request limit was reached"
+		"en": "Number of times the request limit was reached"
 	},
 	"evictions": {
-	    "en": "Number of objects removed from cache (memory limit)"
+		"en": "Number of objects removed from cache (memory limit)"
+	},
+	"libevent": {
+		"en": "Libevent version"
+	},
+	"reserved_fds": {
+		"en": "Number of misc fds used internally"
+	},
+	"cmd_touch": {
+		"en": "Cumulative number of touch reqs"
+	},
+	"touch_hits": {
+		"en": "Number of keys that have been touched with a new expiration time"
+	},
+	"touch_misses": {
+		"en": "Number of items that have been touched and not found"
+	},
+	"hash_power_level": {
+		"en": "Current size multiplier for hash table"
+	},
+	"hash_bytes": {
+		"en": "Bytes currently used by hash tables"
+	},
+	"hash_is_expanding": {
+		"en": "Indicates if the hash table is being grown to a new size"
+	},
+	"expired_unfetched": {
+		"en": "Items pulled from LRU that were never touched before expiring"
+	},
+	"evicted_unfetched": {
+		"en": "Items pulled from LRU that were never touched"
+	},
+	"reclaimed": {
+		"en": "Number of times an entry was stored using memory from an expired entry"
 	}
 }
diff --git a/modules/memcacheMonitor/hooks/hook_sanitycheck.php b/modules/memcacheMonitor/hooks/hook_sanitycheck.php
index 1513981245f27998b51b20a5ddd73f60e6934bff..da802f3117c6df8b9d8e2e330c8e7112698ae60c 100644
--- a/modules/memcacheMonitor/hooks/hook_sanitycheck.php
+++ b/modules/memcacheMonitor/hooks/hook_sanitycheck.php
@@ -7,29 +7,30 @@
  *
  * @param array &$hookinfo  hookinfo
  */
+
 function memcacheMonitor_hook_sanitycheck(&$hookinfo) {
-	assert(is_array($hookinfo));
-	assert(array_key_exists('errors', $hookinfo));
-	assert(array_key_exists('info', $hookinfo));
+    assert(is_array($hookinfo));
+    assert(array_key_exists('errors', $hookinfo));
+    assert(array_key_exists('info', $hookinfo));
 
-	try {
-		$servers = SimpleSAML_Memcache::getRawStats();
-	} catch (Exception $e) {
-		$hookinfo['errors'][] = '[memcacheMonitor] Error parsing memcache configuration: ' . $e->getMessage();
-		return;
-	}
+    try {
+        $servers = \SimpleSAML\Memcache::getRawStats();
+    } catch (\Exception $e) {
+        $hookinfo['errors'][] = '[memcacheMonitor] Error parsing memcache configuration: ' . $e->getMessage();
+        return;
+    }
 
-	$allOK = TRUE;
-	foreach ($servers as $group) {
-		foreach ($group as $server => $status) {
-			if ($status === FALSE) {
-				$hookinfo['errors'][] = '[memcacheMonitor] No response from server: ' . $server;
-				$allOK = FALSE;
-			}
-		}
-	}
+    $allOK = true;
+    foreach ($servers as $group) {
+        foreach ($group as $server => $status) {
+            if ($status === false) {
+                $hookinfo['errors'][] = '[memcacheMonitor] No response from server: ' . $server;
+                $allOK = false;
+            }
+        }
+    }
 
-	if ($allOK) {
-		$hookinfo['info'][] = '[memcacheMonitor] All servers responding.';
-	}
+    if ($allOK) {
+        $hookinfo['info'][] = '[memcacheMonitor] All servers responding.';
+    }
 }
diff --git a/modules/memcacheMonitor/locales/en/LC_MESSAGES/memcacheMonitor.po b/modules/memcacheMonitor/locales/en/LC_MESSAGES/memcacheMonitor.po
index a71c1988257e3acad4925ffbcb6269ab81d05144..bab82dd3f380481d57cb1d0c8356a57d9fef53e9 100644
--- a/modules/memcacheMonitor/locales/en/LC_MESSAGES/memcacheMonitor.po
+++ b/modules/memcacheMonitor/locales/en/LC_MESSAGES/memcacheMonitor.po
@@ -15,6 +15,39 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Generated-By: Babel 2.3.4\n"
 
+msgid "{memcacheMonitor:memcachestat:libevent}"
+msgstr "Libevent version"
+
+msgid "{memcacheMonitor:memcachestat:reserved_fds}"
+msgstr "Number of misc fds used internally"
+
+msgid "{memcacheMonitor:memcachestat:cmd_touch}"
+msgstr "Cumulative number of touch reqs"
+
+msgid "{memcacheMonitor:memcachestat:touch_hits}"
+msgstr "Number of keys that have been touched with a new expiration time"
+
+msgid "{memcacheMonitor:memcachestat:touch_misses}"
+msgstr "Number of items that have been touched and not found"
+
+msgid "{memcacheMonitor:memcachestat:hash_power_level}"
+msgstr "Current size multiplier for hash table"
+
+msgid "{memcacheMonitor:memcachestat:hash_bytes}"
+msgstr "Bytes currently used by hash tables"
+
+msgid "{memcacheMonitor:memcachestat:hash_is_expanding}"
+msgstr "Indicates if the hash table is being grown to a new size"
+
+msgid "{memcacheMonitor:memcachestat:expired_unfetched}"
+msgstr "Items pulled from LRU that were never touched before expiring"
+
+msgid "{memcacheMonitor:memcachestat:evicted_unfetched}"
+msgstr "Items pulled from LRU that were never touched"
+
+msgid "{memcacheMonitor:memcachestat:reclaimed}"
+msgstr "Number of times an entry was stored using memory from an expired entry"
+
 msgid "{memcacheMonitor:memcachestat:delete_misses}"
 msgstr "Total DELETE commands (failed)"
 
diff --git a/modules/memcacheMonitor/www/memcachestat.php b/modules/memcacheMonitor/www/memcachestat.php
index e9651ceefb064161aa8a072d4fabe103db57fa8b..afbc3d4303b667467dea9907706a32246d849b92 100644
--- a/modules/memcacheMonitor/www/memcachestat.php
+++ b/modules/memcacheMonitor/www/memcachestat.php
@@ -62,10 +62,10 @@ function humanreadable($input) {
     return $output;
 }
 
-$config = SimpleSAML_Configuration::getInstance();
+$config = \SimpleSAML\Configuration::getInstance();
 
 // Make sure that the user has admin access rights
-SimpleSAML\Utils\Auth::requireAdmin();
+\SimpleSAML\Utils\Auth::requireAdmin();
 
 $formats = array(
     'bytes' => 'humanreadable',
@@ -76,8 +76,9 @@ $formats = array(
     'uptime' => 'hours',
 );
 
-$statsRaw = SimpleSAML_Memcache::getStats();
-$stats = $statsRaw;
+$statsraw = \SimpleSAML\Memcache::getStats();
+
+$stats = $statsraw;
 
 foreach ($stats as $key => &$entry) {
     if (array_key_exists($key, $formats)) {
@@ -88,44 +89,56 @@ foreach ($stats as $key => &$entry) {
     }
 }
 
-$t = new SimpleSAML_XHTML_Template($config, 'memcacheMonitor:memcachestat.tpl.php');
+$t = new \SimpleSAML\XHTML\Template($config, 'memcacheMonitor:memcachestat.tpl.php');
 $rowTitles = array(
-    'accepting_conns' => $t->noop('{memcacheMonitor:memcachestat:accepting_conns}'),
-    'auth_cmds' => $t->noop('{memcacheMonitor:memcachestat:auth_cmds}'),
-    'auth_errors' => $t->noop('{memcacheMonitor:memcachestat:auth_errors}'),
-    'bytes' => $t->noop('{memcacheMonitor:memcachestat:bytes}'),
-    'bytes_read' => $t->noop('{memcacheMonitor:memcachestat:bytes_read}'),
-    'bytes_written' => $t->noop('{memcacheMonitor:memcachestat:bytes_written}'),
-    'cas_badval' => $t->noop('{memcacheMonitor:memcachestat:cas_badval}'),
-    'cas_hits' => $t->noop('{memcacheMonitor:memcachestat:cas_hits}'),
-    'cas_misses' => $t->noop('{memcacheMonitor:memcachestat:cas_misses}'),
-    'cmd_get' => $t->noop('{memcacheMonitor:memcachestat:cmd_get}'),
-    'cmd_set' => $t->noop('{memcacheMonitor:memcachestat:cmd_set}'),
-    'connection_structures' => $t->noop('{memcacheMonitor:memcachestat:connection_structures}'),
-    'conn_yields' => $t->noop('{memcacheMonitor:memcachestat:conn_yields}'),
-    'curr_connections' => $t->noop('{memcacheMonitor:memcachestat:curr_connections}'),
-    'curr_items' => $t->noop('{memcacheMonitor:memcachestat:curr_items}'),
-    'decr_hits' => $t->noop('{memcacheMonitor:memcachestat:decr_hits}'),
-    'decr_misses' => $t->noop('{memcacheMonitor:memcachestat:decr_misses}'),
-    'delete_hits' => $t->noop('{memcacheMonitor:memcachestat:delete_hits}'),
-    'delete_misses' => $t->noop('{memcacheMonitor:memcachestat:delete_misses}'),
-    'evictions' => $t->noop('{memcacheMonitor:memcachestat:evictions}'),
-    'get_hits' => $t->noop('{memcacheMonitor:memcachestat:get_hits}'),
-    'get_misses' => $t->noop('{memcacheMonitor:memcachestat:get_misses}'),
-    'incr_hits' => $t->noop('{memcacheMonitor:memcachestat:incr_hits}'),
-    'incr_misses' => $t->noop('{memcacheMonitor:memcachestat:incr_misses}'),
-    'limit_maxbytes' => $t->noop('{memcacheMonitor:memcachestat:limit_maxbytes}'),
-    'listen_disabled_num' => $t->noop('{memcacheMonitor:memcachestat:listen_disabled_num}'),
-    'pid' => $t->noop('{memcacheMonitor:memcachestat:pid}'),
-    'pointer_size' => $t->noop('{memcacheMonitor:memcachestat:pointer_size}'),
-    'rusage_system' => $t->noop('{memcacheMonitor:memcachestat:rusage_system}'),
-    'rusage_user' => $t->noop('{memcacheMonitor:memcachestat:rusage_user}'),
-    'threads' => $t->noop('{memcacheMonitor:memcachestat:threads}'),
-    'time' => $t->noop('{memcacheMonitor:memcachestat:time}'),
-    'total_connections' => $t->noop('{memcacheMonitor:memcachestat:total_connections}'),
-    'total_items' => $t->noop('{memcacheMonitor:memcachestat:total_items}'),
-    'uptime' => $t->noop('{memcacheMonitor:memcachestat:uptime}'),
-    'version' => $t->noop('{memcacheMonitor:memcachestat:version}'),
+    'accepting_conns' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:accepting_conns}'),
+    'auth_cmds' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:auth_cmds}'),
+    'auth_errors' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:auth_errors}'),
+    'bytes' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:bytes}'),
+    'bytes_read' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:bytes_read}'),
+    'bytes_written' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:bytes_written}'),
+    'cas_badval' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:cas_badval}'),
+    'cas_hits' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:cas_hits}'),
+    'cas_misses' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:cas_misses}'),
+    'cmd_flush' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:cmd_flush}'),
+    'cmd_get' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:cmd_get}'),
+    'cmd_set' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:cmd_set}'),
+    'cmd_touch' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:cmd_touch}'),
+    'connection_structures' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:connection_structures}'),
+    'conn_yields' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:conn_yields}'),
+    'curr_connections' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:curr_connections}'),
+    'curr_items' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:curr_items}'),
+    'decr_hits' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:decr_hits}'),
+    'decr_misses' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:decr_misses}'),
+    'delete_hits' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:delete_hits}'),
+    'delete_misses' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:delete_misses}'),
+    'expired_unfetched' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:expired_unfetched}'),
+    'evicted_unfetched' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:evicted_unfetched}'),
+    'evictions' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:evictions}'),
+    'get_hits' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:get_hits}'),
+    'get_misses' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:get_misses}'),
+    'hash_bytes' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:hash_bytes}'),
+    'hash_is_expanding' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:hash_is_expanding}'),
+    'hash_power_level' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:hash_power_level}'),
+    'incr_hits' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:incr_hits}'),
+    'incr_misses' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:incr_misses}'),
+    'libevent' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:libevent}'),
+    'limit_maxbytes' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:limit_maxbytes}'),
+    'listen_disabled_num' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:listen_disabled_num}'),
+    'pid' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:pid}'),
+    'pointer_size' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:pointer_size}'),
+    'reclaimed' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:reclaimed}'),
+    'reserved_fds' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:reserved_fds}'),
+    'rusage_system' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:rusage_system}'),
+    'rusage_user' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:rusage_user}'),
+    'threads' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:threads}'),
+    'time' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:time}'),
+    'total_connections' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:total_connections}'),
+    'total_items' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:total_items}'),
+    'touch_hits' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:touch_hits}'),
+    'touch_misses' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:touch_misses}'),
+    'uptime' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:uptime}'),
+    'version' => \SimpleSAML\Locale\Translate::noop('{memcacheMonitor:memcachestat:version}'),
 );
 
 // Identify column headings
diff --git a/modules/metarefresh/bin/metarefresh.php b/modules/metarefresh/bin/metarefresh.php
index bad5c37a06088ed244689f2371a6005396e78e9d..aa18eb65d540e6d240410e1636a8df61800bdd25 100755
--- a/modules/metarefresh/bin/metarefresh.php
+++ b/modules/metarefresh/bin/metarefresh.php
@@ -13,7 +13,7 @@ $baseDir = dirname(dirname(dirname(dirname(__FILE__))));
 // Add library autoloader.
 require_once($baseDir . '/lib/_autoload.php');
 
-if(!SimpleSAML\Module::isModuleEnabled('metarefresh')) {
+if(!\SimpleSAML\Module::isModuleEnabled('metarefresh')) {
 	echo("You need to enable the metarefresh module before this script can be used.\n");
 	echo("You can enable it by running the following command:\n");
 	echo('  echo >"' . $baseDir . '/modules/metarefresh/enable' . "\"\n");
@@ -21,8 +21,8 @@ if(!SimpleSAML\Module::isModuleEnabled('metarefresh')) {
 }
 
 /* Initialize the configuration. */
-$configdir = SimpleSAML\Utils\Config::getConfigDir();
-SimpleSAML_Configuration::setConfigDir($configdir);
+$configdir = \SimpleSAML\Utils\Config::getConfigDir();
+\SimpleSAML\Configuration::setConfigDir($configdir);
 
 /* $outputDir contains the directory we will store the generated metadata in. */
 $outputDir = $baseDir . '/metadata-generated';
@@ -128,7 +128,7 @@ if(count($files) === 0) {
 
 
 /* The metadata global variable will be filled with the metadata we extract. */
-$metaloader = new sspmod_metarefresh_MetaLoader();
+$metaloader = new \SimpleSAML\Module\metarefresh\MetaLoader();
 
 foreach($files as $f) {
 	$source = array('src' => $f);
diff --git a/modules/metarefresh/dictionaries/metarefresh.definition.json b/modules/metarefresh/dictionaries/metarefresh.definition.json
new file mode 100644
index 0000000000000000000000000000000000000000..8bfb51c4af39570be0a83c43531693df4caa64c1
--- /dev/null
+++ b/modules/metarefresh/dictionaries/metarefresh.definition.json
@@ -0,0 +1,12 @@
+{
+    "frontpage_link": {
+        "en": "Metarefresh: fetch metadata"
+    },
+    "metarefresh_header": {
+        "en": "Metarefresh fetch"
+    },
+    "no_output": {
+        "en": "No output from metarefresh."
+    }
+}
+
diff --git a/modules/metarefresh/dictionaries/metarefresh.translation.json b/modules/metarefresh/dictionaries/metarefresh.translation.json
new file mode 100644
index 0000000000000000000000000000000000000000..2023ecba4f39e60385911c6708ac187bf2db6c8e
--- /dev/null
+++ b/modules/metarefresh/dictionaries/metarefresh.translation.json
@@ -0,0 +1,9 @@
+{
+    "frontpage_link": {
+    },
+    "metarefresh_header": {
+    },
+    "no_output": {
+    }
+}
+
diff --git a/modules/metarefresh/hooks/hook_cron.php b/modules/metarefresh/hooks/hook_cron.php
index a845396012e2bdb154bb55061cb0596531220e02..8b627292d358b19ae06ba0f81803266f6694fdbf 100644
--- a/modules/metarefresh/hooks/hook_cron.php
+++ b/modules/metarefresh/hooks/hook_cron.php
@@ -12,8 +12,8 @@ function metarefresh_hook_cron(&$croninfo) {
 	SimpleSAML\Logger::info('cron [metarefresh]: Running cron in cron tag [' . $croninfo['tag'] . '] ');
 
 	try {
-		$config = SimpleSAML_Configuration::getInstance();
-		$mconfig = SimpleSAML_Configuration::getOptionalConfig('config-metarefresh.php');
+		$config = \SimpleSAML\Configuration::getInstance();
+		$mconfig = \SimpleSAML\Configuration::getOptionalConfig('config-metarefresh.php');
 
 		$sets = $mconfig->getConfigList('sets', array());
 		$stateFile = $config->getPathValue('datadir', 'data/') . 'metarefresh-state.php';
@@ -23,7 +23,7 @@ function metarefresh_hook_cron(&$croninfo) {
 			$cronTags = $set->getArray('cron');
 			if (!in_array($croninfo['tag'], $cronTags, true)) continue;
 
-			SimpleSAML\Logger::info('cron [metarefresh]: Executing set [' . $setkey . ']');
+			\SimpleSAML\Logger::info('cron [metarefresh]: Executing set [' . $setkey . ']');
 
 			$expireAfter = $set->getInteger('expireAfter', NULL);
 			if ($expireAfter !== NULL) {
@@ -36,12 +36,12 @@ function metarefresh_hook_cron(&$croninfo) {
 			$outputDir = $config->resolvePath($outputDir);
 			$outputFormat = $set->getValueValidate('outputFormat', array('flatfile', 'serialize'), 'flatfile');
 
-			$oldMetadataSrc = SimpleSAML_Metadata_MetaDataStorageSource::getSource(array(
+			$oldMetadataSrc = \SimpleSAML\Metadata\MetaDataStorageSource::getSource(array(
 				'type' => $outputFormat,
 				'directory' => $outputDir,
 			));
 
-			$metaloader = new sspmod_metarefresh_MetaLoader($expire, $stateFile, $oldMetadataSrc);
+			$metaloader = new \SimpleSAML\Module\metarefresh\MetaLoader($expire, $stateFile, $oldMetadataSrc);
 
 			# Get global blacklist, whitelist and caching info
 			$blacklist = $mconfig->getArray('blacklist', array());
@@ -86,7 +86,7 @@ function metarefresh_hook_cron(&$croninfo) {
 					$source['conditionalGET'] = $conditionalGET;
 				}
 
-				SimpleSAML\Logger::debug('cron [metarefresh]: In set [' . $setkey . '] loading source ['  . $source['src'] . ']');
+				\SimpleSAML\Logger::debug('cron [metarefresh]: In set [' . $setkey . '] loading source ['  . $source['src'] . ']');
 				$metaloader->loadSource($source);
 			}
 
@@ -103,12 +103,12 @@ function metarefresh_hook_cron(&$croninfo) {
 			}
 
 			if ($set->hasValue('arp')) {
-				$arpconfig = SimpleSAML_Configuration::loadFromArray($set->getValue('arp'));
+				$arpconfig = \SimpleSAML\Configuration::loadFromArray($set->getValue('arp'));
 				$metaloader->writeARPfile($arpconfig);
 			}
 		}
 
-	} catch (Exception $e) {
+	} catch (\Exception $e) {
 		$croninfo['summary'][] = 'Error during metarefresh: ' . $e->getMessage();
 	}
 }
diff --git a/modules/metarefresh/hooks/hook_frontpage.php b/modules/metarefresh/hooks/hook_frontpage.php
index ee378dec9ddf34280f7b1fda282310e4c9f177a4..0c5c2b17529f9e5a10e9e85d9035003f49a2d52f 100644
--- a/modules/metarefresh/hooks/hook_frontpage.php
+++ b/modules/metarefresh/hooks/hook_frontpage.php
@@ -10,7 +10,7 @@ function metarefresh_hook_frontpage(&$links) {
 
 	$links['federation'][] = array(
 		'href' => SimpleSAML\Module::getModuleURL('metarefresh/fetch.php'),
-		'text' => '{core:frontpage:link_metarefresh}',
+		'text' => '{metarefresh:metarefresh:frontpage_link}',
 	);
 
 }
diff --git a/modules/metarefresh/lib/ARP.php b/modules/metarefresh/lib/ARP.php
index 20f5c764d7b4f04334ee4f2540b44f17f8069125..52c61d4687550e235c8db187b91a8a8aa2aba762 100644
--- a/modules/metarefresh/lib/ARP.php
+++ b/modules/metarefresh/lib/ARP.php
@@ -1,99 +1,152 @@
 <?php
+
+namespace SimpleSAML\Module\metarefresh;
+
 /*
  * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
  * @package SimpleSAMLphp
  */
-class sspmod_metarefresh_ARP {
 
+class ARP
+{
+    /**
+     * @var array
+     */
+    private $metadata;
+
+    /**
+     * @var array
+     */
+    private $attributes;
+
+    /**
+     * @var string
+     */
+    private $prefix;
 
-	private $metadata;
-	private $attributes;
-	private $prefix;
-	private $suffix;
+    /**
+     * @var
+     */
+    private $suffix;
 
-	/**
-	 * Constructor
-	 *
-	 * @param 
+    /**
+     * Constructor
+     *
+     * @param array $metadata
+     * @param string $attributemap_filename
+     * @param string $prefix
+     * @param string $suffix
 	 */
-	public function __construct($metadata, $attributemap, $prefix, $suffix) {
-		$this->metadata = $metadata;
-		
-		$this->prefix = $prefix;
-		$this->suffix = $suffix;
-		
-		if (isset($attributemap)) $this->loadAttributeMap($attributemap);
-	}
+    public function __construct($metadata, $attributemap_filename, $prefix, $suffix)
+    {
+        $this->metadata = $metadata;
+        $this->prefix = $prefix;
+        $this->suffix = $suffix;
+
+        if (isset($attributemap_filename)) {
+            $this->loadAttributeMap($attributemap_filename);
+        }
+    }
 	
-	private function loadAttributeMap($attributemap) {
-		$config = SimpleSAML_Configuration::getInstance();
-		include($config->getPathValue('attributemap', 'attributemap/') . $attributemap . '.php');
-		$this->attributes = $attributemap;
-	}
-
-	private function surround($name) {
-		$ret = '';
-		if (!empty($this->prefix)) $ret .= $this->prefix;
-		$ret .= $name;
-		if (!empty($this->suffix)) $ret .= $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"
+    /**
+     * @param string $attributemap_filename
+     *
+     * @return void
+     */
+    private function loadAttributeMap($attributemap_filename)
+    {
+        $config = \SimpleSAML\Configuration::getInstance();
+        include($config->getPathValue('attributemap', 'attributemap/') . $attributemap_filename . '.php');
+        // Note that $attributemap is defined in the included attributemap-file!
+        $this->attributes = $attributemap;
+    }
+
+    /**
+     * @param string $name
+     *
+     * @return string
+     */
+    private function surround($name)
+    {
+        $ret = '';
+        if (!empty($this->prefix)) {
+            $ret .= $this->prefix;
+        }
+        $ret .= $name;
+        if (!empty($this->suffix)) {
+            $ret .= $this->suffix;
+        }
+        return $ret;
+    }
+
+    /**
+     * @param string $name
+     *
+     * @return string
+     */
+    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);
+    }
+
+    /**
+     * @return string
+     */
+    public function getXML()
+    {
+        $xml = <<<MSG
+        <?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) {
-			$xml .= $this->getEntryXML($metadata['metadata']);
-		}
-		
-		$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;
-	}
+MSG;
 
-}
+        foreach ($this->metadata as $metadata) {
+            $xml .= $this->getEntryXML($metadata['metadata']);
+        }
+
+        $xml .= '</AttributeFilterPolicyGroup>';
+        return $xml;
+    }
 
+    /**
+     * @param array $entry
+     *
+     * @return string
+     */
+    private function getEntryXML($entry)
+    {
+        $entityid = $entry['entityid'];
+        return '    <AttributeFilterPolicy id="' . $entityid .
+            '"><PolicyRequirementRule xsi:type="basic:AttributeRequesterString" value="' . $entityid .
+            '" />' . $this->getEntryXMLcontent($entry) . '</AttributeFilterPolicy>';
+    }
+
+    /**
+     * @param array $entry
+     *
+     * @return string
+     */
+    private function getEntryXMLcontent($entry)
+    {
+        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/metarefresh/lib/MetaLoader.php b/modules/metarefresh/lib/MetaLoader.php
index 82b57e1c8b96ad85517fa775ebbf00895ed483b4..87afecf209edc3f41821b35ee8841c0b790930a0 100644
--- a/modules/metarefresh/lib/MetaLoader.php
+++ b/modules/metarefresh/lib/MetaLoader.php
@@ -1,486 +1,501 @@
 <?php
-/*
- * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
+
+namespace SimpleSAML\Module\metarefresh;
+
+/**
  * @package SimpleSAMLphp
+ * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
  */
-class sspmod_metarefresh_MetaLoader {
-
-
-	private $expire;
-	private $metadata;
-	private $oldMetadataSrc;
-	private $stateFile;
-	private $changed;
-	private $types = array(
-		'saml20-idp-remote',
-		'saml20-sp-remote',
-		'shib13-idp-remote',
-		'shib13-sp-remote',
-		'attributeauthority-remote'
-	);
-
-
-	/**
-	 * Constructor
-	 *
-	 * @param array $sources 	Sources...
-	 * @param 
-	 */
-	public function __construct($expire = NULL, $stateFile = NULL, $oldMetadataSrc = NULL) {
-		$this->expire = $expire;
-		$this->metadata = array();
-		$this->oldMetadataSrc = $oldMetadataSrc;
-		$this->stateFile = $stateFile;
-		$this->changed = FALSE;
-
-		// Read file containing $state from disk
-		if(is_readable($stateFile)) {
-			require($stateFile);
-		}
-
-		$this->state = (isset($state)) ? $state : array();
-
-	}
-
-
-	/**
-	 * Get the types of entities that will be loaded.
-	 *
-	 * @return array The entity types allowed.
-	 */
-	public function getTypes()
-	{
-		return $this->types;
-	}
-
-
-	/**
-	 * Set the types of entities that will be loaded.
-	 *
-	 * @param string|array $types Either a string with the name of one single type allowed, or an array with a list of
-	 * types. Pass an empty array to reset to all types of entities.
-	 */
-	public function setTypes($types)
-	{
-		if (!is_array($types)) {
-			$types = array($types);
-		}
-		$this->types = $types;
-	}
-
-
-	/**
-	 * This function processes a SAML metadata file.
-	 *
-	 * @param $source
-	 */
-	public function loadSource($source) {
-
-		if (preg_match('@^https?://@i', $source['src'])) {
-			// Build new HTTP context
-			$context = $this->createContext($source);
-
-			// GET!
-			try {
-				list($data, $responseHeaders) = \SimpleSAML\Utils\HTTP::fetch($source['src'], $context, TRUE);
-			} catch(Exception $e) {
-				SimpleSAML\Logger::warning('metarefresh: ' . $e->getMessage());
-			}
-
-			// We have response headers, so the request succeeded
-			if(!isset($responseHeaders)) {
-				// No response headers, this means the request failed in some way, so re-use old data
-				SimpleSAML\Logger::debug('No response from ' . $source['src'] . ' - attempting to re-use cached metadata');
-				$this->addCachedMetadata($source);
-				return;
-			} elseif(preg_match('@^HTTP/1\.[01]\s304\s@', $responseHeaders[0])) {
-				// 304 response
-				SimpleSAML\Logger::debug('Received HTTP 304 (Not Modified) - attempting to re-use cached metadata');
-				$this->addCachedMetadata($source);
-				return;
-			} elseif(!preg_match('@^HTTP/1\.[01]\s200\s@', $responseHeaders[0])) {
-				// Other error
-				SimpleSAML\Logger::debug('Error from ' . $source['src'] . ' - attempting to re-use cached metadata');
-				$this->addCachedMetadata($source);
-				return;
-			}
-		} else {
-			// Local file.
-			$data = file_get_contents($source['src']);
-			$responseHeaders = NULL;
-		}
-
-		// Everything OK. Proceed.
-		if (isset($source['conditionalGET']) && $source['conditionalGET']) {
-			// Stale or no metadata, so a fresh copy
-			SimpleSAML\Logger::debug('Downloaded fresh copy');
-		}
-
-		try {
-			$entities = $this->loadXML($data, $source);
-		} catch(Exception $e) {
-			SimpleSAML\Logger::debug('XML parser error when parsing ' . $source['src'] . ' - attempting to re-use cached metadata');
-			$this->addCachedMetadata($source);
-			return;
-		}
-
-		foreach($entities as $entity) {
-
-			if(isset($source['blacklist'])) {
-				if(!empty($source['blacklist']) && in_array($entity->getEntityID(), $source['blacklist'], true)) {
-					SimpleSAML\Logger::info('Skipping "' .  $entity->getEntityID() . '" - blacklisted.' . "\n");
-					continue;
-				}
-			}
-
-			if(isset($source['whitelist'])) {
-				if(!empty($source['whitelist']) && !in_array($entity->getEntityID(), $source['whitelist'], true)) {
-					SimpleSAML\Logger::info('Skipping "' .  $entity->getEntityID() . '" - not in the whitelist.' . "\n");
-					continue;
-				}
-			}
-
-			if(array_key_exists('certificates', $source) && $source['certificates'] !== NULL) {
-				if(!$entity->validateSignature($source['certificates'])) {
-					SimpleSAML\Logger::info('Skipping "' . $entity->getEntityId() . '" - could not verify signature using certificate.' . "\n");
-					continue;
-				}
-			}
-
-			if(array_key_exists('validateFingerprint', $source) && $source['validateFingerprint'] !== NULL) {
-				if(!array_key_exists('certificates', $source) || $source['certificates'] == NULL) {
-					if(!$entity->validateFingerprint($source['validateFingerprint'])) {
-						SimpleSAML\Logger::info('Skipping "' . $entity->getEntityId() . '" - could not verify signature using fingerprint.' . "\n");
-						continue;
-					}
-				} else {
-					SimpleSAML\Logger::info('Skipping validation with fingerprint since option certificate is set.' . "\n");
-				}
-			}
-
-			$template = NULL;
-			if (array_key_exists('template', $source)) $template = $source['template'];
-
-			$this->addMetadata($source['src'], $entity->getMetadata1xSP(), 'shib13-sp-remote', $template);
-			$this->addMetadata($source['src'], $entity->getMetadata1xIdP(), 'shib13-idp-remote', $template);
-			$this->addMetadata($source['src'], $entity->getMetadata20SP(), 'saml20-sp-remote', $template);
-			$this->addMetadata($source['src'], $entity->getMetadata20IdP(), 'saml20-idp-remote', $template);
-			$attributeAuthorities = $entity->getAttributeAuthorities();
-			if (!empty($attributeAuthorities)) {
-				$this->addMetadata($source['src'], $attributeAuthorities[0], 'attributeauthority-remote', $template);
-			}
-		}
-
-		$this->saveState($source, $responseHeaders);
-	}
-
-	/**
-	 * Create HTTP context, with any available caches taken into account
-	 */
-	private function createContext($source) {
-
-		$context = NULL;
-
-		$config = SimpleSAML_Configuration::getInstance();
-		$name = $config->getString('technicalcontact_name', NULL);
-		$mail = $config->getString('technicalcontact_email', NULL);
-
-		$rawheader = "User-Agent: SimpleSAMLphp metarefresh, run by $name <$mail>\r\n";
-
-		if (isset($source['conditionalGET']) && $source['conditionalGET']) {
-			if(array_key_exists($source['src'], $this->state)) {
-
-				$sourceState = $this->state[$source['src']];
-
-				if(isset($sourceState['last-modified'])) {
-					$rawheader .= 'If-Modified-Since: ' . $sourceState['last-modified'] . "\r\n";
-				}
-
-				if(isset($sourceState['etag'])) {
-					$rawheader .= 'If-None-Match: ' . $sourceState['etag'] . "\r\n";
-				}
-			}
-		}
-
-		return array('http' => array('header' => $rawheader));
-	}
-
-
-	private function addCachedMetadata($source) {
-		if(isset($this->oldMetadataSrc)) {
-			foreach($this->types as $type) {
-				foreach($this->oldMetadataSrc->getMetadataSet($type) as $entity) {
-					if(array_key_exists('metarefresh:src', $entity)) {
-						if($entity['metarefresh:src'] == $source['src']) {
-							$this->addMetadata($source['src'], $entity, $type);
-						}
-					}
-				}
-			}
-		}
-	}
-
-
-	/**
-	 * Store caching state data for a source
-	 */
-	private function saveState($source, $responseHeaders) {
-
-		if (isset($source['conditionalGET']) && $source['conditionalGET']) {
-
-			// Headers section
-			$candidates = array('last-modified', 'etag');
-
-			foreach($candidates as $candidate) {
-				if(array_key_exists($candidate, $responseHeaders)) {
-					$this->state[$source['src']][$candidate] = $responseHeaders[$candidate];
-				}
-			}
-
-			if(!empty($this->state[$source['src']])) {
-				// Timestamp when this src was requested.
-				$this->state[$source['src']]['requested_at'] = $this->getTime();
-
-				$this->changed = TRUE;
-			}
-		}
-	}
-
-
-	/**
-	 * Parse XML metadata and return entities
-	 */
-	private function loadXML($data, $source) {
-		$entities = array();
-		try {
-			$doc = \SAML2\DOMDocumentFactory::fromString($data);
-		} catch (Exception $e) {
-			throw new Exception('Failed to read XML from ' . $source['src']);
-		}
-		if ($doc->documentElement === NULL) {
-			throw new Exception('Opened file is not an XML document: ' . $source['src']);
-		}
-		$entities = SimpleSAML_Metadata_SAMLParser::parseDescriptorsElement($doc->documentElement);
-		return $entities;
-	}
-
-
-	/**
-	 * This function writes the state array back to disk
-	 */
-	public function writeState() {
-		if($this->changed) {
-			SimpleSAML\Logger::debug('Writing: ' . $this->stateFile);
-            SimpleSAML\Utils\System::writeFile(
-				$this->stateFile,
-				"<?php\n/* This file was generated by the metarefresh module at ".$this->getTime() . ".\n".
-				" Do not update it manually as it will get overwritten. */\n".
-				'$state = ' . var_export($this->state, TRUE) . ";\n?>\n",
-				0644
-			);
-		}
-	}
-
-
-	/**
-	 * This function writes the metadata to stdout.
-	 */
-	public function dumpMetadataStdOut() {
-	
-		foreach($this->metadata as $category => $elements) {
-	
-			echo('/* The following data should be added to metadata/' . $category . '.php. */' . "\n");
-	
-	
-			foreach($elements as $m) {
-				$filename = $m['filename'];
-				$entityID = $m['metadata']['entityid'];
-	
-				echo("\n");
-				echo('/* The following metadata was generated from ' . $filename . ' on ' . $this->getTime() . '. */' . "\n");
-				echo('$metadata[\'' . addslashes($entityID) . '\'] = ' . var_export($m['metadata'], TRUE) . ';' . "\n");
-			}
-	
-	
-			echo("\n");
-			echo('/* End of data which should be added to metadata/' . $category . '.php. */' . "\n");
-			echo("\n");
-		}
-	}
-
-	
-	/**
-	 * This function adds metadata from the specified file to the list of metadata.
-	 * This function will return without making any changes if $metadata is NULL.
-	 *
-	 * @param $filename The filename the metadata comes from.
-	 * @param $metadata The metadata.
-	 * @param $type The metadata type.
-	 */
-	private function addMetadata($filename, $metadata, $type, $template = NULL) {
-	
-		if($metadata === NULL) {
-			return;
-		}
-	
-		if (isset($template)) {
-			$metadata = array_merge($metadata, $template);
-		}
-	
-		$metadata['metarefresh:src'] = $filename;
-		if(!array_key_exists($type, $this->metadata)) {
-			$this->metadata[$type] = array();
-		}
-		
-		// If expire is defined in constructor...
-		if (!empty($this->expire)) {
-			
-			// If expire is already in metadata
-			if (array_key_exists('expire', $metadata)) {
-			
-				// Override metadata expire with more restrictive global config-
-				if ($this->expire < $metadata['expire'])
-					$metadata['expire'] = $this->expire;
-					
-			// If expire is not already in metadata use global config
-			} else {
-				$metadata['expire'] = $this->expire;
-			}
-		}
-		
-
-	
-		$this->metadata[$type][] = array('filename' => $filename, 'metadata' => $metadata);
-	}
-
-
-	/**
-	 * This function writes the metadata to an ARP file
-	 */
-	public function writeARPfile($config) {
-		
-		assert($config instanceof SimpleSAML_Configuration);
-		
-		$arpfile = $config->getValue('arpfile');
-		$types = array('saml20-sp-remote');
-		
-		$md = array();
-		foreach($this->metadata as $category => $elements) {
-			if (!in_array($category, $types, true)) continue;
-			$md = array_merge($md, $elements);
-		}
-		
-		// $metadata, $attributemap, $prefix, $suffix
-		$arp = new sspmod_metarefresh_ARP($md, 
-			$config->getValue('attributemap', ''),  
-			$config->getValue('prefix', ''),  
-			$config->getValue('suffix', '')
-		);
-		
-		
-		$arpxml = $arp->getXML();
-
-		SimpleSAML\Logger::info('Writing ARP file: ' . $arpfile . "\n");
-		file_put_contents($arpfile, $arpxml);
-
-	}
-	
-	
-	/**
-	 * This function writes the metadata to to separate files in the output directory.
-	 */
-	public function writeMetadataFiles($outputDir) {
-	
-		while(strlen($outputDir) > 0 && $outputDir[strlen($outputDir) - 1] === '/') {
-			$outputDir = substr($outputDir, 0, strlen($outputDir) - 1);
-		}
-	
-		if(!file_exists($outputDir)) {
-			SimpleSAML\Logger::info('Creating directory: ' . $outputDir . "\n");
-			$res = @mkdir($outputDir, 0777, TRUE);
-			if ($res === FALSE) {
-				throw new Exception('Error creating directory: ' . $outputDir);
-			}
-		}
-	
-		foreach($this->types as $type) {
-
-			$filename = $outputDir . '/' . $type . '.php';
-
-			if(array_key_exists($type, $this->metadata)) {
-				$elements = $this->metadata[$type];
-				SimpleSAML\Logger::debug('Writing: ' . $filename);
-
-				$content  = '<?php' . "\n" . '/* This file was generated by the metarefresh module at '. $this->getTime() . "\n";
-				$content .= ' Do not update it manually as it will get overwritten' . "\n" . '*/' . "\n";
-
-				foreach($elements as $m) {
-					$entityID = $m['metadata']['entityid'];
-					$content .= "\n";
-					$content .= '$metadata[\'' . addslashes($entityID) . '\'] = ' . var_export($m['metadata'], TRUE) . ';' . "\n";
-				}
-
-				$content .= "\n" . '?>';
-
-                SimpleSAML\Utils\System::writeFile($filename, $content, 0644);
-			} elseif(is_file($filename)) {
-				if(unlink($filename)) {
-					SimpleSAML\Logger::debug('Deleting stale metadata file: ' . $filename);
-				} else {
-					SimpleSAML\Logger::warning('Could not delete stale metadata file: ' . $filename);
-				}
-			}
-		}
-	}
-
-
-	/**
-	 * Save metadata for loading with the 'serialize' metadata loader.
-	 *
-	 * @param string $outputDir  The directory we should save the metadata to.
-	 */
-	public function writeMetadataSerialize($outputDir) {
-		assert(is_string($outputDir));
-
-		$metaHandler = new SimpleSAML_Metadata_MetaDataStorageHandlerSerialize(array('directory' => $outputDir));
-
-		/* First we add all the metadata entries to the metadata handler. */
-		foreach ($this->metadata as $set => $elements) {
-			foreach ($elements as $m) {
-				$entityId = $m['metadata']['entityid'];
-
-				SimpleSAML\Logger::debug('metarefresh: Add metadata entry ' .
-					var_export($entityId, TRUE) . ' in set ' . var_export($set, TRUE) . '.');
-				$metaHandler->saveMetadata($entityId, $set, $m['metadata']);
-			}
-		}
-
-		/* Then we delete old entries which should no longer exist. */
-		$ct = time();
-		foreach ($metaHandler->getMetadataSets() as $set) {
-			foreach ($metaHandler->getMetadataSet($set) as $entityId => $metadata) {
-				if (!array_key_exists('expire', $metadata)) {
-					SimpleSAML\Logger::warning('metarefresh: Metadata entry without expire timestamp: ' . var_export($entityId, TRUE) .
-						' in set ' . var_export($set, TRUE) . '.');
-					continue;
-				}
-				if ($metadata['expire'] > $ct) {
-					continue;
-				}
-				SimpleSAML\Logger::debug('metarefresh: ' . $entityId . ' expired ' . date('l jS \of F Y h:i:s A', $metadata['expire']) );
-				SimpleSAML\Logger::debug('metarefresh: Delete expired metadata entry ' .
-					var_export($entityId, TRUE) . ' in set ' . var_export($set, TRUE) . '. (' . ($ct - $metadata['expire']) . ' sec)');
-				$metaHandler->deleteMetadata($entityId, $set);
-			}
-		}
-	}
-
-
-	private function getTime() {
-		/* The current date, as a string. */
-		date_default_timezone_set('UTC');
-		$when = date('Y-m-d\\TH:i:s\\Z');
-		return $when;
-	}
 
+class MetaLoader
+{
+    private $expire;
+    private $metadata;
+    private $oldMetadataSrc;
+    private $stateFile;
+    private $changed;
+    private $state;
+    private $types = array(
+        'saml20-idp-remote',
+        'saml20-sp-remote',
+        'shib13-idp-remote',
+        'shib13-sp-remote',
+        'attributeauthority-remote'
+    );
+
+
+    /**
+     * Constructor
+     *
+     * @param integer $expire
+     * @param string  $stateFile
+     * @param object  $oldMetadataSrc
+     */
+    public function __construct($expire = null, $stateFile = null, $oldMetadataSrc = null)
+    {
+        $this->expire = $expire;
+        $this->metadata = array();
+        $this->oldMetadataSrc = $oldMetadataSrc;
+        $this->stateFile = $stateFile;
+        $this->changed = false;
+
+        // Read file containing $state from disk
+        if (is_readable($stateFile)) {
+            include $stateFile;
+        }
+
+        $this->state = array();
+    }
+
+
+    /**
+     * Get the types of entities that will be loaded.
+     *
+     * @return array The entity types allowed.
+     */
+    public function getTypes()
+    {
+        return $this->types;
+    }
+
+
+    /**
+     * Set the types of entities that will be loaded.
+     *
+     * @param string|array $types Either a string with the name of one single type allowed, or an array with a list of
+     * types. Pass an empty array to reset to all types of entities.
+     */
+    public function setTypes($types)
+    {
+        if (!is_array($types)) {
+            $types = array($types);
+        }
+        $this->types = $types;
+    }
+
+
+    /**
+     * This function processes a SAML metadata file.
+     *
+     * @param $source
+     */
+    public function loadSource($source)
+    {
+        if (preg_match('@^https?://@i', $source['src'])) {
+            // Build new HTTP context
+            $context = $this->createContext($source);
+
+            // GET!
+            try {
+                list($data, $responseHeaders) = \SimpleSAML\Utils\HTTP::fetch($source['src'], $context, true);
+            } catch(\Exception $e) {
+                \SimpleSAML\Logger::warning('metarefresh: ' . $e->getMessage());
+            }
+
+            // We have response headers, so the request succeeded
+            if (!isset($responseHeaders)) {
+                // No response headers, this means the request failed in some way, so re-use old data
+                \SimpleSAML\Logger::debug('No response from ' . $source['src'] . ' - attempting to re-use cached metadata');
+                $this->addCachedMetadata($source);
+                return;
+            } elseif (preg_match('@^HTTP/1\.[01]\s304\s@', $responseHeaders[0])) {
+                // 304 response
+                \SimpleSAML\Logger::debug('Received HTTP 304 (Not Modified) - attempting to re-use cached metadata');
+                $this->addCachedMetadata($source);
+                return;
+            } elseif (!preg_match('@^HTTP/1\.[01]\s200\s@', $responseHeaders[0])) {
+                // Other error
+                \SimpleSAML\Logger::debug('Error from ' . $source['src'] . ' - attempting to re-use cached metadata');
+                $this->addCachedMetadata($source);
+                return;
+            }
+        } else {
+            // Local file.
+            $data = file_get_contents($source['src']);
+            $responseHeaders = null;
+        }
+
+        // Everything OK. Proceed.
+        if (isset($source['conditionalGET']) && $source['conditionalGET']) {
+            // Stale or no metadata, so a fresh copy
+            \SimpleSAML\Logger::debug('Downloaded fresh copy');
+        }
+
+        try {
+            $entities = $this->loadXML($data, $source);
+        } catch(\Exception $e) {
+            \SimpleSAML\Logger::debug('XML parser error when parsing ' . $source['src'] . ' - attempting to re-use cached metadata');
+            \SimpleSAML\Logger::debug('XML parser returned: ' . $e->getMessage());
+            $this->addCachedMetadata($source);
+            return;
+        }
+
+        foreach ($entities as $entity) {
+
+            if (isset($source['blacklist'])) {
+                if (!empty($source['blacklist']) && in_array($entity->getEntityID(), $source['blacklist'], true)) {
+                    \SimpleSAML\Logger::info('Skipping "' .  $entity->getEntityID() . '" - blacklisted.' . "\n");
+                    continue;
+                }
+            }
+
+            if (isset($source['whitelist'])) {
+                if (!empty($source['whitelist']) && !in_array($entity->getEntityID(), $source['whitelist'], true)) {
+                    \SimpleSAML\Logger::info('Skipping "' .  $entity->getEntityID() . '" - not in the whitelist.' . "\n");
+                    continue;
+                }
+            }
+
+            if (array_key_exists('certificates', $source) && $source['certificates'] !== null) {
+                if (!$entity->validateSignature($source['certificates'])) {
+                    \SimpleSAML\Logger::info('Skipping "' . $entity->getEntityId() . '" - could not verify signature using certificate.' . "\n");
+                    continue;
+                }
+            }
+
+            if (array_key_exists('validateFingerprint', $source) && $source['validateFingerprint'] !== null) {
+                if (!array_key_exists('certificates', $source) || $source['certificates'] == null) {
+                    if (!$entity->validateFingerprint($source['validateFingerprint'])) {
+                        \SimpleSAML\Logger::info('Skipping "' . $entity->getEntityId() . '" - could not verify signature using fingerprint.' . "\n");
+                        continue;
+                    }
+                } else {
+                    \SimpleSAML\Logger::info('Skipping validation with fingerprint since option certificate is set.' . "\n");
+                }
+            }
+
+            $template = null;
+            if (array_key_exists('template', $source)) {
+                $template = $source['template'];
+            }
+
+            if (in_array('shib13-sp-remote', $this->types, true)) {
+                $this->addMetadata($source['src'], $entity->getMetadata1xSP(), 'shib13-sp-remote', $template);
+            }
+            if (in_array('shib13-idp-remote', $this->types, true)) {
+                $this->addMetadata($source['src'], $entity->getMetadata1xIdP(), 'shib13-idp-remote', $template);
+            }
+            if (in_array('saml20-sp-remote', $this->types, true)) {
+                $this->addMetadata($source['src'], $entity->getMetadata20SP(), 'saml20-sp-remote', $template);
+            }
+            if (in_array('saml20-idp-remote', $this->types, true)) {
+                $this->addMetadata($source['src'], $entity->getMetadata20IdP(), 'saml20-idp-remote', $template);
+            }
+            if (in_array('attributeauthority-remote', $this->types, true)) {
+                $attributeAuthorities = $entity->getAttributeAuthorities();
+                if (!empty($attributeAuthorities)) {
+                     $this->addMetadata($source['src'], $attributeAuthorities[0], 'attributeauthority-remote', $template);
+                }
+            }
+        }
+
+        $this->saveState($source, $responseHeaders);
+    }
+
+    /**
+     * Create HTTP context, with any available caches taken into account
+     */
+    private function createContext($source)
+    {
+        $config = \SimpleSAML\Configuration::getInstance();
+        $name = $config->getString('technicalcontact_name', null);
+        $mail = $config->getString('technicalcontact_email', null);
+
+        $rawheader = "User-Agent: SimpleSAMLphp metarefresh, run by $name <$mail>\r\n";
+
+        if (isset($source['conditionalGET']) && $source['conditionalGET']) {
+            if (array_key_exists($source['src'], $this->state)) {
+                $sourceState = $this->state[$source['src']];
+
+                if (isset($sourceState['last-modified'])) {
+                    $rawheader .= 'If-Modified-Since: ' . $sourceState['last-modified'] . "\r\n";
+                }
+
+                if (isset($sourceState['etag'])) {
+                    $rawheader .= 'If-None-Match: ' . $sourceState['etag'] . "\r\n";
+                }
+            }
+        }
+
+        return array('http' => array('header' => $rawheader));
+    }
+
+
+    private function addCachedMetadata($source)
+    {
+        if (isset($this->oldMetadataSrc)) {
+            foreach ($this->types as $type) {
+                foreach ($this->oldMetadataSrc->getMetadataSet($type) as $entity) {
+                    if (array_key_exists('metarefresh:src', $entity)) {
+                        if ($entity['metarefresh:src'] == $source['src']) {
+                            $this->addMetadata($source['src'], $entity, $type);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Store caching state data for a source
+     */
+    private function saveState($source, $responseHeaders)
+    {
+        if (isset($source['conditionalGET']) && $source['conditionalGET']) {
+            // Headers section
+            if ($responseHeaders !== null) {
+                $candidates = array('last-modified', 'etag');
+
+                foreach ($candidates as $candidate) {
+                    if (array_key_exists($candidate, $responseHeaders)) {
+                        $this->state[$source['src']][$candidate] = $responseHeaders[$candidate];
+                    }
+                }
+            }
+
+            if (!empty($this->state[$source['src']])) {
+                // Timestamp when this src was requested.
+                $this->state[$source['src']]['requested_at'] = $this->getTime();
+                $this->changed = true;
+            }
+        }
+    }
+
+    /**
+     * Parse XML metadata and return entities
+     */
+    private function loadXML($data, $source)
+    {
+        try {
+            $doc = \SAML2\DOMDocumentFactory::fromString($data);
+        } catch (\Exception $e) {
+            throw new \Exception('Failed to read XML from ' . $source['src']);
+        }
+        if ($doc->documentElement === null) {
+            throw new \Exception('Opened file is not an XML document: ' . $source['src']);
+        }
+        return \SimpleSAML\Metadata\SAMLParser::parseDescriptorsElement($doc->documentElement);
+    }
+
+
+    /**
+     * This function writes the state array back to disk
+     */
+    public function writeState()
+    {
+        if ($this->changed) {
+            \SimpleSAML\Logger::debug('Writing: ' . $this->stateFile);
+            \SimpleSAML\Utils\System::writeFile(
+                $this->stateFile,
+                "<?php\n/* This file was generated by the metarefresh module at ".$this->getTime() . ".\n".
+                " Do not update it manually as it will get overwritten. */\n".
+                '$state = ' . var_export($this->state, true) . ";\n?>\n",
+                0644
+            );
+        }
+    }
+
+
+    /**
+     * This function writes the metadata to stdout.
+     */
+    public function dumpMetadataStdOut()
+    {
+        foreach ($this->metadata as $category => $elements) {
+
+            echo '/* The following data should be added to metadata/' . $category . '.php. */' . "\n";
+
+            foreach ($elements as $m) {
+                $filename = $m['filename'];
+                $entityID = $m['metadata']['entityid'];
+
+                echo "\n";
+                echo '/* The following metadata was generated from ' . $filename . ' on ' . $this->getTime() . '. */' . "\n";
+                echo '$metadata[\'' . addslashes($entityID) . '\'] = ' . var_export($m['metadata'], true) . ';' . "\n";
+            }
+
+            echo "\n";
+            echo '/* End of data which should be added to metadata/' . $category . '.php. */' . "\n";
+            echo "\n";
+        }
+    }
+
+
+    /**
+     * This function adds metadata from the specified file to the list of metadata.
+     * This function will return without making any changes if $metadata is NULL.
+     *
+     * @param string $filename The filename the metadata comes from.
+     * @param array  $metadata The metadata.
+     * @param string $type The metadata type.
+     */
+    private function addMetadata($filename, $metadata, $type, $template = null)
+    {
+        if ($metadata === null) {
+            return;
+        }
+
+        if (isset($template)) {
+            $metadata = array_merge($metadata, $template);
+        }
+
+        $metadata['metarefresh:src'] = $filename;
+        if (!array_key_exists($type, $this->metadata)) {
+            $this->metadata[$type] = array();
+        }
+
+        // If expire is defined in constructor...
+        if (!empty($this->expire)) {
+            // If expire is already in metadata
+            if (array_key_exists('expire', $metadata)) {
+                // Override metadata expire with more restrictive global config-
+                if ($this->expire < $metadata['expire']) {
+                    $metadata['expire'] = $this->expire;
+                }
+
+                // If expire is not already in metadata use global config
+            } else {
+                $metadata['expire'] = $this->expire;
+            }
+        }
+        $this->metadata[$type][] = array('filename' => $filename, 'metadata' => $metadata);
+    }
+
+
+    /**
+     * This function writes the metadata to an ARP file
+     */
+    public function writeARPfile($config)
+    {
+        assert($config instanceof \SimpleSAML\Configuration);
+
+        $arpfile = $config->getValue('arpfile');
+        $types = array('saml20-sp-remote');
+
+        $md = array();
+        foreach ($this->metadata as $category => $elements) {
+            if (!in_array($category, $types, true)) {
+                continue;
+            }
+            $md = array_merge($md, $elements);
+        }
+
+        // $metadata, $attributemap, $prefix, $suffix
+        $arp = new \SimpleSAML\Module\metarefresh\ARP($md,
+            $config->getValue('attributemap', ''),
+            $config->getValue('prefix', ''),
+            $config->getValue('suffix', '')
+        );
+
+
+        $arpxml = $arp->getXML();
+
+        \SimpleSAML\Logger::info('Writing ARP file: ' . $arpfile . "\n");
+        file_put_contents($arpfile, $arpxml);
+    }
+
+
+    /**
+     * This function writes the metadata to to separate files in the output directory.
+     */
+    public function writeMetadataFiles($outputDir)
+    {
+        while (strlen($outputDir) > 0 && $outputDir[strlen($outputDir) - 1] === '/') {
+            $outputDir = substr($outputDir, 0, strlen($outputDir) - 1);
+        }
+
+        if (!file_exists($outputDir)) {
+            \SimpleSAML\Logger::info('Creating directory: ' . $outputDir . "\n");
+            $res = @mkdir($outputDir, 0777, true);
+            if ($res === false) {
+                throw new \Exception('Error creating directory: ' . $outputDir);
+            }
+        }
+
+        foreach ($this->types as $type) {
+            $filename = $outputDir . '/' . $type . '.php';
+
+            if (array_key_exists($type, $this->metadata)) {
+                $elements = $this->metadata[$type];
+                \SimpleSAML\Logger::debug('Writing: ' . $filename);
+
+                $content  = '<?php' . "\n" . '/* This file was generated by the metarefresh module at '. $this->getTime() . "\n";
+                $content .= ' Do not update it manually as it will get overwritten' . "\n" . '*/' . "\n";
+
+                foreach ($elements as $m) {
+                    $entityID = $m['metadata']['entityid'];
+                    $content .= "\n";
+                    $content .= '$metadata[\'' . addslashes($entityID) . '\'] = ' . var_export($m['metadata'], true) . ';' . "\n";
+                }
+
+                $content .= "\n" . '?>';
+
+                \SimpleSAML\Utils\System::writeFile($filename, $content, 0644);
+            } elseif (is_file($filename)) {
+                if (unlink($filename)) {
+                    \SimpleSAML\Logger::debug('Deleting stale metadata file: ' . $filename);
+                } else {
+                    \SimpleSAML\Logger::warning('Could not delete stale metadata file: ' . $filename);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Save metadata for loading with the 'serialize' metadata loader.
+     *
+     * @param string $outputDir  The directory we should save the metadata to.
+     */
+    public function writeMetadataSerialize($outputDir)
+    {
+        assert(is_string($outputDir));
+
+        $metaHandler = new \SimpleSAML\Metadata\MetaDataStorageHandlerSerialize(array('directory' => $outputDir));
+
+        /* First we add all the metadata entries to the metadata handler. */
+        foreach ($this->metadata as $set => $elements) {
+            foreach ($elements as $m) {
+                $entityId = $m['metadata']['entityid'];
+
+                \SimpleSAML\Logger::debug(
+                    'metarefresh: Add metadata entry ' .
+                    var_export($entityId, true) . ' in set ' . var_export($set, true) . '.'
+                );
+                $metaHandler->saveMetadata($entityId, $set, $m['metadata']);
+            }
+        }
+
+        /* Then we delete old entries which should no longer exist. */
+        $ct = time();
+        foreach ($metaHandler->getMetadataSets() as $set) {
+            foreach ($metaHandler->getMetadataSet($set) as $entityId => $metadata) {
+                if (!array_key_exists('expire', $metadata)) {
+                    \SimpleSAML\Logger::warning(
+                        'metarefresh: Metadata entry without expire timestamp: ' . var_export($entityId, true) .
+                        ' in set ' . var_export($set, true) . '.'
+                    );
+                    continue;
+                }
+                if ($metadata['expire'] > $ct) {
+                    continue;
+                }
+                \SimpleSAML\Logger::debug('metarefresh: ' . $entityId . ' expired ' . date('l jS \of F Y h:i:s A', $metadata['expire']));
+                \SimpleSAML\Logger::debug(
+                    'metarefresh: Delete expired metadata entry ' .
+                    var_export($entityId, true) . ' in set ' . var_export($set, true) . '. (' . ($ct - $metadata['expire']) . ' sec)'
+                );
+                $metaHandler->deleteMetadata($entityId, $set);
+            }
+        }
+    }
+
+
+    private function getTime()
+    {
+        /* The current date, as a string. */
+        date_default_timezone_set('UTC');
+        return date('Y-m-d\\TH:i:s\\Z');
+    }
 }
diff --git a/modules/metarefresh/templates/fetch.tpl.php b/modules/metarefresh/templates/fetch.tpl.php
index 512f6f429f3cc6b937ee5e38a062ca66d61d98da..780e98c894c86ca40c45cbddb8c8878c255ce83a 100644
--- a/modules/metarefresh/templates/fetch.tpl.php
+++ b/modules/metarefresh/templates/fetch.tpl.php
@@ -1,20 +1,20 @@
 <?php
-$this->data['header'] = $this->t('{aggregator:aggregator:aggregator_header}');
+$this->data['header'] = $this->t('{metarefresh:metarefresh:metarefresh_header}');
 $this->includeAtTemplateBase('includes/header.php');
 
-echo('<h1>Metarefresh fetch</h1>');
+echo('<h1>'.$this->data['header'].'</h1>');
 
 
 if (!empty($this->data['logentries'])) {
-	
+
 	echo '<pre style="border: 1px solid #aaa; padding: .5em; overflow: scroll">';
 	foreach($this->data['logentries'] AS $l) {
-		echo $l . "\n";		
+		echo $l . "\n";
 	}
 	echo '</pre>';
-	
+
 } else {
-	echo 'No output from metarefresh.';
+	echo $this->t('{metarefresh:metarefresh:no_output}');
 }
 
 
diff --git a/modules/metarefresh/www/fetch.php b/modules/metarefresh/www/fetch.php
index 097fb85c062ddb8aa42d6113e65b12d850bd7e9d..8c3120b2d4f1b6645b233c00acb37938f9ec56ee 100644
--- a/modules/metarefresh/www/fetch.php
+++ b/modules/metarefresh/www/fetch.php
@@ -1,22 +1,20 @@
 <?php
 
-$config = SimpleSAML_Configuration::getInstance();
-$mconfig = SimpleSAML_Configuration::getOptionalConfig('config-metarefresh.php');
+$config = \SimpleSAML\Configuration::getInstance();
+$mconfig = \SimpleSAML\Configuration::getOptionalConfig('config-metarefresh.php');
 
-SimpleSAML\Utils\Auth::requireAdmin();
+\SimpleSAML\Utils\Auth::requireAdmin();
 
-SimpleSAML\Logger::setCaptureLog(TRUE);
+\SimpleSAML\Logger::setCaptureLog(TRUE);
 
 
 $sets = $mconfig->getConfigList('sets', array());
 
 foreach ($sets AS $setkey => $set) {
 
-	SimpleSAML\Logger::info('[metarefresh]: Executing set [' . $setkey . ']');
+	\SimpleSAML\Logger::info('[metarefresh]: Executing set [' . $setkey . ']');
 
 	try {
-		
-
 		$expireAfter = $set->getInteger('expireAfter', NULL);
 		if ($expireAfter !== NULL) {
 			$expire = time() + $expireAfter;
@@ -24,7 +22,7 @@ foreach ($sets AS $setkey => $set) {
 			$expire = NULL;
 		}
 
-		$metaloader = new sspmod_metarefresh_MetaLoader($expire);
+		$metaloader = new \SimpleSAML\Module\metarefresh\MetaLoader($expire);
 
 		# Get global black/whitelists
 		$blacklist = $mconfig->getArray('blacklist', array());
@@ -63,7 +61,7 @@ foreach ($sets AS $setkey => $set) {
 				$source['whitelist'] = $whitelist;
 			}
 
-			SimpleSAML\Logger::debug('[metarefresh]: In set [' . $setkey . '] loading source ['  . $source['src'] . ']');
+			\SimpleSAML\Logger::debug('[metarefresh]: In set [' . $setkey . '] loading source ['  . $source['src'] . ']');
 			$metaloader->loadSource($source);
 		}
 
@@ -79,16 +77,14 @@ foreach ($sets AS $setkey => $set) {
 				$metaloader->writeMetadataSerialize($outputDir);
 				break;
 		}
-	} catch (Exception $e) {
-		$e = SimpleSAML_Error_Exception::fromException($e);
+	} catch (\Exception $e) {
+		$e = \SimpleSAML\Error\Exception::fromException($e);
 		$e->logWarning();
 	}
-	
-
 }
 
-$logentries = SimpleSAML\Logger::getCapturedLog();
+$logentries = \SimpleSAML\Logger::getCapturedLog();
 
-$t = new SimpleSAML_XHTML_Template($config, 'metarefresh:fetch.tpl.php');
+$t = new \SimpleSAML\XHTML\Template($config, 'metarefresh:fetch.tpl.php');
 $t->data['logentries'] = $logentries;
-$t->show();
\ No newline at end of file
+$t->show();
diff --git a/modules/multiauth/lib/Auth/Source/MultiAuth.php b/modules/multiauth/lib/Auth/Source/MultiAuth.php
index 56960f154c6f0705e14ebf57c9c6330fc706531a..6714560e281eeff71158900e27e2f6d0b52215f6 100644
--- a/modules/multiauth/lib/Auth/Source/MultiAuth.php
+++ b/modules/multiauth/lib/Auth/Source/MultiAuth.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\multiauth\Auth\Source;
+
 /**
  * Authentication source which let the user chooses among a list of
  * other authentication sources
@@ -8,22 +10,22 @@
  * @package SimpleSAMLphp
  */
 
-class sspmod_multiauth_Auth_Source_MultiAuth extends SimpleSAML_Auth_Source {
-
+class MultiAuth extends \SimpleSAML\Auth\Source
+{
 	/**
 	 * The key of the AuthId field in the state.
 	 */
-	const AUTHID = 'sspmod_multiauth_Auth_Source_MultiAuth.AuthId';
+	const AUTHID = '\SimpleSAML\Module\multiauth\Auth\Source\MultiAuth.AuthId';
 
 	/**
 	 * The string used to identify our states.
 	 */
-	const STAGEID = 'sspmod_multiauth_Auth_Source_MultiAuth.StageId';
+	const STAGEID = '\SimpleSAML\Module\multiauth\Auth\Source\MultiAuth.StageId';
 
 	/**
 	 * The key where the sources is saved in the state.
 	 */
-	const SOURCESID = 'sspmod_multiauth_Auth_Source_MultiAuth.SourceId';
+	const SOURCESID = '\SimpleSAML\Module\multiauth\Auth\Source\MultiAuth.SourceId';
 
 	/**
 	 * The key where the selected source is saved in the session.
@@ -49,12 +51,12 @@ class sspmod_multiauth_Auth_Source_MultiAuth extends SimpleSAML_Auth_Source {
 		parent::__construct($info, $config);
 
 		if (!array_key_exists('sources', $config)) {
-			throw new Exception('The required "sources" config option was not found');
+			throw new \Exception('The required "sources" config option was not found');
 		}
 
-		$globalConfiguration = SimpleSAML_Configuration::getInstance();
+		$globalConfiguration = \SimpleSAML\Configuration::getInstance();
 		$defaultLanguage = $globalConfiguration->getString('language.default', 'en');
-		$authsources = SimpleSAML_Configuration::getConfig('authsources.php');
+		$authsources = \SimpleSAML\Configuration::getConfig('authsources.php');
 		$this->sources = array();
 		foreach($config['sources'] as $source => $info) {
 
@@ -112,11 +114,11 @@ class sspmod_multiauth_Auth_Source_MultiAuth extends SimpleSAML_Auth_Source {
 		$state[self::SOURCESID] = $this->sources;
 
 		/* Save the $state array, so that we can restore if after a redirect */
-		$id = SimpleSAML_Auth_State::saveState($state, self::STAGEID);
+		$id = \SimpleSAML\Auth\State::saveState($state, self::STAGEID);
 
 		/* Redirect to the select source page. We include the identifier of the
 		saved state array as a parameter to the login form */
-		$url = SimpleSAML\Module::getModuleURL('multiauth/selectsource.php');
+		$url = \SimpleSAML\Module::getModuleURL('multiauth/selectsource.php');
 		$params = array('AuthState' => $id);
 
 		// Allowes the user to specify the auth souce to be used
@@ -146,7 +148,7 @@ class sspmod_multiauth_Auth_Source_MultiAuth extends SimpleSAML_Auth_Source {
 		assert(is_string($authId));
 		assert(is_array($state));
 
-		$as = SimpleSAML_Auth_Source::getById($authId);
+		$as = \SimpleSAML\Auth\Source::getById($authId);
 		$valid_sources = array_map(
 			function($src) {
 				return $src['source'];
@@ -154,22 +156,22 @@ class sspmod_multiauth_Auth_Source_MultiAuth extends SimpleSAML_Auth_Source {
 			$state[self::SOURCESID]
         );
 		if ($as === NULL || !in_array($authId, $valid_sources, true)) {
-			throw new Exception('Invalid authentication source: ' . $authId);
+			throw new \Exception('Invalid authentication source: ' . $authId);
 		}
 
 		/* Save the selected authentication source for the logout process. */
-		$session = SimpleSAML_Session::getSessionFromRequest();
-		$session->setData(self::SESSION_SOURCE, $state[self::AUTHID], $authId, SimpleSAML_Session::DATA_TIMEOUT_SESSION_END);
+		$session = \SimpleSAML\Session::getSessionFromRequest();
+		$session->setData(self::SESSION_SOURCE, $state[self::AUTHID], $authId, \SimpleSAML\Session::DATA_TIMEOUT_SESSION_END);
 
 		try {
 			$as->authenticate($state);
-		} catch (SimpleSAML_Error_Exception $e) {
-			SimpleSAML_Auth_State::throwException($state, $e);
-		} catch (Exception $e) {
-			$e = new SimpleSAML_Error_UnserializableException($e);
-			SimpleSAML_Auth_State::throwException($state, $e);
+		} catch (\SimpleSAML\Error\Exception $e) {
+			\SimpleSAML\Auth\State::throwException($state, $e);
+		} catch (\Exception $e) {
+			$e = new \SimpleSAML\Error\UnserializableException($e);
+			\SimpleSAML\Auth\State::throwException($state, $e);
 		}
-		SimpleSAML_Auth_Source::completeAuth($state);
+		\SimpleSAML\Auth\Source::completeAuth($state);
 	}
 
 	/**
@@ -184,12 +186,12 @@ class sspmod_multiauth_Auth_Source_MultiAuth extends SimpleSAML_Auth_Source {
 		assert(is_array($state));
 
 		/* Get the source that was used to authenticate */
-		$session = SimpleSAML_Session::getSessionFromRequest();
+		$session = \SimpleSAML\Session::getSessionFromRequest();
 		$authId = $session->getData(self::SESSION_SOURCE, $this->authId);
 
-		$source = SimpleSAML_Auth_Source::getById($authId);
+		$source = \SimpleSAML\Auth\Source::getById($authId);
 		if ($source === NULL) {
-			throw new Exception('Invalid authentication source during logout: ' . $source);
+			throw new \Exception('Invalid authentication source during logout: ' . $source);
 		}
 		/* Then, do the logout on it */
 		$source->logout($state);
@@ -208,7 +210,7 @@ class sspmod_multiauth_Auth_Source_MultiAuth extends SimpleSAML_Auth_Source {
 
 		$cookieName = 'multiauth_source_' . $this->authId;
 
-		$config = SimpleSAML_Configuration::getInstance();
+		$config = \SimpleSAML\Configuration::getInstance();
 		$params = array(
 			/* We save the cookies for 90 days. */
 			'lifetime' => (60*60*24*90),
diff --git a/modules/multiauth/www/selectsource.php b/modules/multiauth/www/selectsource.php
index af8c454e7a5b936d388cf9ce01b24ab553b5d40d..93faebdfaf4e0277f079e92b290de08a12ed3358 100644
--- a/modules/multiauth/www/selectsource.php
+++ b/modules/multiauth/www/selectsource.php
@@ -3,7 +3,7 @@
 /**
  * This page shows a list of authentication sources. When the user selects
  * one of them if pass this information to the
- * sspmod_multiauth_Auth_Source_MultiAuth class and call the
+ * \SimpleSAML\Module\multiauth\Auth\Source\MultiAuth class and call the
  * delegateAuthentication method on it.
  *
  * @author Lorenzo Gil, Yaco Sistemas S.L.
@@ -12,13 +12,14 @@
 
 // Retrieve the authentication state
 if (!array_key_exists('AuthState', $_REQUEST)) {
-    throw new SimpleSAML_Error_BadRequest('Missing AuthState parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing AuthState parameter.');
 }
 $authStateId = $_REQUEST['AuthState'];
-$state = SimpleSAML_Auth_State::loadState($authStateId, sspmod_multiauth_Auth_Source_MultiAuth::STAGEID);
-if (array_key_exists("SimpleSAML_Auth_Source.id", $state)) {
-    $authId = $state["SimpleSAML_Auth_Source.id"];
-    $as = SimpleSAML_Auth_Source::getById($authId);
+$state = \SimpleSAML\Auth\State::loadState($authStateId, \SimpleSAML\Module\multiauth\Auth\Source\MultiAuth::STAGEID);
+
+if (array_key_exists("\SimpleSAML\Auth\Source.id", $state)) {
+    $authId = $state["\SimpleSAML\Auth\Source.id"];
+    $as = \SimpleSAML\Auth\Source::getById($authId);
 } else {
     $as = null;
 }
@@ -38,21 +39,21 @@ if ($source !== null) {
     if ($as !== null) {
         $as->setPreviousSource($source);
     }
-    sspmod_multiauth_Auth_Source_MultiAuth::delegateAuthentication($source, $state);
+    \SimpleSAML\Module\multiauth\Auth\Source\MultiAuth::delegateAuthentication($source, $state);
 }
 
 if (array_key_exists('multiauth:preselect', $state)) {
     $source = $state['multiauth:preselect'];
-    sspmod_multiauth_Auth_Source_MultiAuth::delegateAuthentication($source, $state);
+    \SimpleSAML\Module\multiauth\Auth\Source\MultiAuth::delegateAuthentication($source, $state);
 }
 
-$globalConfig = SimpleSAML_Configuration::getInstance();
-$t = new SimpleSAML_XHTML_Template($globalConfig, 'multiauth:selectsource.php');
+$globalConfig = \SimpleSAML\Configuration::getInstance();
+$t = new \SimpleSAML\XHTML\Template($globalConfig, 'multiauth:selectsource.php');
 
 $defaultLanguage = $globalConfig->getString('language.default', 'en');
 $language = $t->getLanguage();
 
-$sources = $state[sspmod_multiauth_Auth_Source_MultiAuth::SOURCESID];
+$sources = $state[\SimpleSAML\Module\multiauth\Auth\Source\MultiAuth::SOURCESID];
 foreach ($sources as $key => $source){
     $sources[$key]['source64'] = base64_encode($sources[$key]['source']);
     $sources[$key]['text'] = (isSet($sources[$key]['text'][$language]) ? $sources[$key]['text'][$language] : $sources[$key]['text'][$defaultLanguage]);
diff --git a/modules/negotiate/docs/negotiate.md b/modules/negotiate/docs/negotiate.md
index a57044de9bb5f059a1c0767b5751c5c29f95c7b4..3a3dd76f0f81bce8e0313cc0e2288fb737f47026 100644
--- a/modules/negotiate/docs/negotiate.md
+++ b/modules/negotiate/docs/negotiate.md
@@ -196,23 +196,23 @@ One can add this bit of code to the template in the fallback AuthN
 module:
 
 // This should be placed in your www script
-$nego_session = FALSE;
-$nego_perm = FALSE;
-$nego_retry = NULL;
+$nego_session = false;
+$nego_perm = false;
+$nego_retry = null;
 if (array_key_exists('negotiate:authId', $state)) {
-    $nego = SimpleSAML_Auth_Source::getById($state['negotiate:authId']);
+    $nego = \SimpleSAML\Auth\Source::getById($state['negotiate:authId']);
     $mask = $nego->checkMask();
     $disabled = $nego->spDisabledInMetadata($spMetadata);
     $session_disabled = $session->getData('negotiate:disable', 'session');
     if ($mask and !$disabled) {
         if(array_key_exists('NEGOTIATE_AUTOLOGIN_DISABLE_PERMANENT', $_COOKIE) &&
            $_COOKIE['NEGOTIATE_AUTOLOGIN_DISABLE_PERMANENT'] == 'True') {
-            $nego_perm = TRUE;
+            $nego_perm = true;
         } elseif ($session_disabled) {
-            $retryState = SimpleSAML_Auth_State::cloneState($state);
-            unset($retryState[SimpleSAML_Auth_State::ID]);
-            $nego_retry = SimpleSAML_Auth_State::saveState($retryState, 'sspmod_negotiate_Auth_Source_Negotiate.StageId');
-            $nego_session = TRUE;
+            $retryState = \SimpleSAML\Auth\State::cloneState($state);
+            unset($retryState[\SimpleSAML\Auth\State::ID]);
+            $nego_retry = \SimpleSAML\Auth\State::saveState($retryState, '\SimpleSAML\Module\negotiate\Auth\Source\Negotiate.StageId');
+            $nego_session = true;
         }
     }
 }
@@ -247,7 +247,7 @@ security check in SSP's state handling library. If you omit this and
 pass on the original state you will see a warning in the log like
 this:
 
-    Sep 27 13:47:36 simplesamlphp WARNING [b99e6131ee] Wrong stage in state. Was 'foo', should be 'sspmod_negotiate_Auth_Source_Negotiate.StageId'.
+    Sep 27 13:47:36 simplesamlphp WARNING [b99e6131ee] Wrong stage in state. Was 'foo', should be '\SimpleSAML\Module\negotiate\Auth\Source\Negotiate.StageId'.
 
 It will work as loadState will take controll and call
 Negotiate->authenticate() but remaining code in retry.php will be
diff --git a/modules/negotiate/lib/Auth/Source/Negotiate.php b/modules/negotiate/lib/Auth/Source/Negotiate.php
index 85d5187c84006b6a2251fbabf513df5b91572a98..ed9b8c5e81adfe5b4dbbd04d8621fb0bf3a8daf9 100644
--- a/modules/negotiate/lib/Auth/Source/Negotiate.php
+++ b/modules/negotiate/lib/Auth/Source/Negotiate.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML\Module\negotiate\Auth\Source;
 
 /**
  * The Negotiate module. Allows for password-less, secure login by Kerberos and Negotiate.
@@ -7,11 +8,11 @@
  * @author Mathias Meisfjordskar, University of Oslo <mathias.meisfjordskar@usit.uio.no>
  * @package SimpleSAMLphp
  */
-class sspmod_negotiate_Auth_Source_Negotiate extends SimpleSAML_Auth_Source
-{
 
+class Negotiate extends \SimpleSAML\Auth\Source
+{
     // Constants used in the module
-    const STAGEID = 'sspmod_negotiate_Auth_Source_Negotiate.StageId';
+    const STAGEID = '\SimpleSAML\Module\negotiate\Auth\Source\Negotiate.StageId';
 
     protected $ldap = null;
     protected $backend = '';
@@ -44,13 +45,13 @@ class sspmod_negotiate_Auth_Source_Negotiate extends SimpleSAML_Auth_Source
         assert(is_array($config));
 
         if (!extension_loaded('krb5')) {
-            throw new Exception('KRB5 Extension not installed');
+            throw new \Exception('KRB5 Extension not installed');
         }
 
         // call the parent constructor first, as required by the interface
         parent::__construct($info, $config);
 
-        $config = SimpleSAML_Configuration::loadFromArray($config);
+        $config = \SimpleSAML\Configuration::loadFromArray($config);
 
         $this->backend = $config->getString('fallback');
         $this->hostname = $config->getString('hostname');
@@ -97,14 +98,14 @@ class sspmod_negotiate_Auth_Source_Negotiate extends SimpleSAML_Auth_Source
         }
         /* Go straight to fallback if Negotiate is disabled or if you are sent back to the IdP directly from the SP
         after having logged out. */
-        $session = SimpleSAML_Session::getSessionFromRequest();
+        $session = \SimpleSAML\Session::getSessionFromRequest();
         $disabled = $session->getData('negotiate:disable', 'session');
 
         if ($disabled ||
             (!empty($_COOKIE['NEGOTIATE_AUTOLOGIN_DISABLE_PERMANENT']) &&
                 $_COOKIE['NEGOTIATE_AUTOLOGIN_DISABLE_PERMANENT'] == 'True')
         ) {
-            SimpleSAML\Logger::debug('Negotiate - session disabled. falling back');
+            \SimpleSAML\Logger::debug('Negotiate - session disabled. falling back');
             $this->fallBack($state);
             // never executed
             assert(false);
@@ -116,10 +117,10 @@ class sspmod_negotiate_Auth_Source_Negotiate extends SimpleSAML_Auth_Source
             assert(false);
         }
 
-        SimpleSAML\Logger::debug('Negotiate - authenticate(): looking for Negotiate');
+        \SimpleSAML\Logger::debug('Negotiate - authenticate(): looking for Negotiate');
         if (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
-            SimpleSAML\Logger::debug('Negotiate - authenticate(): Negotiate found');
-            $this->ldap = new SimpleSAML_Auth_LDAP(
+            \SimpleSAML\Logger::debug('Negotiate - authenticate(): Negotiate found');
+            $this->ldap = new \SimpleSAML\Auth\LDAP(
                 $this->hostname,
                 $this->enableTLS,
                 $this->debugLDAP,
@@ -128,28 +129,28 @@ class sspmod_negotiate_Auth_Source_Negotiate extends SimpleSAML_Auth_Source
                 $this->referrals
             );
 
-            list($mech, $data) = explode(' ', $_SERVER['HTTP_AUTHORIZATION'], 2);
+            list($mech,) = explode(' ', $_SERVER['HTTP_AUTHORIZATION'], 2);
             if (strtolower($mech) == 'basic') {
-                SimpleSAML\Logger::debug('Negotiate - authenticate(): Basic found. Skipping.');
+                \SimpleSAML\Logger::debug('Negotiate - authenticate(): Basic found. Skipping.');
             } else {
                 if (strtolower($mech) != 'negotiate') {
-                    SimpleSAML\Logger::debug('Negotiate - authenticate(): No "Negotiate" found. Skipping.');
+                    \SimpleSAML\Logger::debug('Negotiate - authenticate(): No "Negotiate" found. Skipping.');
                 }
             }
 
-            $auth = new KRB5NegotiateAuth($this->keytab);
+            $auth = new \KRB5NegotiateAuth($this->keytab);
             // attempt Kerberos authentication
             try {
                 $reply = $auth->doAuthentication();
-            } catch (Exception $e) {
-                SimpleSAML\Logger::error('Negotiate - authenticate(): doAuthentication() exception: '.$e->getMessage());
+            } catch (\Exception $e) {
+                \SimpleSAML\Logger::error('Negotiate - authenticate(): doAuthentication() exception: '.$e->getMessage());
                 $reply = null;
             }
 
             if ($reply) {
                 // success! krb TGS received
                 $user = $auth->getAuthenticatedUser();
-                SimpleSAML\Logger::info('Negotiate - authenticate(): '.$user.' authenticated.');
+                \SimpleSAML\Logger::info('Negotiate - authenticate(): '.$user.' authenticated.');
                 $lookup = $this->lookupUserData($user);
                 if ($lookup !== null) {
                     $state['Attributes'] = $lookup;
@@ -157,28 +158,28 @@ class sspmod_negotiate_Auth_Source_Negotiate extends SimpleSAML_Auth_Source
                     $state['LogoutState'] = array(
                         'negotiate:backend' => null,
                     );
-                    SimpleSAML\Logger::info('Negotiate - authenticate(): '.$user.' authorized.');
-                    SimpleSAML_Auth_Source::completeAuth($state);
+                    \SimpleSAML\Logger::info('Negotiate - authenticate(): '.$user.' authorized.');
+                    \SimpleSAML\Auth\Source::completeAuth($state);
                     // Never reached.
                     assert(false);
                 }
             } else {
                 // Some error in the received ticket. Expired?
-                SimpleSAML\Logger::info('Negotiate - authenticate(): Kerberos authN failed. Skipping.');
+                \SimpleSAML\Logger::info('Negotiate - authenticate(): Kerberos authN failed. Skipping.');
             }
         } else {
             // No auth token. Send it.
-            SimpleSAML\Logger::debug('Negotiate - authenticate(): Sending Negotiate.');
+            \SimpleSAML\Logger::debug('Negotiate - authenticate(): Sending Negotiate.');
             // Save the $state array, so that we can restore if after a redirect
-            SimpleSAML\Logger::debug('Negotiate - fallback: '.$state['LogoutState']['negotiate:backend']);
-            $id = SimpleSAML_Auth_State::saveState($state, self::STAGEID);
+            \SimpleSAML\Logger::debug('Negotiate - fallback: '.$state['LogoutState']['negotiate:backend']);
+            $id = \SimpleSAML\Auth\State::saveState($state, self::STAGEID);
             $params = array('AuthState' => $id);
 
             $this->sendNegotiate($params);
             exit;
         }
 
-        SimpleSAML\Logger::info('Negotiate - authenticate(): Client failed Negotiate. Falling back');
+        \SimpleSAML\Logger::info('Negotiate - authenticate(): Client failed Negotiate. Falling back');
         $this->fallBack($state);
         /* The previous function never returns, so this code is never
            executed */
@@ -190,13 +191,13 @@ class sspmod_negotiate_Auth_Source_Negotiate extends SimpleSAML_Auth_Source
     {
         if (array_key_exists('negotiate:disable', $spMetadata)) {
             if ($spMetadata['negotiate:disable'] == true) {
-                SimpleSAML\Logger::debug('Negotiate - SP disabled. falling back');
+                \SimpleSAML\Logger::debug('Negotiate - SP disabled. falling back');
                 return true;
             } else {
-                SimpleSAML\Logger::debug('Negotiate - SP disable flag found but set to FALSE');
+                \SimpleSAML\Logger::debug('Negotiate - SP disable flag found but set to FALSE');
             }
         } else {
-            SimpleSAML\Logger::debug('Negotiate - SP disable flag not found');
+            \SimpleSAML\Logger::debug('Negotiate - SP disable flag not found');
         }
         return false;
     }
@@ -218,13 +219,13 @@ class sspmod_negotiate_Auth_Source_Negotiate extends SimpleSAML_Auth_Source
         }
         $ip = $_SERVER['REMOTE_ADDR'];
         foreach ($this->subnet as $cidr) {
-            $ret = SimpleSAML\Utils\Net::ipCIDRcheck($cidr);
+            $ret = \SimpleSAML\Utils\Net::ipCIDRcheck($cidr);
             if ($ret) {
-                SimpleSAML\Logger::debug('Negotiate: Client "'.$ip.'" matched subnet.');
+                \SimpleSAML\Logger::debug('Negotiate: Client "'.$ip.'" matched subnet.');
                 return true;
             }
         }
-        SimpleSAML\Logger::debug('Negotiate: Client "'.$ip.'" did not match subnet.');
+        \SimpleSAML\Logger::debug('Negotiate: Client "'.$ip.'" did not match subnet.');
         return false;
     }
 
@@ -237,7 +238,7 @@ class sspmod_negotiate_Auth_Source_Negotiate extends SimpleSAML_Auth_Source
      */
     protected function sendNegotiate($params)
     {
-        $url = htmlspecialchars(SimpleSAML\Module::getModuleURL('negotiate/backend.php', $params));
+        $url = htmlspecialchars(\SimpleSAML\Module::getModuleURL('negotiate/backend.php', $params));
         $json_url = json_encode($url);
 
         header('HTTP/1.1 401 Unauthorized');
@@ -259,31 +260,31 @@ EOF;
     /**
      * Passes control of the login process to a different module.
      *
-     * @param string $state Information about the current authentication.
+     * @param array $state Information about the current authentication.
      *
-     * @throws SimpleSAML_Error_Error If couldn't determine the auth source.
-     * @throws SimpleSAML_Error_Exception
-     * @throws Exception
+     * @throws \SimpleSAML\Error\Error If couldn't determine the auth source.
+     * @throws \SimpleSAML\Error\Exception
+     * @throws \Exception
      */
     public static function fallBack(&$state)
     {
         $authId = $state['LogoutState']['negotiate:backend'];
 
         if ($authId === null) {
-            throw new SimpleSAML_Error_Error(500, "Unable to determine auth source.");
+            throw new \SimpleSAML\Error\Error(array(500, "Unable to determine auth source."));
         }
-        $source = SimpleSAML_Auth_Source::getById($authId);
+        $source = \SimpleSAML\Auth\Source::getById($authId);
 
         try {
             $source->authenticate($state);
-        } catch (SimpleSAML_Error_Exception $e) {
-            SimpleSAML_Auth_State::throwException($state, $e);
-        } catch (Exception $e) {
-            $e = new SimpleSAML_Error_UnserializableException($e);
-            SimpleSAML_Auth_State::throwException($state, $e);
+        } catch (\SimpleSAML\Error\Exception $e) {
+            \SimpleSAML\Auth\State::throwException($state, $e);
+        } catch (\Exception $e) {
+            $e = new \SimpleSAML\Error\UnserializableException($e);
+            \SimpleSAML\Auth\State::throwException($state, $e);
         }
         // fallBack never returns after loginCompleted()
-        SimpleSAML\Logger::debug('Negotiate: backend returned');
+        \SimpleSAML\Logger::debug('Negotiate: backend returned');
         self::loginCompleted($state);
     }
 
@@ -309,8 +310,8 @@ EOF;
         try {
             $dn = $this->ldap->searchfordn($this->base, $this->attr, $uid);
             return $this->ldap->getAttributes($dn, $this->attributes);
-        } catch (SimpleSAML_Error_Exception $e) {
-            SimpleSAML\Logger::debug('Negotiate - ldap lookup failed: '.$e);
+        } catch (\SimpleSAML\Error\Exception $e) {
+            \SimpleSAML\Logger::debug('Negotiate - ldap lookup failed: '.$e);
             return null;
         }
     }
@@ -326,14 +327,14 @@ EOF;
             // no admin user
             return;
         }
-        SimpleSAML\Logger::debug(
+        \SimpleSAML\Logger::debug(
             'Negotiate - authenticate(): Binding as system user '.var_export($this->admin_user, true)
         );
 
         if (!$this->ldap->bind($this->admin_user, $this->admin_pw)) {
             $msg = 'Unable to authenticate system user (LDAP_INVALID_CREDENTIALS) '.var_export($this->admin_user, true);
-            SimpleSAML\Logger::error('Negotiate - authenticate(): '.$msg);
-            throw new SimpleSAML_Error_AuthSource('negotiate', $msg);
+            \SimpleSAML\Logger::error('Negotiate - authenticate(): '.$msg);
+            throw new \SimpleSAML\Error\AuthSource('negotiate', $msg);
         }
     }
 
@@ -351,14 +352,14 @@ EOF;
         assert(is_array($state));
         // get the source that was used to authenticate
         $authId = $state['negotiate:backend'];
-        SimpleSAML\Logger::debug('Negotiate - logout has the following authId: "'.$authId.'"');
+        \SimpleSAML\Logger::debug('Negotiate - logout has the following authId: "'.$authId.'"');
 
         if ($authId === null) {
-            $session = SimpleSAML_Session::getSessionFromRequest();
+            $session = \SimpleSAML\Session::getSessionFromRequest();
             $session->setData('negotiate:disable', 'session', true, 24 * 60 * 60);
             parent::logout($state);
         } else {
-            $source = SimpleSAML_Auth_Source::getById($authId);
+            $source = \SimpleSAML\Auth\Source::getById($authId);
             $source->logout($state);
         }
     }
diff --git a/modules/negotiate/www/backend.php b/modules/negotiate/www/backend.php
index 5fa2619a4f160044026be82006777f31198a2373..07550c9e07337cc1d9cc2aef6bfd5c0aa47f0bdc 100644
--- a/modules/negotiate/www/backend.php
+++ b/modules/negotiate/www/backend.php
@@ -8,9 +8,9 @@
  * @package SimpleSAMLphp
  */
 
-$state = SimpleSAML_Auth_State::loadState($_REQUEST['AuthState'], sspmod_negotiate_Auth_Source_Negotiate::STAGEID);
-SimpleSAML\Logger::debug('backend - fallback: '.$state['LogoutState']['negotiate:backend']);
+$state = \SimpleSAML\Auth\State::loadState($_REQUEST['AuthState'], \SimpleSAML\Module\negotiate\Auth\Source\Negotiate::STAGEID);
+\SimpleSAML\Logger::debug('backend - fallback: '.$state['LogoutState']['negotiate:backend']);
 
-sspmod_negotiate_Auth_Source_Negotiate::fallBack($state);
+\SimpleSAML\Module\negotiate\Auth\Source\Negotiate::fallBack($state);
 
 exit;
diff --git a/modules/negotiate/www/disable.php b/modules/negotiate/www/disable.php
index 9cf8c592bfade86c515c6cec924a925ffe5f3a74..fafe79a067aebf3aa2797adb4f60f6b3c348b74d 100644
--- a/modules/negotiate/www/disable.php
+++ b/modules/negotiate/www/disable.php
@@ -15,9 +15,9 @@ $params = array(
 );
 \SimpleSAML\Utils\HTTP::setCookie('NEGOTIATE_AUTOLOGIN_DISABLE_PERMANENT', 'True', $params, FALSE);
 
-$globalConfig = SimpleSAML_Configuration::getInstance();
-$session = SimpleSAML_Session::getSessionFromRequest();
+$globalConfig = \SimpleSAML\Configuration::getInstance();
+$session = \SimpleSAML\Session::getSessionFromRequest();
 $session->setData('negotiate:disable', 'session', FALSE, 24*60*60);
-$t = new SimpleSAML_XHTML_Template($globalConfig, 'negotiate:disable.php');
-$t->data['url'] = SimpleSAML\Module::getModuleURL('negotiate/enable.php');
+$t = new \SimpleSAML\XHTML\Template($globalConfig, 'negotiate:disable.php');
+$t->data['url'] = \SimpleSAML\Module::getModuleURL('negotiate/enable.php');
 $t->show();
diff --git a/modules/negotiate/www/enable.php b/modules/negotiate/www/enable.php
index 04c5e16ffc17c2a40fa5a3849e836b3d3efa8a73..293b7b97c19882dfcac12258dc2f4fa03ea0bec9 100644
--- a/modules/negotiate/www/enable.php
+++ b/modules/negotiate/www/enable.php
@@ -14,9 +14,9 @@ $params = array(
 );
 \SimpleSAML\Utils\HTTP::setCookie('NEGOTIATE_AUTOLOGIN_DISABLE_PERMANENT', NULL, $params, FALSE);
 
-$globalConfig = SimpleSAML_Configuration::getInstance();
-$session = SimpleSAML_Session::getSessionFromRequest();
+$globalConfig = \SimpleSAML\Configuration::getInstance();
+$session = \SimpleSAML\Session::getSessionFromRequest();
 $session->setData('negotiate:disable', 'session', FALSE, 24*60*60);
-$t = new SimpleSAML_XHTML_Template($globalConfig, 'negotiate:enable.php');
-$t->data['url'] = SimpleSAML\Module::getModuleURL('negotiate/disable.php');
+$t = new \SimpleSAML\XHTML\Template($globalConfig, 'negotiate:enable.php');
+$t->data['url'] = \SimpleSAML\Module::getModuleURL('negotiate/disable.php');
 $t->show();
diff --git a/modules/negotiate/www/retry.php b/modules/negotiate/www/retry.php
index a39b9596bd94597c3bca7542444ee9146e77e2f3..8378714f71d86a964da8c64d92a9322987ba88ec 100644
--- a/modules/negotiate/www/retry.php
+++ b/modules/negotiate/www/retry.php
@@ -1,30 +1,31 @@
 <?php
 
 /**
- *
  *
  * @author Mathias Meisfjordskar, University of Oslo.
  *         <mathias.meisfjordskar@usit.uio.no>
  * @package SimpleSAMLphp
+ *
  */
 
-$state = SimpleSAML_Auth_State::loadState($_REQUEST['AuthState'], sspmod_negotiate_Auth_Source_Negotiate::STAGEID);
+$state = \SimpleSAML\Auth\State::loadState($_REQUEST['AuthState'], \SimpleSAML\Module\negotiate\Auth\Source\Negotiate::STAGEID);
 
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 $idpid = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted', 'metaindex');
 $idpmeta = $metadata->getMetaData($idpid, 'saml20-idp-hosted');
 
 if (isset($idpmeta['auth'])) {
-	$source = SimpleSAML_Auth_Source::getById($idpmeta['auth']);
-	if ($source === NULL)
-		throw new SimpleSAML_Error_BadRequest('Invalid AuthId "' . $idpmeta['auth'] . '" - not found.');
+    $source = \SimpleSAML\Auth\Source::getById($idpmeta['auth']);
+    if ($source === null) {
+        throw new \SimpleSAML\Error\BadRequest('Invalid AuthId "' . $idpmeta['auth'] . '" - not found.');
+    }
 
-	$session = SimpleSAML_Session::getSessionFromRequest();
-	$session->setData('negotiate:disable', 'session', FALSE, 24*60*60);
-	SimpleSAML\Logger::debug('Negotiate(retry) - session enabled, retrying.');
-	$source->authenticate($state);
-	assert(false);
+    $session = \SimpleSAML\Session::getSessionFromRequest();
+    $session->setData('negotiate:disable', 'session', FALSE, 24*60*60);
+    \SimpleSAML\Logger::debug('Negotiate(retry) - session enabled, retrying.');
+    $source->authenticate($state);
+    assert(false);
 } else {
-	SimpleSAML\Logger::error('Negotiate - retry - no "auth" parameter found in IdP metadata.');
-	assert(false);
+    \SimpleSAML\Logger::error('Negotiate - retry - no "auth" parameter found in IdP metadata.');
+    assert(false);
 }
diff --git a/modules/oauth/hooks/hook_cron.php b/modules/oauth/hooks/hook_cron.php
index 9d99fad2a3ac608cb297bbe54dbe531e86cceaaa..b3f991bb3705bf1e78a5594278101aa727b99479 100644
--- a/modules/oauth/hooks/hook_cron.php
+++ b/modules/oauth/hooks/hook_cron.php
@@ -1,16 +1,18 @@
 <?php
+
 /**
  * Hook to run a cron job.
  *
  * @param array &$croninfo  Output
  */
+
 function oauth_hook_cron(&$croninfo)
 {
     assert(is_array($croninfo));
     assert(array_key_exists('summary', $croninfo));
     assert(array_key_exists('tag', $croninfo));
 
-    $oauthconfig = SimpleSAML_Configuration::getOptionalConfig('module_statistics.php');
+    $oauthconfig = \SimpleSAML\Configuration::getOptionalConfig('module_statistics.php');
 
     if (is_null($oauthconfig->getValue('cron_tag', 'hourly'))) {
         return;
@@ -20,12 +22,12 @@ function oauth_hook_cron(&$croninfo)
     }
 
     try {
-        $store = new sspmod_core_Storage_SQLPermanentStorage('oauth');
+        $store = new \SimpleSAML\Module\core\Storage\SQLPermanentStorage('oauth');
         $cleaned = $store->removeExpired();
         $croninfo['summary'][] = 'OAuth clean up. Removed ' . $cleaned . ' expired entries from OAuth storage.';
-    } catch (Exception $e) {
+    } catch (\Exception $e) {
         $message = 'OAuth clean up cron script failed: ' . $e->getMessage();
-        SimpleSAML\Logger::warning($message);
+        \SimpleSAML\Logger::warning($message);
         $croninfo['summary'][] = $message;
     }
 }
diff --git a/modules/oauth/lib/Consumer.php b/modules/oauth/lib/Consumer.php
index 62f1fc4d305db9fb4dcb933f65fca14eb39981da..f655368ff6f4c368356856753c7b4162e4b5acd7 100644
--- a/modules/oauth/lib/Consumer.php
+++ b/modules/oauth/lib/Consumer.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\oauth;
+
 require_once(dirname(dirname(__FILE__)) . '/libextinc/OAuth.php');
 
 /**
@@ -8,15 +10,16 @@ require_once(dirname(dirname(__FILE__)) . '/libextinc/OAuth.php');
  * @author Andreas Ă…kre Solberg, <andreas.solberg@uninett.no>, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class sspmod_oauth_Consumer
+
+class Consumer
 {
     private $consumer;
     private $signer;
 
     public function __construct($key, $secret)
     {
-        $this->consumer = new OAuthConsumer($key, $secret, null);
-        $this->signer = new OAuthSignatureMethod_HMAC_SHA1();
+        $this->consumer = new \OAuthConsumer($key, $secret, null);
+        $this->signer = new \OAuthSignatureMethod_HMAC_SHA1();
     }
 
     // Used only to load the libextinc library early
@@ -55,25 +58,47 @@ class sspmod_oauth_Consumer
     {
         try {
             $response = \SimpleSAML\Utils\HTTP::fetch($url);
-        } catch (\SimpleSAML_Error_Exception $e) {
+        } catch (\SimpleSAML\Error\Exception $e) {
             $statuscode = 'unknown';
             if (preg_match('/^HTTP.*\s([0-9]{3})/', $http_response_header[0], $matches)) {
                 $statuscode = $matches[1];
             }
+
             $error = $context . ' [statuscode: ' . $statuscode . ']: ';
             $oautherror = self::getOAuthError($http_response_header);
 
-
             if (!empty($oautherror)) {
                 $error .= $oautherror;
             }
 
-            throw new Exception($error . ':' . $url);
+            throw new \Exception($error . ':' . $url);
         } 
         // Fall back to return response, if could not reckognize HTTP header. Should not happen.
         return $response;
     }
 
+    public function getRequestToken($url, $parameters = null)
+    {
+        $req_req = \OAuthRequest::from_consumer_and_token($this->consumer, null, "GET", $url, $parameters);
+        $req_req->sign_request($this->signer, $this->consumer, null);
+
+        $response_req = self::getHTTP(
+            $req_req->to_url(),
+            'Contacting request_token endpoint on the OAuth Provider'
+        );
+
+        parse_str($response_req, $responseParsed);
+
+        if (array_key_exists('error', $responseParsed)) {
+            throw new \Exception('Error getting request token: ' . $responseParsed['error']);
+        }
+
+        $requestToken = $responseParsed['oauth_token'];
+        $requestTokenSecret = $responseParsed['oauth_token_secret'];
+
+        return new \OAuthToken($requestToken, $requestTokenSecret);
+    }
+
     public function getAuthorizeRequest($url, $requestToken, $redirect = true, $callback = null)
     {
         $params = array('oauth_token' => $requestToken->key);
@@ -90,32 +115,32 @@ class sspmod_oauth_Consumer
 
     public function getAccessToken($url, $requestToken, $parameters = null)
     {
-        $acc_req = OAuthRequest::from_consumer_and_token($this->consumer, $requestToken, "GET", $url, $parameters);
+        $acc_req = \OAuthRequest::from_consumer_and_token($this->consumer, $requestToken, "GET", $url, $parameters);
         $acc_req->sign_request($this->signer, $this->consumer, $requestToken);
 
         try {
             $response_acc = \SimpleSAML\Utils\HTTP::fetch($acc_req->to_url());
-        } catch (\SimpleSAML_Error_Exception $e) {
-            throw new Exception('Error contacting request_token endpoint on the OAuth Provider');
+        } catch (\SimpleSAML\Error\Exception $e) {
+            throw new \Exception('Error contacting request_token endpoint on the OAuth Provider');
         }
 
-        SimpleSAML\Logger::debug('oauth: Reponse to get access token: '. $response_acc);
+        \SimpleSAML\Logger::debug('oauth: Reponse to get access token: '. $response_acc);
 
         parse_str($response_acc, $accessResponseParsed);
 
         if (array_key_exists('error', $accessResponseParsed)) {
-            throw new Exception('Error getting request token: ' . $accessResponseParsed['error']);
+            throw new \Exception('Error getting request token: ' . $accessResponseParsed['error']);
         }
 
         $accessToken = $accessResponseParsed['oauth_token'];
         $accessTokenSecret = $accessResponseParsed['oauth_token_secret'];
 
-        return new OAuthToken($accessToken, $accessTokenSecret);
+        return new \OAuthToken($accessToken, $accessTokenSecret);
     }
 
     public function postRequest($url, $accessToken, $parameters)
     {
-        $data_req = OAuthRequest::from_consumer_and_token($this->consumer, $accessToken, "POST", $url, $parameters);
+        $data_req = \OAuthRequest::from_consumer_and_token($this->consumer, $accessToken, "POST", $url, $parameters);
         $data_req->sign_request($this->signer, $this->consumer, $accessToken);
         $postdata = $data_req->to_postdata();
 
@@ -134,15 +159,15 @@ class sspmod_oauth_Consumer
 
         try {
             $response = \SimpleSAML\Utils\HTTP::fetch($url, $opts);
-        } catch (\SimpleSAML_Error_Exception $e) {
-            throw new SimpleSAML_Error_Exception('Failed to push definition file to ' . $url);
+        } catch (\SimpleSAML\Error\Exception $e) {
+            throw new \SimpleSAML\Error\Exception('Failed to push definition file to ' . $url);
         }
         return $response;
     }
 
     public function getUserInfo($url, $accessToken, $opts = null)
     {
-        $data_req = OAuthRequest::from_consumer_and_token($this->consumer, $accessToken, "GET", $url, null);
+        $data_req = \OAuthRequest::from_consumer_and_token($this->consumer, $accessToken, "GET", $url, null);
         $data_req->sign_request($this->signer, $this->consumer, $accessToken);
 
         if (is_array($opts)) {
diff --git a/modules/oauth/lib/OAuthServer.php b/modules/oauth/lib/OAuthServer.php
index c812ac38710e70fbaa1c58887d0a58fe3d22b90e..30087c6da5fb3e6be1dedd6d9bcee197905ca0c5 100644
--- a/modules/oauth/lib/OAuthServer.php
+++ b/modules/oauth/lib/OAuthServer.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\oauth;
+
 require_once(dirname(dirname(__FILE__)) . '/libextinc/OAuth.php');
 
 /**
@@ -8,8 +10,14 @@ require_once(dirname(dirname(__FILE__)) . '/libextinc/OAuth.php');
  * @author Andreas Ă…kre Solberg, <andreas.solberg@uninett.no>, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class sspmod_oauth_OAuthServer extends OAuthServer
+
+class OAuthServer extends OAuthServer
 {
+    public function __construct($store)
+    {
+        parent::__construct($store);
+    }
+
     public function get_signature_methods()
     {
         return $this->signature_methods;
diff --git a/modules/oauth/lib/OAuthStore.php b/modules/oauth/lib/OAuthStore.php
index 8695b077cb1739755583558cb1abed46417234f2..4b7bd9a7c0906f362280b7a66254f3c582c319af 100644
--- a/modules/oauth/lib/OAuthStore.php
+++ b/modules/oauth/lib/OAuthStore.php
@@ -1,4 +1,7 @@
 <?php
+
+namespace SimpleSAML\Module\oauth;
+
 require_once(dirname(dirname(__FILE__)) . '/libextinc/OAuth.php');
 
 /**
@@ -11,7 +14,8 @@ require_once(dirname(dirname(__FILE__)) . '/libextinc/OAuth.php');
  * @author Mark Dobrinic, <mdobrinic@cozmanova.com>, Cozmanova bv
  * @package SimpleSAMLphp
  */
-class sspmod_oauth_OAuthStore extends OAuthDataStore
+
+class OAuthStore extends \OAuthDataStore
 {
     private $store;
     private $config;
@@ -26,16 +30,18 @@ class sspmod_oauth_OAuthStore extends OAuthDataStore
         'request' => 'requestToken.key+consumerKey = requesttoken',
     );
 
+
     public function __construct()
     {
-        $this->store = new sspmod_core_Storage_SQLPermanentStorage('oauth');
-        $this->config = SimpleSAML_Configuration::getOptionalConfig('module_oauth.php');
+        $this->store = new \SimpleSAML\Module\core\Storage\SQLPermanentStorage('oauth');
+        $this->config = \SimpleSAML\Configuration::getOptionalConfig('module_oauth.php');
     }
 
+
     /**
      * Attach the data to the token, and establish the Callback URL and verifier
-     * @param $requestTokenKey RequestToken that was authorized
-     * @param $data Data that is authorized and to be attached to the requestToken
+     * @param string $requestTokenKey RequestToken that was authorized
+     * @param string $data Data that is authorized and to be attached to the requestToken
      * @return array(string:url, string:verifier) ; empty verifier for 1.0-response
      */
     public function authorize($requestTokenKey, $data)
@@ -59,7 +65,7 @@ class sspmod_oauth_OAuthStore extends OAuthDataStore
             $url = $oConsumer->callback_url;
         }
 
-        $verifier = SimpleSAML\Utils\Random::generateID();
+        $verifier = \SimpleSAML\Utils\Random::generateID();
         $url = \SimpleSAML\Utils\HTTP::addURLParameters($url, array("oauth_verifier"=>$verifier));
 
         $this->store->set('authorized', $requestTokenKey, $verifier, $data, $this->config->getValue('requestTokenDuration', 60*30));
@@ -71,26 +77,26 @@ class sspmod_oauth_OAuthStore extends OAuthDataStore
      * Perform lookup whether a given token exists in the list of authorized tokens; if a verifier is
      * passed as well, the verifier *must* match the verifier that was registered with the token<br/>
      * Note that an accessToken should never be stored with a verifier
-     * @param $requestToken
-     * @param $verifier
-     * @return unknown_type
+     * @param string $requestToken
+     * @param string $verifier
+     * @return bool
      */
     public function isAuthorized($requestToken, $verifier = '')
     {
-        SimpleSAML\Logger::info('OAuth isAuthorized(' . $requestToken . ')');
+        \SimpleSAML\Logger::info('OAuth isAuthorized(' . $requestToken . ')');
         return $this->store->exists('authorized', $requestToken, $verifier);
     }
 
     public function getAuthorizedData($token, $verifier = '')
     {
-        SimpleSAML\Logger::info('OAuth getAuthorizedData(' . $token . ')');
+        \SimpleSAML\Logger::info('OAuth getAuthorizedData(' . $token . ')');
         $data = $this->store->get('authorized', $token, $verifier);
         return $data['value'];
     }
 
     public function moveAuthorizedData($requestToken, $verifier, $accessTokenKey)
     {
-        SimpleSAML\Logger::info('OAuth moveAuthorizedData(' . $requestToken . ', ' . $accessTokenKey . ')');
+        \SimpleSAML\Logger::info('OAuth moveAuthorizedData(' . $requestToken . ', ' . $accessTokenKey . ')');
 
         // Retrieve authorizedData from authorized.requestToken (with provider verifier)
         $authorizedData = $this->getAuthorizedData($requestToken, $verifier);
@@ -105,7 +111,7 @@ class sspmod_oauth_OAuthStore extends OAuthDataStore
 
     public function lookup_consumer($consumer_key)
     {
-        SimpleSAML\Logger::info('OAuth lookup_consumer(' . $consumer_key . ')');
+        \SimpleSAML\Logger::info('OAuth lookup_consumer(' . $consumer_key . ')');
         if (!$this->store->exists('consumers', $consumer_key, '')) {
             return null;
         }
@@ -117,25 +123,25 @@ class sspmod_oauth_OAuthStore extends OAuthDataStore
         }
 
         if ($consumer['value']['RSAcertificate']) {
-            return new OAuthConsumer($consumer['value']['key'], $consumer['value']['RSAcertificate'], $callback);
+            return new \OAuthConsumer($consumer['value']['key'], $consumer['value']['RSAcertificate'], $callback);
         } else {
-            return new OAuthConsumer($consumer['value']['key'], $consumer['value']['secret'], $callback);
+            return new \OAuthConsumer($consumer['value']['key'], $consumer['value']['secret'], $callback);
         }
     }
 
-    function lookup_token($consumer, $tokenType = 'default', $token)
+    public function lookup_token($consumer, $tokenType = 'default', $token)
     {
-        SimpleSAML\Logger::info('OAuth lookup_token(' . $consumer->key . ', ' . $tokenType. ',' . $token . ')');
+        \SimpleSAML\Logger::info('OAuth lookup_token(' . $consumer->key . ', ' . $tokenType. ',' . $token . ')');
         $data = $this->store->get($tokenType, $token, $consumer->key);
         if ($data == null) {
-            throw new Exception('Could not find token');
+            throw new \Exception('Could not find token');
         }
         return $data['value'];
     }
 
-    function lookup_nonce($consumer, $token, $nonce, $timestamp)
+    public function lookup_nonce($consumer, $token, $nonce, $timestamp)
     {
-        SimpleSAML\Logger::info('OAuth lookup_nonce(' . $consumer . ', ' . $token. ',' . $nonce . ')');
+        \SimpleSAML\Logger::info('OAuth lookup_nonce(' . $consumer . ', ' . $token. ',' . $nonce . ')');
         if ($this->store->exists('nonce', $nonce, $consumer->key)) {
             return true;
         }
@@ -143,14 +149,14 @@ class sspmod_oauth_OAuthStore extends OAuthDataStore
         return false;
     }
 
-    function new_request_token($consumer, $callback = null, $version = null)
+    public function new_request_token($consumer, $callback = null, $version = null)
     {
-        SimpleSAML\Logger::info('OAuth new_request_token(' . $consumer . ')');
+        \SimpleSAML\Logger::info('OAuth new_request_token(' . $consumer . ')');
 
         $lifetime = $this->config->getValue('requestTokenDuration', 60*30); 
 
-        $token = new OAuthToken(SimpleSAML\Utils\Random::generateID(), SimpleSAML\Utils\Random::generateID());
-        $token->callback = $callback; // OAuth1.0-RevA
+        $token = new \OAuthToken(\SimpleSAML\Utils\Random::generateID(), \SimpleSAML\Utils\Random::generateID());
+        $token->callback = $callback;	// OAuth1.0-RevA
         $this->store->set('request', $token->key, $consumer->key, $token, $lifetime);
 
         // also store in requestToken->key => array('callback'=>CallbackURL, 'version'=>oauth_version
@@ -167,22 +173,22 @@ class sspmod_oauth_OAuthStore extends OAuthDataStore
         return $token;
     }
 
-    function new_access_token($requestToken, $consumer, $verifier = null)
+    public function new_access_token($requestToken, $consumer, $verifier = null)
     {
-        SimpleSAML\Logger::info('OAuth new_access_token(' . $requestToken . ',' . $consumer . ')');
-        $accesstoken = new OAuthToken(SimpleSAML\Utils\Random::generateID(), SimpleSAML\Utils\Random::generateID());
+        \SimpleSAML\Logger::info('OAuth new_access_token(' . $requestToken . ',' . $consumer . ')');
+        $accesstoken = new \OAuthToken(\SimpleSAML\Utils\Random::generateID(), \SimpleSAML\Utils\Random::generateID());
         $this->store->set('access', $accesstoken->key, $consumer->key, $accesstoken, $this->config->getValue('accessTokenDuration', 60*60*24) );
         return $accesstoken;
     }
-    
+
     /**
      * Return OAuthConsumer-instance that a given requestToken was issued to
-     * @param $requestTokenKey
-     * @return unknown_type
+     * @param string $requestTokenKey
+     * @return mixed
      */
     public function lookup_consumer_by_requestToken($requestTokenKey)
     {
-        SimpleSAML\Logger::info('OAuth lookup_consumer_by_requestToken(' . $requestTokenKey . ')');
+        \SimpleSAML\Logger::info('OAuth lookup_consumer_by_requestToken(' . $requestTokenKey . ')');
         if (!$this->store->exists('requesttorequest', $requestTokenKey, '')) {
             return null;
         }
diff --git a/modules/oauth/lib/Registry.php b/modules/oauth/lib/Registry.php
index ee78438c4a4d6aee342305d6b681eaa9ae94c50f..f8e5f0b2cd3cde0c27effd91685d55b8a0db7bd8 100644
--- a/modules/oauth/lib/Registry.php
+++ b/modules/oauth/lib/Registry.php
@@ -1,21 +1,22 @@
 <?php
 
+namespace SimpleSAML\Module\oauth;
+
 /**
  * Editor for OAuth Client Registry
  *
  * @author Andreas Ă…kre Solberg <andreas@uninett.no>, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class sspmod_oauth_Registry
+
+class Registry
 {
     protected function getStandardField($request, &$entry, $key)
     {
         if (array_key_exists('field_' . $key, $request)) {
             $entry[$key] = $request['field_' . $key];
-        } else {
-            if (isset($entry[$key])) {
-                unset($entry[$key]);
-            }
+        } else if (isset($entry[$key])) {
+            unset($entry[$key]);
         }
     }
 
diff --git a/modules/oauth/libextinc/OAuth.php b/modules/oauth/libextinc/OAuth.php
index 073d9d807cb1dbbd8f339b4b9c857f7c841ec2a7..bffaa4b021645b9269f93b49aef544b3a4a090ec 100644
--- a/modules/oauth/libextinc/OAuth.php
+++ b/modules/oauth/libextinc/OAuth.php
@@ -23,6 +23,7 @@ if (!class_exists('OAuthConsumer')) {
     {
         public $key;
         public $secret;
+        public $callback_url;
 
         public function __construct($key, $secret, $callback_url = null)
         {
@@ -216,13 +217,13 @@ abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod
     // (3) some sort of specific discovery code based on request
     //
     // Either way should return a string representation of the certificate
-    protected abstract function fetch_public_cert(&$request);
+    abstract protected function fetch_public_cert(&$request);
 
     // Up to the SP to implement this lookup of keys. Possible ideas are:
     // (1) do a lookup in a table of trusted certs keyed off of consumer
     //
     // Either way should return a string representation of the certificate
-    protected abstract function fetch_private_cert(&$request);
+    abstract protected function fetch_private_cert(&$request);
 
     public function build_signature($request, $consumer, $token)
     {
@@ -279,7 +280,7 @@ class OAuthRequest
     public function __construct($http_method, $http_url, $parameters = null)
     {
         $parameters = ($parameters) ? $parameters : array();
-        $parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
+        $parameters = array_merge(OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
         $this->parameters = $parameters;
         $this->http_method = $http_method;
         $this->http_url = $http_url;
@@ -484,11 +485,14 @@ class OAuthRequest
         if ($realm) {
             $out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"';
             $first = false;
-        } else
+        } else {
             $out = 'Authorization: OAuth';
+        }
 
         foreach ($this->parameters as $k => $v) {
-            if (substr($k, 0, 5) != "oauth") continue;
+            if (substr($k, 0, 5) != "oauth") {
+                continue;
+            }
             if (is_array($v)) {
                 throw new OAuthException('Arrays not supported in headers');
             }
@@ -784,7 +788,6 @@ class OAuthServer
             throw new OAuthException("Nonce already used: $nonce");
         }
     }
-
 }
 
 class OAuthDataStore
@@ -877,7 +880,7 @@ class OAuthUtil
             // returns the headers in the same case as they are in the
             // request
             $out = array();
-            foreach ($headers AS $key => $value) {
+            foreach ($headers as $key => $value) {
                 $key = str_replace(
                     " ",
                     "-",
@@ -889,10 +892,12 @@ class OAuthUtil
             // otherwise we don't have apache and are just going to have to hope
             // that $_SERVER actually contains what we need
             $out = array();
-            if( isset($_SERVER['CONTENT_TYPE']) )
+            if (isset($_SERVER['CONTENT_TYPE'])) {
                 $out['Content-Type'] = $_SERVER['CONTENT_TYPE'];
-            if( isset($_ENV['CONTENT_TYPE']) )
+            }
+            if (isset($_ENV['CONTENT_TYPE'])) {
                 $out['Content-Type'] = $_ENV['CONTENT_TYPE'];
+            }
 
             foreach ($_SERVER as $key => $value) {
                 if (substr($key, 0, 5) == "HTTP_") {
diff --git a/modules/oauth/templates/registry.edit.tpl.php b/modules/oauth/templates/registry.edit.tpl.php
index e1eb05dd2fadf2bbb06d531be9ec2eec062c18c8..4c97f36f57300b845bbecb62620bff0241371cf9 100644
--- a/modules/oauth/templates/registry.edit.tpl.php
+++ b/modules/oauth/templates/registry.edit.tpl.php
@@ -1,7 +1,7 @@
 <?php
 
-$this->data['jquery'] = array('core' => TRUE, 'ui' => TRUE, 'css' => TRUE);
-$this->data['head']  = '<link rel="stylesheet" type="text/css" href="/' . $this->data['baseurlpath'] . 'module.php/metaedit/resources/style.css" />' . "\n";
+$this->data['jquery'] = array('core' => true, 'ui' => true, 'css' => true);
+$this->data['head']  = '<link rel="stylesheet" type="text/css" href="/' . $this->data['baseurlpath'] . 'module.php/oauth/resources/style.css" />' . "\n";
 $this->data['head'] .= '<script type="text/javascript">
 $(document).ready(function() {
 	$("#tabdiv").tabs();
diff --git a/modules/oauth/www/getUserInfo.php b/modules/oauth/www/getUserInfo.php
index 09e894f6a1475f14001bbbc147ca4e8bc033dc3e..e68808add1ecd8158d2be9726a3f8046b1bd2e55 100644
--- a/modules/oauth/www/getUserInfo.php
+++ b/modules/oauth/www/getUserInfo.php
@@ -2,14 +2,14 @@
 
 require_once(dirname(dirname(__FILE__)) . '/libextinc/OAuth.php');
 
-$oauthconfig = SimpleSAML_Configuration::getConfig('module_oauth.php');
+$oauthconfig = \SimpleSAML\Configuration::getConfig('module_oauth.php');
 
 if (!$oauthconfig->getBoolean('getUserInfo.enable', false)) {
-    throw new Exception('Get user info endpoint is disabled. This endpoint can be enabled in the module_oauth.php configuration file.');
+    throw new \Exception('Get user info endpoint is disabled. This endpoint can be enabled in the module_oauth.php configuration file.');
 }
 
-$store = new sspmod_oauth_OAuthStore();
-$server = new sspmod_oauth_OAuthServer($store);
+$store = new \SimpleSAML\Module\oauth\OAuthStore();
+$server = new \SimpleSAML\Module\oauth\OAuthServer($store);
 
 $hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
 $plaintext_method = new OAuthSignatureMethod_PLAINTEXT();
diff --git a/modules/oauth/www/registry.edit.php b/modules/oauth/www/registry.edit.php
index 9ce47e8a255b47d2617a25f60b6d29c4c0e1b1ab..5ac5d26a386a72a5242646826a60079f74ca0c5c 100644
--- a/modules/oauth/www/registry.edit.php
+++ b/modules/oauth/www/registry.edit.php
@@ -1,11 +1,11 @@
 <?php
 
 // Load SimpleSAMLphp, configuration and metadata
-$config = SimpleSAML_Configuration::getInstance();
-$session = SimpleSAML_Session::getSessionFromRequest();
-$oauthconfig = SimpleSAML_Configuration::getOptionalConfig('module_oauth.php');
+$config = \SimpleSAML\Configuration::getInstance();
+$session = \SimpleSAML\Session::getSessionFromRequest();
+$oauthconfig = \SimpleSAML\Configuration::getOptionalConfig('module_oauth.php');
 
-$store = new sspmod_core_Storage_SQLPermanentStorage('oauth');
+$store = new \SimpleSAML\Module\core\Storage\SQLPermanentStorage('oauth');
 
 $authsource = "admin";	// force admin to authenticate as registry maintainer
 $useridattr = $oauthconfig->getValue('useridattr', 'user');
@@ -14,20 +14,20 @@ if ($session->isValid($authsource)) {
     $attributes = $session->getAuthData($authsource, 'Attributes');
     // Check if userid exists
     if (!isset($attributes[$useridattr])) {
-        throw new Exception('User ID is missing');
+        throw new \Exception('User ID is missing');
     }
     $userid = $attributes[$useridattr][0];
 } else {
-    $as = SimpleSAML_Auth_Source::getById($authsource);
+    $as = \SimpleSAML\Auth\Source::getById($authsource);
     $as->initLogin(\SimpleSAML\Utils\HTTP::getSelfURL());
 }
 
 function requireOwnership($entry, $userid)
 {
     if (!isset($entry['owner']))
-        throw new Exception('OAuth Consumer has no owner. Which means no one is granted access, not even you.');
+        throw new \Exception('OAuth Consumer has no owner. Which means no one is granted access, not even you.');
     if ($entry['owner'] !== $userid) 
-        throw new Exception('OAuth Consumer has an owner that is not equal to your userid, hence you are not granted access.');
+        throw new \Exception('OAuth Consumer has an owner that is not equal to your userid, hence you are not granted access.');
 }
 
 if (array_key_exists('editkey', $_REQUEST)) {
@@ -37,12 +37,12 @@ if (array_key_exists('editkey', $_REQUEST)) {
 } else {
     $entry = array(
         'owner' => $userid,
-        'key' => SimpleSAML\Utils\Random::generateID(),
-        'secret' => SimpleSAML\Utils\Random::generateID(),
+        'key' => \SimpleSAML\Utils\Random::generateID(),
+        'secret' => \SimpleSAML\Utils\Random::generateID(),
     );
 }
 
-$editor = new sspmod_oauth_Registry();
+$editor = new \SimpleSAML\Module\oauth\Registry();
 
 if (isset($_POST['submit'])) {
     $editor->checkForm($_POST);
@@ -53,7 +53,7 @@ if (isset($_POST['submit'])) {
 
     $store->set('consumers', $entry['key'], '', $entry);
 
-    $template = new SimpleSAML_XHTML_Template($config, 'oauth:registry.saved.php');
+    $template = new \SimpleSAML\XHTML\Template($config, 'oauth:registry.saved.php');
     $template->data['entry'] = $entry;
     $template->show();
     exit;
@@ -61,7 +61,7 @@ if (isset($_POST['submit'])) {
 
 $form = $editor->metaToForm($entry);
 
-$template = new SimpleSAML_XHTML_Template($config, 'oauth:registry.edit.tpl.php');
+$template = new \SimpleSAML\XHTML\Template($config, 'oauth:registry.edit.tpl.php');
 $template->data['form'] = $form;
 $template->data['jquery'] = array('core' => false, 'ui' => true, 'css' => true);
 $template->show();
diff --git a/modules/oauth/www/registry.php b/modules/oauth/www/registry.php
index ebf5a93a532b6df6e576f1360306b455b76c7f5d..95ed1d955f63c4f1605cabab861f59a9f170ff51 100644
--- a/modules/oauth/www/registry.php
+++ b/modules/oauth/www/registry.php
@@ -1,10 +1,11 @@
 <?php
 
 // Load SimpleSAMLphp, configuration and metadata
-$config = SimpleSAML_Configuration::getInstance();
-$session = SimpleSAML_Session::getSessionFromRequest();
-$oauthconfig = SimpleSAML_Configuration::getOptionalConfig('module_oauth.php');
-$store = new sspmod_core_Storage_SQLPermanentStorage('oauth');
+$config = \SimpleSAML\Configuration::getInstance();
+$session = \SimpleSAML\Session::getSessionFromRequest();
+$oauthconfig = \SimpleSAML\Configuration::getOptionalConfig('module_oauth.php');
+
+$store = new \SimpleSAML\Module\core\Storage\SQLPermanentStorage('oauth');
 
 $authsource = "admin"; // force admin to authenticate as registry maintainer
 $useridattr = $oauthconfig->getValue('useridattr', 'user');
@@ -13,20 +14,20 @@ if ($session->isValid($authsource)) {
     $attributes = $session->getAuthData($authsource, 'Attributes');
     // Check if userid exists
     if (!isset($attributes[$useridattr])) {
-        throw new Exception('User ID is missing');
+        throw new \Exception('User ID is missing');
     }
     $userid = $attributes[$useridattr][0];
 } else {
-    $as = SimpleSAML_Auth_Source::getById($authsource);
+    $as = \SimpleSAML\Auth\Source::getById($authsource);
     $as->initLogin(\SimpleSAML\Utils\HTTP::getSelfURL());
 }
 
 function requireOwnership($entry, $userid)
 {
     if (!isset($entry['owner']))
-        throw new Exception('OAuth Consumer has no owner. Which means no one is granted access, not even you.');
+        throw new \Exception('OAuth Consumer has no owner. Which means no one is granted access, not even you.');
     if ($entry['owner'] !== $userid) 
-        throw new Exception('OAuth Consumer has an owner that is not equal to your userid, hence you are not granted access.');
+        throw new \Exception('OAuth Consumer has an owner that is not equal to your userid, hence you are not granted access.');
 }
 
 if (isset($_REQUEST['delete'])) {
@@ -51,7 +52,7 @@ if (is_array($list)) {
     $slist['others'][] = $listitem;
 }
 
-$template = new SimpleSAML_XHTML_Template($config, 'oauth:registry.list.php');
+$template = new \SimpleSAML\XHTML\Template($config, 'oauth:registry.list.php');
 $template->data['entries'] = $slist;
 $template->data['userid'] = $userid;
 $template->show();
diff --git a/modules/portal/hooks/hook_htmlinject.php b/modules/portal/hooks/hook_htmlinject.php
index 3abbf8898a3bb0eb871a2855366c50c434fe4040..c4c060cbdde752bd230a230411d0712f7ff6a6ad 100644
--- a/modules/portal/hooks/hook_htmlinject.php
+++ b/modules/portal/hooks/hook_htmlinject.php
@@ -12,9 +12,9 @@ function portal_hook_htmlinject(&$hookinfo) {
 	assert(array_key_exists('page', $hookinfo));
 
 	$links = array('links' => array());
-	SimpleSAML\Module::callHooks('frontpage', $links);
+	\SimpleSAML\Module::callHooks('frontpage', $links);
 
-	$portalConfig = SimpleSAML_Configuration::getOptionalConfig('module_portal.php');
+	$portalConfig = \SimpleSAML\Configuration::getOptionalConfig('module_portal.php');
 	
 	$allLinks = array();
 	foreach($links AS $ls) {
@@ -24,8 +24,8 @@ function portal_hook_htmlinject(&$hookinfo) {
 	$pagesets = $portalConfig->getValue('pagesets', array(
 		array('frontpage_welcome', 'frontpage_config', 'frontpage_auth', 'frontpage_federation'),
 	));
-	SimpleSAML\Module::callHooks('portalextras', $pagesets);
-	$portal = new sspmod_portal_Portal($allLinks, $pagesets);
+	\SimpleSAML\Module::callHooks('portalextras', $pagesets);
+	$portal = new \SimpleSAML\Module\portal\Portal($allLinks, $pagesets);
 	
 	if (!$portal->isPortalized($hookinfo['page'])) return;
 
diff --git a/modules/portal/lib/Portal.php b/modules/portal/lib/Portal.php
index 45d5ca5952e5e8f3f06330ee5994053c0b369b50..fd4e909cbad64253b20975c308de48a6b5f98a57 100644
--- a/modules/portal/lib/Portal.php
+++ b/modules/portal/lib/Portal.php
@@ -1,55 +1,67 @@
 <?php
 
-class sspmod_portal_Portal {
-	
+namespace SimpleSAML\Module\portal;
+
+class Portal
+{
 	private $pages;
 	private $config;
 	
-	function __construct($pages, $config = NULL) {
+	public function __construct($pages, $config = null)
+    {
 		$this->pages = $pages;
 		$this->config = $config;
 	}
 	
-	function getTabset($thispage) {
-		if (!isset($this->config)) return NULL;
-		foreach($this->config AS $set) {
+	public function getTabset($thispage)
+    {
+		if (!isset($this->config)) {
+            return null;
+        }
+		foreach($this->config as $set) {
 			if (in_array($thispage, $set, true)) {
 				return $set;
 			}
 		}
-		return NULL;
+		return null;
 	}
 	
-	function isPortalized($thispage) {
-		
-		foreach($this->config AS $set) {
+	public function isPortalized($thispage)
+    {
+		foreach($this->config as $set) {
 			if (in_array($thispage, $set, true)) {
-				return TRUE;
+				return true;
 			}
 		}
-		return FALSE;
+		return false;
 	}
 	
-	function getLoginInfo($translator, $thispage) {
+	public function getLoginInfo($translator, $thispage)
+    {
 		$info = array('info' => '', 'translator' => $translator, 'thispage' => $thispage);
-		SimpleSAML\Module::callHooks('portalLoginInfo', $info);
+		\SimpleSAML\Module::callHooks('portalLoginInfo', $info);
 		return $info['info'];
 	}
 	
-	function getMenu($thispage) {
-		$config = SimpleSAML_Configuration::getInstance();
-		$t = new SimpleSAML\Locale\Translate($config);
+	public function getMenu($thispage)
+    {
+		$config = \SimpleSAML\Configuration::getInstance();
+		$t = new \SimpleSAML\Locale\Translate($config);
 		$tabset = $this->getTabset($thispage);
 		$logininfo = $this->getLoginInfo($t, $thispage);
 		$text = '';
 		$text .= '<ul class="tabset_tabs ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all">';
-		foreach($this->pages AS $pageid => $page) {
-			
-			if (isset($tabset) && !in_array($pageid, $tabset, TRUE)) continue;
+		foreach ($this->pages as $pageid => $page) {
+			if (isset($tabset) && !in_array($pageid, $tabset, true)) {
+                continue;
+            }
 			$name = 'uknown';
-			if (isset($page['text'])) $name = $page['text'];
-			if (isset($page['shorttext'])) $name = $page['shorttext'];
-			
+			if (isset($page['text'])) {
+                $name = $page['text'];
+            }
+			if (isset($page['shorttext'])) {
+                $name = $page['shorttext'];
+            }
 			if (!isset($page['href'])) {
 				$text .= '<li class="ui-state-default ui-corner-top ui-tabs-selected ui-state-active"><a href="#">' . $t->t($name) . '</a></li>';
 			} else if($pageid === $thispage ) {
@@ -66,6 +78,4 @@ class sspmod_portal_Portal {
 
 		return $text;
 	}
-	
-	
 }
diff --git a/modules/preprodwarning/lib/Auth/Process/Warning.php b/modules/preprodwarning/lib/Auth/Process/Warning.php
index 9ece3fa4bd5532eff56e96a36dfb66c6c5ede471..5ea5b400d212e2a7c1613585a13d43eb717f2d93 100644
--- a/modules/preprodwarning/lib/Auth/Process/Warning.php
+++ b/modules/preprodwarning/lib/Auth/Process/Warning.php
@@ -1,14 +1,15 @@
 <?php
 
+namespace SimpleSAML\Module\preprodwarning\Auth\Process;
+
 /**
  * Give a warning that the user is accessing a test system, not a production system.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_preprodwarning_Auth_Process_Warning extends SimpleSAML_Auth_ProcessingFilter {
-
-
 
+class Warning extends \SimpleSAML\Auth\ProcessingFilter
+{
 	/**
 	 * Process a authentication response.
 	 *
@@ -26,11 +27,8 @@ class sspmod_preprodwarning_Auth_Process_Warning extends SimpleSAML_Auth_Process
 		}
 
 		// Save state and redirect.
-		$id = SimpleSAML_Auth_State::saveState($state, 'warning:request');
-		$url = SimpleSAML\Module::getModuleURL('preprodwarning/showwarning.php');
+		$id = \SimpleSAML\Auth\State::saveState($state, 'warning:request');
+		$url = \SimpleSAML\Module::getModuleURL('preprodwarning/showwarning.php');
 		\SimpleSAML\Utils\HTTP::redirectTrustedURL($url, array('StateId' => $id));
 	}
-	
-
-
 }
diff --git a/modules/preprodwarning/www/showwarning.php b/modules/preprodwarning/www/showwarning.php
index 47490183842db9e396a7bc354e77b9abbcfdb04e..41eff20555e739aceb016ba574a55162637410fa 100644
--- a/modules/preprodwarning/www/showwarning.php
+++ b/modules/preprodwarning/www/showwarning.php
@@ -7,26 +7,22 @@
  * @package SimpleSAMLphp
  */
 
-SimpleSAML\Logger::info('PreProdWarning - Showing warning to user');
+\SimpleSAML\Logger::info('PreProdWarning - Showing warning to user');
 
 if (!array_key_exists('StateId', $_REQUEST)) {
-	throw new SimpleSAML_Error_BadRequest('Missing required StateId query parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing required StateId query parameter.');
 }
 $id = $_REQUEST['StateId'];
-$state = SimpleSAML_Auth_State::loadState($id, 'warning:request');
-
+$state = \SimpleSAML\Auth\State::loadState($id, 'warning:request');
 
 if (array_key_exists('yes', $_REQUEST)) {
-	// The user has pressed the yes-button
-
-	SimpleSAML_Auth_ProcessingChain::resumeProcessing($state);
+    // The user has pressed the yes-button
+    \SimpleSAML\Auth\ProcessingChain::resumeProcessing($state);
 }
 
+$globalConfig = \SimpleSAML\Configuration::getInstance();
 
-
-$globalConfig = SimpleSAML_Configuration::getInstance();
-
-$t = new SimpleSAML_XHTML_Template($globalConfig, 'preprodwarning:warning.php');
-$t->data['yesTarget'] = SimpleSAML\Module::getModuleURL('preprodwarning/showwarning.php');
+$t = new \SimpleSAML\XHTML\Template($globalConfig, 'preprodwarning:warning.php');
+$t->data['yesTarget'] = \SimpleSAML\Module::getModuleURL('preprodwarning/showwarning.php');
 $t->data['yesData'] = array('StateId' => $id);
 $t->show();
diff --git a/modules/radius/lib/Auth/Source/Radius.php b/modules/radius/lib/Auth/Source/Radius.php
index 649df807b768dcdc4f0abd3e9e8fe6d007bd1cab..1688d85ef2180409e2415afb4a1c57759cdb4443 100644
--- a/modules/radius/lib/Auth/Source/Radius.php
+++ b/modules/radius/lib/Auth/Source/Radius.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\radius\Auth\Source;
+
 /**
  * RADIUS authentication source.
  *
@@ -7,7 +9,8 @@
  *
  * @package SimpleSAMLphp
  */
-class sspmod_radius_Auth_Source_Radius extends sspmod_core_Auth_UserPassBase
+
+class Radius extends \SimpleSAML\Module\core\Auth\UserPassBase
 {
     /**
      * The list of radius servers to use.
@@ -80,7 +83,7 @@ class sspmod_radius_Auth_Source_Radius extends sspmod_core_Auth_UserPassBase
         parent::__construct($info, $config);
 
         // Parse configuration.
-        $config = SimpleSAML_Configuration::loadFromArray($config,
+        $config = \SimpleSAML\Configuration::loadFromArray($config,
             'Authentication source ' . var_export($this->authId, true));
 
         $this->servers = $config->getArray('servers', array());
@@ -130,42 +133,42 @@ class sspmod_radius_Auth_Source_Radius extends sspmod_core_Auth_UserPassBase
             if (!radius_add_server($radius,
                 $server['hostname'], $server['port'], $server['secret'], 
                 $this->timeout, $this->retries)) {
-                SimpleSAML\Logger::info("Could not add radius server: " .
+                \SimpleSAML\Logger::info("Could not add radius server: " .
                     radius_strerror($radius));
                 continue;
             }
             $success = true;
         }
         if (!$success) {
-            throw new Exception('Error adding radius servers, no servers available');
+            throw new \Exception('Error adding radius servers, no servers available');
         }
 
-        if (!radius_create_request($radius, RADIUS_ACCESS_REQUEST)) {
-            throw new Exception('Error creating radius request: ' .
+        if (!radius_create_request($radius, \RADIUS_ACCESS_REQUEST)) {
+            throw new \Exception('Error creating radius request: ' .
                 radius_strerror($radius));
         }
 
         if ($this->realm === null) {
-            radius_put_attr($radius, RADIUS_USER_NAME, $username);
+            radius_put_attr($radius, \RADIUS_USER_NAME, $username);
         } else {
-            radius_put_attr($radius, RADIUS_USER_NAME, $username . '@' . $this->realm);
+            radius_put_attr($radius, \RADIUS_USER_NAME, $username . '@' . $this->realm);
         }
-        radius_put_attr($radius, RADIUS_USER_PASSWORD, $password);
+        radius_put_attr($radius, \RADIUS_USER_PASSWORD, $password);
 
         if ($this->nasIdentifier !== null) {
-            radius_put_attr($radius, RADIUS_NAS_IDENTIFIER, $this->nasIdentifier);
+            radius_put_attr($radius, \RADIUS_NAS_IDENTIFIER, $this->nasIdentifier);
         }
 
         $res = radius_send_request($radius);
-        if ($res != RADIUS_ACCESS_ACCEPT) {
+        if ($res != \RADIUS_ACCESS_ACCEPT) {
             switch ($res) {
-            case RADIUS_ACCESS_REJECT:
+            case \RADIUS_ACCESS_REJECT:
                 /* Invalid username or password. */
-                throw new SimpleSAML_Error_Error('WRONGUSERPASS');
-            case RADIUS_ACCESS_CHALLENGE:
-                throw new Exception('Radius authentication error: Challenge requested, but not supported.');
+                throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
+            case \RADIUS_ACCESS_CHALLENGE:
+                throw new \Exception('Radius authentication error: Challenge requested, but not supported.');
             default:
-                throw new Exception('Error during radius authentication: ' .
+                throw new \Exception('Error during radius authentication: ' .
                     radius_strerror($radius));
             }
         }
@@ -190,23 +193,23 @@ class sspmod_radius_Auth_Source_Radius extends sspmod_core_Auth_UserPassBase
         while ($resa = radius_get_attr($radius)) {
 
             if (!is_array($resa)) {
-                throw new Exception('Error getting radius attributes: ' .
+                throw new \Exception('Error getting radius attributes: ' .
                     radius_strerror($radius));
             }
 
             /* Use the received user name */
-            if ($resa['attr'] == RADIUS_USER_NAME) {
+            if ($resa['attr'] == \RADIUS_USER_NAME) {
                 $attributes[$this->usernameAttribute] = array($resa['data']);
                 continue;
             }
 
-            if ($resa['attr'] !== RADIUS_VENDOR_SPECIFIC) {
+            if ($resa['attr'] !== \RADIUS_VENDOR_SPECIFIC) {
                 continue;
             }
 
             $resv = radius_get_vendor_attr($resa['data']);
             if (!is_array($resv)) {
-                throw new Exception('Error getting vendor specific attribute: ' .
+                throw new \Exception('Error getting vendor specific attribute: ' .
                     radius_strerror($radius));
             }
 
diff --git a/modules/riak/hooks/hook_cron.php b/modules/riak/hooks/hook_cron.php
index 6e1ab68fcc75ebdc419c2892c3cbb65abe9f770d..cce9cec0ecfcde9aa428ca25b70005a2718d11ea 100644
--- a/modules/riak/hooks/hook_cron.php
+++ b/modules/riak/hooks/hook_cron.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\riak;
+
 /*
  * Copyright (c) 2012 The University of Queensland
  *
@@ -36,18 +38,18 @@ function riak_hook_cron(&$croninfo) {
 	if ($croninfo['tag'] !== 'hourly') return;
 
 	try {
-		$store = new sspmod_riak_Store_Store();
+		$store = new \SimpleSAML\Module\riak\Store\Store();
 		$result = $store->bucket->indexSearch('expires', 'int',
 		    1, time() - 30);
 		foreach ($result as $link) {
 			$link->getBinary()->delete();
 		}
 
-		SimpleSAML\Logger::info(sprintf("deleted %s riak key%s",
+		\SimpleSAML\Logger::info(sprintf("deleted %s riak key%s",
 		    sizeof($result), sizeof($result) == 1 ? '' : 's'));
-	} catch (Exception $e) {
+	} catch (\Exception $e) {
 		$message = 'riak threw exception: ' . $e->getMessage();
-		SimpleSAML\Logger::warning($message);
+		\SimpleSAML\Logger::warning($message);
 		$croninfo['summary'][] = $message;
 	}
 }
diff --git a/modules/riak/lib/Store/Store.php b/modules/riak/lib/Store/Store.php
index a1ddcb013bb2338156a979e1d7c941fa5ca77a9e..89b62d60cc2aea7d0cbe70f12fd06337f94e217b 100644
--- a/modules/riak/lib/Store/Store.php
+++ b/modules/riak/lib/Store/Store.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\riak\Store;
+
 /*
  * Copyright (c) 2012 The University of Queensland
  *
@@ -22,9 +24,14 @@
  * and Information Technology.
  */
 
-class sspmod_riak_Store_Store extends SimpleSAML\Store {
-	protected function __construct() {
-		$config = SimpleSAML_Configuration::getConfig('module_riak.php');
+class Store extends \SimpleSAML\Store
+{
+    public $client;
+    public $bucket;
+
+	protected function __construct()
+    {
+		$config = \SimpleSAML\Configuration::getConfig('module_riak.php');
 
 		$path = $config->getString('path', 'riak-php-client/riak.php');
 		$host = $config->getString('host', 'localhost');
@@ -43,19 +50,20 @@ class sspmod_riak_Store_Store extends SimpleSAML\Store {
 	 * @param string $key  The key.
 	 * @return mixed|NULL  The value.
 	 */
-	public function get($type, $key) {
+	public function get($type, $key)
+    {
 		assert(is_string($type));
 		assert(is_string($key));
 
 		$v = $this->bucket->getBinary("$type.$key");
 		if (!$v->exists()) {
-			return (NULL);
+			return null;
 		}
 
 		$expires = $v->getIndex('Expires', 'int');
 		if (sizeof($expires) && (int)array_shift($expires) <= time()) {
 			$v->delete();
-			return (NULL);
+			return null;
 		}
 
 		return (unserialize($v->getData()));
@@ -70,7 +78,8 @@ class sspmod_riak_Store_Store extends SimpleSAML\Store {
 	 * @param mixed $value  The value.
 	 * @param int|NULL $expire  The expiration time (unix timestamp), or NULL if it never expires.
 	 */
-	public function set($type, $key, $value, $expire = NULL) {
+	public function set($type, $key, $value, $expire = null)
+    {
 		assert(is_string($type));
 		assert(is_string($key));
 		assert($expire === null || (is_int($expire) && $expire > 2592000));
@@ -89,7 +98,8 @@ class sspmod_riak_Store_Store extends SimpleSAML\Store {
 	 * @param string $type  The datatype.
 	 * @param string $key  The key.
 	 */
-	public function delete($type, $key) {
+	public function delete($type, $key)
+    {
 		assert(is_string($type));
 		assert(is_string($key));
 
diff --git a/modules/saml/docs/sp.md b/modules/saml/docs/sp.md
index f72df230ec97a590325a073e4e599cb0a29e8e06..9ee03c584d827514ec4b4c0014a8ba8c0b9bf5f9 100644
--- a/modules/saml/docs/sp.md
+++ b/modules/saml/docs/sp.md
@@ -125,6 +125,13 @@ Options
 `attributes.NameFormat`
 :   The `NameFormat` for the requested attributes.
 
+`attributes.index`
+:   The `index` attribute that is set in the md:AttributeConsumingService element. Integer value that defaults to `0`.
+
+`attributes.isDefault`
+:   If present, sets the `isDefault` attribute in the md:AttributeConsumingService element. Boolean value, when
+    unset, the attribute will be omitted.
+
 `attributes.required`
 : If you have attributes added you can here specify which should be marked as required.
 : The attributes should still be present in `attributes`.
@@ -362,12 +369,13 @@ Options
 :   *Note*: SAML 2 specific.
 
 `signature.algorithm`
-:   The algorithm to use when signing any message generated by this service provider. Defaults to RSA-SHA1.
+:   The algorithm to use when signing any message generated by this service provider. Defaults to RSA-SHA256.
 :   Possible values:
 
     * `http://www.w3.org/2000/09/xmldsig#rsa-sha1`
        *Note*: the use of SHA1 is **deprecated** and will be disallowed in the future.
     * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha256`
+      The default.
     * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha384`
     * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha512`
 
@@ -460,7 +468,7 @@ Here we will list some examples for this authentication source.
             // Specify friendly names for these attributes:
             'sn' => 'urn:oid:2.5.4.4',
             'givenName' => 'urn:oid:2.5.4.42',
-        )
+        ),
         'attributes.required' => array (
             'eduPersonPrincipalName',
         ),
diff --git a/modules/saml/hooks/hook_metadata_hosted.php b/modules/saml/hooks/hook_metadata_hosted.php
index b2babd05683b57800c48daf5fecf9012d4a60863..d27f5246d619e48f054b9b53b44229f747946f5d 100644
--- a/modules/saml/hooks/hook_metadata_hosted.php
+++ b/modules/saml/hooks/hook_metadata_hosted.php
@@ -5,32 +5,32 @@
  *
  * @param array &$metadataHosted  The metadata links for hosted metadata on the frontpage.
  */
-function saml_hook_metadata_hosted(&$metadataHosted) {
-	assert(is_array($metadataHosted));
-
-	$sources = SimpleSAML_Auth_Source::getSourcesOfType('saml:SP');
-
-	foreach ($sources as $source) {
-
-		$metadata = $source->getMetadata();
-
-		$name = $metadata->getValue('name', NULL);
-		if ($name === NULL) {
-			$name = $metadata->getValue('OrganizationDisplayName', NULL);
-		}
-		if ($name === NULL) {
-			$name = $source->getAuthID();
-		}
-
-		$md = array(
-			'entityid' => $source->getEntityId(),
-			'metadata-index' => $source->getEntityId(),
-			'metadata-set' => 'saml20-sp-hosted',
-			'metadata-url' => $source->getMetadataURL() . '?output=xhtml',
-			'name' => $name,
-		);
-
-		$metadataHosted[] = $md;
-	}
 
+function saml_hook_metadata_hosted(&$metadataHosted)
+{
+    assert(is_array($metadataHosted));
+
+    $sources = \SimpleSAML\Auth\Source::getSourcesOfType('saml:SP');
+
+    foreach ($sources as $source) {
+        $metadata = $source->getMetadata();
+
+        $name = $metadata->getValue('name', null);
+        if ($name === null) {
+            $name = $metadata->getValue('OrganizationDisplayName', null);
+        }
+        if ($name === null) {
+            $name = $source->getAuthID();
+        }
+
+        $md = array(
+            'entityid' => $source->getEntityId(),
+            'metadata-index' => $source->getEntityId(),
+            'metadata-set' => 'saml20-sp-hosted',
+            'metadata-url' => $source->getMetadataURL() . '?output=xhtml',
+            'name' => $name,
+        );
+
+        $metadataHosted[] = $md;
+    }
 }
diff --git a/modules/saml/lib/Auth/Process/AttributeNameID.php b/modules/saml/lib/Auth/Process/AttributeNameID.php
index 1bb86a74e9669cc0af8a7ef9297bb5b746cd4a86..fbb5669a80e3a4ca04503f729151d8262b69b6a0 100644
--- a/modules/saml/lib/Auth/Process/AttributeNameID.php
+++ b/modules/saml/lib/Auth/Process/AttributeNameID.php
@@ -1,14 +1,15 @@
 <?php
 
+namespace SimpleSAML\Module\saml\Auth\Process;
 
 /**
  * Authentication processing filter to create a NameID from an attribute.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_saml_Auth_Process_AttributeNameID extends sspmod_saml_BaseNameIDGenerator
-{
 
+class AttributeNameID extends \SimpleSAML\Module\saml\BaseNameIDGenerator
+{
     /**
      * The attribute we should use as the NameID.
      *
@@ -23,7 +24,7 @@ class sspmod_saml_Auth_Process_AttributeNameID extends sspmod_saml_BaseNameIDGen
      * @param array $config Configuration information about this filter.
      * @param mixed $reserved For future use.
      *
-     * @throws SimpleSAML_Error_Exception If the required options 'Format' or 'attribute' are missing.
+     * @throws \SimpleSAMLError\Exception If the required options 'Format' or 'attribute' are missing.
      */
     public function __construct($config, $reserved)
     {
@@ -31,12 +32,12 @@ class sspmod_saml_Auth_Process_AttributeNameID extends sspmod_saml_BaseNameIDGen
         assert(is_array($config));
 
         if (!isset($config['Format'])) {
-            throw new SimpleSAML_Error_Exception("AttributeNameID: Missing required option 'Format'.");
+            throw new \SimpleSAML\Error\Exception("AttributeNameID: Missing required option 'Format'.");
         }
         $this->format = (string) $config['Format'];
 
         if (!isset($config['attribute'])) {
-            throw new SimpleSAML_Error_Exception("AttributeNameID: Missing required option 'attribute'.");
+            throw new \SimpleSAML\Error\Exception("AttributeNameID: Missing required option 'attribute'.");
         }
         $this->attribute = (string) $config['attribute'];
     }
@@ -52,14 +53,14 @@ class sspmod_saml_Auth_Process_AttributeNameID extends sspmod_saml_BaseNameIDGen
     {
 
         if (!isset($state['Attributes'][$this->attribute]) || count($state['Attributes'][$this->attribute]) === 0) {
-            SimpleSAML\Logger::warning(
+            \SimpleSAML\Logger::warning(
                 'Missing attribute '.var_export($this->attribute, true).
                 ' on user - not generating attribute NameID.'
             );
             return null;
         }
         if (count($state['Attributes'][$this->attribute]) > 1) {
-            SimpleSAML\Logger::warning(
+            \SimpleSAML\Logger::warning(
                 'More than one value in attribute '.var_export($this->attribute, true).
                 ' on user - not generating attribute NameID.'
             );
@@ -69,7 +70,7 @@ class sspmod_saml_Auth_Process_AttributeNameID extends sspmod_saml_BaseNameIDGen
         $value = $value[0];
 
         if (empty($value)) {
-            SimpleSAML\Logger::warning(
+            \SimpleSAML\Logger::warning(
                 'Empty value in attribute '.var_export($this->attribute, true).
                 ' on user - not generating persistent NameID.'
             );
@@ -78,5 +79,4 @@ class sspmod_saml_Auth_Process_AttributeNameID extends sspmod_saml_BaseNameIDGen
 
         return $value;
     }
-
 }
diff --git a/modules/saml/lib/Auth/Process/AuthnContextClassRef.php b/modules/saml/lib/Auth/Process/AuthnContextClassRef.php
index d1ebbf0efe3dc582a02bf92cd5d9e37b27504dbd..106d7b51f06f7472ece5bc013f6f38e3fa938958 100644
--- a/modules/saml/lib/Auth/Process/AuthnContextClassRef.php
+++ b/modules/saml/lib/Auth/Process/AuthnContextClassRef.php
@@ -1,14 +1,15 @@
 <?php
 
+namespace SimpleSAML\Module\saml\Auth\Process;
 
 /**
  * Filter for setting the AuthnContextClassRef in the response.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_saml_Auth_Process_AuthnContextClassRef extends SimpleSAML_Auth_ProcessingFilter
-{
 
+class AuthnContextClassRef extends \SimpleSAML\Auth\ProcessingFilter
+{
     /**
      * The URI we should set as the AuthnContextClassRef in the login response.
      *
@@ -23,7 +24,7 @@ class sspmod_saml_Auth_Process_AuthnContextClassRef extends SimpleSAML_Auth_Proc
      * @param array $config Configuration information about this filter.
      * @param mixed $reserved For future use.
      *
-     * @throws SimpleSAML_Error_Exception if the mandatory 'AuthnContextClassRef' option is missing.
+     * @throws \SimpleSAML\Error\_Exception if the mandatory 'AuthnContextClassRef' option is missing.
      */
     public function __construct($config, $reserved)
     {
@@ -31,7 +32,7 @@ class sspmod_saml_Auth_Process_AuthnContextClassRef extends SimpleSAML_Auth_Proc
         assert(is_array($config));
 
         if (!isset($config['AuthnContextClassRef'])) {
-            throw new SimpleSAML_Error_Exception('Missing AuthnContextClassRef option in processing filter.');
+            throw new \SimpleSAML\Error\Exception('Missing AuthnContextClassRef option in processing filter.');
         }
 
         $this->authnContextClassRef = (string) $config['AuthnContextClassRef'];
diff --git a/modules/saml/lib/Auth/Process/ExpectedAuthnContextClassRef.php b/modules/saml/lib/Auth/Process/ExpectedAuthnContextClassRef.php
index b8e77dc709c354a7d9ed0b4a0583bed1604fa80a..d7ae42fbc6b15949d8fbb60214c3f7481a8797d7 100644
--- a/modules/saml/lib/Auth/Process/ExpectedAuthnContextClassRef.php
+++ b/modules/saml/lib/Auth/Process/ExpectedAuthnContextClassRef.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace SimpleSAML\Module\saml\Auth\Process;
 
 /**
  * Attribute filter to validate AuthnContextClassRef values.
@@ -16,9 +17,9 @@
  *
  * @package SimpleSAMLphp
  */
-class sspmod_saml_Auth_Process_ExpectedAuthnContextClassRef extends SimpleSAML_Auth_ProcessingFilter
-{
 
+class ExpectedAuthnContextClassRef extends \SimpleSAML\Auth\ProcessingFilter
+{
     /**
      * Array of accepted AuthnContextClassRef
      * @var array
@@ -39,7 +40,7 @@ class sspmod_saml_Auth_Process_ExpectedAuthnContextClassRef extends SimpleSAML_A
      * @param array $config Configuration information about this filter.
      * @param mixed $reserved For future use.
      *
-     * @throws SimpleSAML_Error_Exception if the mandatory 'accepted' configuration option is missing.
+     * @throws \SimpleSAML\Error\Exception if the mandatory 'accepted' configuration option is missing.
      */
     public function __construct($config, $reserved)
     {
@@ -47,10 +48,10 @@ class sspmod_saml_Auth_Process_ExpectedAuthnContextClassRef extends SimpleSAML_A
 
         assert(is_array($config));
         if (empty($config['accepted'])) {
-            SimpleSAML\Logger::error(
+            \SimpleSAML\Logger::error(
                 'ExpectedAuthnContextClassRef: Configuration error. There is no accepted AuthnContextClassRef.'
             );
-            throw new SimpleSAML_Error_Exception(
+            throw new \SimpleSAML\Error\Exception(
                 'ExpectedAuthnContextClassRef: Configuration error. There is no accepted AuthnContextClassRef.'
             );
         }
@@ -89,13 +90,13 @@ class sspmod_saml_Auth_Process_ExpectedAuthnContextClassRef extends SimpleSAML_A
      */
     protected function unauthorized(&$request)
     {
-        SimpleSAML\Logger::error(
+        \SimpleSAML\Logger::error(
             'ExpectedAuthnContextClassRef: Invalid authentication context: '.$this->AuthnContextClassRef.
             '. Accepted values are: '.var_export($this->accepted, true)
         );
 
-        $id = SimpleSAML_Auth_State::saveState($request, 'saml:ExpectedAuthnContextClassRef:unauthorized');
-        $url = SimpleSAML\Module::getModuleURL(
+        $id = \SimpleSAML\Auth\State::saveState($request, 'saml:ExpectedAuthnContextClassRef:unauthorized');
+        $url = \SimpleSAML\Module::getModuleURL(
             'saml/sp/wrong_authncontextclassref.php'
         );
         \SimpleSAML\Utils\HTTP::redirectTrustedURL($url, array('StateId' => $id));
diff --git a/modules/saml/lib/Auth/Process/FilterScopes.php b/modules/saml/lib/Auth/Process/FilterScopes.php
index 3f497e1e96cdc9d7ab404ba636271a89d9df23e7..6b9eda30f63dcb0601300a9ab86147b9fef00a53 100644
--- a/modules/saml/lib/Auth/Process/FilterScopes.php
+++ b/modules/saml/lib/Auth/Process/FilterScopes.php
@@ -11,9 +11,9 @@ use SimpleSAML\Logger;
  * @author Jaime Pérez Crespo, UNINETT AS <jaime.perez@uninett.no>
  * @package SimpleSAMLphp
  */
-class FilterScopes extends \SimpleSAML_Auth_ProcessingFilter
-{
 
+class FilterScopes extends \SimpleSAML\Auth\ProcessingFilter
+{
     /**
      * Stores any pre-configured scoped attributes which come from the filter configuration.
      */
diff --git a/modules/saml/lib/Auth/Process/NameIDAttribute.php b/modules/saml/lib/Auth/Process/NameIDAttribute.php
index 10aae10b633084f19f73b3a9525620ef1f2810a0..29387ba0acdcc03a7f2d353164193cf8df341c70 100644
--- a/modules/saml/lib/Auth/Process/NameIDAttribute.php
+++ b/modules/saml/lib/Auth/Process/NameIDAttribute.php
@@ -1,14 +1,15 @@
 <?php
 
+namespace SimpleSAML\Module\saml\Auth\Process;
 
 /**
  * Authentication processing filter to create an attribute from a NameID.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_saml_Auth_Process_NameIDAttribute extends SimpleSAML_Auth_ProcessingFilter
-{
 
+class NameIDAttribute extends \SimpleSAML\Auth\ProcessingFilter
+{
     /**
      * The attribute we should save the NameID in.
      *
@@ -58,7 +59,7 @@ class sspmod_saml_Auth_Process_NameIDAttribute extends SimpleSAML_Auth_Processin
      * @param string $format The format string.
      * @return array The format string broken into its individual components.
      *
-     * @throws SimpleSAML_Error_Exception if the replacement is invalid.
+     * @throws \SimpleSAML\Error\Exception if the replacement is invalid.
      */
     private static function parseFormat($format)
     {
@@ -81,13 +82,13 @@ class sspmod_saml_Auth_Process_NameIDAttribute extends SimpleSAML_Auth_Processin
                     $ret[] = 'SPNameQualifier';
                     break;
                 case 'V':
-                    $ret[] = 'Value';
+                    $ret[] = 'value';
                     break;
                 case '%':
                     $ret[] = '%';
                     break;
                 default:
-                    throw new SimpleSAML_Error_Exception('NameIDAttribute: Invalid replacement: "%'.$replacement.'"');
+                    throw new \SimpleSAML\Error\Exception('NameIDAttribute: Invalid replacement: "%'.$replacement.'"');
             }
 
             $pos = $next + 2;
@@ -114,17 +115,17 @@ class sspmod_saml_Auth_Process_NameIDAttribute extends SimpleSAML_Auth_Processin
         }
 
         $rep = $state['saml:sp:NameID'];
-        assert(isset($rep['Value']));
+        assert(isset($rep->value));
 
-        $rep['%'] = '%';
-        if (!isset($rep['Format'])) {
-            $rep['Format'] = \SAML2\Constants::NAMEID_UNSPECIFIED;
+        $rep->{'%'} = '%';
+        if (!isset($rep->Format)) {
+            $rep->Format = \SAML2\Constants::NAMEID_UNSPECIFIED;
         }
-        if (!isset($rep['NameQualifier'])) {
-            $rep['NameQualifier'] = $state['Source']['entityid'];
+        if (!isset($rep->NameQualifier)) {
+            $rep->NameQualifier = $state['Source']['entityid'];
         }
-        if (!isset($rep['SPNameQualifier'])) {
-            $rep['SPNameQualifier'] = $state['Destination']['entityid'];
+        if (!isset($rep->SPNameQualifier)) {
+            $rep->SPNameQualifier = $state['Destination']['entityid'];
         }
 
         $value = '';
@@ -133,7 +134,7 @@ class sspmod_saml_Auth_Process_NameIDAttribute extends SimpleSAML_Auth_Processin
             if ($isString) {
                 $value .= $element;
             } else {
-                $value .= $rep[$element];
+                $value .= $rep->$element;
             }
             $isString = !$isString;
         }
diff --git a/modules/saml/lib/Auth/Process/PersistentNameID.php b/modules/saml/lib/Auth/Process/PersistentNameID.php
index 4d6d0bc2260ac4e8e72a458066cb888f4f9f6539..a70c7493291050a32e215c20e888017d3ad4748b 100644
--- a/modules/saml/lib/Auth/Process/PersistentNameID.php
+++ b/modules/saml/lib/Auth/Process/PersistentNameID.php
@@ -1,14 +1,15 @@
 <?php
 
+namespace SimpleSAML\Module\saml\Auth\Process;
 
 /**
  * Authentication processing filter to generate a persistent NameID.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_saml_Auth_Process_PersistentNameID extends sspmod_saml_BaseNameIDGenerator
-{
 
+class PersistentNameID extends \SimpleSAML\Module\saml\BaseNameIDGenerator
+{
     /**
      * Which attribute contains the unique identifier of the user.
      *
@@ -23,7 +24,7 @@ class sspmod_saml_Auth_Process_PersistentNameID extends sspmod_saml_BaseNameIDGe
      * @param array $config Configuration information about this filter.
      * @param mixed $reserved For future use.
      *
-     * @throws SimpleSAML_Error_Exception If the required option 'attribute' is missing.
+     * @throws \SimpleSAML\Error\Exception If the required option 'attribute' is missing.
      */
     public function __construct($config, $reserved)
     {
@@ -33,7 +34,7 @@ class sspmod_saml_Auth_Process_PersistentNameID extends sspmod_saml_BaseNameIDGe
         $this->format = \SAML2\Constants::NAMEID_PERSISTENT;
 
         if (!isset($config['attribute'])) {
-            throw new SimpleSAML_Error_Exception("PersistentNameID: Missing required option 'attribute'.");
+            throw new \SimpleSAML\Error\Exception("PersistentNameID: Missing required option 'attribute'.");
         }
         $this->attribute = $config['attribute'];
     }
@@ -47,28 +48,27 @@ class sspmod_saml_Auth_Process_PersistentNameID extends sspmod_saml_BaseNameIDGe
      */
     protected function getValue(array &$state)
     {
-
         if (!isset($state['Destination']['entityid'])) {
-            SimpleSAML\Logger::warning('No SP entity ID - not generating persistent NameID.');
+            \SimpleSAML\Logger::warning('No SP entity ID - not generating persistent NameID.');
             return null;
         }
         $spEntityId = $state['Destination']['entityid'];
 
         if (!isset($state['Source']['entityid'])) {
-            SimpleSAML\Logger::warning('No IdP entity ID - not generating persistent NameID.');
+            \SimpleSAML\Logger::warning('No IdP entity ID - not generating persistent NameID.');
             return null;
         }
         $idpEntityId = $state['Source']['entityid'];
 
         if (!isset($state['Attributes'][$this->attribute]) || count($state['Attributes'][$this->attribute]) === 0) {
-            SimpleSAML\Logger::warning(
+            \SimpleSAML\Logger::warning(
                 'Missing attribute '.var_export($this->attribute, true).
                 ' on user - not generating persistent NameID.'
             );
             return null;
         }
         if (count($state['Attributes'][$this->attribute]) > 1) {
-            SimpleSAML\Logger::warning(
+            \SimpleSAML\Logger::warning(
                 'More than one value in attribute '.var_export($this->attribute, true).
                 ' on user - not generating persistent NameID.'
             );
@@ -78,14 +78,14 @@ class sspmod_saml_Auth_Process_PersistentNameID extends sspmod_saml_BaseNameIDGe
         $uid = $uid[0];
 
         if (empty($uid)) {
-            SimpleSAML\Logger::warning(
+            \SimpleSAML\Logger::warning(
                 'Empty value in attribute '.var_export($this->attribute, true).
                 ' on user - not generating persistent NameID.'
             );
             return null;
         }
 
-        $secretSalt = SimpleSAML\Utils\Config::getSecretSalt();
+        $secretSalt = \SimpleSAML\Utils\Config::getSecretSalt();
 
         $uidData = 'uidhashbase'.$secretSalt;
         $uidData .= strlen($idpEntityId).':'.$idpEntityId;
diff --git a/modules/saml/lib/Auth/Process/PersistentNameID2TargetedID.php b/modules/saml/lib/Auth/Process/PersistentNameID2TargetedID.php
index 604c2214713adf5edee4694b93289b6e845bf13d..021630afab65a03840afd3ce15004d5492b320b8 100644
--- a/modules/saml/lib/Auth/Process/PersistentNameID2TargetedID.php
+++ b/modules/saml/lib/Auth/Process/PersistentNameID2TargetedID.php
@@ -1,14 +1,15 @@
 <?php
 
+namespace SimpleSAML\Module\saml\Auth\Process;
 
 /**
  * Authentication processing filter to create the eduPersonTargetedID attribute from the persistent NameID.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_saml_Auth_Process_PersistentNameID2TargetedID extends SimpleSAML_Auth_ProcessingFilter
-{
 
+class PersistentNameID2TargetedID extends \SimpleSAML\Auth\ProcessingFilter
+{
     /**
      * The attribute we should save the NameID in.
      *
@@ -60,7 +61,7 @@ class sspmod_saml_Auth_Process_PersistentNameID2TargetedID extends SimpleSAML_Au
         assert(is_array($state));
 
         if (!isset($state['saml:NameID'][\SAML2\Constants::NAMEID_PERSISTENT])) {
-            SimpleSAML\Logger::warning(
+            \SimpleSAML\Logger::warning(
                 'Unable to generate eduPersonTargetedID because no persistent NameID was available.'
             );
             return;
diff --git a/modules/saml/lib/Auth/Process/SQLPersistentNameID.php b/modules/saml/lib/Auth/Process/SQLPersistentNameID.php
index 00891824a7ce7cafb972820a222a3aa96cf50d1d..c1b3bf51a35fe1809c9ca3c3a00742d6b3efe728 100644
--- a/modules/saml/lib/Auth/Process/SQLPersistentNameID.php
+++ b/modules/saml/lib/Auth/Process/SQLPersistentNameID.php
@@ -1,14 +1,15 @@
 <?php
 
+namespace SimpleSAML\Module\saml\Auth\Process;
 
 /**
  * Authentication processing filter to generate a persistent NameID.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_saml_Auth_Process_SQLPersistentNameID extends sspmod_saml_BaseNameIDGenerator
-{
 
+class SQLPersistentNameID extends \SimpleSAML\Module\saml\BaseNameIDGenerator
+{
     /**
      * Which attribute contains the unique identifier of the user.
      *
@@ -44,7 +45,7 @@ class sspmod_saml_Auth_Process_SQLPersistentNameID extends sspmod_saml_BaseNameI
      * @param array $config Configuration information about this filter.
      * @param mixed $reserved For future use.
      *
-     * @throws SimpleSAML_Error_Exception If the 'attribute' option is not specified.
+     * @throws \SimpleSAML\Error\Exception If the 'attribute' option is not specified.
      */
     public function __construct($config, $reserved)
     {
@@ -54,7 +55,7 @@ class sspmod_saml_Auth_Process_SQLPersistentNameID extends sspmod_saml_BaseNameI
         $this->format = \SAML2\Constants::NAMEID_PERSISTENT;
 
         if (!isset($config['attribute'])) {
-            throw new SimpleSAML_Error_Exception("PersistentNameID: Missing required option 'attribute'.");
+            throw new \SimpleSAML\Error\Exception("PersistentNameID: Missing required option 'attribute'.");
         }
         $this->attribute = $config['attribute'];
 
@@ -78,13 +79,13 @@ class sspmod_saml_Auth_Process_SQLPersistentNameID extends sspmod_saml_BaseNameI
      * @param array $state The state array.
      * @return string|null The NameID value.
      *
-     * @throws sspmod_saml_Error if the NameID creation policy is invalid.
+     * @throws \SimpleSAML\Module\saml\Error if the NameID creation policy is invalid.
      */
     protected function getValue(array &$state)
     {
 
         if (!isset($state['saml:NameIDFormat']) && !$this->allowUnspecified) {
-            SimpleSAML\Logger::debug(
+            \SimpleSAML\Logger::debug(
                 'SQLPersistentNameID: Request did not specify persistent NameID format, '.
                 'not generating persistent NameID.'
             );
@@ -99,7 +100,7 @@ class sspmod_saml_Auth_Process_SQLPersistentNameID extends sspmod_saml_BaseNameI
         if (count($validNameIdFormats) && !in_array($this->format, $validNameIdFormats, true) &&
             !$this->allowDifferent
         ) {
-            SimpleSAML\Logger::debug(
+            \SimpleSAML\Logger::debug(
                 'SQLPersistentNameID: SP expects different NameID format ('.
                 implode(', ', $validNameIdFormats).'),  not generating persistent NameID.'
             );
@@ -107,26 +108,26 @@ class sspmod_saml_Auth_Process_SQLPersistentNameID extends sspmod_saml_BaseNameI
         }
 
         if (!isset($state['Destination']['entityid'])) {
-            SimpleSAML\Logger::warning('SQLPersistentNameID: No SP entity ID - not generating persistent NameID.');
+            \SimpleSAML\Logger::warning('SQLPersistentNameID: No SP entity ID - not generating persistent NameID.');
             return null;
         }
         $spEntityId = $state['Destination']['entityid'];
 
         if (!isset($state['Source']['entityid'])) {
-            SimpleSAML\Logger::warning('SQLPersistentNameID: No IdP entity ID - not generating persistent NameID.');
+            \SimpleSAML\Logger::warning('SQLPersistentNameID: No IdP entity ID - not generating persistent NameID.');
             return null;
         }
         $idpEntityId = $state['Source']['entityid'];
 
         if (!isset($state['Attributes'][$this->attribute]) || count($state['Attributes'][$this->attribute]) === 0) {
-            SimpleSAML\Logger::warning(
+            \SimpleSAML\Logger::warning(
                 'SQLPersistentNameID: Missing attribute '.var_export($this->attribute, true).
                 ' on user - not generating persistent NameID.'
             );
             return null;
         }
         if (count($state['Attributes'][$this->attribute]) > 1) {
-            SimpleSAML\Logger::warning(
+            \SimpleSAML\Logger::warning(
                 'SQLPersistentNameID: More than one value in attribute '.var_export($this->attribute, true).
                 ' on user - not generating persistent NameID.'
             );
@@ -136,16 +137,16 @@ class sspmod_saml_Auth_Process_SQLPersistentNameID extends sspmod_saml_BaseNameI
         $uid = $uid[0];
 
         if (empty($uid)) {
-            SimpleSAML\Logger::warning(
+            \SimpleSAML\Logger::warning(
                 'Empty value in attribute '.var_export($this->attribute, true).
                 ' on user - not generating persistent NameID.'
             );
             return null;
         }
 
-        $value = sspmod_saml_IdP_SQLNameID::get($idpEntityId, $spEntityId, $uid);
+        $value = \SimpleSAML\Module\saml\IdP\SQLNameID::get($idpEntityId, $spEntityId, $uid);
         if ($value !== null) {
-            SimpleSAML\Logger::debug(
+            \SimpleSAML\Logger::debug(
                 'SQLPersistentNameID: Found persistent NameID '.var_export($value, true).' for user '.
                 var_export($uid, true).'.'
             );
@@ -153,21 +154,21 @@ class sspmod_saml_Auth_Process_SQLPersistentNameID extends sspmod_saml_BaseNameI
         }
 
         if ((!isset($state['saml:AllowCreate']) || !$state['saml:AllowCreate']) && !$this->alwaysCreate) {
-            SimpleSAML\Logger::warning(
+            \SimpleSAML\Logger::warning(
                 'SQLPersistentNameID: Did not find persistent NameID for user, and not allowed to create new NameID.'
             );
-            throw new sspmod_saml_Error(
+            throw new \SimpleSAML\Module\saml\Error(
                 \SAML2\Constants::STATUS_RESPONDER,
                 'urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy'
             );
         }
 
         $value = bin2hex(openssl_random_pseudo_bytes(20));
-        SimpleSAML\Logger::debug(
+        \SimpleSAML\Logger::debug(
             'SQLPersistentNameID: Created persistent NameID '.var_export($value, true).' for user '.
             var_export($uid, true).'.'
         );
-        sspmod_saml_IdP_SQLNameID::add($idpEntityId, $spEntityId, $uid, $value);
+        \SimpleSAML\Module\saml\IdP\SQLNameID::add($idpEntityId, $spEntityId, $uid, $value);
 
         return $value;
     }
diff --git a/modules/saml/lib/Auth/Process/TransientNameID.php b/modules/saml/lib/Auth/Process/TransientNameID.php
index c43c19a00a6501c3a91f4abb9d2ec31800640797..b4a24de5ecc08fa5d1cc41d1561460f107c5a28b 100644
--- a/modules/saml/lib/Auth/Process/TransientNameID.php
+++ b/modules/saml/lib/Auth/Process/TransientNameID.php
@@ -1,14 +1,15 @@
 <?php
 
+namespace SimpleSAML\Module\saml\Auth\Process;
 
 /**
  * Authentication processing filter to generate a transient NameID.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_saml_Auth_Process_TransientNameID extends sspmod_saml_BaseNameIDGenerator
-{
 
+class TransientNameID extends \SimpleSAML\Module\saml\BaseNameIDGenerator
+{
     /**
      * Initialize this filter, parse configuration
      *
@@ -32,6 +33,6 @@ class sspmod_saml_Auth_Process_TransientNameID extends sspmod_saml_BaseNameIDGen
      */
     protected function getValue(array &$state)
     {
-        return SimpleSAML\Utils\Random::generateID();
+        return \SimpleSAML\Utils\Random::generateID();
     }
 }
diff --git a/modules/saml/lib/Auth/Source/SP.php b/modules/saml/lib/Auth/Source/SP.php
index c379c99c8284f3b2d623870113d25c8ca708cbc8..8eb262208d915aecff119eadbbee42066fe6270c 100644
--- a/modules/saml/lib/Auth/Source/SP.php
+++ b/modules/saml/lib/Auth/Source/SP.php
@@ -1,793 +1,805 @@
 <?php
 
-class sspmod_saml_Auth_Source_SP extends SimpleSAML_Auth_Source {
-
-	/**
-	 * The entity ID of this SP.
-	 *
-	 * @var string
-	 */
-	private $entityId;
-
-
-	/**
-	 * The metadata of this SP.
-	 *
-	 * @var SimpleSAML_Configuration.
-	 */
-	private $metadata;
-
-
-	/**
-	 * The IdP the user is allowed to log into.
-	 *
-	 * @var string|NULL  The IdP the user can log into, or NULL if the user can log into all IdPs.
-	 */
-	private $idp;
-
-
-	/**
-	 * URL to discovery service.
-	 *
-	 * @var string|NULL
-	 */
-	private $discoURL;
-
-
-	/**
-	 * Constructor for SAML SP authentication source.
-	 *
-	 * @param array $info  Information about this authentication source.
-	 * @param array $config  Configuration.
-	 */
-	public function __construct($info, $config) {
-		assert(is_array($info));
-		assert(is_array($config));
-
-		// Call the parent constructor first, as required by the interface
-		parent::__construct($info, $config);
-
-		if (!isset($config['entityID'])) {
-			$config['entityID'] = $this->getMetadataURL();
-		}
-
-		/* For compatibility with code that assumes that $metadata->getString('entityid') gives the entity id. */
-		$config['entityid'] = $config['entityID'];
-
-		$this->metadata = SimpleSAML_Configuration::loadFromArray($config, 'authsources[' . var_export($this->authId, TRUE) . ']');
-		$this->entityId = $this->metadata->getString('entityID');
-		$this->idp = $this->metadata->getString('idp', NULL);
-		$this->discoURL = $this->metadata->getString('discoURL', NULL);
-		
-		if (empty($this->discoURL) && SimpleSAML\Module::isModuleEnabled('discojuice')) {
-			$this->discoURL = SimpleSAML\Module::getModuleURL('discojuice/central.php');
-		}
-	}
-
-
-	/**
-	 * Retrieve the URL to the metadata of this SP.
-	 *
-	 * @return string  The metadata URL.
-	 */
-	public function getMetadataURL() {
-
-		return SimpleSAML\Module::getModuleURL('saml/sp/metadata.php/' . urlencode($this->authId));
-	}
-
-
-	/**
-	 * Retrieve the entity id of this SP.
-	 *
-	 * @return string  The entity id of this SP.
-	 */
-	public function getEntityId() {
-
-		return $this->entityId;
-	}
-
-
-	/**
-	 * Retrieve the metadata of this SP.
-	 *
-	 * @return SimpleSAML_Configuration  The metadata of this SP.
-	 */
-	public function getMetadata() {
-
-		return $this->metadata;
-
-	}
-
-
-	/**
-	 * Retrieve the metadata of an IdP.
-	 *
-	 * @param string $entityId  The entity id of the IdP.
-	 * @return SimpleSAML_Configuration  The metadata of the IdP.
-	 */
-	public function getIdPMetadata($entityId) {
-		assert(is_string($entityId));
-
-		if ($this->idp !== NULL && $this->idp !== $entityId) {
-			throw new SimpleSAML_Error_Exception('Cannot retrieve metadata for IdP ' . var_export($entityId, TRUE) .
-				' because it isn\'t a valid IdP for this SP.');
-		}
-
-		$metadataHandler = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-
-		// First, look in saml20-idp-remote.
-		try {
-			return $metadataHandler->getMetaDataConfig($entityId, 'saml20-idp-remote');
-		} catch (Exception $e) {
-			/* Metadata wasn't found. */
-            SimpleSAML\Logger::debug('getIdpMetadata: ' . $e->getMessage());
-		}
-
-		/* Not found in saml20-idp-remote, look in shib13-idp-remote. */
-		try {
-			return $metadataHandler->getMetaDataConfig($entityId, 'shib13-idp-remote');
-		} catch (Exception $e) {
-			/* Metadata wasn't found. */
-            SimpleSAML\Logger::debug('getIdpMetadata: ' . $e->getMessage());
-		}
-
-		/* Not found. */
-		throw new SimpleSAML_Error_Exception('Could not find the metadata of an IdP with entity ID ' . var_export($entityId, TRUE));
-	}
-
-
-	/**
-	 * Send a SAML1 SSO request to an IdP.
-	 *
-	 * @param SimpleSAML_Configuration $idpMetadata  The metadata of the IdP.
-	 * @param array $state  The state array for the current authentication.
-	 */
-	private function startSSO1(SimpleSAML_Configuration $idpMetadata, array $state) {
-
-		$idpEntityId = $idpMetadata->getString('entityid');
-
-		$state['saml:idp'] = $idpEntityId;
-
-		$ar = new \SimpleSAML\XML\Shib13\AuthnRequest();
-		$ar->setIssuer($this->entityId);
-
-		$id = SimpleSAML_Auth_State::saveState($state, 'saml:sp:sso');
-		$ar->setRelayState($id);
-
-		$useArtifact = $idpMetadata->getBoolean('saml1.useartifact', NULL);
-		if ($useArtifact === NULL) {
-			$useArtifact = $this->metadata->getBoolean('saml1.useartifact', FALSE);
-		}
-
-		if ($useArtifact) {
-			$shire = SimpleSAML\Module::getModuleURL('saml/sp/saml1-acs.php/' . $this->authId . '/artifact');
-		} else {
-			$shire = SimpleSAML\Module::getModuleURL('saml/sp/saml1-acs.php/' . $this->authId);
-		}
-
-		$url = $ar->createRedirect($idpEntityId, $shire);
-
-		SimpleSAML\Logger::debug('Starting SAML 1 SSO to ' . var_export($idpEntityId, TRUE) .
-			' from ' . var_export($this->entityId, TRUE) . '.');
-		\SimpleSAML\Utils\HTTP::redirectTrustedURL($url);
-	}
-
-
-	/**
-	 * Send a SAML2 SSO request to an IdP.
-	 *
-	 * @param SimpleSAML_Configuration $idpMetadata  The metadata of the IdP.
-	 * @param array $state  The state array for the current authentication.
-	 */
-	private function startSSO2(SimpleSAML_Configuration $idpMetadata, array $state) {
-	
-		if (isset($state['saml:ProxyCount']) && $state['saml:ProxyCount'] < 0) {
-			SimpleSAML_Auth_State::throwException(
-				$state,
-				new \SimpleSAML\Module\saml\Error\ProxyCountExceeded(\SAML2\Constants::STATUS_RESPONDER)
-			);
-		}
-
-		$ar = sspmod_saml_Message::buildAuthnRequest($this->metadata, $idpMetadata);
-
-		$ar->setAssertionConsumerServiceURL(SimpleSAML\Module::getModuleURL('saml/sp/saml2-acs.php/' . $this->authId));
-
-		if (isset($state['SimpleSAML_Auth_Source.ReturnURL'])) {
-			$ar->setRelayState($state['SimpleSAML_Auth_Source.ReturnURL']);
-		}
-
-		if (isset($state['saml:AuthnContextClassRef'])) {
-			$accr = SimpleSAML\Utils\Arrays::arrayize($state['saml:AuthnContextClassRef']);
-			$comp = SAML2\Constants::COMPARISON_EXACT;
-			if (isset($state['saml:AuthnContextComparison']) && in_array($state['AuthnContextComparison'], array(
-						SAML2\Constants::COMPARISON_EXACT,
-						SAML2\Constants::COMPARISON_MINIMUM,
-						SAML2\Constants::COMPARISON_MAXIMUM,
-						SAML2\Constants::COMPARISON_BETTER,
-			), true)) {
-				$comp = $state['saml:AuthnContextComparison'];
-			}
-			$ar->setRequestedAuthnContext(array('AuthnContextClassRef' => $accr, 'Comparison' => $comp));
-		}
-
-		if (isset($state['ForceAuthn'])) {
-			$ar->setForceAuthn((bool)$state['ForceAuthn']);
-		}
-
-		if (isset($state['isPassive'])) {
-			$ar->setIsPassive((bool)$state['isPassive']);
-		}
-
-		if (isset($state['saml:NameID'])) {
-			if (!is_array($state['saml:NameID']) && !is_a($state['saml:NameID'], '\SAML2\XML\saml\NameID')) {
-				throw new SimpleSAML_Error_Exception('Invalid value of $state[\'saml:NameID\'].');
-			}
-			$ar->setNameId($state['saml:NameID']);
-		}
-
-		if (isset($state['saml:NameIDPolicy'])) {
-			if (is_string($state['saml:NameIDPolicy'])) {
-				$policy = array(
-					'Format' => (string)$state['saml:NameIDPolicy'],
-					'AllowCreate' => TRUE,
-				);
-			} elseif (is_array($state['saml:NameIDPolicy'])) {
-				$policy = $state['saml:NameIDPolicy'];
-			} else {
-				throw new SimpleSAML_Error_Exception('Invalid value of $state[\'saml:NameIDPolicy\'].');
-			}
-			$ar->setNameIdPolicy($policy);
-		}
-
-		if (isset($state['saml:IDPList'])) {
-			$IDPList = $state['saml:IDPList'];
-		} else {
-			$IDPList = array();
-		}
-		
-		$ar->setIDPList(array_unique(array_merge($this->metadata->getArray('IDPList', array()), 
-												$idpMetadata->getArray('IDPList', array()),
-												(array) $IDPList)));
-		
-		if (isset($state['saml:ProxyCount']) && $state['saml:ProxyCount'] !== null) {
-			$ar->setProxyCount($state['saml:ProxyCount']);
-		} elseif ($idpMetadata->getInteger('ProxyCount', null) !== null) {
-			$ar->setProxyCount($idpMetadata->getInteger('ProxyCount', null));
-		} elseif ($this->metadata->getInteger('ProxyCount', null) !== null) {
-			$ar->setProxyCount($this->metadata->getInteger('ProxyCount', null));
-		}
-		
-		$requesterID = array();
-		if (isset($state['saml:RequesterID'])) {
-			$requesterID = $state['saml:RequesterID'];
-		}
-		
-		if (isset($state['core:SP'])) {
-			$requesterID[] = $state['core:SP'];
-		}
-		
-		$ar->setRequesterID($requesterID);
-		
-		if (isset($state['saml:Extensions'])) {
-			$ar->setExtensions($state['saml:Extensions']);
-		}
-
-		// save IdP entity ID as part of the state
-		$state['ExpectedIssuer'] = $idpMetadata->getString('entityid');
-
-		$id = SimpleSAML_Auth_State::saveState($state, 'saml:sp:sso', TRUE);
-		$ar->setId($id);
-
-		SimpleSAML\Logger::debug('Sending SAML 2 AuthnRequest to ' . var_export($idpMetadata->getString('entityid'), TRUE));
-
-		/* Select appropriate SSO endpoint */
-		if ($ar->getProtocolBinding() === \SAML2\Constants::BINDING_HOK_SSO) {
-			$dst = $idpMetadata->getDefaultEndpoint('SingleSignOnService', array(
-				\SAML2\Constants::BINDING_HOK_SSO)
-			);
-		} else {
-			$dst = $idpMetadata->getDefaultEndpoint('SingleSignOnService', array(
-				\SAML2\Constants::BINDING_HTTP_REDIRECT,
-				\SAML2\Constants::BINDING_HTTP_POST)
-			);
-		}
-		$ar->setDestination($dst['Location']);
-
-		$b = \SAML2\Binding::getBinding($dst['Binding']);
-
-		$this->sendSAML2AuthnRequest($state, $b, $ar);
-
-		assert(false);
-	}
-
-
-	/**
-	 * Function to actually send the authentication request.
-	 *
-	 * This function does not return.
-	 *
-	 * @param array &$state  The state array.
-	 * @param \SAML2\Binding $binding  The binding.
-	 * @param \SAML2\AuthnRequest  $ar  The authentication request.
-	 */
-	public function sendSAML2AuthnRequest(array &$state, \SAML2\Binding $binding, \SAML2\AuthnRequest $ar) {
-		$binding->send($ar);
-		assert(false);
-	}
-
-
-	/**
-	 * Send a SSO request to an IdP.
-	 *
-	 * @param string $idp  The entity ID of the IdP.
-	 * @param array $state  The state array for the current authentication.
-	 */
-	public function startSSO($idp, array $state) {
-		assert(is_string($idp));
-
-		$idpMetadata = $this->getIdPMetadata($idp);
-
-		$type = $idpMetadata->getString('metadata-set');
-		switch ($type) {
-		case 'shib13-idp-remote':
-			$this->startSSO1($idpMetadata, $state);
-			assert(false); /* Should not return. */
-		case 'saml20-idp-remote':
-			$this->startSSO2($idpMetadata, $state);
-			assert(false); /* Should not return. */
-		default:
-			/* Should only be one of the known types. */
-			assert(false);
-		}
-	}
-
-
-	/**
-	 * Start an IdP discovery service operation.
-	 *
-	 * @param array $state  The state array.
-	 */
-	private function startDisco(array $state) {
-
-		$id = SimpleSAML_Auth_State::saveState($state, 'saml:sp:sso');
-
-		$config = SimpleSAML_Configuration::getInstance();
-
-		$discoURL = $this->discoURL;
-		if ($discoURL === NULL) {
-			/* Fallback to internal discovery service. */
-			$discoURL = SimpleSAML\Module::getModuleURL('saml/disco.php');
-		}
-
-		$returnTo = SimpleSAML\Module::getModuleURL('saml/sp/discoresp.php', array('AuthID' => $id));
-		
-		$params = array(
-			'entityID' => $this->entityId,
-			'return' => $returnTo,
-			'returnIDParam' => 'idpentityid'
-		);
-		
-		if(isset($state['saml:IDPList'])) {
-			$params['IDPList'] = $state['saml:IDPList'];
-		}
-
-		if (isset($state['isPassive']) && $state['isPassive']) {
-			$params['isPassive'] = 'true';
-		}
-
-		\SimpleSAML\Utils\HTTP::redirectTrustedURL($discoURL, $params);
-	}
-
-
-	/**
-	 * Start login.
-	 *
-	 * This function saves the information about the login, and redirects to the IdP.
-	 *
-	 * @param array &$state  Information about the current authentication.
-	 */
-	public function authenticate(&$state) {
-		assert(is_array($state));
-
-		/* We are going to need the authId in order to retrieve this authentication source later. */
-		$state['saml:sp:AuthId'] = $this->authId;
-
-		$idp = $this->idp;
-
-		if (isset($state['saml:idp'])) {
-			$idp = (string)$state['saml:idp'];
-		}
-
-		if (isset($state['saml:IDPList']) && sizeof($state['saml:IDPList']) > 0) {
-			// we have a SAML IDPList (we are a proxy): filter the list of IdPs available
-			$mdh = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-			$known_idps = $mdh->getList();
-			$intersection = array_intersect($state['saml:IDPList'], array_keys($known_idps));
-
-			if (empty($intersection)) { // all requested IdPs are unknown
-				throw new SimpleSAML\Module\saml\Error\NoSupportedIDP(
-					\SAML2\Constants::STATUS_REQUESTER,
-					'None of the IdPs requested are supported by this proxy.'
-				);
-			}
-
-			if (!is_null($idp) && !in_array($idp, $intersection, true)) { // the IdP is enforced but not in the IDPList
-				throw new SimpleSAML\Module\saml\Error\NoAvailableIDP(
-					\SAML2\Constants::STATUS_REQUESTER,
-					'None of the IdPs requested are available to this proxy.'
-				);
-			}
-
-			if (is_null($idp) && sizeof($intersection) === 1) { // only one IdP requested or valid
-				$idp = current($state['saml:IDPList']);
-			}
-		}
-
-		if ($idp === null) {
-			$this->startDisco($state);
-			assert(false);
-		}
-
-		$this->startSSO($idp, $state);
-		assert(false);
-	}
-
-
-	/**
-	 * Re-authenticate an user.
-	 *
-	 * This function is called by the IdP to give the authentication source a chance to
-	 * interact with the user even in the case when the user is already authenticated.
-	 *
-	 * @param array &$state  Information about the current authentication.
-	 */
-	public function reauthenticate(array &$state) {
-		assert(is_array($state));
-
-		$session = SimpleSAML_Session::getSessionFromRequest();
-		$data = $session->getAuthState($this->authId);
-		foreach ($data as $k => $v) {
-			$state[$k] = $v;
-		}
-
-		// check if we have an IDPList specified in the request
-		if (isset($state['saml:IDPList']) && sizeof($state['saml:IDPList']) > 0 &&
-			!in_array($state['saml:sp:IdP'], $state['saml:IDPList'], true))
-		{
-			/*
-			 * The user has an existing, valid session. However, the SP provided a list of IdPs it accepts for
-			 * authentication, and the IdP the existing session is related to is not in that list.
-			 *
-			 * First, check if we recognize any of the IdPs requested.
-			 */
-
-			$mdh = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-			$known_idps = $mdh->getList();
-			$intersection = array_intersect($state['saml:IDPList'], array_keys($known_idps));
-
-			if (empty($intersection)) { // all requested IdPs are unknown
-				throw new SimpleSAML\Module\saml\Error\NoSupportedIDP(
-					\SAML2\Constants::STATUS_REQUESTER,
-					'None of the IdPs requested are supported by this proxy.'
-				);
-			}
-
-			/*
-			 * We have at least one IdP in the IDPList that we recognize, and it's not the one currently in use. Let's
-			 * see if this proxy enforces the use of one single IdP.
-			 */
-			if (!is_null($this->idp) && !in_array($this->idp, $intersection, true)) { // an IdP is enforced but not requested
-				throw new SimpleSAML\Module\saml\Error\NoAvailableIDP(
-					\SAML2\Constants::STATUS_REQUESTER,
-					'None of the IdPs requested are available to this proxy.'
-				);
-			}
-
-			/*
-			 * We need to inform the user, and ask whether we should logout before starting the authentication process
-			 * again with a different IdP, or cancel the current SSO attempt.
-			 */
-			SimpleSAML\Logger::warning(
-				"Reauthentication after logout is needed. The IdP '${state['saml:sp:IdP']}' is not in the IDPList ".
-				"provided by the Service Provider '${state['core:SP']}'."
-			);
-
-			$state['saml:sp:IdPMetadata'] = $this->getIdPMetadata($state['saml:sp:IdP']);
-			$state['saml:sp:AuthId'] = $this->authId;
-			self::askForIdPChange($state);
-		}
-	}
-
-
-	/**
-	 * Ask the user to log out before being able to log in again with a different identity provider. Note that this
-	 * method is intended for instances of SimpleSAMLphp running as a SAML proxy, and therefore acting both as an SP
-	 * and an IdP at the same time.
-	 *
-	 * This method will never return.
-	 *
-	 * @param array $state The state array. The following keys must be defined in the array:
-	 * - 'saml:sp:IdPMetadata': a SimpleSAML_Configuration object containing the metadata of the IdP that authenticated
-	 *   the user in the current session.
-	 * - 'saml:sp:AuthId': the identifier of the current authentication source.
-	 * - 'core:IdP': the identifier of the local IdP.
-	 * - 'SPMetadata': an array with the metadata of this local SP.
-	 *
-	 * @throws SimpleSAML_Error_NoPassive In case the authentication request was passive.
-	 */
-	public static function askForIdPChange(array &$state)
-	{
-		assert(array_key_exists('saml:sp:IdPMetadata', $state));
-		assert(array_key_exists('saml:sp:AuthId', $state));
-		assert(array_key_exists('core:IdP', $state));
-		assert(array_key_exists('SPMetadata', $state));
-
-		if (isset($state['isPassive']) && (bool)$state['isPassive']) {
-			// passive request, we cannot authenticate the user
-			throw new SimpleSAML_Error_NoPassive('Reauthentication required');
-		}
-
-		// save the state WITHOUT a restart URL, so that we don't try an IdP-initiated login if something goes wrong
-		$id = SimpleSAML_Auth_State::saveState($state, 'saml:proxy:invalid_idp', true);
-		$url = SimpleSAML\Module::getModuleURL('saml/proxy/invalid_session.php');
-		SimpleSAML\Utils\HTTP::redirectTrustedURL($url, array('AuthState' => $id));
-		assert(false);
-	}
-
-
-	/**
-	 * Log the user out before logging in again.
-	 *
-	 * This method will never return.
-	 *
-	 * @param array $state The state array.
-	 */
-	public static function reauthLogout(array $state)
-	{
-		SimpleSAML\Logger::debug('Proxy: logging the user out before re-authentication.');
-
-		if (isset($state['Responder'])) {
-			$state['saml:proxy:reauthLogout:PrevResponder'] = $state['Responder'];
-		}
-		$state['Responder'] = array('sspmod_saml_Auth_Source_SP', 'reauthPostLogout');
-
-		$idp = SimpleSAML_IdP::getByState($state);
-		$idp->handleLogoutRequest($state, null);
-		assert(false);
-	}
-
-
-	/**
-	 * Complete login operation after re-authenticating the user on another IdP.
-	 *
-	 * @param array $state  The authentication state.
-	 */
-	public static function reauthPostLogin(array $state) {
-		assert(isset($state['ReturnCallback']));
-
-		// Update session state
-		$session = SimpleSAML_Session::getSessionFromRequest();
-		$authId = $state['saml:sp:AuthId'];
-		$session->doLogin($authId, SimpleSAML_Auth_State::getPersistentAuthData($state));
-
-		// resume the login process
-		call_user_func($state['ReturnCallback'], $state);
-		assert(false);
-	}
-
-
-	/**
-	 * Post-logout handler for re-authentication.
-	 *
-	 * This method will never return.
-	 *
-	 * @param SimpleSAML_IdP $idp The IdP we are logging out from.
-	 * @param array &$state The state array with the state during logout.
-	 */
-	public static function reauthPostLogout(SimpleSAML_IdP $idp, array $state) {
-		assert(isset($state['saml:sp:AuthId']));
-
-		SimpleSAML\Logger::debug('Proxy: logout completed.');
-
-		if (isset($state['saml:proxy:reauthLogout:PrevResponder'])) {
-			$state['Responder'] = $state['saml:proxy:reauthLogout:PrevResponder'];
-		}
-
-		$sp = SimpleSAML_Auth_Source::getById($state['saml:sp:AuthId'], 'sspmod_saml_Auth_Source_SP');
-		/** @var sspmod_saml_Auth_Source_SP $authSource */
-		SimpleSAML\Logger::debug('Proxy: logging in again.');
-		$sp->authenticate($state);
-		assert(false);
-	}
-
-
-	/**
-	 * Start a SAML 2 logout operation.
-	 *
-	 * @param array $state  The logout state.
-	 */
-	public function startSLO2(&$state) {
-		assert(is_array($state));
-		assert(array_key_exists('saml:logout:IdP', $state));
-		assert(array_key_exists('saml:logout:NameID', $state));
-		assert(array_key_exists('saml:logout:SessionIndex', $state));
-
-		$id = SimpleSAML_Auth_State::saveState($state, 'saml:slosent');
-
-		$idp = $state['saml:logout:IdP'];
-		$nameId = $state['saml:logout:NameID'];
-		$sessionIndex = $state['saml:logout:SessionIndex'];
-
-		$idpMetadata = $this->getIdPMetadata($idp);
-
-		$endpoint = $idpMetadata->getEndpointPrioritizedByBinding('SingleLogoutService', array(
-			\SAML2\Constants::BINDING_HTTP_REDIRECT,
-			\SAML2\Constants::BINDING_HTTP_POST), FALSE);
-		if ($endpoint === FALSE) {
-			SimpleSAML\Logger::info('No logout endpoint for IdP ' . var_export($idp, TRUE) . '.');
-			return;
-		}
-
-		$lr = sspmod_saml_Message::buildLogoutRequest($this->metadata, $idpMetadata);
-		$lr->setNameId($nameId);
-		$lr->setSessionIndex($sessionIndex);
-		$lr->setRelayState($id);
-		$lr->setDestination($endpoint['Location']);
-
-		$encryptNameId = $idpMetadata->getBoolean('nameid.encryption', NULL);
-		if ($encryptNameId === NULL) {
-			$encryptNameId = $this->metadata->getBoolean('nameid.encryption', FALSE);
-		}
-		if ($encryptNameId) {
-			$lr->encryptNameId(sspmod_saml_Message::getEncryptionKey($idpMetadata));
-		}
-
-		$b = \SAML2\Binding::getBinding($endpoint['Binding']);
-		$b->send($lr);
-
-		assert(false);
-	}
-
-
-	/**
-	 * Start logout operation.
-	 *
-	 * @param array $state  The logout state.
-	 */
-	public function logout(&$state) {
-		assert(is_array($state));
-		assert(array_key_exists('saml:logout:Type', $state));
-
-		$logoutType = $state['saml:logout:Type'];
-		switch ($logoutType) {
-		case 'saml1':
-			/* Nothing to do. */
-			return;
-		case 'saml2':
-			$this->startSLO2($state);
-			return;
-		default:
-			/* Should never happen. */
-			assert(false);
-		}
-	}
-
-
-	/**
-	 * Handle a response from a SSO operation.
-	 *
-	 * @param array $state  The authentication state.
-	 * @param string $idp  The entity id of the IdP.
-	 * @param array $attributes  The attributes.
-	 */
-	public function handleResponse(array $state, $idp, array $attributes) {
-		assert(is_string($idp));
-		assert(array_key_exists('LogoutState', $state));
-		assert(array_key_exists('saml:logout:Type', $state['LogoutState']));
-		
-		$idpMetadata = $this->getIdpMetadata($idp);
-
-		$spMetadataArray = $this->metadata->toArray();
-		$idpMetadataArray = $idpMetadata->toArray();
-
-		/* Save the IdP in the state array. */
-		$state['saml:sp:IdP'] = $idp;
-		$state['PersistentAuthData'][] = 'saml:sp:IdP';
-
-		$authProcState = array(
-			'saml:sp:IdP' => $idp,
-			'saml:sp:State' => $state,
-			'ReturnCall' => array('sspmod_saml_Auth_Source_SP', 'onProcessingCompleted'),
-
-			'Attributes' => $attributes,
-			'Destination' => $spMetadataArray,
-			'Source' => $idpMetadataArray,
-		);
-
-		if (isset($state['saml:sp:NameID'])) {
-			$authProcState['saml:sp:NameID'] = $state['saml:sp:NameID'];
-		}
-		if (isset($state['saml:sp:SessionIndex'])) {
-			$authProcState['saml:sp:SessionIndex'] = $state['saml:sp:SessionIndex'];
-		}
-
-		$pc = new SimpleSAML_Auth_ProcessingChain($idpMetadataArray, $spMetadataArray, 'sp');
-		$pc->processState($authProcState);
-
-		self::onProcessingCompleted($authProcState);
-	}
-
-
-	/**
-	 * Handle a logout request from an IdP.
-	 *
-	 * @param string $idpEntityId  The entity ID of the IdP.
-	 */
-	public function handleLogout($idpEntityId) {
-		assert(is_string($idpEntityId));
-
-		/* Call the logout callback we registered in onProcessingCompleted(). */
-		$this->callLogoutCallback($idpEntityId);
-	}
-
-
-	/**
-	 * Handle an unsolicited login operations.
-	 *
-	 * This method creates a session from the information received. It will then redirect to the given URL. This is used
-	 * to handle IdP initiated SSO. This method will never return.
-	 *
-	 * @param string $authId The id of the authentication source that received the request.
-	 * @param array $state A state array.
-	 * @param string $redirectTo The URL we should redirect the user to after updating the session. The function will
-	 * check if the URL is allowed, so there is no need to manually check the URL on beforehand. Please refer to the
-	 * 'trusted.url.domains' configuration directive for more information about allowing (or disallowing) URLs.
-	 */
-	public static function handleUnsolicitedAuth($authId, array $state, $redirectTo) {
-		assert(is_string($authId));
-		assert(is_string($redirectTo));
-
-		$session = SimpleSAML_Session::getSessionFromRequest();
-		$session->doLogin($authId, SimpleSAML_Auth_State::getPersistentAuthData($state));
-
-		\SimpleSAML\Utils\HTTP::redirectUntrustedURL($redirectTo);
-	}
-
-
-	/**
-	 * Called when we have completed the procssing chain.
-	 *
-	 * @param array $authProcState  The processing chain state.
-	 */
-	public static function onProcessingCompleted(array $authProcState) {
-		assert(array_key_exists('saml:sp:IdP', $authProcState));
-		assert(array_key_exists('saml:sp:State', $authProcState));
-		assert(array_key_exists('Attributes', $authProcState));
-
-		$idp = $authProcState['saml:sp:IdP'];
-		$state = $authProcState['saml:sp:State'];
-
-		$sourceId = $state['saml:sp:AuthId'];
-		$source = SimpleSAML_Auth_Source::getById($sourceId);
-		if ($source === NULL) {
-			throw new Exception('Could not find authentication source with id ' . $sourceId);
-		}
-
-		/* Register a callback that we can call if we receive a logout request from the IdP. */
-		$source->addLogoutCallback($idp, $state);
-
-		$state['Attributes'] = $authProcState['Attributes'];
-
-		if (isset($state['saml:sp:isUnsolicited']) && (bool)$state['saml:sp:isUnsolicited']) {
-			if (!empty($state['saml:sp:RelayState'])) {
-				$redirectTo = $state['saml:sp:RelayState'];
-			} else {
-				$redirectTo = $source->getMetadata()->getString('RelayState', '/');
-			}
-			self::handleUnsolicitedAuth($sourceId, $state, $redirectTo);
-		}
-
-		SimpleSAML_Auth_Source::completeAuth($state);
-	}
-
+namespace SimpleSAML\Module\saml\Auth\Source;
+
+use SimpleSAML\Auth\Source;
+use SimpleSAML\Auth\State;
+
+class SP extends Source
+{
+    /**
+     * The entity ID of this SP.
+     *
+     * @var string
+     */
+    private $entityId;
+
+    /**
+     * The metadata of this SP.
+     *
+     * @var \SimpleSAML\Configuration
+     */
+    private $metadata;
+
+    /**
+     * The IdP the user is allowed to log into.
+     *
+     * @var string|null  The IdP the user can log into, or null if the user can log into all IdPs.
+     */
+    private $idp;
+
+    /**
+     * URL to discovery service.
+     *
+     * @var string|null
+     */
+    private $discoURL;
+
+    /**
+     * Constructor for SAML SP authentication source.
+     *
+     * @param array $info  Information about this authentication source.
+     * @param array $config  Configuration.
+     */
+    public function __construct($info, $config)
+    {
+        assert(is_array($info));
+        assert(is_array($config));
+
+        // Call the parent constructor first, as required by the interface
+        parent::__construct($info, $config);
+
+        if (!isset($config['entityID'])) {
+            $config['entityID'] = $this->getMetadataURL();
+        }
+
+        /* For compatibility with code that assumes that $metadata->getString('entityid')
+         * gives the entity id. */
+        $config['entityid'] = $config['entityID'];
+
+        $this->metadata = \SimpleSAML\Configuration::loadFromArray($config,
+            'authsources[' . var_export($this->authId, true) . ']');
+        $this->entityId = $this->metadata->getString('entityID');
+        $this->idp = $this->metadata->getString('idp', null);
+        $this->discoURL = $this->metadata->getString('discoURL', null);
+
+        if (empty($this->discoURL) && \SimpleSAML\Module::isModuleEnabled('discojuice')) {
+            $this->discoURL = \SimpleSAML\Module::getModuleURL('discojuice/central.php');
+        }
+    }
+
+    /**
+     * Retrieve the URL to the metadata of this SP.
+     *
+     * @return string  The metadata URL.
+     */
+    public function getMetadataURL()
+    {
+        return \SimpleSAML\Module::getModuleURL('saml/sp/metadata.php/' . urlencode($this->authId));
+    }
+
+    /**
+     * Retrieve the entity id of this SP.
+     *
+     * @return string  The entity id of this SP.
+     */
+    public function getEntityId()
+    {
+        return $this->entityId;
+    }
+
+    /**
+     * Retrieve the metadata of this SP.
+     *
+     * @return \SimpleSAML\Configuration  The metadata of this SP.
+     */
+    public function getMetadata()
+    {
+        return $this->metadata;
+    }
+
+    /**
+     * Retrieve the metadata of an IdP.
+     *
+     * @param string $entityId  The entity id of the IdP.
+     * @return \SimpleSAML\Configuration  The metadata of the IdP.
+     */
+    public function getIdPMetadata($entityId)
+    {
+        assert(is_string($entityId));
+
+        if ($this->idp !== null && $this->idp !== $entityId) {
+            throw new \SimpleSAML\Error\Exception('Cannot retrieve metadata for IdP ' .
+                var_export($entityId, true) .
+                ' because it isn\'t a valid IdP for this SP.');
+        }
+
+        $metadataHandler = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
+
+        // First, look in saml20-idp-remote.
+        try {
+            return $metadataHandler->getMetaDataConfig($entityId, 'saml20-idp-remote');
+        } catch (\Exception $e) {
+            /* Metadata wasn't found. */
+            \SimpleSAML\Logger::debug('getIdpMetadata: ' . $e->getMessage());
+        }
+
+        /* Not found in saml20-idp-remote, look in shib13-idp-remote. */
+        try {
+            return $metadataHandler->getMetaDataConfig($entityId, 'shib13-idp-remote');
+        } catch (\Exception $e) {
+            /* Metadata wasn't found. */
+            \SimpleSAML\Logger::debug('getIdpMetadata: ' . $e->getMessage());
+        }
+
+        /* Not found. */
+        throw new \SimpleSAML\Error\Exception('Could not find the metadata of an IdP with entity ID ' .
+            var_export($entityId, true));
+    }
+
+    /**
+     * Send a SAML1 SSO request to an IdP.
+     *
+     * @param \SimpleSAML\Configuration $idpMetadata  The metadata of the IdP.
+     * @param array $state  The state array for the current authentication.
+     */
+    private function startSSO1(\SimpleSAML\Configuration $idpMetadata, array $state)
+    {
+        $idpEntityId = $idpMetadata->getString('entityid');
+
+        $state['saml:idp'] = $idpEntityId;
+
+        $ar = new \SimpleSAML\XML\Shib13\AuthnRequest();
+        $ar->setIssuer($this->entityId);
+
+        $id = State::saveState($state, 'saml:sp:sso');
+        $ar->setRelayState($id);
+
+        $useArtifact = $idpMetadata->getBoolean('saml1.useartifact', null);
+        if ($useArtifact === null) {
+            $useArtifact = $this->metadata->getBoolean('saml1.useartifact', false);
+        }
+
+        if ($useArtifact) {
+            $shire = \SimpleSAML\Module::getModuleURL('saml/sp/saml1-acs.php/' . $this->authId . '/artifact');
+        } else {
+            $shire = \SimpleSAML\Module::getModuleURL('saml/sp/saml1-acs.php/' . $this->authId);
+        }
+
+        $url = $ar->createRedirect($idpEntityId, $shire);
+
+        \SimpleSAML\Logger::debug('Starting SAML 1 SSO to ' . var_export($idpEntityId, true) .
+            ' from ' . var_export($this->entityId, true) . '.');
+        \SimpleSAML\Utils\HTTP::redirectTrustedURL($url);
+    }
+
+    /**
+     * Send a SAML2 SSO request to an IdP.
+     *
+     * @param \SimpleSAML\Configuration $idpMetadata  The metadata of the IdP.
+     * @param array $state  The state array for the current authentication.
+     */
+    private function startSSO2(\SimpleSAML\Configuration $idpMetadata, array $state)
+    {
+        if (isset($state['saml:ProxyCount']) && $state['saml:ProxyCount'] < 0) {
+            State::throwException(
+                $state,
+                new \SimpleSAML\Module\saml\Error\ProxyCountExceeded(\SAML2\Constants::STATUS_RESPONDER)
+            );
+        }
+
+        $ar = \SimpleSAML\Module\saml\Message::buildAuthnRequest($this->metadata, $idpMetadata);
+
+        $ar->setAssertionConsumerServiceURL(\SimpleSAML\Module::getModuleURL('saml/sp/saml2-acs.php/' . $this->authId));
+
+        if (isset($state['\SimpleSAML\Auth\Source.ReturnURL'])) {
+            $ar->setRelayState($state['\SimpleSAML\Auth\Source.ReturnURL']);
+        }
+
+        if (isset($state['saml:AuthnContextClassRef'])) {
+            $accr = \SimpleSAML\Utils\Arrays::arrayize($state['saml:AuthnContextClassRef']);
+            $comp = \SAML2\Constants::COMPARISON_EXACT;
+            if (isset($state['saml:AuthnContextComparison']) && in_array($state['AuthnContextComparison'], array(
+                        \SAML2\Constants::COMPARISON_EXACT,
+                        \SAML2\Constants::COMPARISON_MINIMUM,
+                        \SAML2\Constants::COMPARISON_MAXIMUM,
+                        \SAML2\Constants::COMPARISON_BETTER,
+            ), true)) {
+                $comp = $state['saml:AuthnContextComparison'];
+            }
+            $ar->setRequestedAuthnContext(array('AuthnContextClassRef' => $accr, 'Comparison' => $comp));
+        }
+
+        if (isset($state['ForceAuthn'])) {
+            $ar->setForceAuthn((bool)$state['ForceAuthn']);
+        }
+
+        if (isset($state['isPassive'])) {
+            $ar->setIsPassive((bool)$state['isPassive']);
+        }
+
+        if (isset($state['saml:NameID'])) {
+            if (!is_array($state['saml:NameID']) && !is_a($state['saml:NameID'], '\SAML2\XML\saml\NameID')) {
+                throw new \SimpleSAML\Error\Exception('Invalid value of $state[\'saml:NameID\'].');
+            }
+            $ar->setNameId($state['saml:NameID']);
+        }
+
+        if (isset($state['saml:NameIDPolicy'])) {
+            if (is_string($state['saml:NameIDPolicy'])) {
+                $policy = array(
+                    'Format' => (string)$state['saml:NameIDPolicy'],
+                    'AllowCreate' => true,
+                );
+            } elseif (is_array($state['saml:NameIDPolicy'])) {
+                $policy = $state['saml:NameIDPolicy'];
+            } else {
+                throw new \SimpleSAML\Error\Exception('Invalid value of $state[\'saml:NameIDPolicy\'].');
+            }
+            $ar->setNameIdPolicy($policy);
+        }
+
+        if (isset($state['saml:IDPList'])) {
+            $IDPList = $state['saml:IDPList'];
+        } else {
+            $IDPList = array();
+        }
+
+        $ar->setIDPList(array_unique(array_merge($this->metadata->getArray('IDPList', array()), 
+                                                $idpMetadata->getArray('IDPList', array()),
+                                                (array) $IDPList)));
+
+        if (isset($state['saml:ProxyCount']) && $state['saml:ProxyCount'] !== null) {
+            $ar->setProxyCount($state['saml:ProxyCount']);
+        } elseif ($idpMetadata->getInteger('ProxyCount', null) !== null) {
+            $ar->setProxyCount($idpMetadata->getInteger('ProxyCount', null));
+        } elseif ($this->metadata->getInteger('ProxyCount', null) !== null) {
+            $ar->setProxyCount($this->metadata->getInteger('ProxyCount', null));
+        }
+
+        $requesterID = array();
+        if (isset($state['saml:RequesterID'])) {
+            $requesterID = $state['saml:RequesterID'];
+        }
+
+        if (isset($state['core:SP'])) {
+            $requesterID[] = $state['core:SP'];
+        }
+
+        $ar->setRequesterID($requesterID);
+
+        if (isset($state['saml:Extensions'])) {
+            $ar->setExtensions($state['saml:Extensions']);
+        }
+
+        // save IdP entity ID as part of the state
+        $state['ExpectedIssuer'] = $idpMetadata->getString('entityid');
+
+        $id = State::saveState($state, 'saml:sp:sso', true);
+        $ar->setId($id);
+
+        \SimpleSAML\Logger::debug('Sending SAML 2 AuthnRequest to ' .
+            var_export($idpMetadata->getString('entityid'), true));
+
+        /* Select appropriate SSO endpoint */
+        if ($ar->getProtocolBinding() === \SAML2\Constants::BINDING_HOK_SSO) {
+            $dst = $idpMetadata->getDefaultEndpoint('SingleSignOnService', array(
+                \SAML2\Constants::BINDING_HOK_SSO)
+            );
+        } else {
+            $dst = $idpMetadata->getDefaultEndpoint('SingleSignOnService', array(
+                \SAML2\Constants::BINDING_HTTP_REDIRECT,
+                \SAML2\Constants::BINDING_HTTP_POST)
+            );
+        }
+        $ar->setDestination($dst['Location']);
+
+        $b = \SAML2\Binding::getBinding($dst['Binding']);
+
+        $this->sendSAML2AuthnRequest($state, $b, $ar);
+
+        assert(false);
+    }
+
+    /**
+     * Function to actually send the authentication request.
+     *
+     * This function does not return.
+     *
+     * @param array &$state  The state array.
+     * @param \SAML2\Binding $binding  The binding.
+     * @param \SAML2\AuthnRequest  $ar  The authentication request.
+     */
+    public function sendSAML2AuthnRequest(array &$state, \SAML2\Binding $binding, \SAML2\AuthnRequest $ar)
+    {
+        $binding->send($ar);
+        assert(false);
+    }
+
+    /**
+     * Send a SSO request to an IdP.
+     *
+     * @param string $idp  The entity ID of the IdP.
+     * @param array $state  The state array for the current authentication.
+     */
+    public function startSSO($idp, array $state)
+    {
+        assert(is_string($idp));
+
+        $idpMetadata = $this->getIdPMetadata($idp);
+
+        $type = $idpMetadata->getString('metadata-set');
+        switch ($type) {
+        case 'shib13-idp-remote':
+            $this->startSSO1($idpMetadata, $state);
+            assert(false); /* Should not return. */
+        case 'saml20-idp-remote':
+            $this->startSSO2($idpMetadata, $state);
+            assert(false); /* Should not return. */
+        default:
+            /* Should only be one of the known types. */
+            assert(false);
+        }
+    }
+
+    /**
+     * Start an IdP discovery service operation.
+     *
+     * @param array $state  The state array.
+     */
+    private function startDisco(array $state)
+    {
+        $id = State::saveState($state, 'saml:sp:sso');
+
+        $discoURL = $this->discoURL;
+        if ($discoURL === null) {
+            /* Fallback to internal discovery service. */
+            $discoURL = \SimpleSAML\Module::getModuleURL('saml/disco.php');
+        }
+
+        $returnTo = \SimpleSAML\Module::getModuleURL('saml/sp/discoresp.php', array('AuthID' => $id));
+
+        $params = array(
+            'entityID' => $this->entityId,
+            'return' => $returnTo,
+            'returnIDParam' => 'idpentityid'
+        );
+
+        if(isset($state['saml:IDPList'])) {
+            $params['IDPList'] = $state['saml:IDPList'];
+        }
+
+        if (isset($state['isPassive']) && $state['isPassive']) {
+            $params['isPassive'] = 'true';
+        }
+
+        \SimpleSAML\Utils\HTTP::redirectTrustedURL($discoURL, $params);
+    }
+
+    /**
+     * Start login.
+     *
+     * This function saves the information about the login, and redirects to the IdP.
+     *
+     * @param array &$state  Information about the current authentication.
+     */
+    public function authenticate(&$state)
+    {
+        assert(is_array($state));
+
+        /* We are going to need the authId in order to retrieve this authentication source later. */
+        $state['saml:sp:AuthId'] = $this->authId;
+
+        $idp = $this->idp;
+
+        if (isset($state['saml:idp'])) {
+            $idp = (string)$state['saml:idp'];
+        }
+
+        if (isset($state['saml:IDPList']) && sizeof($state['saml:IDPList']) > 0) {
+            // we have a SAML IDPList (we are a proxy): filter the list of IdPs available
+            $mdh = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
+            $known_idps = $mdh->getList();
+            $intersection = array_intersect($state['saml:IDPList'], array_keys($known_idps));
+
+            if (empty($intersection)) {
+                // all requested IdPs are unknown
+                throw new \SimpleSAML\Module\saml\Error\NoSupportedIDP(
+                    \SAML2\Constants::STATUS_REQUESTER,
+                    'None of the IdPs requested are supported by this proxy.'
+                );
+            }
+
+            if (!is_null($idp) && !in_array($idp, $intersection, true)) {
+                // the IdP is enforced but not in the IDPList
+                throw new \SimpleSAML\Module\saml\Error\NoAvailableIDP(
+                    \SAML2\Constants::STATUS_REQUESTER,
+                    'None of the IdPs requested are available to this proxy.'
+                );
+            }
+
+            if (is_null($idp) && sizeof($intersection) === 1) {
+                // only one IdP requested or valid
+                $idp = current($state['saml:IDPList']);
+            }
+        }
+
+        if ($idp === null) {
+            $this->startDisco($state);
+            assert(false);
+        }
+
+        $this->startSSO($idp, $state);
+        assert(false);
+    }
+
+    /**
+     * Re-authenticate an user.
+     *
+     * This function is called by the IdP to give the authentication source a chance to
+     * interact with the user even in the case when the user is already authenticated.
+     *
+     * @param array &$state  Information about the current authentication.
+     */
+    public function reauthenticate(array &$state)
+    {
+        assert(is_array($state));
+
+        $session = \SimpleSAML\Session::getSessionFromRequest();
+        $data = $session->getAuthState($this->authId);
+        foreach ($data as $k => $v) {
+            $state[$k] = $v;
+        }
+
+        // check if we have an IDPList specified in the request
+        if (isset($state['saml:IDPList']) && sizeof($state['saml:IDPList']) > 0 &&
+            !in_array($state['saml:sp:IdP'], $state['saml:IDPList'], true))
+        {
+            /*
+             * The user has an existing, valid session. However, the SP
+             * provided a list of IdPs it accepts for authentication, and
+             * the IdP the existing session is related to is not in that list.
+             *
+             * First, check if we recognize any of the IdPs requested.
+             */
+
+            $mdh = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
+            $known_idps = $mdh->getList();
+            $intersection = array_intersect($state['saml:IDPList'], array_keys($known_idps));
+
+            if (empty($intersection)) {
+                // all requested IdPs are unknown
+                throw new \SimpleSAML\Module\saml\Error\NoSupportedIDP(
+                    \SAML2\Constants::STATUS_REQUESTER,
+                    'None of the IdPs requested are supported by this proxy.'
+                );
+            }
+
+            /*
+             * We have at least one IdP in the IDPList that we recognize, and
+             * it's not the one currently in use. Let's see if this proxy
+             * enforces the use of one single IdP.
+             */
+            if (!is_null($this->idp) && !in_array($this->idp, $intersection, true)) {
+                // an IdP is enforced but not requested
+                throw new \SimpleSAML\Module\saml\Error\NoAvailableIDP(
+                    \SAML2\Constants::STATUS_REQUESTER,
+                    'None of the IdPs requested are available to this proxy.'
+                );
+            }
+
+            /*
+             * We need to inform the user, and ask whether we should logout before
+             * starting the authentication process again with a different IdP, or
+             * cancel the current SSO attempt.
+             */
+            \SimpleSAML\Logger::warning(
+                "Reauthentication after logout is needed. The IdP '${state['saml:sp:IdP']}' is not in the IDPList ".
+                "provided by the Service Provider '${state['core:SP']}'."
+            );
+
+            $state['saml:sp:IdPMetadata'] = $this->getIdPMetadata($state['saml:sp:IdP']);
+            $state['saml:sp:AuthId'] = $this->authId;
+            self::askForIdPChange($state);
+        }
+    }
+
+
+    /**
+     * Ask the user to log out before being able to log in again with a
+     * different identity provider. Note that this method is intended for
+     * instances of SimpleSAMLphp running as a SAML proxy, and therefore
+     * acting both as an SP and an IdP at the same time.
+     *
+     * This method will never return.
+     *
+     * @param array $state The state array.
+     * The following keys must be defined in the array:
+     * - 'saml:sp:IdPMetadata': a \SimpleSAML\Configuration object containing
+     *   the metadata of the IdP that authenticated the user in the current
+     *   session.
+     * - 'saml:sp:AuthId': the identifier of the current authentication source.
+     * - 'core:IdP': the identifier of the local IdP.
+     * - 'SPMetadata': an array with the metadata of this local SP.
+     *
+     * @throws \SimpleSAML\Error\NoPassive In case the authentication request was passive.
+     */
+    public static function askForIdPChange(array &$state)
+    {
+        assert(array_key_exists('saml:sp:IdPMetadata', $state));
+        assert(array_key_exists('saml:sp:AuthId', $state));
+        assert(array_key_exists('core:IdP', $state));
+        assert(array_key_exists('SPMetadata', $state));
+
+        if (isset($state['isPassive']) && (bool)$state['isPassive']) {
+            // passive request, we cannot authenticate the user
+            throw new \SimpleSAML\Module\saml\Error\NoPassive(
+                    \SAML2\Constants::STATUS_REQUESTER,
+                    'Reauthentication required'
+            );
+        }
+
+        // save the state WITHOUT a restart URL, so that we don't try an IdP-initiated login if something goes wrong
+        $id = State::saveState($state, 'saml:proxy:invalid_idp', true);
+        $url = \SimpleSAML\Module::getModuleURL('saml/proxy/invalid_session.php');
+        \SimpleSAML\Utils\HTTP::redirectTrustedURL($url, array('AuthState' => $id));
+        assert(false);
+    }
+
+    /**
+     * Log the user out before logging in again.
+     *
+     * This method will never return.
+     *
+     * @param array $state The state array.
+     */
+    public static function reauthLogout(array $state)
+    {
+        \SimpleSAML\Logger::debug('Proxy: logging the user out before re-authentication.');
+
+        if (isset($state['Responder'])) {
+            $state['saml:proxy:reauthLogout:PrevResponder'] = $state['Responder'];
+        }
+        $state['Responder'] = array('\SimpleSAML\Module\saml\Auth\Source\SP', 'reauthPostLogout');
+
+        $idp = \SimpleSAML\IdP::getByState($state);
+        $idp->handleLogoutRequest($state, null);
+        assert(false);
+    }
+
+    /**
+     * Complete login operation after re-authenticating the user on another IdP.
+     *
+     * @param array $state  The authentication state.
+     */
+    public static function reauthPostLogin(array $state)
+    {
+        assert(isset($state['ReturnCallback']));
+
+        // Update session state
+        $session = \SimpleSAML\Session::getSessionFromRequest();
+        $authId = $state['saml:sp:AuthId'];
+        $session->doLogin($authId, State::getPersistentAuthData($state));
+
+        // resume the login process
+        call_user_func($state['ReturnCallback'], $state);
+        assert(false);
+    }
+
+    /**
+     * Post-logout handler for re-authentication.
+     *
+     * This method will never return.
+     *
+     * @param \SimpleSAML\IdP $idp The IdP we are logging out from.
+     * @param array &$state The state array with the state during logout.
+     */
+    public static function reauthPostLogout(\SimpleSAML\IdP $idp, array $state)
+    {
+        assert(isset($state['saml:sp:AuthId']));
+
+        \SimpleSAML\Logger::debug('Proxy: logout completed.');
+
+        if (isset($state['saml:proxy:reauthLogout:PrevResponder'])) {
+            $state['Responder'] = $state['saml:proxy:reauthLogout:PrevResponder'];
+        }
+
+        $sp = Source::getById($state['saml:sp:AuthId'], '\SimpleSAML\Module\saml\Auth\Source\SP');
+        /** @var \SimpleSAML\Module\saml\Auth\Source\SP $authSource */
+        \SimpleSAML\Logger::debug('Proxy: logging in again.');
+        $sp->authenticate($state);
+        assert(false);
+    }
+
+    /**
+     * Start a SAML 2 logout operation.
+     *
+     * @param array $state  The logout state.
+     */
+    public function startSLO2(&$state)
+    {
+        assert(is_array($state));
+        assert(array_key_exists('saml:logout:IdP', $state));
+        assert(array_key_exists('saml:logout:NameID', $state));
+        assert(array_key_exists('saml:logout:SessionIndex', $state));
+
+        $id = State::saveState($state, 'saml:slosent');
+
+        $idp = $state['saml:logout:IdP'];
+        $nameId = $state['saml:logout:NameID'];
+        $sessionIndex = $state['saml:logout:SessionIndex'];
+
+        $idpMetadata = $this->getIdPMetadata($idp);
+
+        $endpoint = $idpMetadata->getEndpointPrioritizedByBinding('SingleLogoutService', array(
+            \SAML2\Constants::BINDING_HTTP_REDIRECT,
+            \SAML2\Constants::BINDING_HTTP_POST), false);
+        if ($endpoint === false) {
+            \SimpleSAML\Logger::info('No logout endpoint for IdP ' . var_export($idp, true) . '.');
+            return;
+        }
+
+        $lr = \SimpleSAML\Module\saml\Message::buildLogoutRequest($this->metadata, $idpMetadata);
+        $lr->setNameId($nameId);
+        $lr->setSessionIndex($sessionIndex);
+        $lr->setRelayState($id);
+        $lr->setDestination($endpoint['Location']);
+
+        $encryptNameId = $idpMetadata->getBoolean('nameid.encryption', null);
+        if ($encryptNameId === null) {
+            $encryptNameId = $this->metadata->getBoolean('nameid.encryption', false);
+        }
+        if ($encryptNameId) {
+            $lr->encryptNameId(\SimpleSAML\Module\saml\Message::getEncryptionKey($idpMetadata));
+        }
+
+        $b = \SAML2\Binding::getBinding($endpoint['Binding']);
+        $b->send($lr);
+
+        assert(false);
+    }
+
+    /**
+     * Start logout operation.
+     *
+     * @param array $state  The logout state.
+     */
+    public function logout(&$state)
+    {
+        assert(is_array($state));
+        assert(array_key_exists('saml:logout:Type', $state));
+
+        $logoutType = $state['saml:logout:Type'];
+        switch ($logoutType) {
+        case 'saml1':
+            /* Nothing to do. */
+            return;
+        case 'saml2':
+            $this->startSLO2($state);
+            return;
+        default:
+            /* Should never happen. */
+            assert(false);
+        }
+    }
+
+    /**
+     * Handle a response from a SSO operation.
+     *
+     * @param array $state  The authentication state.
+     * @param string $idp  The entity id of the IdP.
+     * @param array $attributes  The attributes.
+     */
+    public function handleResponse(array $state, $idp, array $attributes)
+    {
+        assert(is_string($idp));
+        assert(array_key_exists('LogoutState', $state));
+        assert(array_key_exists('saml:logout:Type', $state['LogoutState']));
+
+        $idpMetadata = $this->getIdpMetadata($idp);
+
+        $spMetadataArray = $this->metadata->toArray();
+        $idpMetadataArray = $idpMetadata->toArray();
+
+        /* Save the IdP in the state array. */
+        $state['saml:sp:IdP'] = $idp;
+        $state['PersistentAuthData'][] = 'saml:sp:IdP';
+
+        $authProcState = array(
+            'saml:sp:IdP' => $idp,
+            'saml:sp:State' => $state,
+            'ReturnCall' => array('\SimpleSAML\Module\saml\Auth\Source\SP', 'onProcessingCompleted'),
+
+            'Attributes' => $attributes,
+            'Destination' => $spMetadataArray,
+            'Source' => $idpMetadataArray,
+        );
+
+        if (isset($state['saml:sp:NameID'])) {
+            $authProcState['saml:sp:NameID'] = $state['saml:sp:NameID'];
+        }
+        if (isset($state['saml:sp:SessionIndex'])) {
+            $authProcState['saml:sp:SessionIndex'] = $state['saml:sp:SessionIndex'];
+        }
+
+        $pc = new \SimpleSAML\Auth\ProcessingChain($idpMetadataArray, $spMetadataArray, 'sp');
+        $pc->processState($authProcState);
+
+        self::onProcessingCompleted($authProcState);
+    }
+
+    /**
+     * Handle a logout request from an IdP.
+     *
+     * @param string $idpEntityId  The entity ID of the IdP.
+     */
+    public function handleLogout($idpEntityId)
+    {
+        assert(is_string($idpEntityId));
+
+        /* Call the logout callback we registered in onProcessingCompleted(). */
+        $this->callLogoutCallback($idpEntityId);
+    }
+
+    /**
+     * Handle an unsolicited login operations.
+     *
+     * This method creates a session from the information received. It will
+     * then redirect to the given URL. This is used to handle IdP initiated
+     * SSO. This method will never return.
+     *
+     * @param string $authId The id of the authentication source that received the request.
+     * @param array $state A state array.
+     * @param string $redirectTo The URL we should redirect the user to after updating
+     * the session. The function will check if the URL is allowed, so there is no need to
+     * manually check the URL on beforehand. Please refer to the 'trusted.url.domains'
+     * configuration directive for more information about allowing (or disallowing) URLs.
+     */
+    public static function handleUnsolicitedAuth($authId, array $state, $redirectTo)
+    {
+        assert(is_string($authId));
+        assert(is_string($redirectTo));
+
+        $session = \SimpleSAML\Session::getSessionFromRequest();
+        $session->doLogin($authId, State::getPersistentAuthData($state));
+
+        \SimpleSAML\Utils\HTTP::redirectUntrustedURL($redirectTo);
+    }
+
+    /**
+     * Called when we have completed the procssing chain.
+     *
+     * @param array $authProcState  The processing chain state.
+     */
+    public static function onProcessingCompleted(array $authProcState)
+    {
+        assert(array_key_exists('saml:sp:IdP', $authProcState));
+        assert(array_key_exists('saml:sp:State', $authProcState));
+        assert(array_key_exists('Attributes', $authProcState));
+
+        $idp = $authProcState['saml:sp:IdP'];
+        $state = $authProcState['saml:sp:State'];
+
+        $sourceId = $state['saml:sp:AuthId'];
+        $source = Source::getById($sourceId);
+        if ($source === null) {
+            throw new \Exception('Could not find authentication source with id ' . $sourceId);
+        }
+
+        /* Register a callback that we can call if we receive a logout request from the IdP. */
+        $source->addLogoutCallback($idp, $state);
+
+        $state['Attributes'] = $authProcState['Attributes'];
+
+        if (isset($state['saml:sp:isUnsolicited']) && (bool)$state['saml:sp:isUnsolicited']) {
+            if (!empty($state['saml:sp:RelayState'])) {
+                $redirectTo = $state['saml:sp:RelayState'];
+            } else {
+                $redirectTo = $source->getMetadata()->getString('RelayState', '/');
+            }
+            self::handleUnsolicitedAuth($sourceId, $state, $redirectTo);
+        }
+
+        Source::completeAuth($state);
+    }
 }
diff --git a/modules/saml/lib/BaseNameIDGenerator.php b/modules/saml/lib/BaseNameIDGenerator.php
index 342c51d6619f78386fe8c96bdc1ef05bd0b1d35f..12115dc37dfb5769db9cdbeca9193c47c349f7f7 100644
--- a/modules/saml/lib/BaseNameIDGenerator.php
+++ b/modules/saml/lib/BaseNameIDGenerator.php
@@ -1,116 +1,121 @@
 <?php
 
+namespace SimpleSAML\Module\saml;
+
 /**
  * Base filter for generating NameID values.
  *
  * @package SimpleSAMLphp
  */
-abstract class sspmod_saml_BaseNameIDGenerator extends SimpleSAML_Auth_ProcessingFilter {
-
-	/**
-	 * What NameQualifier should be used.
-	 * Can be one of:
-	 *  - a string: The qualifier to use.
-	 *  - FALSE: Do not include a NameQualifier. This is the default.
-	 *  - TRUE: Use the IdP entity ID.
-	 *
-	 * @var string|bool
-	 */
-	private $nameQualifier;
-
-
-	/**
-	 * What SPNameQualifier should be used.
-	 * Can be one of:
-	 *  - a string: The qualifier to use.
-	 *  - FALSE: Do not include a SPNameQualifier.
-	 *  - TRUE: Use the SP entity ID. This is the default.
-	 *
-	 * @var string|bool
-	 */
-	private $spNameQualifier;
-
-
-	/**
-	 * The format of this NameID.
-	 *
-	 * This property must be initialized the subclass.
-	 *
-	 * @var string
-	 */
-	protected $format;
-
-
-	/**
-	 * Initialize this filter, parse configuration.
-	 *
-	 * @param array $config  Configuration information about this filter.
-	 * @param mixed $reserved  For future use.
-	 */
-	public function __construct($config, $reserved) {
-		parent::__construct($config, $reserved);
-		assert(is_array($config));
-
-		if (isset($config['NameQualifier'])) {
-			$this->nameQualifier = $config['NameQualifier'];
-		} else {
-			$this->nameQualifier = FALSE;
-		}
-
-		if (isset($config['SPNameQualifier'])) {
-			$this->spNameQualifier = $config['SPNameQualifier'];
-		} else {
-			$this->spNameQualifier = TRUE;
-		}
-	}
-
-
-	/**
-	 * Get the NameID value.
-	 *
-	 * @return string|NULL  The NameID value.
-	 */
-	abstract protected function getValue(array &$state);
-
-
-	/**
-	 * Generate transient NameID.
-	 *
-	 * @param array &$state  The request state.
-	 */
-	public function process(&$state) {
-		assert(is_array($state));
-		assert(is_string($this->format));
-
-		$value = $this->getValue($state);
-		if ($value === NULL) {
-			return;
-		}
-
-		$nameId = new \SAML2\XML\saml\NameID();
-		$nameId->value = $value;
-
-		if ($this->nameQualifier === TRUE) {
-			if (isset($state['IdPMetadata']['entityid'])) {
-				$nameId->NameQualifier = $state['IdPMetadata']['entityid'];
-			} else {
-				SimpleSAML\Logger::warning('No IdP entity ID, unable to set NameQualifier.');
-			}
-		} elseif (is_string($this->nameQualifier)) {
-			$nameId->NameQualifier = $this->nameQualifier;
-		}
-
-		if ($this->spNameQualifier === TRUE) {
-			if (isset($state['SPMetadata']['entityid'])) {
-				$nameId->SPNameQualifier = $state['SPMetadata']['entityid'];
-			} else {
-				SimpleSAML\Logger::warning('No SP entity ID, unable to set SPNameQualifier.');
-			}
-		} elseif (is_string($this->spNameQualifier)) {
-			$nameId->SPNameQualifier = $this->spNameQualifier;
-		}
-
-		$state['saml:NameID'][$this->format] = $nameId;
-	}
+
+abstract class BaseNameIDGenerator extends \SimpleSAML\Auth\ProcessingFilter
+{
+    /**
+     * What NameQualifier should be used.
+     * Can be one of:
+     *  - a string: The qualifier to use.
+     *  - FALSE: Do not include a NameQualifier. This is the default.
+     *  - TRUE: Use the IdP entity ID.
+     *
+     * @var string|bool
+     */
+    private $nameQualifier;
+
+
+    /**
+     * What SPNameQualifier should be used.
+     * Can be one of:
+     *  - a string: The qualifier to use.
+     *  - FALSE: Do not include a SPNameQualifier.
+     *  - TRUE: Use the SP entity ID. This is the default.
+     *
+     * @var string|bool
+     */
+    private $spNameQualifier;
+
+
+    /**
+     * The format of this NameID.
+     *
+     * This property must be initialized the subclass.
+     *
+     * @var string
+     */
+    protected $format;
+
+
+    /**
+     * Initialize this filter, parse configuration.
+     *
+     * @param array $config  Configuration information about this filter.
+     * @param mixed $reserved  For future use.
+     */
+    public function __construct($config, $reserved)
+    {
+        parent::__construct($config, $reserved);
+        assert(is_array($config));
+
+        if (isset($config['NameQualifier'])) {
+            $this->nameQualifier = $config['NameQualifier'];
+        } else {
+            $this->nameQualifier = false;
+        }
+
+        if (isset($config['SPNameQualifier'])) {
+            $this->spNameQualifier = $config['SPNameQualifier'];
+        } else {
+            $this->spNameQualifier = true;
+        }
+    }
+
+
+    /**
+     * Get the NameID value.
+     *
+     * @return string|null  The NameID value.
+     */
+    abstract protected function getValue(array &$state);
+
+
+    /**
+     * Generate transient NameID.
+     *
+     * @param array &$state  The request state.
+     */
+    public function process(&$state)
+    {
+        assert(is_array($state));
+        assert(is_string($this->format));
+
+        $value = $this->getValue($state);
+        if ($value === null) {
+            return;
+        }
+
+        $nameId = new \SAML2\XML\saml\NameID();
+        $nameId->value = $value;
+
+        if ($this->nameQualifier === true) {
+            if (isset($state['IdPMetadata']['entityid'])) {
+                $nameId->NameQualifier = $state['IdPMetadata']['entityid'];
+            } else {
+                \SimpleSAML\Logger::warning('No IdP entity ID, unable to set NameQualifier.');
+            }
+        } elseif (is_string($this->nameQualifier)) {
+            $nameId->NameQualifier = $this->nameQualifier;
+        }
+
+        if ($this->spNameQualifier === true) {
+            if (isset($state['SPMetadata']['entityid'])) {
+                $nameId->SPNameQualifier = $state['SPMetadata']['entityid'];
+            } else {
+                \SimpleSAML\Logger::warning('No SP entity ID, unable to set SPNameQualifier.');
+            }
+        } elseif (is_string($this->spNameQualifier)) {
+            $nameId->SPNameQualifier = $this->spNameQualifier;
+        }
+
+        $state['saml:NameID'][$this->format] = $nameId;
+    }
 
 }
diff --git a/modules/saml/lib/Error.php b/modules/saml/lib/Error.php
index 22a031db45c08e7d6239f5a2242f8baf06d533ac..605624190fdc6c708cc4027a6770996e5479a55a 100644
--- a/modules/saml/lib/Error.php
+++ b/modules/saml/lib/Error.php
@@ -1,194 +1,197 @@
 <?php
 
+namespace SimpleSAML\Module\saml;
+
 /**
  * Class for representing a SAML 2 error.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_saml_Error extends SimpleSAML_Error_Exception {
-
-	/**
-	 * The top-level status code.
-	 *
-	 * @var string
-	 */
-	private $status;
-
-
-	/**
-	 * The second-level status code, or NULL if no second-level status code is defined.
-	 *
-	 * @var string|NULL
-	 */
-	private $subStatus;
-
-
-	/**
-	 * The status message, or NULL if no status message is defined.
-	 *
-	 * @var string|NULL
-	 */
-	private $statusMessage;
-
-
-	/**
-	 * Create a SAML 2 error.
-	 *
-	 * @param string $status  The top-level status code.
-	 * @param string|NULL $subStatus  The second-level status code. Can be NULL, in which case there is no second-level status code.
-	 * @param string|NULL $statusMessage  The status message. Can be NULL, in which case there is no status message.
-	 * @param Exception|NULL $cause  The cause of this exception. Can be NULL.
-	 */
-	public function __construct($status, $subStatus = NULL, $statusMessage = NULL, Exception $cause = NULL) {
-		assert(is_string($status));
-		assert($subStatus === null || is_string($subStatus));
-		assert($statusMessage === null || is_string($statusMessage));
-
-		$st = self::shortStatus($status);
-		if ($subStatus !== null) {
-			$st .= '/' . self::shortStatus($subStatus);
-		}
-		if ($statusMessage !== null) {
-			$st .= ': ' . $statusMessage;
-		}
-		parent::__construct($st, 0, $cause);
-
-		$this->status = $status;
-		$this->subStatus = $subStatus;
-		$this->statusMessage = $statusMessage;
-	}
-
-
-	/**
-	 * Get the top-level status code.
-	 *
-	 * @return string  The top-level status code.
-	 */
-	public function getStatus() {
-		return $this->status;
-	}
-
-
-	/**
-	 * Get the second-level status code.
-	 *
-	 * @return string|NULL  The second-level status code or NULL if no second-level status code is present.
-	 */
-	public function getSubStatus() {
-		return $this->subStatus;
-	}
-
-
-	/**
-	 * Get the status message.
-	 *
-	 * @return string|NULL  The status message or NULL if no status message is present.
-	 */
-	public function getStatusMessage() {
-		return $this->statusMessage;
-	}
-
-
-	/**
-	 * Create a SAML2 error from an exception.
-	 *
-	 * This function attempts to create a SAML2 error with the appropriate
-	 * status codes from an arbitrary exception.
-	 *
-	 * @param Exception $exception  The original exception.
-	 * @return sspmod_saml_Error  The new exception.
-	 */
-	public static function fromException(Exception $exception) {
-
-		if ($exception instanceof sspmod_saml_Error) {
-			// Return the original exception unchanged
-			return $exception;
-
-		// TODO: remove this branch in 2.0
-		} elseif ($exception instanceof SimpleSAML_Error_NoPassive) {
-			$e = new self(
-				\SAML2\Constants::STATUS_RESPONDER,
-				\SAML2\Constants::STATUS_NO_PASSIVE,
-				$exception->getMessage(),
-				$exception
-				);
-		// TODO: remove this branch in 2.0
-		} elseif ($exception instanceof SimpleSAML_Error_ProxyCountExceeded) {
-			$e = new self(
-				\SAML2\Constants::STATUS_RESPONDER,
-				\SAML2\Constants::STATUS_PROXY_COUNT_EXCEEDED,
-				$exception->getMessage(),
-				$exception
-			);
-		} else {
-			$e = new self(
-				\SAML2\Constants::STATUS_RESPONDER,
-				NULL,
-				get_class($exception) . ': ' . $exception->getMessage(),
-				$exception
-				);
-		}
-
-		return $e;
-	}
-
-
-	/**
-	 * Create a normal exception from a SAML2 error.
-	 *
-	 * This function attempts to reverse the operation of the fromException() function.
-	 * If it is unable to create a more specific exception, it will return the current
-	 * object.
-	 *
-	 * @see sspmod_saml_Error::fromException()
-	 *
-	 * @return SimpleSAML_Error_Exception  An exception representing this error.
-	 */
-	public function toException() {
-
-		if ($this->statusMessage !== NULL) {
-			$msg = $this->statusMessage;
-		} else {
-			$msg = '';
-		}
-
-		$e = NULL;
-
-		switch ($this->status) {
-		case \SAML2\Constants::STATUS_RESPONDER:
-			switch ($this->subStatus) {
-			case \SAML2\Constants::STATUS_NO_PASSIVE:
-				$e = new SimpleSAML_Error_NoPassive($this->statusMessage, 0, $this);
-				break;
-			}
-			break;
-		}
-
-		if ($e === NULL) {
-			return $this;
-		}
-
-		return $e;
-	}
-
-
-	/**
-	 * Create a short version of the status code.
-	 *
-	 * Remove the 'urn:oasis:names:tc:SAML:2.0:status:'-prefix of status codes
-	 * if it is present.
-	 *
-	 * @param string $status  The status code.
-	 * @return string  A shorter version of the status code.
-	 */
-	private static function shortStatus($status) {
-		assert(is_string($status));
-
-		$t = 'urn:oasis:names:tc:SAML:2.0:status:';
-		if (substr($status, 0, strlen($t)) === $t) {
-			return substr($status, strlen($t));
-		}
-
-		return $status;
-	}
+
+class Error extends \SimpleSAML\Error\Exception
+{
+    /**
+     * The top-level status code.
+     *
+     * @var string
+     */
+    private $status;
+
+    /**
+     * The second-level status code, or NULL if no second-level status code is defined.
+     *
+     * @var string|null
+     */
+    private $subStatus;
+
+    /**
+     * The status message, or NULL if no status message is defined.
+     *
+     * @var string|null
+     */
+    private $statusMessage;
+
+
+    /**
+     * Create a SAML 2 error.
+     *
+     * @param string $status  The top-level status code.
+     * @param string|null $subStatus  The second-level status code. Can be NULL, in which case there is no second-level status code.
+     * @param string|null $statusMessage  The status message. Can be NULL, in which case there is no status message.
+     * @param \Exception|null $cause  The cause of this exception. Can be NULL.
+     */
+    public function __construct($status, $subStatus = null, $statusMessage = null, \Exception $cause = null)
+    {
+        assert(is_string($status));
+        assert($subStatus === null || is_string($subStatus));
+        assert($statusMessage === null || is_string($statusMessage));
+
+        $st = self::shortStatus($status);
+        if ($subStatus !== null) {
+            $st .= '/' . self::shortStatus($subStatus);
+        }
+        if ($statusMessage !== null) {
+            $st .= ': ' . $statusMessage;
+        }
+        parent::__construct($st, 0, $cause);
+
+        $this->status = $status;
+        $this->subStatus = $subStatus;
+        $this->statusMessage = $statusMessage;
+    }
+
+
+    /**
+     * Get the top-level status code.
+     *
+     * @return string  The top-level status code.
+     */
+    public function getStatus()
+    {
+        return $this->status;
+    }
+
+
+    /**
+     * Get the second-level status code.
+     *
+     * @return string|null  The second-level status code or NULL if no second-level status code is present.
+     */
+    public function getSubStatus()
+    {
+        return $this->subStatus;
+    }
+
+
+    /**
+     * Get the status message.
+     *
+     * @return string|null  The status message or NULL if no status message is present.
+     */
+    public function getStatusMessage()
+    {
+        return $this->statusMessage;
+    }
+
+
+    /**
+     * Create a SAML2 error from an exception.
+     *
+     * This function attempts to create a SAML2 error with the appropriate
+     * status codes from an arbitrary exception.
+     *
+     * @param \SimpleSAML\Error\Exception $exception  The original exception.
+     * @return \SimpleSAML\Module\saml\Error  The new exception.
+     */
+    public static function fromException(\SimpleSAML\Error\Exception $exception)
+    {
+        if ($exception instanceof \SimpleSAML\Module\saml\Error) {
+            // Return the original exception unchanged
+            return $exception;
+
+        // TODO: remove this branch in 2.0
+        } elseif ($exception instanceof \SimpleSAML\Error\NoPassive) {
+            $e = new self(
+                \SAML2\Constants::STATUS_RESPONDER,
+                \SAML2\Constants::STATUS_NO_PASSIVE,
+                $exception->getMessage(),
+                $exception
+                );
+        // TODO: remove this branch in 2.0
+        } elseif ($exception instanceof \SimpleSAML\Error\ProxyCountExceeded) {
+            $e = new self(
+                \SAML2\Constants::STATUS_RESPONDER,
+                \SAML2\Constants::STATUS_PROXY_COUNT_EXCEEDED,
+                $exception->getMessage(),
+                $exception
+            );
+        } else {
+            $e = new self(
+                \SAML2\Constants::STATUS_RESPONDER,
+                null,
+                get_class($exception) . ': ' . $exception->getMessage(),
+                $exception
+                );
+        }
+
+        return $e;
+    }
+
+
+    /**
+     * Create a normal exception from a SAML2 error.
+     *
+     * This function attempts to reverse the operation of the fromException() function.
+     * If it is unable to create a more specific exception, it will return the current
+     * object.
+     *
+     * @see \SimpleSAML\Module\saml\Error::fromException()
+     *
+     * @return \SimpleSAML\Error\Exception  An exception representing this error.
+     */
+    public function toException()
+    {
+        $e = null;
+
+        switch ($this->status) {
+            case \SAML2\Constants::STATUS_RESPONDER:
+                switch ($this->subStatus) {
+                    case \SAML2\Constants::STATUS_NO_PASSIVE:
+                        $e = new \SimpleSAML\Module\saml\Error\NoPassive(
+                            \SAML2\Constants::STATUS_RESPONDER,
+                            $this->statusMessage
+                        );
+                        break;
+                }
+            break;
+        }
+
+        if ($e === null) {
+            return $this;
+        }
+
+        return $e;
+    }
+
+
+    /**
+     * Create a short version of the status code.
+     *
+     * Remove the 'urn:oasis:names:tc:SAML:2.0:status:'-prefix of status codes
+     * if it is present.
+     *
+     * @param string $status  The status code.
+     * @return string  A shorter version of the status code.
+     */
+    private static function shortStatus($status)
+    {
+        assert(is_string($status));
+
+        $t = 'urn:oasis:names:tc:SAML:2.0:status:';
+        if (substr($status, 0, strlen($t)) === $t) {
+            return substr($status, strlen($t));
+        }
+
+        return $status;
+    }
 }
diff --git a/modules/saml/lib/Error/NoAuthnContext.php b/modules/saml/lib/Error/NoAuthnContext.php
index 27f5ecf559c6c67e6786e55b6ddb0ba82ed925b4..54a147463ba3dca10f7ac8eeb15c702b3a92257a 100644
--- a/modules/saml/lib/Error/NoAuthnContext.php
+++ b/modules/saml/lib/Error/NoAuthnContext.php
@@ -1,4 +1,7 @@
 <?php
+
+namespace SimpleSAML\Module\saml\Error;
+
 /**
  * A SAML error indicating that none of the requested Authentication Contexts can be used.
  *
@@ -6,11 +9,9 @@
  * @package SimpleSAMLphp
  */
 
-namespace SimpleSAML\Module\saml\Error;
-
 use SAML2\Constants;
 
-class NoAuthnContext extends \sspmod_saml_Error
+class NoAuthnContext extends \SimpleSAML\Module\saml\Error
 {
     /**
      * NoAuthnContext error constructor.
diff --git a/modules/saml/lib/Error/NoAvailableIDP.php b/modules/saml/lib/Error/NoAvailableIDP.php
index 9245ef993498164a083fa53654cea01f9d18d73d..92f78d00b539c5208e978bed6f9d9a3c2d94c41f 100644
--- a/modules/saml/lib/Error/NoAvailableIDP.php
+++ b/modules/saml/lib/Error/NoAvailableIDP.php
@@ -1,4 +1,7 @@
 <?php
+
+namespace SimpleSAML\Module\saml\Error;
+
 /**
  * A SAML error indicating that none of the requested IdPs can be used.
  *
@@ -6,11 +9,9 @@
  * @package SimpleSAMLphp
  */
 
-namespace SimpleSAML\Module\saml\Error;
-
 use SAML2\Constants;
 
-class NoAvailableIDP extends \sspmod_saml_Error
+class NoAvailableIDP extends \SimpleSAML\Module\saml\Error
 {
     /**
      * NoAvailableIDP error constructor.
diff --git a/modules/saml/lib/Error/NoPassive.php b/modules/saml/lib/Error/NoPassive.php
index 2fa30be6bd13b376d62fef2cad2dbc7ffe3cf823..8602bce1fc30db10426bb1d5de5557a3412f9baa 100644
--- a/modules/saml/lib/Error/NoPassive.php
+++ b/modules/saml/lib/Error/NoPassive.php
@@ -1,4 +1,7 @@
 <?php
+
+namespace SimpleSAML\Module\saml\Error;
+
 /**
  * A SAML error indicating that passive authentication cannot be used.
  *
@@ -6,11 +9,9 @@
  * @package SimpleSAMLphp
  */
 
-namespace SimpleSAML\Module\saml\Error;
-
 use SAML2\Constants;
 
-class NoPassive extends \sspmod_saml_Error
+class NoPassive extends \SimpleSAML\Module\saml\Error
 {
     /**
      * NoPassive error constructor.
diff --git a/modules/saml/lib/Error/NoSupportedIDP.php b/modules/saml/lib/Error/NoSupportedIDP.php
index 0e1e6d7f78abb6eab55902cfa5f177c00733354c..5eedd1d27ae13a3e10c84af65fc67da117ec385c 100644
--- a/modules/saml/lib/Error/NoSupportedIDP.php
+++ b/modules/saml/lib/Error/NoSupportedIDP.php
@@ -1,4 +1,7 @@
 <?php
+
+namespace SimpleSAML\Module\saml\Error;
+
 /**
  * A SAML error indicating that none of the IdPs requested are supported.
  *
@@ -6,11 +9,9 @@
  * @package SimpleSAMLphp
  */
 
-namespace SimpleSAML\Module\saml\Error;
-
 use SAML2\Constants;
 
-class NoSupportedIDP extends \sspmod_saml_Error
+class NoSupportedIDP extends \SimpleSAML\Module\saml\Error
 {
     /**
      * NoSupportedIDP error constructor.
diff --git a/modules/saml/lib/Error/ProxyCountExceeded.php b/modules/saml/lib/Error/ProxyCountExceeded.php
index 7ded7b61b7f99459b53c2464e0978f7d8d00ed2a..f85216d82298252dd4a7b9f3154bd5ae2c3702a2 100644
--- a/modules/saml/lib/Error/ProxyCountExceeded.php
+++ b/modules/saml/lib/Error/ProxyCountExceeded.php
@@ -1,4 +1,7 @@
 <?php
+
+namespace SimpleSAML\Module\saml\Error;
+
 /**
  * A SAML error indicating that the maximum amount of proxies traversed has been reached.
  *
@@ -6,11 +9,9 @@
  * @package SimpleSAMLphp
  */
 
-namespace SimpleSAML\Module\saml\Error;
-
 use SAML2\Constants;
 
-class ProxyCountExceeded extends \sspmod_saml_Error
+class ProxyCountExceeded extends \SimpleSAML\Module\saml\Error
 {
     /**
      * ProxyCountExceeded error constructor.
diff --git a/modules/saml/lib/IdP/SAML1.php b/modules/saml/lib/IdP/SAML1.php
index cd8affad9fc9a25d02f1c3d5fc56e9f31be9069d..8e5226c472f4bc185df6ee87ec1e9b2c14e8b825 100644
--- a/modules/saml/lib/IdP/SAML1.php
+++ b/modules/saml/lib/IdP/SAML1.php
@@ -1,135 +1,140 @@
 <?php
+
+namespace SimpleSAML\Module\saml\IdP;
+
 use SimpleSAML\Bindings\Shib13\HTTPPost;
+use SimpleSAML\Utils\HTTP;
 
 /**
  * IdP implementation for SAML 1.1 protocol.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_saml_IdP_SAML1 {
-
-	/**
-	 * Send a response to the SP.
-	 *
-	 * @param array $state  The authentication state.
-	 */
-	public static function sendResponse(array $state) {
-		assert(isset($state['Attributes']));
-		assert(isset($state['SPMetadata']));
-		assert(isset($state['saml:shire']));
-		assert(array_key_exists('saml:target', $state)); // Can be NULL
-
-		$spMetadata = $state["SPMetadata"];
-		$spEntityId = $spMetadata['entityid'];
-		$spMetadata = SimpleSAML_Configuration::loadFromArray($spMetadata,
-			'$metadata[' . var_export($spEntityId, TRUE) . ']');
-
-		SimpleSAML\Logger::info('Sending SAML 1.1 Response to ' . var_export($spEntityId, TRUE));
-
-		$attributes = $state['Attributes'];
-		$shire = $state['saml:shire'];
-		$target = $state['saml:target'];
-
-		$idp = SimpleSAML_IdP::getByState($state);
-
-		$idpMetadata = $idp->getConfig();
-
-		$config = SimpleSAML_Configuration::getInstance();
-		$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-
-		$statsData = array(
-			'spEntityID' => $spEntityId,
-			'idpEntityID' => $idpMetadata->getString('entityid'),
-			'protocol' => 'saml1',
-		);
-		if (isset($state['saml:AuthnRequestReceivedAt'])) {
-			$statsData['logintime'] = microtime(TRUE) - $state['saml:AuthnRequestReceivedAt'];
-		}
-		SimpleSAML_Stats::log('saml:idp:Response', $statsData);
-
-		// Generate and send response.
-		$ar = new \SimpleSAML\XML\Shib13\AuthnResponse();
-		$authnResponseXML = $ar->generate($idpMetadata, $spMetadata, $shire, $attributes);
-
-		$httppost = new HTTPPost($config, $metadata);
-		$httppost->sendResponse($authnResponseXML, $idpMetadata, $spMetadata, $target, $shire);
-	}
-
-
-	/**
-	 * Receive an authentication request.
-	 *
-	 * @param SimpleSAML_IdP $idp  The IdP we are receiving it for.
-	 */
-	public static function receiveAuthnRequest(SimpleSAML_IdP $idp) {
-
-		if (isset($_REQUEST['cookieTime'])) {
-			$cookieTime = (int)$_REQUEST['cookieTime'];
-			if ($cookieTime + 5 > time()) {
-				/*
-				 * Less than five seconds has passed since we were
-				 * here the last time. Cookies are probably disabled.
-				 */
-				\SimpleSAML\Utils\HTTP::checkSessionCookie(\SimpleSAML\Utils\HTTP::getSelfURL());
-			}
-		}
-
-		if (!isset($_REQUEST['providerId'])) {
-			throw new SimpleSAML_Error_BadRequest('Missing providerId parameter.');
-		}
-		$spEntityId = (string)$_REQUEST['providerId'];
-
-		if (!isset($_REQUEST['shire'])) {
-			throw new SimpleSAML_Error_BadRequest('Missing shire parameter.');
-		}
-		$shire = (string)$_REQUEST['shire'];
-
-		if (isset($_REQUEST['target'])) {
-			$target = $_REQUEST['target'];
-		} else {
-			$target = NULL;
-		}
-
-		SimpleSAML\Logger::info('Shib1.3 - IdP.SSOService: Got incoming Shib authnRequest from ' . var_export($spEntityId, TRUE) . '.');
-
-		$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
-		$spMetadata = $metadata->getMetaDataConfig($spEntityId, 'shib13-sp-remote');
-
-		$found = FALSE;
-		foreach ($spMetadata->getEndpoints('AssertionConsumerService') as $ep) {
-			if ($ep['Binding'] !== 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post') {
-				continue;
-			}
-			if ($ep['Location'] !== $shire) {
-				continue;
-			}
-			$found = TRUE;
-			break;
-		}
-		if (!$found) {
-			throw new Exception('Invalid AssertionConsumerService for SP ' .
-				var_export($spEntityId, TRUE) . ': ' . var_export($shire, TRUE));
-		}
-
-		SimpleSAML_Stats::log('saml:idp:AuthnRequest', array(
-			'spEntityID' => $spEntityId,
-			'protocol' => 'saml1',
-		));
-
-		$sessionLostURL = \SimpleSAML\Utils\HTTP::addURLParameters(
-            \SimpleSAML\Utils\HTTP::getSelfURL(),
-			array('cookieTime' => time()));
-
-		$state = array(
-			'Responder' => array('sspmod_saml_IdP_SAML1', 'sendResponse'),
-			'SPMetadata' => $spMetadata->toArray(),
-			SimpleSAML_Auth_State::RESTART => $sessionLostURL,
-			'saml:shire' => $shire,
-			'saml:target' => $target,
-			'saml:AuthnRequestReceivedAt' => microtime(TRUE),
-		);
-
-		$idp->handleAuthenticationRequest($state);
-	}
 
+class SAML1
+{
+    /**
+     * Send a response to the SP.
+     *
+     * @param array $state  The authentication state.
+     */
+    public static function sendResponse(array $state)
+    {
+        assert(isset($state['Attributes']));
+        assert(isset($state['SPMetadata']));
+        assert(isset($state['saml:shire']));
+        assert(array_key_exists('saml:target', $state)); // Can be NULL
+
+        $spMetadata = $state["SPMetadata"];
+        $spEntityId = $spMetadata['entityid'];
+        $spMetadata = \SimpleSAML\Configuration::loadFromArray($spMetadata,
+            '$metadata[' . var_export($spEntityId, true) . ']');
+
+        \SimpleSAML\Logger::info('Sending SAML 1.1 Response to ' . var_export($spEntityId, true));
+
+        $attributes = $state['Attributes'];
+        $shire = $state['saml:shire'];
+        $target = $state['saml:target'];
+
+        $idp = \SimpleSAML\IdP::getByState($state);
+
+        $idpMetadata = $idp->getConfig();
+
+        $config = \SimpleSAML\Configuration::getInstance();
+        $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
+
+        $statsData = array(
+            'spEntityID' => $spEntityId,
+            'idpEntityID' => $idpMetadata->getString('entityid'),
+            'protocol' => 'saml1',
+        );
+        if (isset($state['saml:AuthnRequestReceivedAt'])) {
+            $statsData['logintime'] = microtime(true) - $state['saml:AuthnRequestReceivedAt'];
+        }
+        \SimpleSAML\Stats::log('saml:idp:Response', $statsData);
+
+        // Generate and send response.
+        $ar = new \SimpleSAML\XML\Shib13\AuthnResponse();
+        $authnResponseXML = $ar->generate($idpMetadata, $spMetadata, $shire, $attributes);
+
+        $httppost = new HTTPPost($config, $metadata);
+        $httppost->sendResponse($authnResponseXML, $idpMetadata, $spMetadata, $target, $shire);
+    }
+
+
+    /**
+     * Receive an authentication request.
+     *
+     * @param \SimpleSAML\IdP $idp  The IdP we are receiving it for.
+     */
+    public static function receiveAuthnRequest(\SimpleSAML\IdP $idp)
+    {
+        if (isset($_REQUEST['cookieTime'])) {
+            $cookieTime = (int)$_REQUEST['cookieTime'];
+            if ($cookieTime + 5 > time()) {
+                /*
+                 * Less than five seconds has passed since we were
+                 * here the last time. Cookies are probably disabled.
+                 */
+                HTTP::checkSessionCookie(HTTP::getSelfURL());
+            }
+        }
+
+        if (!isset($_REQUEST['providerId'])) {
+            throw new \SimpleSAML\Error\BadRequest('Missing providerId parameter.');
+        }
+        $spEntityId = (string)$_REQUEST['providerId'];
+
+        if (!isset($_REQUEST['shire'])) {
+            throw new \SimpleSAML\Error\BadRequest('Missing shire parameter.');
+        }
+        $shire = (string)$_REQUEST['shire'];
+
+        if (isset($_REQUEST['target'])) {
+            $target = $_REQUEST['target'];
+        } else {
+            $target = null;
+        }
+
+        \SimpleSAML\Logger::info('Shib1.3 - IdP.SSOService: Got incoming Shib authnRequest from ' . var_export($spEntityId, true) . '.');
+
+        $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
+        $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'shib13-sp-remote');
+
+        $found = false;
+        foreach ($spMetadata->getEndpoints('AssertionConsumerService') as $ep) {
+            if ($ep['Binding'] !== 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post') {
+                continue;
+            }
+            if ($ep['Location'] !== $shire) {
+                continue;
+            }
+            $found = true;
+            break;
+        }
+        if (!$found) {
+            throw new \Exception('Invalid AssertionConsumerService for SP ' .
+                var_export($spEntityId, true) . ': ' . var_export($shire, true));
+        }
+
+        \SimpleSAML\Stats::log('saml:idp:AuthnRequest', array(
+            'spEntityID' => $spEntityId,
+            'protocol' => 'saml1',
+        ));
+
+        $sessionLostURL = HTTP::addURLParameters(
+            HTTP::getSelfURL(),
+            array('cookieTime' => time()));
+
+        $state = array(
+            'Responder' => array('\SimpleSAML\Module\saml\IdP\SAML1', 'sendResponse'),
+            'SPMetadata' => $spMetadata->toArray(),
+            \SimpleSAML\Auth\State::RESTART => $sessionLostURL,
+            'saml:shire' => $shire,
+            'saml:target' => $target,
+            'saml:AuthnRequestReceivedAt' => microtime(true),
+        );
+
+        $idp->handleAuthenticationRequest($state);
+    }
 }
diff --git a/modules/saml/lib/IdP/SAML2.php b/modules/saml/lib/IdP/SAML2.php
index af4f4691f6c514c7779fe5b3aab03bffe82cfd28..3e72e1402dca9d7e255ebe9e990fbd2c251ee64e 100644
--- a/modules/saml/lib/IdP/SAML2.php
+++ b/modules/saml/lib/IdP/SAML2.php
@@ -1,16 +1,20 @@
 <?php
 
+namespace SimpleSAML\Module\saml\IdP;
 
 use RobRichards\XMLSecLibs\XMLSecurityKey;
+use SimpleSAML\Configuration;
+use SimpleSAML\Logger;
+use SAML2\SOAP;
 
 /**
  * IdP implementation for SAML 2.0 protocol.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_saml_IdP_SAML2
-{
 
+class SAML2
+{
     /**
      * Send a response to the SP.
      *
@@ -26,19 +30,19 @@ class sspmod_saml_IdP_SAML2
 
         $spMetadata = $state["SPMetadata"];
         $spEntityId = $spMetadata['entityid'];
-        $spMetadata = SimpleSAML_Configuration::loadFromArray(
+        $spMetadata = Configuration::loadFromArray(
             $spMetadata,
             '$metadata['.var_export($spEntityId, true).']'
         );
 
-        SimpleSAML\Logger::info('Sending SAML 2.0 Response to '.var_export($spEntityId, true));
+        Logger::info('Sending SAML 2.0 Response to '.var_export($spEntityId, true));
 
         $requestId = $state['saml:RequestId'];
         $relayState = $state['saml:RelayState'];
         $consumerURL = $state['saml:ConsumerURL'];
         $protocolBinding = $state['saml:Binding'];
 
-        $idp = SimpleSAML_IdP::getByState($state);
+        $idp = \SimpleSAML\IdP::getByState($state);
 
         $idpMetadata = $idp->getConfig();
 
@@ -51,7 +55,7 @@ class sspmod_saml_IdP_SAML2
         // create the session association (for logout)
         $association = array(
             'id'                => 'saml:'.$spEntityId,
-            'Handler'           => 'sspmod_saml_IdP_SAML2',
+            'Handler'           => '\SimpleSAML\Modulesaml\IdP\SAML2',
             'Expires'           => $assertion->getSessionNotOnOrAfter(),
             'saml:entityID'     => $spEntityId,
             'saml:NameID'       => $state['saml:idp:NameID'],
@@ -78,7 +82,7 @@ class sspmod_saml_IdP_SAML2
         if (isset($state['saml:AuthnRequestReceivedAt'])) {
             $statsData['logintime'] = microtime(true) - $state['saml:AuthnRequestReceivedAt'];
         }
-        SimpleSAML_Stats::log('saml:idp:Response', $statsData);
+        \SimpleSAML\Stats::log('saml:idp:Response', $statsData);
 
         // send the response
         $binding = \SAML2\Binding::getBinding($protocolBinding);
@@ -89,11 +93,11 @@ class sspmod_saml_IdP_SAML2
     /**
      * Handle authentication error.
      *
-     * SimpleSAML_Error_Exception $exception  The exception.
+     * \SimpleSAML\Error\Exception $exception  The exception.
      *
      * @param array $state The error state.
      */
-    public static function handleAuthError(SimpleSAML_Error_Exception $exception, array $state)
+    public static function handleAuthError(\SimpleSAML\Error\Exception $exception, array $state)
     {
         assert(isset($state['SPMetadata']));
         assert(isset($state['saml:ConsumerURL']));
@@ -102,7 +106,7 @@ class sspmod_saml_IdP_SAML2
 
         $spMetadata = $state["SPMetadata"];
         $spEntityId = $spMetadata['entityid'];
-        $spMetadata = SimpleSAML_Configuration::loadFromArray(
+        $spMetadata = Configuration::loadFromArray(
             $spMetadata,
             '$metadata['.var_export($spEntityId, true).']'
         );
@@ -112,14 +116,14 @@ class sspmod_saml_IdP_SAML2
         $consumerURL = $state['saml:ConsumerURL'];
         $protocolBinding = $state['saml:Binding'];
 
-        $idp = SimpleSAML_IdP::getByState($state);
+        $idp = \SimpleSAML\IdP::getByState($state);
 
         $idpMetadata = $idp->getConfig();
 
-        $error = sspmod_saml_Error::fromException($exception);
+        $error = \SimpleSAML\Module\saml\Error::fromException($exception);
 
-        SimpleSAML\Logger::warning("Returning error to SP with entity ID '".var_export($spEntityId, true)."'.");
-        $exception->log(SimpleSAML\Logger::WARNING);
+        Logger::warning("Returning error to SP with entity ID '".var_export($spEntityId, true)."'.");
+        $exception->log(Logger::WARNING);
 
         $ar = self::buildResponse($idpMetadata, $spMetadata, $consumerURL);
         $ar->setInResponseTo($requestId);
@@ -141,7 +145,7 @@ class sspmod_saml_IdP_SAML2
         if (isset($state['saml:AuthnRequestReceivedAt'])) {
             $statsData['logintime'] = microtime(true) - $state['saml:AuthnRequestReceivedAt'];
         }
-        SimpleSAML_Stats::log('saml:idp:Response:error', $statsData);
+        \SimpleSAML\Stats::log('saml:idp:Response:error', $statsData);
 
         $binding = \SAML2\Binding::getBinding($protocolBinding);
         $binding->send($ar);
@@ -151,17 +155,17 @@ class sspmod_saml_IdP_SAML2
     /**
      * Find SP AssertionConsumerService based on parameter in AuthnRequest.
      *
-     * @param array                    $supportedBindings The bindings we allow for the response.
-     * @param SimpleSAML_Configuration $spMetadata The metadata for the SP.
-     * @param string|NULL              $AssertionConsumerServiceURL AssertionConsumerServiceURL from request.
-     * @param string|NULL              $ProtocolBinding ProtocolBinding from request.
-     * @param int|NULL                 $AssertionConsumerServiceIndex AssertionConsumerServiceIndex from request.
+     * @param array                     $supportedBindings The bindings we allow for the response.
+     * @param \SimpleSAML\Configuration $spMetadata The metadata for the SP.
+     * @param string|NULL               $AssertionConsumerServiceURL AssertionConsumerServiceURL from request.
+     * @param string|NULL               $ProtocolBinding ProtocolBinding from request.
+     * @param int|NULL                  $AssertionConsumerServiceIndex AssertionConsumerServiceIndex from request.
      *
      * @return array  Array with the Location and Binding we should use for the response.
      */
     private static function getAssertionConsumerService(
         array $supportedBindings,
-        SimpleSAML_Configuration $spMetadata,
+        \SimpleSAML\Configuration $spMetadata,
         $AssertionConsumerServiceURL,
         $ProtocolBinding,
         $AssertionConsumerServiceIndex
@@ -221,15 +225,15 @@ class sspmod_saml_IdP_SAML2
             return $firstFalse;
         }
 
-        SimpleSAML\Logger::warning('Authentication request specifies invalid AssertionConsumerService:');
+        Logger::warning('Authentication request specifies invalid AssertionConsumerService:');
         if ($AssertionConsumerServiceURL !== null) {
-            SimpleSAML\Logger::warning('AssertionConsumerServiceURL: '.var_export($AssertionConsumerServiceURL, true));
+            Logger::warning('AssertionConsumerServiceURL: '.var_export($AssertionConsumerServiceURL, true));
         }
         if ($ProtocolBinding !== null) {
-            SimpleSAML\Logger::warning('ProtocolBinding: '.var_export($ProtocolBinding, true));
+            Logger::warning('ProtocolBinding: '.var_export($ProtocolBinding, true));
         }
         if ($AssertionConsumerServiceIndex !== null) {
-            SimpleSAML\Logger::warning(
+            Logger::warning(
                 'AssertionConsumerServiceIndex: '.var_export($AssertionConsumerServiceIndex, true)
             );
         }
@@ -242,13 +246,12 @@ class sspmod_saml_IdP_SAML2
     /**
      * Receive an authentication request.
      *
-     * @param SimpleSAML_IdP $idp The IdP we are receiving it for.
-     * @throws SimpleSAML_Error_BadRequest In case an error occurs when trying to receive the request.
+     * @param \SimpleSAML\IdP $idp The IdP we are receiving it for.
+     * @throws \SimpleSAML\Error\BadRequest In case an error occurs when trying to receive the request.
      */
-    public static function receiveAuthnRequest(SimpleSAML_IdP $idp)
+    public static function receiveAuthnRequest(\SimpleSAML\IdP $idp)
     {
-
-        $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+        $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
         $idpMetadata = $idp->getConfig();
 
         $supportedBindings = array(\SAML2\Constants::BINDING_HTTP_POST);
@@ -258,6 +261,9 @@ class sspmod_saml_IdP_SAML2
         if ($idpMetadata->getBoolean('saml20.hok.assertion', false)) {
             $supportedBindings[] = \SAML2\Constants::BINDING_HOK_SSO;
         }
+        if ($idpMetadata->getBoolean('saml20.ecp', false)) {
+            $supportedBindings[] = \SAML2\Constants::BINDING_PAOS;
+        }
 
         if (isset($_REQUEST['spentityid'])) {
             /* IdP initiated authentication. */
@@ -305,10 +311,11 @@ class sspmod_saml_IdP_SAML2
             $extensions = null;
             $allowCreate = true;
             $authnContext = null;
+            $binding = null;
 
             $idpInit = true;
 
-            SimpleSAML\Logger::info(
+            Logger::info(
                 'SAML2.0 - IdP.SSOService: IdP initiated authentication: '.var_export($spEntityId, true)
             );
         } else {
@@ -316,20 +323,20 @@ class sspmod_saml_IdP_SAML2
             $request = $binding->receive();
 
             if (!($request instanceof \SAML2\AuthnRequest)) {
-                throw new SimpleSAML_Error_BadRequest(
+                throw new \SimpleSAML\Error\BadRequest(
                     'Message received on authentication request endpoint wasn\'t an authentication request.'
                 );
             }
 
             $spEntityId = $request->getIssuer();
             if ($spEntityId === null) {
-                throw new SimpleSAML_Error_BadRequest(
+                throw new \SimpleSAML\Error\BadRequest(
                     'Received message on authentication request endpoint without issuer.'
                 );
             }
             $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote');
 
-            sspmod_saml_Message::validateMessage($spMetadata, $idpMetadata, $request);
+            \SimpleSAML\Module\saml\Message::validateMessage($spMetadata, $idpMetadata, $request);
 
             $relayState = $request->getRelayState();
 
@@ -362,12 +369,12 @@ class sspmod_saml_IdP_SAML2
 
             $idpInit = false;
 
-            SimpleSAML\Logger::info(
+            Logger::info(
                 'SAML2.0 - IdP.SSOService: incoming authentication request: '.var_export($spEntityId, true)
             );
         }
 
-        SimpleSAML_Stats::log('saml:idp:AuthnRequest', array(
+        \SimpleSAML\Stats::log('saml:idp:AuthnRequest', array(
             'spEntityID'  => $spEntityId,
             'idpEntityID' => $idpMetadata->getString('entityid'),
             'forceAuthn'  => $forceAuthn,
@@ -407,9 +414,9 @@ class sspmod_saml_IdP_SAML2
         );
 
         $state = array(
-            'Responder'                                   => array('sspmod_saml_IdP_SAML2', 'sendResponse'),
-            SimpleSAML_Auth_State::EXCEPTION_HANDLER_FUNC => array('sspmod_saml_IdP_SAML2', 'handleAuthError'),
-            SimpleSAML_Auth_State::RESTART                => $sessionLostURL,
+            'Responder'                                   => array('\SimpleSAML\Module\saml\IdP\SAML2', 'sendResponse'),
+            \SimpleSAML\Auth\State::EXCEPTION_HANDLER_FUNC => array('\SimpleSAML\Module\saml\IdP\SAML2', 'handleAuthError'),
+            \SimpleSAML\Auth\State::RESTART                => $sessionLostURL,
 
             'SPMetadata'                  => $spMetadata->toArray(),
             'saml:RelayState'             => $relayState,
@@ -428,28 +435,44 @@ class sspmod_saml_IdP_SAML2
             'saml:RequestedAuthnContext'  => $authnContext,
         );
 
+        // ECP AuthnRequests need to supply credentials
+        if ($binding instanceof SOAP) {
+            self::processSOAPAuthnRequest($state);
+        }
+
         $idp->handleAuthenticationRequest($state);
     }
 
+    public static function processSOAPAuthnRequest(array &$state)
+    {
+        if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) {
+            Logger::error("ECP AuthnRequest did not contain Basic Authentication header");
+            // TODO Throw some sort of ECP-specific exception / convert this to SOAP fault
+            throw new \SimpleSAML\Error\Error("WRONGUSERPASS");
+        }
+
+        $state['core:auth:username'] = $_SERVER['PHP_AUTH_USER'];
+        $state['core:auth:password'] = $_SERVER['PHP_AUTH_PW'];
+    }
 
     /**
      * Send a logout request to a given association.
      *
-     * @param SimpleSAML_IdP $idp The IdP we are sending a logout request from.
-     * @param array          $association The association that should be terminated.
-     * @param string|NULL    $relayState An id that should be carried across the logout.
+     * @param \SimpleSAML\IdP $idp The IdP we are sending a logout request from.
+     * @param array           $association The association that should be terminated.
+     * @param string|NULL     $relayState An id that should be carried across the logout.
      */
-    public static function sendLogoutRequest(SimpleSAML_IdP $idp, array $association, $relayState)
+    public static function sendLogoutRequest(\SimpleSAML\IdP $idp, array $association, $relayState)
     {
         assert(is_string($relayState) || $relayState === null);
 
-        SimpleSAML\Logger::info('Sending SAML 2.0 LogoutRequest to: '.var_export($association['saml:entityID'], true));
+        Logger::info('Sending SAML 2.0 LogoutRequest to: '.var_export($association['saml:entityID'], true));
 
-        $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+        $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
         $idpMetadata = $idp->getConfig();
         $spMetadata = $metadata->getMetaDataConfig($association['saml:entityID'], 'saml20-sp-remote');
 
-        SimpleSAML_Stats::log('saml:idp:LogoutRequest:sent', array(
+        \SimpleSAML\Stats::log('saml:idp:LogoutRequest:sent', array(
             'spEntityID'  => $association['saml:entityID'],
             'idpEntityID' => $idpMetadata->getString('entityid'),
         ));
@@ -472,10 +495,10 @@ class sspmod_saml_IdP_SAML2
     /**
      * Send a logout response.
      *
-     * @param SimpleSAML_IdP $idp The IdP we are sending a logout request from.
-     * @param array          &$state The logout state array.
+     * @param \SimpleSAML\IdP $idp The IdP we are sending a logout request from.
+     * @param array           &$state The logout state array.
      */
-    public static function sendLogoutResponse(SimpleSAML_IdP $idp, array $state)
+    public static function sendLogoutResponse(\SimpleSAML\IdP $idp, array $state)
     {
         assert(isset($state['saml:SPEntityId']));
         assert(isset($state['saml:RequestId']));
@@ -483,11 +506,11 @@ class sspmod_saml_IdP_SAML2
 
         $spEntityId = $state['saml:SPEntityId'];
 
-        $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+        $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
         $idpMetadata = $idp->getConfig();
         $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote');
 
-        $lr = sspmod_saml_Message::buildLogoutResponse($idpMetadata, $spMetadata);
+        $lr = \SimpleSAML\Module\saml\Message::buildLogoutResponse($idpMetadata, $spMetadata);
         $lr->setInResponseTo($state['saml:RequestId']);
         $lr->setRelayState($state['saml:RelayState']);
 
@@ -497,13 +520,13 @@ class sspmod_saml_IdP_SAML2
                 'Code'    => \SAML2\Constants::STATUS_SUCCESS,
                 'SubCode' => \SAML2\Constants::STATUS_PARTIAL_LOGOUT,
             ));
-            SimpleSAML\Logger::info('Sending logout response for partial logout to SP '.var_export($spEntityId, true));
+            Logger::info('Sending logout response for partial logout to SP '.var_export($spEntityId, true));
         } else {
             $partial = false;
-            SimpleSAML\Logger::debug('Sending logout response to SP '.var_export($spEntityId, true));
+            Logger::debug('Sending logout response to SP '.var_export($spEntityId, true));
         }
 
-        SimpleSAML_Stats::log('saml:idp:LogoutResponse:sent', array(
+        \SimpleSAML\Stats::log('saml:idp:LogoutResponse:sent', array(
             'spEntityID'  => $spEntityId,
             'idpEntityID' => $idpMetadata->getString('entityid'),
             'partial'     => $partial
@@ -530,29 +553,28 @@ class sspmod_saml_IdP_SAML2
     /**
      * Receive a logout message.
      *
-     * @param SimpleSAML_IdP $idp The IdP we are receiving it for.
-     * @throws SimpleSAML_Error_BadRequest In case an error occurs while trying to receive the logout message.
+     * @param \SimpleSAML\IdP $idp The IdP we are receiving it for.
+     * @throws \SimpleSAML\Error\BadRequest In case an error occurs while trying to receive the logout message.
      */
-    public static function receiveLogoutMessage(SimpleSAML_IdP $idp)
+    public static function receiveLogoutMessage(\SimpleSAML\IdP $idp)
     {
-
         $binding = \SAML2\Binding::getCurrentBinding();
         $message = $binding->receive();
 
         $spEntityId = $message->getIssuer();
         if ($spEntityId === null) {
             /* Without an issuer we have no way to respond to the message. */
-            throw new SimpleSAML_Error_BadRequest('Received message on logout endpoint without issuer.');
+            throw new \SimpleSAML\Error\BadRequest('Received message on logout endpoint without issuer.');
         }
 
-        $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+        $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
         $idpMetadata = $idp->getConfig();
         $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote');
 
-        sspmod_saml_Message::validateMessage($spMetadata, $idpMetadata, $message);
+        \SimpleSAML\Module\saml\Message::validateMessage($spMetadata, $idpMetadata, $message);
 
         if ($message instanceof \SAML2\LogoutResponse) {
-            SimpleSAML\Logger::info('Received SAML 2.0 LogoutResponse from: '.var_export($spEntityId, true));
+            Logger::info('Received SAML 2.0 LogoutResponse from: '.var_export($spEntityId, true));
             $statsData = array(
                 'spEntityID'  => $spEntityId,
                 'idpEntityID' => $idpMetadata->getString('entityid'),
@@ -560,13 +582,13 @@ class sspmod_saml_IdP_SAML2
             if (!$message->isSuccess()) {
                 $statsData['error'] = $message->getStatus();
             }
-            SimpleSAML_Stats::log('saml:idp:LogoutResponse:recv', $statsData);
+            \SimpleSAML\Stats::log('saml:idp:LogoutResponse:recv', $statsData);
 
             $relayState = $message->getRelayState();
 
             if (!$message->isSuccess()) {
-                $logoutError = sspmod_saml_Message::getResponseError($message);
-                SimpleSAML\Logger::warning('Unsuccessful logout. Status was: '.$logoutError);
+                $logoutError = \SimpleSAML\Module\saml\Message::getResponseError($message);
+                Logger::warning('Unsuccessful logout. Status was: '.$logoutError);
             } else {
                 $logoutError = null;
             }
@@ -575,17 +597,17 @@ class sspmod_saml_IdP_SAML2
 
             $idp->handleLogoutResponse($assocId, $relayState, $logoutError);
         } elseif ($message instanceof \SAML2\LogoutRequest) {
-            SimpleSAML\Logger::info('Received SAML 2.0 LogoutRequest from: '.var_export($spEntityId, true));
-            SimpleSAML_Stats::log('saml:idp:LogoutRequest:recv', array(
+            Logger::info('Received SAML 2.0 LogoutRequest from: '.var_export($spEntityId, true));
+            \SimpleSAML\Stats::log('saml:idp:LogoutRequest:recv', array(
                 'spEntityID'  => $spEntityId,
                 'idpEntityID' => $idpMetadata->getString('entityid'),
             ));
 
             $spStatsId = $spMetadata->getString('core:statistics-id', $spEntityId);
-            SimpleSAML\Logger::stats('saml20-idp-SLO spinit '.$spStatsId.' '.$idpMetadata->getString('entityid'));
+            Logger::stats('saml20-idp-SLO spinit '.$spStatsId.' '.$idpMetadata->getString('entityid'));
 
             $state = array(
-                'Responder'       => array('sspmod_saml_IdP_SAML2', 'sendLogoutResponse'),
+                'Responder'       => array('\SimpleSAML\Module\saml\IdP\SAML2', 'sendLogoutResponse'),
                 'saml:SPEntityId' => $spEntityId,
                 'saml:RelayState' => $message->getRelayState(),
                 'saml:RequestId'  => $message->getId(),
@@ -594,7 +616,7 @@ class sspmod_saml_IdP_SAML2
             $assocId = 'saml:'.$spEntityId;
             $idp->handleLogoutRequest($state, $assocId);
         } else {
-            throw new SimpleSAML_Error_BadRequest('Unknown message received on logout endpoint: '.get_class($message));
+            throw new \SimpleSAML\Error\BadRequest('Unknown message received on logout endpoint: '.get_class($message));
         }
     }
 
@@ -602,19 +624,19 @@ class sspmod_saml_IdP_SAML2
     /**
      * Retrieve a logout URL for a given logout association.
      *
-     * @param SimpleSAML_IdP $idp The IdP we are sending a logout request from.
-     * @param array          $association The association that should be terminated.
-     * @param string|NULL    $relayState An id that should be carried across the logout.
+     * @param \SimpleSAML\IdP $idp The IdP we are sending a logout request from.
+     * @param array           $association The association that should be terminated.
+     * @param string|NULL     $relayState An id that should be carried across the logout.
      *
      * @return string The logout URL.
      */
-    public static function getLogoutURL(SimpleSAML_IdP $idp, array $association, $relayState)
+    public static function getLogoutURL(\SimpleSAML\IdP $idp, array $association, $relayState)
     {
         assert(is_string($relayState) || $relayState === null);
 
-        SimpleSAML\Logger::info('Sending SAML 2.0 LogoutRequest to: '.var_export($association['saml:entityID'], true));
+        Logger::info('Sending SAML 2.0 LogoutRequest to: '.var_export($association['saml:entityID'], true));
 
-        $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+        $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
         $idpMetadata = $idp->getConfig();
         $spMetadata = $metadata->getMetaDataConfig($association['saml:entityID'], 'saml20-sp-remote');
 
@@ -629,7 +651,7 @@ class sspmod_saml_IdP_SAML2
             if ($relayState !== null) {
                 $params['RelayState'] = $relayState;
             }
-            return SimpleSAML\Module::getModuleURL('core/idp/logout-iframe-post.php', $params);
+            return \SimpleSAML\Module::getModuleURL('core/idp/logout-iframe-post.php', $params);
         }
 
         $lr = self::buildLogoutRequest($idpMetadata, $spMetadata, $association, $relayState);
@@ -643,18 +665,18 @@ class sspmod_saml_IdP_SAML2
     /**
      * Retrieve the metadata for the given SP association.
      *
-     * @param SimpleSAML_IdP $idp The IdP the association belongs to.
-     * @param array          $association The SP association.
+     * @param \SimpleSAML\IdP $idp The IdP the association belongs to.
+     * @param array           $association The SP association.
      *
-     * @return SimpleSAML_Configuration  Configuration object for the SP metadata.
+     * @return \SimpleSAML\Configuration  Configuration object for the SP metadata.
      */
-    public static function getAssociationConfig(SimpleSAML_IdP $idp, array $association)
+    public static function getAssociationConfig(\SimpleSAML\IdP $idp, array $association)
     {
-        $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+        $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
         try {
             return $metadata->getMetaDataConfig($association['saml:entityID'], 'saml20-sp-remote');
-        } catch (Exception $e) {
-            return SimpleSAML_Configuration::loadFromArray(array(), 'Unknown SAML 2 entity.');
+        } catch (\Exception $e) {
+            return Configuration::loadFromArray(array(), 'Unknown SAML 2 entity.');
         }
     }
 
@@ -662,15 +684,15 @@ class sspmod_saml_IdP_SAML2
     /**
      * Calculate the NameID value that should be used.
      *
-     * @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP.
-     * @param SimpleSAML_Configuration $dstMetadata The metadata of the SP.
-     * @param array                    &$state The authentication state of the user.
+     * @param \SimpleSAML\Configuration $idpMetadata The metadata of the IdP.
+     * @param \SimpleSAML\Configuration $spMetadata The metadata of the SP.
+     * @param array                     &$state The authentication state of the user.
      *
      * @return string  The NameID value.
      */
     private static function generateNameIdValue(
-        SimpleSAML_Configuration $idpMetadata,
-        SimpleSAML_Configuration $spMetadata,
+        Configuration $idpMetadata,
+        Configuration $spMetadata,
         array &$state
     ) {
 
@@ -679,14 +701,14 @@ class sspmod_saml_IdP_SAML2
             $attribute = $idpMetadata->getString('simplesaml.nameidattribute', null);
             if ($attribute === null) {
                 if (!isset($state['UserID'])) {
-                    SimpleSAML\Logger::error('Unable to generate NameID. Check the userid.attribute option.');
+                    Logger::error('Unable to generate NameID. Check the userid.attribute option.');
                     return null;
                 }
                 $attributeValue = $state['UserID'];
                 $idpEntityId = $idpMetadata->getString('entityid');
                 $spEntityId = $spMetadata->getString('entityid');
 
-                $secretSalt = SimpleSAML\Utils\Config::getSecretSalt();
+                $secretSalt = \SimpleSAML\Utils\Config::getSecretSalt();
 
                 $uidData = 'uidhashbase'.$secretSalt;
                 $uidData .= strlen($idpEntityId).':'.$idpEntityId;
@@ -700,7 +722,7 @@ class sspmod_saml_IdP_SAML2
 
         $attributes = $state['Attributes'];
         if (!array_key_exists($attribute, $attributes)) {
-            SimpleSAML\Logger::error('Unable to add NameID: Missing '.var_export($attribute, true).
+            Logger::error('Unable to add NameID: Missing '.var_export($attribute, true).
                 ' in the attributes of the user.');
             return null;
         }
@@ -712,20 +734,19 @@ class sspmod_saml_IdP_SAML2
     /**
      * Helper function for encoding attributes.
      *
-     * @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP.
-     * @param SimpleSAML_Configuration $spMetadata The metadata of the SP.
+     * @param \SimpleSAML\Configuration $idpMetadata The metadata of the IdP.
+     * @param \SimpleSAML\Configuration $spMetadata The metadata of the SP.
      * @param array $attributes The attributes of the user.
      *
      * @return array  The encoded attributes.
      *
-     * @throws SimpleSAML_Error_Exception In case an unsupported encoding is specified by configuration.
+     * @throws \SimpleSAML\Error\Exception In case an unsupported encoding is specified by configuration.
      */
     private static function encodeAttributes(
-        SimpleSAML_Configuration $idpMetadata,
-        SimpleSAML_Configuration $spMetadata,
+        Configuration $idpMetadata,
+        Configuration $spMetadata,
         array $attributes
     ) {
-
         $base64Attributes = $spMetadata->getBoolean('base64attributes', null);
         if ($base64Attributes === null) {
             $base64Attributes = $idpMetadata->getBoolean('base64attributes', false);
@@ -763,7 +784,7 @@ class sspmod_saml_IdP_SAML2
                 }
 
                 $attrval = $value;
-                if ($value instanceof DOMNodeList) {
+                if ($value instanceof \DOMNodeList) {
                     $attrval = new \SAML2\XML\saml\AttributeValue($value->item(0)->parentNode);
                 }
 
@@ -779,10 +800,10 @@ class sspmod_saml_IdP_SAML2
                             $doc = \SAML2\DOMDocumentFactory::fromString('<root>'.$value.'</root>');
                             $value = $doc->firstChild->childNodes;
                         }
-                        assert($value instanceof DOMNodeList || $value instanceof \SAML2\XML\saml\NameID);
+                        assert($value instanceof \DOMNodeList || $value instanceof \SAML2\XML\saml\NameID);
                         break;
                     default:
-                        throw new SimpleSAML_Error_Exception('Invalid encoding for attribute '.
+                        throw new \SimpleSAML\Error\Exception('Invalid encoding for attribute '.
                             var_export($name, true).': '.var_export($encoding, true));
                 }
                 $ret[$name][] = $value;
@@ -796,16 +817,15 @@ class sspmod_saml_IdP_SAML2
     /**
      * Determine which NameFormat we should use for attributes.
      *
-     * @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP.
-     * @param SimpleSAML_Configuration $spMetadata The metadata of the SP.
+     * @param \SimpleSAML\Configuration $idpMetadata The metadata of the IdP.
+     * @param \SimpleSAML\Configuration $spMetadata The metadata of the SP.
      *
      * @return string  The NameFormat.
      */
     private static function getAttributeNameFormat(
-        SimpleSAML_Configuration $idpMetadata,
-        SimpleSAML_Configuration $spMetadata
+        Configuration $idpMetadata,
+        Configuration $spMetadata
     ) {
-
         // try SP metadata first
         $attributeNameFormat = $spMetadata->getString('attributes.NameFormat', null);
         if ($attributeNameFormat !== null) {
@@ -834,17 +854,17 @@ class sspmod_saml_IdP_SAML2
     /**
      * Build an assertion based on information in the metadata.
      *
-     * @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP.
-     * @param SimpleSAML_Configuration $spMetadata The metadata of the SP.
+     * @param \SimpleSAML\Configuration $idpMetadata The metadata of the IdP.
+     * @param \SimpleSAML\Configuration $spMetadata The metadata of the SP.
      * @param array &$state The state array with information about the request.
      *
      * @return \SAML2\Assertion  The assertion.
      *
-     * @throws SimpleSAML_Error_Exception In case an error occurs when creating a holder-of-key assertion.
+     * @throws \SimpleSAML\Error\Exception In case an error occurs when creating a holder-of-key assertion.
      */
     private static function buildAssertion(
-        SimpleSAML_Configuration $idpMetadata,
-        SimpleSAML_Configuration $spMetadata,
+        Configuration $idpMetadata,
+        Configuration $spMetadata,
         array &$state
     ) {
         assert(isset($state['Attributes']));
@@ -857,11 +877,11 @@ class sspmod_saml_IdP_SAML2
             $signAssertion = $idpMetadata->getBoolean('saml20.sign.assertion', true);
         }
 
-        $config = SimpleSAML_Configuration::getInstance();
+        $config = Configuration::getInstance();
 
         $a = new \SAML2\Assertion();
         if ($signAssertion) {
-            sspmod_saml_Message::addSign($idpMetadata, $spMetadata, $a);
+            \SimpleSAML\Module\saml\Message::addSign($idpMetadata, $spMetadata, $a);
         }
 
         $a->setIssuer($idpMetadata->getString('entityid'));
@@ -890,7 +910,7 @@ class sspmod_saml_IdP_SAML2
         $sessionLifetime = $config->getInteger('session.duration', 8 * 60 * 60);
         $a->setSessionNotOnOrAfter($sessionStart + $sessionLifetime);
 
-        $a->setSessionIndex(SimpleSAML\Utils\Random::generateID());
+        $a->setSessionIndex(\SimpleSAML\Utils\Random::generateID());
 
         $sc = new \SAML2\XML\saml\SubjectConfirmation();
         $sc->SubjectConfirmationData = new \SAML2\XML\saml\SubjectConfirmationData();
@@ -928,18 +948,18 @@ class sspmod_saml_IdP_SAML2
 
                         $sc->SubjectConfirmationData->info[] = $keyInfo;
                     } else {
-                        throw new SimpleSAML_Error_Exception(
+                        throw new \SimpleSAML\Error\Exception(
                             'Error creating HoK assertion: No valid client certificate provided during TLS handshake '.
                             'with IdP'
                         );
                     }
                 } else {
-                    throw new SimpleSAML_Error_Exception(
+                    throw new \SimpleSAML\Error\Exception(
                         'Error creating HoK assertion: No client certificate provided during TLS handshake with IdP'
                     );
                 }
             } else {
-                throw new SimpleSAML_Error_Exception(
+                throw new \SimpleSAML\Error\Exception(
                     'Error creating HoK assertion: No HTTPS connection to IdP, but required for Holder-of-Key SSO'
                 );
             }
@@ -983,15 +1003,15 @@ class sspmod_saml_IdP_SAML2
 
             if ($nameIdFormat === \SAML2\Constants::NAMEID_TRANSIENT) {
                 // generate a random id
-                $nameIdValue = SimpleSAML\Utils\Random::generateID();
+                $nameIdValue = \SimpleSAML\Utils\Random::generateID();
             } else {
                 /* this code will end up generating either a fixed assigned id (via nameid.attribute)
                    or random id if not assigned/configured */
                 $nameIdValue = self::generateNameIdValue($idpMetadata, $spMetadata, $state);
                 if ($nameIdValue === null) {
-                    SimpleSAML\Logger::warning('Falling back to transient NameID.');
+                    Logger::warning('Falling back to transient NameID.');
                     $nameIdFormat = \SAML2\Constants::NAMEID_TRANSIENT;
-                    $nameIdValue = SimpleSAML\Utils\Random::generateID();
+                    $nameIdValue = \SimpleSAML\Utils\Random::generateID();
                 }
             }
 
@@ -1010,7 +1030,7 @@ class sspmod_saml_IdP_SAML2
             $encryptNameId = $idpMetadata->getBoolean('nameid.encryption', false);
         }
         if ($encryptNameId) {
-            $a->encryptNameId(sspmod_saml_Message::getEncryptionKey($spMetadata));
+            $a->encryptNameId(\SimpleSAML\Module\saml\Message::getEncryptionKey($spMetadata));
         }
 
         return $a;
@@ -1023,20 +1043,19 @@ class sspmod_saml_IdP_SAML2
      * This function takes in a \SAML2\Assertion and encrypts it if encryption of
      * assertions are enabled in the metadata.
      *
-     * @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP.
-     * @param SimpleSAML_Configuration $spMetadata The metadata of the SP.
+     * @param \SimpleSAML\Configuration $idpMetadata The metadata of the IdP.
+     * @param \SimpleSAML\Configuration $spMetadata The metadata of the SP.
      * @param \SAML2\Assertion $assertion The assertion we are encrypting.
      *
      * @return \SAML2\Assertion|\SAML2\EncryptedAssertion  The assertion.
      *
-     * @throws SimpleSAML_Error_Exception In case the encryption key type is not supported.
+     * @throws \SimpleSAML\Error\Exception In case the encryption key type is not supported.
      */
     private static function encryptAssertion(
-        SimpleSAML_Configuration $idpMetadata,
-        SimpleSAML_Configuration $spMetadata,
+        Configuration $idpMetadata,
+        Configuration $spMetadata,
         \SAML2\Assertion $assertion
     ) {
-
         $encryptAssertion = $spMetadata->getBoolean('assertion.encryption', null);
         if ($encryptAssertion === null) {
             $encryptAssertion = $idpMetadata->getBoolean('assertion.encryption', false);
@@ -1053,20 +1072,28 @@ class sspmod_saml_IdP_SAML2
             $key->loadKey($sharedKey);
         } else {
             $keys = $spMetadata->getPublicKeys('encryption', true);
-            $key = $keys[0];
-            switch ($key['type']) {
-                case 'X509Certificate':
-                    $pemKey = "-----BEGIN CERTIFICATE-----\n".
-                        chunk_split($key['X509Certificate'], 64).
-                        "-----END CERTIFICATE-----\n";
-                    break;
-                default:
-                    throw new SimpleSAML_Error_Exception('Unsupported encryption key type: '.$key['type']);
-            }
+            if (!empty($keys)) {
+                $key = $keys[0];
+                switch ($key['type']) {
+                    case 'X509Certificate':
+                        $pemKey = "-----BEGIN CERTIFICATE-----\n".
+                            chunk_split($key['X509Certificate'], 64).
+                            "-----END CERTIFICATE-----\n";
+                        break;
+                    default:
+                        throw new \SimpleSAML\Error\Exception('Unsupported encryption key type: '.$key['type']);
+                }
 
-            // extract the public key from the certificate for encryption
-            $key = new XMLSecurityKey(XMLSecurityKey::RSA_OAEP_MGF1P, array('type' => 'public'));
-            $key->loadKey($pemKey);
+                // extract the public key from the certificate for encryption
+                $key = new XMLSecurityKey(XMLSecurityKey::RSA_OAEP_MGF1P, array('type' => 'public'));
+                $key->loadKey($pemKey);
+            } else {
+                throw new \SimpleSAML\Error\ConfigurationError(
+                    'Missing encryption key for entity `' . $spMetadata->getString('entityid') . '`',
+                    $spMetadata->getString('metadata-set') . '.php',
+                    null
+                );
+            }
         }
 
         $ea = new \SAML2\EncryptedAssertion();
@@ -1078,21 +1105,20 @@ class sspmod_saml_IdP_SAML2
     /**
      * Build a logout request based on information in the metadata.
      *
-     * @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP.
-     * @param SimpleSAML_Configuration $spMetadata The metadata of the SP.
+     * @param \SimpleSAML\Configuration $idpMetadata The metadata of the IdP.
+     * @param \SimpleSAML\Configuration $spMetadata The metadata of the SP.
      * @param array $association The SP association.
      * @param string|null $relayState An id that should be carried across the logout.
      *
      * @return \SAML2\LogoutResponse The corresponding SAML2 logout response.
      */
     private static function buildLogoutRequest(
-        SimpleSAML_Configuration $idpMetadata,
-        SimpleSAML_Configuration $spMetadata,
+        Configuration $idpMetadata,
+        Configuration $spMetadata,
         array $association,
         $relayState
     ) {
-
-        $lr = sspmod_saml_Message::buildLogoutRequest($idpMetadata, $spMetadata);
+        $lr = \SimpleSAML\Module\saml\Message::buildLogoutRequest($idpMetadata, $spMetadata);
         $lr->setRelayState($relayState);
         $lr->setSessionIndex($association['saml:SessionIndex']);
         $lr->setNameId($association['saml:NameID']);
@@ -1108,7 +1134,7 @@ class sspmod_saml_IdP_SAML2
             $encryptNameId = $idpMetadata->getBoolean('nameid.encryption', false);
         }
         if ($encryptNameId) {
-            $lr->encryptNameId(sspmod_saml_Message::getEncryptionKey($spMetadata));
+            $lr->encryptNameId(\SimpleSAML\Module\saml\Message::getEncryptionKey($spMetadata));
         }
 
         return $lr;
@@ -1118,18 +1144,17 @@ class sspmod_saml_IdP_SAML2
     /**
      * Build a authentication response based on information in the metadata.
      *
-     * @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP.
-     * @param SimpleSAML_Configuration $spMetadata The metadata of the SP.
+     * @param \SimpleSAML\Configuration $idpMetadata The metadata of the IdP.
+     * @param \SimpleSAML\Configuration $spMetadata The metadata of the SP.
      * @param string                   $consumerURL The Destination URL of the response.
      *
      * @return \SAML2\Response The SAML2 response corresponding to the given data.
      */
     private static function buildResponse(
-        SimpleSAML_Configuration $idpMetadata,
-        SimpleSAML_Configuration $spMetadata,
+        Configuration $idpMetadata,
+        Configuration $spMetadata,
         $consumerURL
     ) {
-
         $signResponse = $spMetadata->getBoolean('saml20.sign.response', null);
         if ($signResponse === null) {
             $signResponse = $idpMetadata->getBoolean('saml20.sign.response', true);
@@ -1141,7 +1166,7 @@ class sspmod_saml_IdP_SAML2
         $r->setDestination($consumerURL);
 
         if ($signResponse) {
-            sspmod_saml_Message::addSign($idpMetadata, $spMetadata, $r);
+            \SimpleSAML\Module\saml\Message::addSign($idpMetadata, $spMetadata, $r);
         }
 
         return $r;
diff --git a/modules/saml/lib/IdP/SQLNameID.php b/modules/saml/lib/IdP/SQLNameID.php
index ce5145fd7fd1705133b73707dfe6e0bdc19986dc..3a60939278f072fd541d1597508f77cc4aea46e6 100644
--- a/modules/saml/lib/IdP/SQLNameID.php
+++ b/modules/saml/lib/IdP/SQLNameID.php
@@ -1,178 +1,184 @@
 <?php
 
+namespace SimpleSAML\Module\saml\IdP;
+
 /**
  * Helper class for working with persistent NameIDs stored in SQL datastore.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_saml_IdP_SQLNameID  {
-
-	/**
-	 * Create NameID table in SQL, if it is missing.
-	 *
-	 * @param \SimpleSAML\Store\SQL $store  The datastore.
-	 */
-	private static function createTable(\SimpleSAML\Store\SQL $store) {
-
-		if ($store->getTableVersion('saml_PersistentNameID') === 1) {
-			return;
-		}
-
-		$query = 'CREATE TABLE ' . $store->prefix . '_saml_PersistentNameID (
-			_idp VARCHAR(256) NOT NULL,
-			_sp VARCHAR(256) NOT NULL,
-			_user VARCHAR(256) NOT NULL,
-			_value VARCHAR(40) NOT NULL,
-			UNIQUE (_idp, _sp, _user)
-		)';
-		$store->pdo->exec($query);
-
-		$query = 'CREATE INDEX ' . $store->prefix . '_saml_PersistentNameID_idp_sp ON '  . $store->prefix . '_saml_PersistentNameID (_idp, _sp)';
-		$store->pdo->exec($query);
-
-		$store->setTableVersion('saml_PersistentNameID', 1);
-	}
-
-
-	/**
-	 * Retrieve the SQL datastore.
-	 *
-	 * Will also ensure that the NameID table is present.
-	 *
-	 * @return \SimpleSAML\Store\SQL  SQL datastore.
-	 */
-	private static function getStore() {
-
-		$store = \SimpleSAML\Store::getInstance();
-		if (!($store instanceof \SimpleSAML\Store\SQL)) {
-			throw new SimpleSAML_Error_Exception('SQL NameID store requires SimpleSAMLphp to be configured with a SQL datastore.');
-		}
-
-		self::createTable($store);
-
-		return $store;
-	}
-
-
-	/**
-	 * Add a NameID into the database.
-	 *
-	 * @param \SimpleSAML\Store\SQL $store  The data store.
-	 * @param string $idpEntityId  The IdP entityID.
-	 * @param string $spEntityId  The SP entityID.
-	 * @param string $user  The user's unique identificator (e.g. username).
-	 * @param string $value  The NameID value.
-	 */
-	public static function add($idpEntityId, $spEntityId, $user, $value) {
-		assert(is_string($idpEntityId));
-		assert(is_string($spEntityId));
-		assert(is_string($user));
-		assert(is_string($value));
-
-		$store = self::getStore();
-
-		$params = array(
-			'_idp' => $idpEntityId,
-			'_sp' => $spEntityId,
-			'_user' => $user,
-			'_value' => $value,
-		);
-
-		$query = 'INSERT INTO ' . $store->prefix . '_saml_PersistentNameID (_idp, _sp, _user, _value) VALUES(:_idp, :_sp, :_user, :_value)';
-		$query = $store->pdo->prepare($query);
-		$query->execute($params);
-	}
-
-
-	/**
-	 * Retrieve a NameID into from database.
-	 *
-	 * @param string $idpEntityId  The IdP entityID.
-	 * @param string $spEntityId  The SP entityID.
-	 * @param string $user  The user's unique identificator (e.g. username).
-	 * @return string|NULL $value  The NameID value, or NULL of no NameID value was found.
-	 */
-	public static function get($idpEntityId, $spEntityId, $user) {
-		assert(is_string($idpEntityId));
-		assert(is_string($spEntityId));
-		assert(is_string($user));
-
-		$store = self::getStore();
-
-		$params = array(
-			'_idp' => $idpEntityId,
-			'_sp' => $spEntityId,
-			'_user' => $user,
-		);
-
-		$query = 'SELECT _value FROM ' . $store->prefix . '_saml_PersistentNameID WHERE _idp = :_idp AND _sp = :_sp AND _user = :_user';
-		$query = $store->pdo->prepare($query);
-		$query->execute($params);
-
-		$row = $query->fetch(PDO::FETCH_ASSOC);
-		if ($row === FALSE) {
-			// No NameID found
-			return NULL;
-		}
-
-		return $row['_value'];
-	}
-
-
-	/**
-	 * Delete a NameID from the database.
-	 *
-	 * @param string $idpEntityId  The IdP entityID.
-	 * @param string $spEntityId  The SP entityID.
-	 * @param string $user  The user's unique identificator (e.g. username).
-	 */
-	public static function delete($idpEntityId, $spEntityId, $user) {
-		assert(is_string($idpEntityId));
-		assert(is_string($spEntityId));
-		assert(is_string($user));
-
-		$store = self::getStore();
-
-		$params = array(
-			'_idp' => $idpEntityId,
-			'_sp' => $spEntityId,
-			'_user' => $user,
-		);
-
-		$query = 'DELETE FROM ' . $store->prefix . '_saml_PersistentNameID WHERE _idp = :_idp AND _sp = :_sp AND _user = :_user';
-		$query = $store->pdo->prepare($query);
-		$query->execute($params);
-	}
-
-
-	/**
-	 * Retrieve all federated identities for an IdP-SP pair.
-	 *
-	 * @param string $idpEntityId  The IdP entityID.
-	 * @param string $spEntityId  The SP entityID.
-	 * @return array  Array of userid => NameID.
-	 */
-	public static function getIdentities($idpEntityId, $spEntityId) {
-		assert(is_string($idpEntityId));
-		assert(is_string($spEntityId));
-
-		$store = self::getStore();
-
-		$params = array(
-			'_idp' => $idpEntityId,
-			'_sp' => $spEntityId,
-		);
-
-		$query = 'SELECT _user, _value FROM ' . $store->prefix . '_saml_PersistentNameID WHERE _idp = :_idp AND _sp = :_sp';
-		$query = $store->pdo->prepare($query);
-		$query->execute($params);
-
-		$res = array();
-		while ( ($row = $query->fetch(PDO::FETCH_ASSOC)) !== FALSE) {
-			$res[$row['_user']] = $row['_value'];
-		}
-
-		return $res;
-	}
 
+class SQLNameID
+{
+    /**
+     * Create NameID table in SQL, if it is missing.
+     *
+     * @param \SimpleSAML\Store\SQL $store  The datastore.
+     */
+    private static function createTable(\SimpleSAML\Store\SQL $store)
+    {
+        if ($store->getTableVersion('saml_PersistentNameID') === 1) {
+            return;
+        }
+
+        $query = 'CREATE TABLE ' . $store->prefix . '_saml_PersistentNameID (
+            _idp VARCHAR(256) NOT NULL,
+            _sp VARCHAR(256) NOT NULL,
+            _user VARCHAR(256) NOT NULL,
+            _value VARCHAR(40) NOT NULL,
+            UNIQUE (_idp, _sp, _user)
+        )';
+        $store->pdo->exec($query);
+
+        $query = 'CREATE INDEX ' . $store->prefix . '_saml_PersistentNameID_idp_sp ON '  . $store->prefix . '_saml_PersistentNameID (_idp, _sp)';
+        $store->pdo->exec($query);
+
+        $store->setTableVersion('saml_PersistentNameID', 1);
+    }
+
+
+    /**
+     * Retrieve the SQL datastore.
+     *
+     * Will also ensure that the NameID table is present.
+     *
+     * @return \SimpleSAML\Store\SQL  SQL datastore.
+     */
+    private static function getStore()
+    {
+        $store = \SimpleSAML\Store::getInstance();
+        if (!($store instanceof \SimpleSAML\Store\SQL)) {
+            throw new \SimpleSAML\Error\Exception('SQL NameID store requires SimpleSAMLphp to be configured with a SQL datastore.');
+        }
+
+        self::createTable($store);
+
+        return $store;
+    }
+
+
+    /**
+     * Add a NameID into the database.
+     *
+     * @param \SimpleSAML\Store\SQL $store  The data store.
+     * @param string $idpEntityId  The IdP entityID.
+     * @param string $spEntityId  The SP entityID.
+     * @param string $user  The user's unique identificator (e.g. username).
+     * @param string $value  The NameID value.
+     */
+    public static function add($idpEntityId, $spEntityId, $user, $value)
+    {
+        assert(is_string($idpEntityId));
+        assert(is_string($spEntityId));
+        assert(is_string($user));
+        assert(is_string($value));
+
+        $store = self::getStore();
+
+        $params = array(
+            '_idp' => $idpEntityId,
+            '_sp' => $spEntityId,
+            '_user' => $user,
+            '_value' => $value,
+        );
+
+        $query = 'INSERT INTO ' . $store->prefix . '_saml_PersistentNameID (_idp, _sp, _user, _value) VALUES(:_idp, :_sp, :_user, :_value)';
+        $query = $store->pdo->prepare($query);
+        $query->execute($params);
+    }
+
+
+    /**
+     * Retrieve a NameID into from database.
+     *
+     * @param string $idpEntityId  The IdP entityID.
+     * @param string $spEntityId  The SP entityID.
+     * @param string $user  The user's unique identificator (e.g. username).
+     * @return string|NULL $value  The NameID value, or NULL of no NameID value was found.
+     */
+    public static function get($idpEntityId, $spEntityId, $user)
+    {
+        assert(is_string($idpEntityId));
+        assert(is_string($spEntityId));
+        assert(is_string($user));
+
+        $store = self::getStore();
+
+        $params = array(
+            '_idp' => $idpEntityId,
+            '_sp' => $spEntityId,
+            '_user' => $user,
+        );
+
+        $query = 'SELECT _value FROM ' . $store->prefix . '_saml_PersistentNameID WHERE _idp = :_idp AND _sp = :_sp AND _user = :_user';
+        $query = $store->pdo->prepare($query);
+        $query->execute($params);
+
+        $row = $query->fetch(\PDO::FETCH_ASSOC);
+        if ($row === false) {
+            // No NameID found
+            return null;
+        }
+
+        return $row['_value'];
+    }
+
+
+    /**
+     * Delete a NameID from the database.
+     *
+     * @param string $idpEntityId  The IdP entityID.
+     * @param string $spEntityId  The SP entityID.
+     * @param string $user  The user's unique identificator (e.g. username).
+     */
+    public static function delete($idpEntityId, $spEntityId, $user)
+    {
+        assert(is_string($idpEntityId));
+        assert(is_string($spEntityId));
+        assert(is_string($user));
+
+        $store = self::getStore();
+
+        $params = array(
+            '_idp' => $idpEntityId,
+            '_sp' => $spEntityId,
+            '_user' => $user,
+        );
+
+        $query = 'DELETE FROM ' . $store->prefix . '_saml_PersistentNameID WHERE _idp = :_idp AND _sp = :_sp AND _user = :_user';
+        $query = $store->pdo->prepare($query);
+        $query->execute($params);
+    }
+
+
+    /**
+     * Retrieve all federated identities for an IdP-SP pair.
+     *
+     * @param string $idpEntityId  The IdP entityID.
+     * @param string $spEntityId  The SP entityID.
+     * @return array  Array of userid => NameID.
+     */
+    public static function getIdentities($idpEntityId, $spEntityId)
+    {
+        assert(is_string($idpEntityId));
+        assert(is_string($spEntityId));
+
+        $store = self::getStore();
+
+        $params = array(
+            '_idp' => $idpEntityId,
+            '_sp' => $spEntityId,
+        );
+
+        $query = 'SELECT _user, _value FROM ' . $store->prefix . '_saml_PersistentNameID WHERE _idp = :_idp AND _sp = :_sp';
+        $query = $store->pdo->prepare($query);
+        $query->execute($params);
+
+        $res = array();
+        while (($row = $query->fetch(\PDO::FETCH_ASSOC)) !== false) {
+            $res[$row['_user']] = $row['_value'];
+        }
+
+        return $res;
+    }
 }
diff --git a/modules/saml/lib/Message.php b/modules/saml/lib/Message.php
index 3ba905a8bda23faee4abe590c28ee0278c680399..8cc89f6478f683028838b88f3cdc9e6ca968ea06 100644
--- a/modules/saml/lib/Message.php
+++ b/modules/saml/lib/Message.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\saml;
+
 use RobRichards\XMLSecLibs\XMLSecurityKey;
 
 /**
@@ -7,44 +9,33 @@ use RobRichards\XMLSecLibs\XMLSecurityKey;
  *
  * @package SimpleSAMLphp
  */
-class sspmod_saml_Message
+class Message
 {
-
     /**
      * Add signature key and sender certificate to an element (Message or Assertion).
      *
-     * @param SimpleSAML_Configuration $srcMetadata The metadata of the sender.
-     * @param SimpleSAML_Configuration $dstMetadata The metadata of the recipient.
+     * @param \SimpleSAML\Configuration $srcMetadata The metadata of the sender.
+     * @param \SimpleSAML\Configuration $dstMetadata The metadata of the recipient.
      * @param \SAML2\SignedElement $element The element we should add the data to.
      */
     public static function addSign(
-        SimpleSAML_Configuration $srcMetadata,
-        SimpleSAML_Configuration $dstMetadata,
+        \SimpleSAML\Configuration $srcMetadata,
+        \SimpleSAML\Configuration $dstMetadata,
         \SAML2\SignedElement $element
     ) {
         $dstPrivateKey = $dstMetadata->getString('signature.privatekey', null);
 
         if ($dstPrivateKey !== null) {
-            $keyArray = SimpleSAML\Utils\Crypto::loadPrivateKey($dstMetadata, true, 'signature.');
-            $certArray = SimpleSAML\Utils\Crypto::loadPublicKey($dstMetadata, false, 'signature.');
+            $keyArray = \SimpleSAML\Utils\Crypto::loadPrivateKey($dstMetadata, true, 'signature.');
+            $certArray = \SimpleSAML\Utils\Crypto::loadPublicKey($dstMetadata, false, 'signature.');
         } else {
-            $keyArray = SimpleSAML\Utils\Crypto::loadPrivateKey($srcMetadata, true);
-            $certArray = SimpleSAML\Utils\Crypto::loadPublicKey($srcMetadata, false);
+            $keyArray = \SimpleSAML\Utils\Crypto::loadPrivateKey($srcMetadata, true);
+            $certArray = \SimpleSAML\Utils\Crypto::loadPublicKey($srcMetadata, false);
         }
 
         $algo = $dstMetadata->getString('signature.algorithm', null);
         if ($algo === null) {
-            /*
-             * In the NIST Special Publication 800-131A, SHA-1 became deprecated for generating
-             * new digital signatures in 2011, and will be explicitly disallowed starting the 1st
-             * of January, 2014. We'll keep this as a default for the next release and mark it
-             * as deprecated, as part of the transition to SHA-256.
-             *
-             * See http://csrc.nist.gov/publications/nistpubs/800-131A/sp800-131A.pdf for more info.
-             *
-             * TODO: change default to XMLSecurityKey::RSA_SHA256.
-             */
-            $algo = $srcMetadata->getString('signature.algorithm', XMLSecurityKey::RSA_SHA1);
+            $algo = $srcMetadata->getString('signature.algorithm', XMLSecurityKey::RSA_SHA256);
         }
 
         $privateKey = new XMLSecurityKey($algo, array('type' => 'private'));
@@ -72,13 +63,13 @@ class sspmod_saml_Message
     /**
      * Add signature key and and senders certificate to message.
      *
-     * @param SimpleSAML_Configuration $srcMetadata The metadata of the sender.
-     * @param SimpleSAML_Configuration $dstMetadata The metadata of the recipient.
+     * @param \SimpleSAML\Configuration $srcMetadata The metadata of the sender.
+     * @param \SimpleSAML\Configuration $dstMetadata The metadata of the recipient.
      * @param \SAML2\Message $message The message we should add the data to.
      */
     private static function addRedirectSign(
-        SimpleSAML_Configuration $srcMetadata,
-        SimpleSAML_Configuration $dstMetadata,
+        \SimpleSAML\Configuration $srcMetadata,
+        \SimpleSAML\Configuration $dstMetadata,
         \SAML2\Message $message
     ) {
 
@@ -119,7 +110,7 @@ class sspmod_saml_Message
      *
      * @return string Certificate, in PEM-format.
      *
-     * @throws SimpleSAML_Error_Exception if we cannot find the certificate matching the fingerprint.
+     * @throws \SimpleSAML\Error\Exception if we cannot find the certificate matching the fingerprint.
      */
     private static function findCertificate(array $certFingerprints, array $certificates)
     {
@@ -141,7 +132,7 @@ class sspmod_saml_Message
 
         $candidates = "'".implode("', '", $candidates)."'";
         $fps = "'".implode("', '", $certFingerprints)."'";
-        throw new SimpleSAML_Error_Exception('Unable to find a certificate matching the configured '.
+        throw new \SimpleSAML\Error\Exception('Unable to find a certificate matching the configured '.
             'fingerprint. Candidates: '.$candidates.'; certFingerprint: '.$fps.'.');
     }
 
@@ -149,18 +140,18 @@ class sspmod_saml_Message
     /**
      * Check the signature on a SAML2 message or assertion.
      *
-     * @param SimpleSAML_Configuration $srcMetadata The metadata of the sender.
+     * @param \SimpleSAML\Configuration $srcMetadata The metadata of the sender.
      * @param \SAML2\SignedElement $element Either a \SAML2\Response or a \SAML2\Assertion.
      * @return boolean True if the signature is correct, false otherwise.
      *
-     * @throws \SimpleSAML_Error_Exception if there is not certificate in the metadata for the entity.
+     * @throws \SimpleSAML\Error\Exception if there is not certificate in the metadata for the entity.
      * @throws \Exception if the signature validation fails with an exception.
      */
-    public static function checkSign(SimpleSAML_Configuration $srcMetadata, \SAML2\SignedElement $element)
+    public static function checkSign(\SimpleSAML\Configuration $srcMetadata, \SAML2\SignedElement $element)
     {
         // find the public key that should verify signatures by this entity
         $keys = $srcMetadata->getPublicKeys('signing');
-        if ($keys !== null) {
+        if (!empty($keys)) {
             $pemKeys = array();
             foreach ($keys as $key) {
                 switch ($key['type']) {
@@ -170,11 +161,11 @@ class sspmod_saml_Message
                             "-----END CERTIFICATE-----\n";
                         break;
                     default:
-                        SimpleSAML\Logger::debug('Skipping unknown key type: '.$key['type']);
+                        \SimpleSAML\Logger::debug('Skipping unknown key type: '.$key['type']);
                 }
             }
         } elseif ($srcMetadata->hasValue('certFingerprint')) {
-            SimpleSAML\Logger::notice(
+            \SimpleSAML\Logger::notice(
                 "Validating certificates by fingerprint is deprecated. Please use ".
                 "certData or certificate options in your remote metadata configuration."
             );
@@ -189,38 +180,38 @@ class sspmod_saml_Message
             // we don't have the full certificate stored. Try to find it in the message or the assertion instead
             if (count($certificates) === 0) {
                 /* We need the full certificate in order to match it against the fingerprint. */
-                SimpleSAML\Logger::debug('No certificate in message when validating against fingerprint.');
+                \SimpleSAML\Logger::debug('No certificate in message when validating against fingerprint.');
                 return false;
             } else {
-                SimpleSAML\Logger::debug('Found '.count($certificates).' certificates in '.get_class($element));
+                \SimpleSAML\Logger::debug('Found '.count($certificates).' certificates in '.get_class($element));
             }
 
             $pemCert = self::findCertificate($certFingerprint, $certificates);
             $pemKeys = array($pemCert);
         } else {
-            throw new SimpleSAML_Error_Exception(
+            throw new \SimpleSAML\Error\Exception(
                 'Missing certificate in metadata for '.
                 var_export($srcMetadata->getString('entityid'), true)
             );
         }
 
-        SimpleSAML\Logger::debug('Has '.count($pemKeys).' candidate keys for validation.');
+        \SimpleSAML\Logger::debug('Has '.count($pemKeys).' candidate keys for validation.');
 
         $lastException = null;
         foreach ($pemKeys as $i => $pem) {
-            $key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'public'));
+            $key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, array('type' => 'public'));
             $key->loadKey($pem);
 
             try {
                 // make sure that we have a valid signature on either the response or the assertion
                 $res = $element->validate($key);
                 if ($res) {
-                    SimpleSAML\Logger::debug('Validation with key #'.$i.' succeeded.');
+                    \SimpleSAML\Logger::debug('Validation with key #'.$i.' succeeded.');
                     return true;
                 }
-                SimpleSAML\Logger::debug('Validation with key #'.$i.' failed without exception.');
-            } catch (Exception $e) {
-                SimpleSAML\Logger::debug('Validation with key #'.$i.' failed with exception: '.$e->getMessage());
+                \SimpleSAML\Logger::debug('Validation with key #'.$i.' failed without exception.');
+            } catch (\Exception $e) {
+                \SimpleSAML\Logger::debug('Validation with key #'.$i.' failed with exception: '.$e->getMessage());
                 $lastException = $e;
             }
         }
@@ -237,15 +228,15 @@ class sspmod_saml_Message
     /**
      * Check signature on a SAML2 message if enabled.
      *
-     * @param SimpleSAML_Configuration $srcMetadata The metadata of the sender.
-     * @param SimpleSAML_Configuration $dstMetadata The metadata of the recipient.
+     * @param \SimpleSAML\Configuration $srcMetadata The metadata of the sender.
+     * @param \SimpleSAML\Configuration $dstMetadata The metadata of the recipient.
      * @param \SAML2\Message $message The message we should check the signature on.
      *
-     * @throws \SimpleSAML_Error_Exception if message validation is enabled, but there is no signature in the message.
+     * @throws \SimpleSAML\Error\Exception if message validation is enabled, but there is no signature in the message.
      */
     public static function validateMessage(
-        SimpleSAML_Configuration $srcMetadata,
-        SimpleSAML_Configuration $dstMetadata,
+        \SimpleSAML\Configuration $srcMetadata,
+        \SimpleSAML\Configuration $dstMetadata,
         \SAML2\Message $message
     ) {
         $enabled = null;
@@ -273,7 +264,7 @@ class sspmod_saml_Message
         }
 
         if (!self::checkSign($srcMetadata, $message)) {
-            throw new SimpleSAML_Error_Exception(
+            throw new \SimpleSAML\Error\Exception(
                 'Validation of received messages enabled, but no signature found on message.'
             );
         }
@@ -283,14 +274,14 @@ class sspmod_saml_Message
     /**
      * Retrieve the decryption keys from metadata.
      *
-     * @param SimpleSAML_Configuration $srcMetadata The metadata of the sender (IdP).
-     * @param SimpleSAML_Configuration $dstMetadata The metadata of the recipient (SP).
+     * @param \SimpleSAML\Configuration $srcMetadata The metadata of the sender (IdP).
+     * @param \SimpleSAML\Configuration $dstMetadata The metadata of the recipient (SP).
      *
      * @return array Array of decryption keys.
      */
     public static function getDecryptionKeys(
-        SimpleSAML_Configuration $srcMetadata,
-        SimpleSAML_Configuration $dstMetadata
+        \SimpleSAML\Configuration $srcMetadata,
+        \SimpleSAML\Configuration $dstMetadata
     ) {
         $sharedKey = $srcMetadata->getString('sharedkey', null);
         if ($sharedKey !== null) {
@@ -302,7 +293,7 @@ class sspmod_saml_Message
         $keys = array();
 
         // load the new private key if it exists
-        $keyArray = SimpleSAML\Utils\Crypto::loadPrivateKey($dstMetadata, false, 'new_');
+        $keyArray = \SimpleSAML\Utils\Crypto::loadPrivateKey($dstMetadata, false, 'new_');
         if ($keyArray !== null) {
             assert(isset($keyArray['PEM']));
 
@@ -315,7 +306,7 @@ class sspmod_saml_Message
         }
 
         // find the existing private key
-        $keyArray = SimpleSAML\Utils\Crypto::loadPrivateKey($dstMetadata, true);
+        $keyArray = \SimpleSAML\Utils\Crypto::loadPrivateKey($dstMetadata, true);
         assert(isset($keyArray['PEM']));
 
         $key = new XMLSecurityKey(XMLSecurityKey::RSA_1_5, array('type' => 'private'));
@@ -334,14 +325,14 @@ class sspmod_saml_Message
      *
      * Remote configuration overrides local configuration.
      *
-     * @param SimpleSAML_Configuration $srcMetadata The metadata of the sender.
-     * @param SimpleSAML_Configuration $dstMetadata The metadata of the recipient.
+     * @param \SimpleSAML\Configuration $srcMetadata The metadata of the sender.
+     * @param \SimpleSAML\Configuration $dstMetadata The metadata of the recipient.
      *
      * @return array  Array of blacklisted algorithms.
      */
     public static function getBlacklistedAlgorithms(
-        SimpleSAML_Configuration $srcMetadata,
-        SimpleSAML_Configuration $dstMetadata
+        \SimpleSAML\Configuration $srcMetadata,
+        \SimpleSAML\Configuration $dstMetadata
     ) {
         $blacklist = $srcMetadata->getArray('encryption.blacklisted-algorithms', null);
         if ($blacklist === null) {
@@ -354,19 +345,19 @@ class sspmod_saml_Message
     /**
      * Decrypt an assertion.
      *
-     * @param SimpleSAML_Configuration $srcMetadata The metadata of the sender (IdP).
-     * @param SimpleSAML_Configuration $dstMetadata The metadata of the recipient (SP).
+     * @param \SimpleSAML\Configuration $srcMetadata The metadata of the sender (IdP).
+     * @param \SimpleSAML\Configuration $dstMetadata The metadata of the recipient (SP).
      * @param \SAML2\Assertion|\SAML2\EncryptedAssertion $assertion The assertion we are decrypting.
      *
      * @return \SAML2\Assertion The assertion.
      *
-     * @throws \SimpleSAML_Error_Exception if encryption is enabled but the assertion is not encrypted, or if we cannot
+     * @throws \SimpleSAML\Error\Exception if encryption is enabled but the assertion is not encrypted, or if we cannot
      * get the decryption keys.
      * @throws \Exception if decryption fails for whatever reason.
      */
     private static function decryptAssertion(
-        SimpleSAML_Configuration $srcMetadata,
-        SimpleSAML_Configuration $dstMetadata,
+        \SimpleSAML\Configuration $srcMetadata,
+        \SimpleSAML\Configuration $dstMetadata,
         $assertion
     ) {
         assert($assertion instanceof \SAML2\Assertion || $assertion instanceof \SAML2\EncryptedAssertion);
@@ -378,7 +369,7 @@ class sspmod_saml_Message
             }
             if ($encryptAssertion) {
                 /* The assertion was unencrypted, but we have encryption enabled. */
-                throw new Exception('Received unencrypted assertion, but encryption was enabled.');
+                throw new \Exception('Received unencrypted assertion, but encryption was enabled.');
             }
 
             return $assertion;
@@ -386,8 +377,8 @@ class sspmod_saml_Message
 
         try {
             $keys = self::getDecryptionKeys($srcMetadata, $dstMetadata);
-        } catch (Exception $e) {
-            throw new SimpleSAML_Error_Exception('Error decrypting assertion: '.$e->getMessage());
+        } catch (\Exception $e) {
+            throw new \SimpleSAML\Error\Exception('Error decrypting assertion: '.$e->getMessage());
         }
 
         $blacklist = self::getBlacklistedAlgorithms($srcMetadata, $dstMetadata);
@@ -396,10 +387,10 @@ class sspmod_saml_Message
         foreach ($keys as $i => $key) {
             try {
                 $ret = $assertion->getAssertion($key, $blacklist);
-                SimpleSAML\Logger::debug('Decryption with key #'.$i.' succeeded.');
+                \SimpleSAML\Logger::debug('Decryption with key #'.$i.' succeeded.');
                 return $ret;
-            } catch (Exception $e) {
-                SimpleSAML\Logger::debug('Decryption with key #'.$i.' failed with exception: '.$e->getMessage());
+            } catch (\Exception $e) {
+                \SimpleSAML\Logger::debug('Decryption with key #'.$i.' failed with exception: '.$e->getMessage());
                 $lastException = $e;
             }
         }
@@ -408,29 +399,74 @@ class sspmod_saml_Message
 
 
     /**
-     * Retrieve the status code of a response as a sspmod_saml_Error.
+     * Decrypt any encrypted attributes in an assertion.
+     *
+     * @param \SimpleSAML\Configuration $srcMetadata The metadata of the sender (IdP).
+     * @param \SimpleSAML\Configuration $dstMetadata The metadata of the recipient (SP).
+     * @param \SAML2\Assertion|\SAML2\Assertion $assertion The assertion containing any possibly encrypted attributes.
+     *
+     * @return void
+     *
+     * @throws \SimpleSAML\Error\Exception if we cannot get the decryption keys or decryption fails.
+     */
+    private static function decryptAttributes(
+        \SimpleSAML\Configuration $srcMetadata,
+        \SimpleSAML\Configuration $dstMetadata,
+        \SAML2\Assertion &$assertion
+    ) {
+        if (!$assertion->hasEncryptedAttributes()) {
+            return;
+        }
+
+        try {
+            $keys = self::getDecryptionKeys($srcMetadata, $dstMetadata);
+        } catch (\Exception $e) {
+            throw new \SimpleSAML\Error\Exception('Error decrypting attributes: '.$e->getMessage());
+        }
+
+        $blacklist = self::getBlacklistedAlgorithms($srcMetadata, $dstMetadata);
+
+        $error = true;
+        foreach ($keys as $i => $key) {
+            try {
+                $assertion->decryptAttributes($key, $blacklist);
+                \SimpleSAML\Logger::debug('Attribute decryption with key #'.$i.' succeeded.');
+                $error = false;
+                break;
+            } catch (\Exception $e) {
+                \SimpleSAML\Logger::debug('Attribute decryption failed with exception: '.$e->getMessage());
+            }
+        }
+        if ($error) {
+            throw new \SimpleSAML\Error\Exception('Could not decrypt the attributes');
+        }
+    }
+
+
+    /**
+     * Retrieve the status code of a response as a \SimpleSAML\Module\saml\Error.
      *
      * @param \SAML2\StatusResponse $response The response.
      *
-     * @return sspmod_saml_Error The error.
+     * @return \SimpleSAML\Module\saml\Error The error.
      */
     public static function getResponseError(\SAML2\StatusResponse $response)
     {
         $status = $response->getStatus();
-        return new sspmod_saml_Error($status['Code'], $status['SubCode'], $status['Message']);
+        return new \SimpleSAML\Module\saml\Error($status['Code'], $status['SubCode'], $status['Message']);
     }
 
 
     /**
      * Build an authentication request based on information in the metadata.
      *
-     * @param SimpleSAML_Configuration $spMetadata The metadata of the service provider.
-     * @param SimpleSAML_Configuration $idpMetadata The metadata of the identity provider.
+     * @param \SimpleSAML\Configuration $spMetadata The metadata of the service provider.
+     * @param \SimpleSAML\Configuration $idpMetadata The metadata of the identity provider.
      * @return \SAML2\AuthnRequest An authentication request object.
      */
     public static function buildAuthnRequest(
-        SimpleSAML_Configuration $spMetadata,
-        SimpleSAML_Configuration $idpMetadata
+        \SimpleSAML\Configuration $spMetadata,
+        \SimpleSAML\Configuration $idpMetadata
     ) {
         $ar = new \SAML2\AuthnRequest();
 
@@ -447,7 +483,7 @@ class sspmod_saml_Message
             $nameIdPolicy = array('Format' => $nameIdPolicy);
         }
 
-        $nameIdPolicy_cf = SimpleSAML_Configuration::loadFromArray($nameIdPolicy);
+        $nameIdPolicy_cf = \SimpleSAML\Configuration::loadFromArray($nameIdPolicy);
         $policy = array(
             'Format'      => $nameIdPolicy_cf->getString('Format', \SAML2\Constants::NAMEID_TRANSIENT),
             'AllowCreate' => $nameIdPolicy_cf->getBoolean('AllowCreate', true),
@@ -494,13 +530,13 @@ class sspmod_saml_Message
     /**
      * Build a logout request based on information in the metadata.
      *
-     * @param SimpleSAML_Configuration $srcMetadata The metadata of the sender.
-     * @param SimpleSAML_Configuration $dstMetadata The metadata of the recipient.
+     * @param \SimpleSAML\Configuration $srcMetadata The metadata of the sender.
+     * @param \SimpleSAML\Configuration $dstMetadata The metadata of the recipient.
      * @return \SAML2\LogoutRequest A logout request object.
      */
     public static function buildLogoutRequest(
-        SimpleSAML_Configuration $srcMetadata,
-        SimpleSAML_Configuration $dstMetadata
+        \SimpleSAML\Configuration $srcMetadata,
+        \SimpleSAML\Configuration $dstMetadata
     ) {
         $lr = new \SAML2\LogoutRequest();
         $lr->setIssuer($srcMetadata->getString('entityid'));
@@ -514,13 +550,13 @@ class sspmod_saml_Message
     /**
      * Build a logout response based on information in the metadata.
      *
-     * @param SimpleSAML_Configuration $srcMetadata The metadata of the sender.
-     * @param SimpleSAML_Configuration $dstMetadata The metadata of the recipient.
+     * @param \SimpleSAML\Configuration $srcMetadata The metadata of the sender.
+     * @param \SimpleSAML\Configuration $dstMetadata The metadata of the recipient.
      * @return \SAML2\LogoutResponse A logout response object.
      */
     public static function buildLogoutResponse(
-        SimpleSAML_Configuration $srcMetadata,
-        SimpleSAML_Configuration $dstMetadata
+        \SimpleSAML\Configuration $srcMetadata,
+        \SimpleSAML\Configuration $dstMetadata
     ) {
         $lr = new \SAML2\LogoutResponse();
         $lr->setIssuer($srcMetadata->getString('entityid'));
@@ -534,20 +570,20 @@ class sspmod_saml_Message
     /**
      * Process a response message.
      *
-     * If the response is an error response, we will throw a sspmod_saml_Error exception with the error.
+     * If the response is an error response, we will throw a \SimpleSAML\Module\saml\Error exception with the error.
      *
-     * @param SimpleSAML_Configuration $spMetadata The metadata of the service provider.
-     * @param SimpleSAML_Configuration $idpMetadata The metadata of the identity provider.
+     * @param \SimpleSAML\Configuration $spMetadata The metadata of the service provider.
+     * @param \SimpleSAML\Configuration $idpMetadata The metadata of the identity provider.
      * @param \SAML2\Response $response The response.
      *
      * @return array Array with \SAML2\Assertion objects, containing valid assertions from the response.
      *
-     * @throws \SimpleSAML_Error_Exception if there are no assertions in the response.
+     * @throws \SimpleSAML\Error\Exception if there are no assertions in the response.
      * @throws \Exception if the destination of the response does not match the current URL.
      */
     public static function processResponse(
-        SimpleSAML_Configuration $spMetadata,
-        SimpleSAML_Configuration $idpMetadata,
+        \SimpleSAML\Configuration $spMetadata,
+        \SimpleSAML\Configuration $idpMetadata,
         \SAML2\Response $response
     ) {
         if (!$response->isSuccess()) {
@@ -558,7 +594,7 @@ class sspmod_saml_Message
         $currentURL = \SimpleSAML\Utils\HTTP::getSelfURLNoQuery();
         $msgDestination = $response->getDestination();
         if ($msgDestination !== null && $msgDestination !== $currentURL) {
-            throw new Exception('Destination in response doesn\'t match the current URL. Destination is "'.
+            throw new \Exception('Destination in response doesn\'t match the current URL. Destination is "'.
                 $msgDestination.'", current URL is "'.$currentURL.'".');
         }
 
@@ -570,7 +606,7 @@ class sspmod_saml_Message
          */
         $assertion = $response->getAssertions();
         if (empty($assertion)) {
-            throw new SimpleSAML_Error_Exception('No assertions found in response from IdP.');
+            throw new \SimpleSAML\Error\Exception('No assertions found in response from IdP.');
         }
 
         $ret = array();
@@ -585,22 +621,22 @@ class sspmod_saml_Message
     /**
      * Process an assertion in a response.
      *
-     * @param SimpleSAML_Configuration $spMetadata The metadata of the service provider.
-     * @param SimpleSAML_Configuration $idpMetadata The metadata of the identity provider.
+     * @param \SimpleSAML\Configuration $spMetadata The metadata of the service provider.
+     * @param \SimpleSAML\Configuration $idpMetadata The metadata of the identity provider.
      * @param \SAML2\Response $response The response containing the assertion.
      * @param \SAML2\Assertion|\SAML2\EncryptedAssertion $assertion The assertion.
      * @param bool $responseSigned Whether the response is signed.
      *
      * @return \SAML2\Assertion The assertion, if it is valid.
      *
-     * @throws \SimpleSAML_Error_Exception if an error occurs while trying to validate the assertion, or if a assertion
+     * @throws \SimpleSAML\Error\Exception if an error occurs while trying to validate the assertion, or if a assertion
      * is not signed and it should be, or if we are unable to decrypt the NameID due to a local failure (missing or
      * invalid decryption key).
      * @throws \Exception if we couldn't decrypt the NameID for unexpected reasons.
      */
     private static function processAssertion(
-        SimpleSAML_Configuration $spMetadata,
-        SimpleSAML_Configuration $idpMetadata,
+        \SimpleSAML\Configuration $spMetadata,
+        \SimpleSAML\Configuration $idpMetadata,
         \SAML2\Response $response,
         $assertion,
         $responseSigned
@@ -609,10 +645,11 @@ class sspmod_saml_Message
         assert(is_bool($responseSigned));
 
         $assertion = self::decryptAssertion($idpMetadata, $spMetadata, $assertion);
+        self::decryptAttributes($idpMetadata, $spMetadata, $assertion);
 
         if (!self::checkSign($idpMetadata, $assertion)) {
             if (!$responseSigned) {
-                throw new SimpleSAML_Error_Exception('Neither the assertion nor the response was signed.');
+                throw new \SimpleSAML\Error\Exception('Neither the assertion nor the response was signed.');
             }
         } // at least one valid signature found
 
@@ -621,19 +658,19 @@ class sspmod_saml_Message
         // check various properties of the assertion
         $notBefore = $assertion->getNotBefore();
         if ($notBefore !== null && $notBefore > time() + 60) {
-            throw new SimpleSAML_Error_Exception(
+            throw new \SimpleSAML\Error\Exception(
                 'Received an assertion that is valid in the future. Check clock synchronization on IdP and SP.'
             );
         }
         $notOnOrAfter = $assertion->getNotOnOrAfter();
         if ($notOnOrAfter !== null && $notOnOrAfter <= time() - 60) {
-            throw new SimpleSAML_Error_Exception(
+            throw new \SimpleSAML\Error\Exception(
                 'Received an assertion that has expired. Check clock synchronization on IdP and SP.'
             );
         }
         $sessionNotOnOrAfter = $assertion->getSessionNotOnOrAfter();
         if ($sessionNotOnOrAfter !== null && $sessionNotOnOrAfter <= time() - 60) {
-            throw new SimpleSAML_Error_Exception(
+            throw new \SimpleSAML\Error\Exception(
                 'Received an assertion with a session that has expired. Check clock synchronization on IdP and SP.'
             );
         }
@@ -642,7 +679,7 @@ class sspmod_saml_Message
             $spEntityId = $spMetadata->getString('entityid');
             if (!in_array($spEntityId, $validAudiences, true)) {
                 $candidates = '['.implode('], [', $validAudiences).']';
-                throw new SimpleSAML_Error_Exception('This SP ['.$spEntityId.
+                throw new \SimpleSAML\Error\Exception('This SP ['.$spEntityId.
                     ']  is not a valid audience for the assertion. Candidates were: '.$candidates);
             }
         }
@@ -768,7 +805,7 @@ class sspmod_saml_Message
             break;
         }
         if (!$found) {
-            throw new SimpleSAML_Error_Exception('Error validating SubjectConfirmation in Assertion: '.$lastError);
+            throw new \SimpleSAML\Error\Exception('Error validating SubjectConfirmation in Assertion: '.$lastError);
         } // as far as we can tell, the assertion is valid
 
         // maybe we need to base64 decode the attributes in the assertion?
@@ -790,8 +827,8 @@ class sspmod_saml_Message
         if ($assertion->isNameIdEncrypted()) {
             try {
                 $keys = self::getDecryptionKeys($idpMetadata, $spMetadata);
-            } catch (Exception $e) {
-                throw new SimpleSAML_Error_Exception('Error decrypting NameID: '.$e->getMessage());
+            } catch (\Exception $e) {
+                throw new \SimpleSAML\Error\Exception('Error decrypting NameID: '.$e->getMessage());
             }
 
             $blacklist = self::getBlacklistedAlgorithms($idpMetadata, $spMetadata);
@@ -800,11 +837,11 @@ class sspmod_saml_Message
             foreach ($keys as $i => $key) {
                 try {
                     $assertion->decryptNameId($key, $blacklist);
-                    SimpleSAML\Logger::debug('Decryption with key #'.$i.' succeeded.');
+                    \SimpleSAML\Logger::debug('Decryption with key #'.$i.' succeeded.');
                     $lastException = null;
                     break;
-                } catch (Exception $e) {
-                    SimpleSAML\Logger::debug('Decryption with key #'.$i.' failed with exception: '.$e->getMessage());
+                } catch (\Exception $e) {
+                    \SimpleSAML\Logger::debug('Decryption with key #'.$i.' failed with exception: '.$e->getMessage());
                     $lastException = $e;
                 }
             }
@@ -820,13 +857,13 @@ class sspmod_saml_Message
     /**
      * Retrieve the encryption key for the given entity.
      *
-     * @param SimpleSAML_Configuration $metadata The metadata of the entity.
+     * @param \SimpleSAML\Configuration $metadata The metadata of the entity.
      *
      * @return \RobRichards\XMLSecLibs\XMLSecurityKey  The encryption key.
      *
-     * @throws \SimpleSAML_Error_Exception if there is no supported encryption key in the metadata of this entity.
+     * @throws \SimpleSAML\Error\Exception if there is no supported encryption key in the metadata of this entity.
      */
-    public static function getEncryptionKey(SimpleSAML_Configuration $metadata)
+    public static function getEncryptionKey(\SimpleSAML\Configuration $metadata)
     {
 
         $sharedKey = $metadata->getString('sharedkey', null);
@@ -849,7 +886,7 @@ class sspmod_saml_Message
             }
         }
 
-        throw new SimpleSAML_Error_Exception('No supported encryption key in '.
+        throw new \SimpleSAML\Error\Exception('No supported encryption key in '.
             var_export($metadata->getString('entityid'), true));
     }
 }
diff --git a/modules/saml/lib/SP/LogoutStore.php b/modules/saml/lib/SP/LogoutStore.php
index 95bcffde55931380d657d450ec50de416b72de8b..8d329a8cc6defd98a726dfcc9c6971ba42f654e4 100644
--- a/modules/saml/lib/SP/LogoutStore.php
+++ b/modules/saml/lib/SP/LogoutStore.php
@@ -1,300 +1,305 @@
 <?php
 
+namespace SimpleSAML\Module\saml\SP;
+
 /**
  * A directory over logout information.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_saml_SP_LogoutStore {
-
-	/**
-	 * Create logout table in SQL, if it is missing.
-	 *
-	 * @param \SimpleSAML\Store\SQL $store  The datastore.
-	 */
-	private static function createLogoutTable(\SimpleSAML\Store\SQL $store) {
-
-		$tableVer = $store->getTableVersion('saml_LogoutStore');
-		if ($tableVer === 2) {
-			return;
-		} elseif ($tableVer === 1) {
-			/* TableVersion 2 increased the column size to 255 which is the maximum length of a FQDN. */
-			$query = 'ALTER TABLE ' . $store->prefix . '_saml_LogoutStore MODIFY _authSource VARCHAR(255) NOT NULL';
-			try {
-				$ret = $store->pdo->exec($query);
-			} catch (Exception $e) {
-				SimpleSAML\Logger::warning($store->pdo->errorInfo());
-				return;
-			}
-			$store->setTableVersion('saml_LogoutStore', 2);
-			return;
-		}
-
-		$query = 'CREATE TABLE ' . $store->prefix . '_saml_LogoutStore (
-			_authSource VARCHAR(255) NOT NULL,
-			_nameId VARCHAR(40) NOT NULL,
-			_sessionIndex VARCHAR(50) NOT NULL,
-			_expire TIMESTAMP NOT NULL,
-			_sessionId VARCHAR(50) NOT NULL,
-			UNIQUE (_authSource, _nameID, _sessionIndex)
-		)';
-		$store->pdo->exec($query);
-
-		$query = 'CREATE INDEX ' . $store->prefix . '_saml_LogoutStore_expire ON '  . $store->prefix . '_saml_LogoutStore (_expire)';
-		$store->pdo->exec($query);
-
-		$query = 'CREATE INDEX ' . $store->prefix . '_saml_LogoutStore_nameId ON '  . $store->prefix . '_saml_LogoutStore (_authSource, _nameId)';
-		$store->pdo->exec($query);
-
-		$store->setTableVersion('saml_LogoutStore', 2);
-	}
-
-
-	/**
-	 * Clean the logout table of expired entries.
-	 *
-	 * @param \SimpleSAML\Store\SQL $store  The datastore.
-	 */
-	private static function cleanLogoutStore(\SimpleSAML\Store\SQL $store) {
-
-		SimpleSAML\Logger::debug('saml.LogoutStore: Cleaning logout store.');
-
-		$query = 'DELETE FROM ' . $store->prefix . '_saml_LogoutStore WHERE _expire < :now';
-		$params = array('now' => gmdate('Y-m-d H:i:s'));
-
-		$query = $store->pdo->prepare($query);
-		$query->execute($params);
-	}
-
-
-	/**
-	 * Register a session in the SQL datastore.
-	 *
-	 * @param \SimpleSAML\Store\SQL $store  The datastore.
-	 * @param string $authId  The authsource ID.
-	 * @param string $nameId  The hash of the users NameID.
-	 * @param string $sessionIndex  The SessionIndex of the user.
-	 */
-	private static function addSessionSQL(\SimpleSAML\Store\SQL $store, $authId, $nameId, $sessionIndex, $expire, $sessionId) {
-		assert(is_string($authId));
-		assert(is_string($nameId));
-		assert(is_string($sessionIndex));
-		assert(is_string($sessionId));
-		assert(is_int($expire));
-
-		self::createLogoutTable($store);
-
-		if (rand(0, 1000) < 10) {
-			self::cleanLogoutStore($store);
-		}
-
-		$data = array(
-			'_authSource' => $authId,
-			'_nameId' => $nameId,
-			'_sessionIndex' => $sessionIndex,
-			'_expire' => gmdate('Y-m-d H:i:s', $expire),
-			'_sessionId' => $sessionId,
-		);
-		$store->insertOrUpdate($store->prefix . '_saml_LogoutStore', array('_authSource', '_nameId', '_sessionIndex'), $data);
-	}
-
-
-	/**
-	 * Retrieve sessions from the SQL datastore.
-	 *
-	 * @param \SimpleSAML\Store\SQL $store  The datastore.
-	 * @param string $authId  The authsource ID.
-	 * @param string $nameId  The hash of the users NameID.
-	 * @return array  Associative array of SessionIndex =>  SessionId.
-	 */
-	private static function getSessionsSQL(\SimpleSAML\Store\SQL $store, $authId, $nameId) {
-		assert(is_string($authId));
-		assert(is_string($nameId));
-
-		self::createLogoutTable($store);
-
-		$params = array(
-			'_authSource' => $authId,
-			'_nameId' => $nameId,
-			'now' => gmdate('Y-m-d H:i:s'),
-		);
-
-		// We request the columns in lowercase in order to be compatible with PostgreSQL
-		$query = 'SELECT _sessionIndex AS _sessionindex, _sessionId AS _sessionid FROM ' . $store->prefix . '_saml_LogoutStore' .
-			' WHERE _authSource = :_authSource AND _nameId = :_nameId AND _expire >= :now';
-		$query = $store->pdo->prepare($query);
-		$query->execute($params);
-
-		$res = array();
-		while ( ($row = $query->fetch(PDO::FETCH_ASSOC)) !== FALSE) {
-			$res[$row['_sessionindex']] = $row['_sessionid'];
-		}
-
-		return $res;
-	}
-
-
-	/**
-	 * Retrieve all session IDs from a key-value store.
-	 *
-	 * @param \SimpleSAML\Store $store  The datastore.
-	 * @param string $authId  The authsource ID.
-	 * @param string $nameId  The hash of the users NameID.
-	 * @param array $sessionIndexes  The session indexes.
-	 * @return array  Associative array of SessionIndex =>  SessionId.
-	 */
-	private static function getSessionsStore(\SimpleSAML\Store $store, $authId, $nameId, array $sessionIndexes) {
-		assert(is_string($authId));
-		assert(is_string($nameId));
-
-		$res = array();
-		foreach ($sessionIndexes as $sessionIndex) {
-			$sessionId = $store->get('saml.LogoutStore', $nameId . ':' . $sessionIndex);
-			if ($sessionId === NULL) {
-				continue;
-			}
-			assert(is_string($sessionId));
-			$res[$sessionIndex] = $sessionId;
-		}
-
-		return $res;
-	}
-
-
-	/**
-	 * Register a new session in the datastore.
-	 *
-	 * Please observe the change of the signature in this method. Previously, the second parameter ($nameId) was forced
-	 * to be an array. However, it has no type restriction now, and the documentation states it must be a
-	 * \SAML2\XML\saml\NameID object. Currently, this function still accepts an array passed as $nameId, and will
-	 * silently convert it to a \SAML2\XML\saml\NameID object. This is done to keep backwards-compatibility, though will
-	 * no longer be possible in the future as the $nameId parameter will be required to be an object.
-	 *
-	 * @param string $authId  The authsource ID.
-	 * @param \SAML2\XML\saml\NameID $nameId The NameID of the user.
-	 * @param string|NULL $sessionIndex  The SessionIndex of the user.
-	 */
-	public static function addSession($authId, $nameId, $sessionIndex, $expire) {
-		assert(is_string($authId));
-		assert(is_string($sessionIndex) || $sessionIndex === null);
-		assert(is_int($expire));
-
-		if ($sessionIndex === NULL) {
-			/* This IdP apparently did not include a SessionIndex, and thus probably does not
-			 * support SLO. We still want to add the session to the data store just in case
-			 * it supports SLO, but we don't want an LogoutRequest with a specific
-			 * SessionIndex to match this session. We therefore generate our own session index.
-			 */
-			$sessionIndex = SimpleSAML\Utils\Random::generateID();
-		}
-
-		$store = \SimpleSAML\Store::getInstance();
-		if ($store === FALSE) {
-			// We don't have a datastore.
-			return;
-		}
-
-		// serialize and anonymize the NameID
-        // TODO: remove this conditional statement
-		if (is_array($nameId)) {
-			$nameId = \SAML2\XML\saml\NameID::fromArray($nameId);
-		}
-		$strNameId = serialize($nameId);
-		$strNameId = sha1($strNameId);
-
-		/* Normalize SessionIndex. */
-		if (strlen($sessionIndex) > 50) {
-			$sessionIndex = sha1($sessionIndex);
-		}
-
-		$session = SimpleSAML_Session::getSessionFromRequest();
-		$sessionId = $session->getSessionId();
-
-		if ($store instanceof \SimpleSAML\Store\SQL) {
-			self::addSessionSQL($store, $authId, $strNameId, $sessionIndex, $expire, $sessionId);
-		} else {
-			$store->set('saml.LogoutStore', $strNameId . ':' . $sessionIndex, $sessionId, $expire);
-		}
-	}
-
-
-	/**
-	 * Log out of the given sessions.
-	 *
-	 * @param string $authId  The authsource ID.
-	 * @param \SAML2\XML\saml\NameID $nameId The NameID of the user.
-	 * @param array $sessionIndexes  The SessionIndexes we should log out of. Logs out of all if this is empty.
-	 * @returns int|FALSE  Number of sessions logged out, or FALSE if not supported.
-	 */
-	public static function logoutSessions($authId, $nameId, array $sessionIndexes) {
-		assert(is_string($authId));
-
-		$store = \SimpleSAML\Store::getInstance();
-		if ($store === FALSE) {
-			/* We don't have a datastore. */
-			return FALSE;
-		}
-
-		// serialize and anonymize the NameID
-		// TODO: remove this conditional statement
-		if (is_array($nameId)) {
-			$nameId = \SAML2\XML\saml\NameID::fromArray($nameId);
-		}
-		$strNameId = serialize($nameId);
-		$strNameId = sha1($strNameId);
-
-		/* Normalize SessionIndexes. */
-		foreach ($sessionIndexes as &$sessionIndex) {
-			assert(is_string($sessionIndex));
-			if (strlen($sessionIndex) > 50) {
-				$sessionIndex = sha1($sessionIndex);
-			}
-		}
-		unset($sessionIndex); // Remove reference
-
-		if ($store instanceof \SimpleSAML\Store\SQL) {
-			$sessions = self::getSessionsSQL($store, $authId, $strNameId);
-		} elseif (empty($sessionIndexes)) {
-			/* We cannot fetch all sessions without a SQL store. */
-			return FALSE;
-		} else {
-			/** @var \SimpleSAML\Store $sessions At this point the store cannot be false */
-			$sessions = self::getSessionsStore($store, $authId, $strNameId, $sessionIndexes);
-
-		}
-
-		if (empty($sessionIndexes)) {
-			$sessionIndexes = array_keys($sessions);
-		}
-
-		$sessionHandler = \SimpleSAML\SessionHandler::getSessionHandler();
-
-		$numLoggedOut = 0;
-		foreach ($sessionIndexes as $sessionIndex) {
-			if (!isset($sessions[$sessionIndex])) {
-				SimpleSAML\Logger::info('saml.LogoutStore: Logout requested for unknown SessionIndex.');
-				continue;
-			}
-
-			$sessionId = $sessions[$sessionIndex];
-
-			$session = SimpleSAML_Session::getSession($sessionId);
-			if ($session === NULL) {
-				SimpleSAML\Logger::info('saml.LogoutStore: Skipping logout of missing session.');
-				continue;
-			}
-
-			if (!$session->isValid($authId)) {
-				SimpleSAML\Logger::info('saml.LogoutStore: Skipping logout of session because it isn\'t authenticated.');
-				continue;
-			}
-
-			SimpleSAML\Logger::info('saml.LogoutStore: Logging out of session with trackId [' . $session->getTrackID() . '].');
-			$session->doLogout($authId);
-			$numLoggedOut += 1;
-		}
-
-		return $numLoggedOut;
-	}
 
+class LogoutStore
+{
+    /**
+     * Create logout table in SQL, if it is missing.
+     *
+     * @param \SimpleSAML\Store\SQL $store  The datastore.
+     */
+    private static function createLogoutTable(\SimpleSAML\Store\SQL $store)
+    {
+        $tableVer = $store->getTableVersion('saml_LogoutStore');
+        if ($tableVer === 2) {
+            return;
+        } elseif ($tableVer === 1) {
+            /* TableVersion 2 increased the column size to 255 which is the maximum length of a FQDN. */
+            $query = 'ALTER TABLE ' . $store->prefix . '_saml_LogoutStore MODIFY _authSource VARCHAR(255) NOT NULL';
+            try {
+                $store->pdo->exec($query);
+            } catch (\Exception $e) {
+                \SimpleSAML\Logger::warning($store->pdo->errorInfo());
+                return;
+            }
+            $store->setTableVersion('saml_LogoutStore', 2);
+            return;
+        }
+
+        $query = 'CREATE TABLE ' . $store->prefix . '_saml_LogoutStore (
+            _authSource VARCHAR(255) NOT NULL,
+            _nameId VARCHAR(40) NOT NULL,
+            _sessionIndex VARCHAR(50) NOT NULL,
+            _expire TIMESTAMP NOT NULL,
+            _sessionId VARCHAR(50) NOT NULL,
+            UNIQUE (_authSource, _nameID, _sessionIndex)
+        )';
+        $store->pdo->exec($query);
+
+        $query = 'CREATE INDEX ' . $store->prefix . '_saml_LogoutStore_expire ON '  . $store->prefix . '_saml_LogoutStore (_expire)';
+        $store->pdo->exec($query);
+
+        $query = 'CREATE INDEX ' . $store->prefix . '_saml_LogoutStore_nameId ON '  . $store->prefix . '_saml_LogoutStore (_authSource, _nameId)';
+        $store->pdo->exec($query);
+
+        $store->setTableVersion('saml_LogoutStore', 2);
+    }
+
+
+    /**
+     * Clean the logout table of expired entries.
+     *
+     * @param \SimpleSAML\Store\SQL $store  The datastore.
+     */
+    private static function cleanLogoutStore(\SimpleSAML\Store\SQL $store)
+    {
+        \SimpleSAML\Logger::debug('saml.LogoutStore: Cleaning logout store.');
+
+        $query = 'DELETE FROM ' . $store->prefix . '_saml_LogoutStore WHERE _expire < :now';
+        $params = array('now' => gmdate('Y-m-d H:i:s'));
+
+        $query = $store->pdo->prepare($query);
+        $query->execute($params);
+    }
+
+
+    /**
+     * Register a session in the SQL datastore.
+     *
+     * @param \SimpleSAML\Store\SQL $store  The datastore.
+     * @param string $authId  The authsource ID.
+     * @param string $nameId  The hash of the users NameID.
+     * @param string $sessionIndex  The SessionIndex of the user.
+     */
+    private static function addSessionSQL(\SimpleSAML\Store\SQL $store, $authId, $nameId, $sessionIndex, $expire, $sessionId)
+    {
+        assert(is_string($authId));
+        assert(is_string($nameId));
+        assert(is_string($sessionIndex));
+        assert(is_string($sessionId));
+        assert(is_int($expire));
+
+        self::createLogoutTable($store);
+
+        if (rand(0, 1000) < 10) {
+            self::cleanLogoutStore($store);
+        }
+
+        $data = array(
+            '_authSource' => $authId,
+            '_nameId' => $nameId,
+            '_sessionIndex' => $sessionIndex,
+            '_expire' => gmdate('Y-m-d H:i:s', $expire),
+            '_sessionId' => $sessionId,
+        );
+        $store->insertOrUpdate($store->prefix . '_saml_LogoutStore', array('_authSource', '_nameId', '_sessionIndex'), $data);
+    }
+
+
+    /**
+     * Retrieve sessions from the SQL datastore.
+     *
+     * @param \SimpleSAML\Store\SQL $store  The datastore.
+     * @param string $authId  The authsource ID.
+     * @param string $nameId  The hash of the users NameID.
+     * @return array  Associative array of SessionIndex =>  SessionId.
+     */
+    private static function getSessionsSQL(\SimpleSAML\Store\SQL $store, $authId, $nameId)
+    {
+        assert(is_string($authId));
+        assert(is_string($nameId));
+
+        self::createLogoutTable($store);
+
+        $params = array(
+            '_authSource' => $authId,
+            '_nameId' => $nameId,
+            'now' => gmdate('Y-m-d H:i:s'),
+        );
+
+        // We request the columns in lowercase in order to be compatible with PostgreSQL
+        $query = 'SELECT _sessionIndex AS _sessionindex, _sessionId AS _sessionid FROM ' . $store->prefix . '_saml_LogoutStore' .
+            ' WHERE _authSource = :_authSource AND _nameId = :_nameId AND _expire >= :now';
+        $query = $store->pdo->prepare($query);
+        $query->execute($params);
+
+        $res = array();
+        while ( ($row = $query->fetch(\PDO::FETCH_ASSOC)) !== false) {
+            $res[$row['_sessionindex']] = $row['_sessionid'];
+        }
+
+        return $res;
+    }
+
+
+    /**
+     * Retrieve all session IDs from a key-value store.
+     *
+     * @param \SimpleSAML\Store $store  The datastore.
+     * @param string $authId  The authsource ID.
+     * @param string $nameId  The hash of the users NameID.
+     * @param array $sessionIndexes  The session indexes.
+     * @return array  Associative array of SessionIndex =>  SessionId.
+     */
+    private static function getSessionsStore(\SimpleSAML\Store $store, $authId, $nameId, array $sessionIndexes)
+    {
+        assert(is_string($authId));
+        assert(is_string($nameId));
+
+        $res = array();
+        foreach ($sessionIndexes as $sessionIndex) {
+            $sessionId = $store->get('saml.LogoutStore', $nameId . ':' . $sessionIndex);
+            if ($sessionId === null) {
+                continue;
+            }
+            assert(is_string($sessionId));
+            $res[$sessionIndex] = $sessionId;
+        }
+
+        return $res;
+    }
+
+
+    /**
+     * Register a new session in the datastore.
+     *
+     * Please observe the change of the signature in this method. Previously, the second parameter ($nameId) was forced
+     * to be an array. However, it has no type restriction now, and the documentation states it must be a
+     * \SAML2\XML\saml\NameID object. Currently, this function still accepts an array passed as $nameId, and will
+     * silently convert it to a \SAML2\XML\saml\NameID object. This is done to keep backwards-compatibility, though will
+     * no longer be possible in the future as the $nameId parameter will be required to be an object.
+     *
+     * @param string $authId  The authsource ID.
+     * @param \SAML2\XML\saml\NameID $nameId The NameID of the user.
+     * @param string|null $sessionIndex  The SessionIndex of the user.
+     */
+    public static function addSession($authId, $nameId, $sessionIndex, $expire)
+    {
+        assert(is_string($authId));
+        assert(is_string($sessionIndex) || $sessionIndex === null);
+        assert(is_int($expire));
+
+        if ($sessionIndex === null) {
+            /* This IdP apparently did not include a SessionIndex, and thus probably does not
+             * support SLO. We still want to add the session to the data store just in case
+             * it supports SLO, but we don't want an LogoutRequest with a specific
+             * SessionIndex to match this session. We therefore generate our own session index.
+             */
+            $sessionIndex = \SimpleSAML\Utils\Random::generateID();
+        }
+
+        $store = \SimpleSAML\Store::getInstance();
+        if ($store === false) {
+            // We don't have a datastore.
+            return;
+        }
+
+        // serialize and anonymize the NameID
+        // TODO: remove this conditional statement
+        if (is_array($nameId)) {
+            $nameId = \SAML2\XML\saml\NameID::fromArray($nameId);
+        }
+        $strNameId = serialize($nameId);
+        $strNameId = sha1($strNameId);
+
+        /* Normalize SessionIndex. */
+        if (strlen($sessionIndex) > 50) {
+            $sessionIndex = sha1($sessionIndex);
+        }
+
+        $session = \SimpleSAML\Session::getSessionFromRequest();
+        $sessionId = $session->getSessionId();
+
+        if ($store instanceof \SimpleSAML\Store\SQL) {
+            self::addSessionSQL($store, $authId, $strNameId, $sessionIndex, $expire, $sessionId);
+        } else {
+            $store->set('saml.LogoutStore', $strNameId . ':' . $sessionIndex, $sessionId, $expire);
+        }
+    }
+
+
+    /**
+     * Log out of the given sessions.
+     *
+     * @param string $authId  The authsource ID.
+     * @param \SAML2\XML\saml\NameID $nameId The NameID of the user.
+     * @param array $sessionIndexes  The SessionIndexes we should log out of. Logs out of all if this is empty.
+     * @returns int|false  Number of sessions logged out, or FALSE if not supported.
+     */
+    public static function logoutSessions($authId, $nameId, array $sessionIndexes)
+    {
+        assert(is_string($authId));
+
+        $store = \SimpleSAML\Store::getInstance();
+        if ($store === false) {
+            /* We don't have a datastore. */
+            return false;
+        }
+
+        // serialize and anonymize the NameID
+        // TODO: remove this conditional statement
+        if (is_array($nameId)) {
+            $nameId = \SAML2\XML\saml\NameID::fromArray($nameId);
+        }
+        $strNameId = serialize($nameId);
+        $strNameId = sha1($strNameId);
+
+        /* Normalize SessionIndexes. */
+        foreach ($sessionIndexes as &$sessionIndex) {
+            assert(is_string($sessionIndex));
+            if (strlen($sessionIndex) > 50) {
+                $sessionIndex = sha1($sessionIndex);
+            }
+        }
+        unset($sessionIndex); // Remove reference
+
+        if ($store instanceof \SimpleSAML\Store\SQL) {
+            $sessions = self::getSessionsSQL($store, $authId, $strNameId);
+        } elseif (empty($sessionIndexes)) {
+            /* We cannot fetch all sessions without a SQL store. */
+            return false;
+        } else {
+            /** @var \SimpleSAML\Store $sessions At this point the store cannot be false */
+            $sessions = self::getSessionsStore($store, $authId, $strNameId, $sessionIndexes);
+
+        }
+
+        if (empty($sessionIndexes)) {
+            $sessionIndexes = array_keys($sessions);
+        }
+
+        $numLoggedOut = 0;
+        foreach ($sessionIndexes as $sessionIndex) {
+            if (!isset($sessions[$sessionIndex])) {
+                \SimpleSAML\Logger::info('saml.LogoutStore: Logout requested for unknown SessionIndex.');
+                continue;
+            }
+
+            $sessionId = $sessions[$sessionIndex];
+
+            $session = \SimpleSAML\Session::getSession($sessionId);
+            if ($session === null) {
+                \SimpleSAML\Logger::info('saml.LogoutStore: Skipping logout of missing session.');
+                continue;
+            }
+
+            if (!$session->isValid($authId)) {
+                \SimpleSAML\Logger::info('saml.LogoutStore: Skipping logout of session because it isn\'t authenticated.');
+                continue;
+            }
+
+            \SimpleSAML\Logger::info('saml.LogoutStore: Logging out of session with trackId [' . $session->getTrackID() . '].');
+            $session->doLogout($authId);
+            $numLoggedOut += 1;
+        }
+
+        return $numLoggedOut;
+    }
 }
diff --git a/modules/saml/templates/proxy/invalid_session.php b/modules/saml/templates/proxy/invalid_session.php
index 1131379988f3a9954594674d5d57a72d9fb52ef6..94d63f9cdaa4cf5f510cc01d7c14bf8a427c3536 100644
--- a/modules/saml/templates/proxy/invalid_session.php
+++ b/modules/saml/templates/proxy/invalid_session.php
@@ -2,7 +2,7 @@
 /**
  * Template to ask a user whether to logout because of a reauthentication or not.
  *
- * @var SimpleSAML_XHTML_Template $this
+ * @var \SimpleSAML\XHTML\Template $this
  *
  * @author Jaime Pérez Crespo, UNINETT AS <jaime.perez@uninett.no>
  *
diff --git a/modules/saml/www/disco.php b/modules/saml/www/disco.php
index 1f3bac0857692bcd0760b3bb0bf3ac89ce519fe5..147338f0d6d3ea980bcbcd8eea4afe2fa514a747 100644
--- a/modules/saml/www/disco.php
+++ b/modules/saml/www/disco.php
@@ -4,5 +4,5 @@
  * Built-in IdP discovery service.
  */
 
-$discoHandler = new SimpleSAML_XHTML_IdPDisco(array('saml20-idp-remote', 'shib13-idp-remote'), 'saml');
+$discoHandler = new \SimpleSAML\XHTML\IdPDisco(array('saml20-idp-remote', 'shib13-idp-remote'), 'saml');
 $discoHandler->handleRequest();
diff --git a/modules/saml/www/idp/certs.php b/modules/saml/www/idp/certs.php
index a289d96a2cb473ddb5e8d6e3bd40469db50f5d19..abcffdc98ce02df80a61e78cd3132ea1cb65ac85 100644
--- a/modules/saml/www/idp/certs.php
+++ b/modules/saml/www/idp/certs.php
@@ -1,32 +1,33 @@
 <?php
 
 // Load SimpleSAMLphp, configuration and metadata
-$config = SimpleSAML_Configuration::getInstance();
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$config = \SimpleSAML\Configuration::getInstance();
+$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 
-if (!$config->getBoolean('enable.saml20-idp', false))
-	throw new SimpleSAML_Error_Error('NOACCESS');
+if (!$config->getBoolean('enable.saml20-idp', false)) {
+    throw new \SimpleSAML\Error\Error('NOACCESS');
+}
 
 // Check if valid local session exists..
 if ($config->getBoolean('admin.protectmetadata', false)) {
-    SimpleSAML\Utils\Auth::requireAdmin();
+    \SimpleSAML\Utils\Auth::requireAdmin();
 }
 
 $idpentityid = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
 $idpmeta = $metadata->getMetaDataConfig($idpentityid, 'saml20-idp-hosted');
 
 switch($_SERVER['PATH_INFO']) {
-	case '/new_idp.crt':
-		$certInfo = SimpleSAML\Utils\Crypto::loadPublicKey($idpmeta, FALSE, 'new_');
-		break;
-	case '/idp.crt':
-		$certInfo = SimpleSAML\Utils\Crypto::loadPublicKey($idpmeta, TRUE);
-		break;
-	case '/https.crt':
-		$certInfo = SimpleSAML\Utils\Crypto::loadPublicKey($idpmeta, TRUE, 'https.');
-		break;
-	default:
-		throw new SimpleSAML_Error_NotFound('Unknown certificate.');
+    case '/new_idp.crt':
+        $certInfo = SimpleSAML\Utils\Crypto::loadPublicKey($idpmeta, false, 'new_');
+        break;
+    case '/idp.crt':
+        $certInfo = SimpleSAML\Utils\Crypto::loadPublicKey($idpmeta, true);
+        break;
+    case '/https.crt':
+        $certInfo = SimpleSAML\Utils\Crypto::loadPublicKey($idpmeta, true, 'https.');
+        break;
+    default:
+        throw new \SimpleSAML\Error\NotFound('Unknown certificate.');
 }
 
 header('Content-Disposition: attachment; filename='.substr($_SERVER['PATH_INFO'], 1));
diff --git a/modules/saml/www/proxy/invalid_session.php b/modules/saml/www/proxy/invalid_session.php
index f110f8beb6d60572e16fcbe8848cda5976f836f0..0be45e11def84c4d79388fd4338c664761496420 100644
--- a/modules/saml/www/proxy/invalid_session.php
+++ b/modules/saml/www/proxy/invalid_session.php
@@ -11,24 +11,24 @@
 
 // retrieve the authentication state
 if (!array_key_exists('AuthState', $_REQUEST)) {
-    throw new SimpleSAML_Error_BadRequest('Missing mandatory parameter: AuthState');
+    throw new \SimpleSAML\Error\BadRequest('Missing mandatory parameter: AuthState');
 }
 
 try {
     // try to get the state
-    $state = SimpleSAML_Auth_State::loadState($_REQUEST['AuthState'], 'saml:proxy:invalid_idp');
-} catch (Exception $e) {
+    $state = \SimpleSAML\Auth\State::loadState($_REQUEST['AuthState'], 'saml:proxy:invalid_idp');
+} catch (\Exception $e) {
     // the user probably hit the back button after starting the logout, try to recover the state with another stage
-    $state = SimpleSAML_Auth_State::loadState($_REQUEST['AuthState'], 'core:Logout:afterbridge');
+    $state = \SimpleSAML\Auth\State::loadState($_REQUEST['AuthState'], 'core:Logout:afterbridge');
 
     // success! Try to continue with reauthentication, since we no longer have a valid session here
-    $idp = SimpleSAML_IdP::getById($state['core:IdP']);
-    sspmod_saml_Auth_Source_SP::reauthPostLogout($idp, $state);
+    $idp = \SimpleSAML\IdP::getById($state['core:IdP']);
+    \SimpleSAML\Module\saml\Auth\Source\SP::reauthPostLogout($idp, $state);
 }
 
 if (isset($_POST['cancel'])) {
     // the user does not want to logout, cancel login
-    SimpleSAML_Auth_State::throwException(
+    \SimpleSAML\Auth\State::throwException(
         $state,
         new \SimpleSAML\Module\saml\Error\NoAvailableIDP(
             \SAML2\Constants::STATUS_RESPONDER,
@@ -39,19 +39,19 @@ if (isset($_POST['cancel'])) {
 
 if (isset($_POST['continue'])) {
     // log the user out before being able to login again
-    $as = SimpleSAML_Auth_Source::getById($state['saml:sp:AuthId'], 'sspmod_saml_Auth_Source_SP');
-    /** @var sspmod_saml_Auth_Source_SP $as */
+    $as = \SimpleSAML\Auth\Source::getById($state['saml:sp:AuthId'], '\SimpleSAML\Module\saml\Auth\Source\SP');
+    /** @var \SimpleSAML\Module\saml\Auth\Source\SP $as */
     $as->reauthLogout($state);
 }
 
-$cfg = SimpleSAML_Configuration::getInstance();
-$template = new SimpleSAML_XHTML_Template($cfg, 'saml:proxy/invalid_session.php');
+$cfg = \SimpleSAML\Configuration::getInstance();
+$template = new \SimpleSAML\XHTML\Template($cfg, 'saml:proxy/invalid_session.php');
 $translator = $template->getTranslator();
 $template->data['AuthState'] = (string)$_REQUEST['AuthState'];
 
 // get the name of the IdP
 $idpmdcfg = $state['saml:sp:IdPMetadata'];
-/** @var SimpleSAML_Configuration $idpmdcfg */
+/** @var \SimpleSAML\Configuration $idpmdcfg */
 $idpmd = $idpmdcfg->toArray();
 if (array_key_exists('name', $idpmd)) {
     $template->data['idp_name'] = $translator->getPreferredTranslation($idpmd['name']);
diff --git a/modules/saml/www/sp/discoresp.php b/modules/saml/www/sp/discoresp.php
index db9bda9d5b92fc42f40831fda84c07459b0c1f47..60c15045a629c255ad6505e800bb64b5a9128472 100644
--- a/modules/saml/www/sp/discoresp.php
+++ b/modules/saml/www/sp/discoresp.php
@@ -5,24 +5,24 @@
  */
 
 if (!array_key_exists('AuthID', $_REQUEST)) {
-	throw new SimpleSAML_Error_BadRequest('Missing AuthID to discovery service response handler');
+    throw new \SimpleSAML\Error\BadRequest('Missing AuthID to discovery service response handler');
 }
 
 if (!array_key_exists('idpentityid', $_REQUEST)) {
-	throw new SimpleSAML_Error_BadRequest('Missing idpentityid to discovery service response handler');
+    throw new \SimpleSAML\Error\BadRequest('Missing idpentityid to discovery service response handler');
 }
-$state = SimpleSAML_Auth_State::loadState($_REQUEST['AuthID'], 'saml:sp:sso');
+$state = \SimpleSAML\Auth\State::loadState($_REQUEST['AuthID'], 'saml:sp:sso');
 
 // Find authentication source
 assert(array_key_exists('saml:sp:AuthId', $state));
 $sourceId = $state['saml:sp:AuthId'];
 
-$source = SimpleSAML_Auth_Source::getById($sourceId);
-if ($source === NULL) {
-	throw new Exception('Could not find authentication source with id ' . $sourceId);
+$source = \SimpleSAML\Auth\Source::getById($sourceId);
+if ($source === null) {
+    throw new Exception('Could not find authentication source with id ' . $sourceId);
 }
-if (!($source instanceof sspmod_saml_Auth_Source_SP)) {
-	throw new SimpleSAML_Error_Exception('Source type changed?');
+if (!($source instanceof \SimpleSAML\Module\saml\Auth\Source\SP)) {
+    throw new \SimpleSAML\Error\Exception('Source type changed?');
 }
 
 $source->startSSO($_REQUEST['idpentityid'], $state);
diff --git a/modules/saml/www/sp/metadata.php b/modules/saml/www/sp/metadata.php
index 9aa17835e25aaa0361f5275b5f17079af62d7d7d..395bc3552f6957aa34ca1393d118cf8063663c0b 100644
--- a/modules/saml/www/sp/metadata.php
+++ b/modules/saml/www/sp/metadata.php
@@ -1,21 +1,21 @@
 <?php
 
 if (!array_key_exists('PATH_INFO', $_SERVER)) {
-    throw new SimpleSAML_Error_BadRequest('Missing authentication source id in metadata URL');
+    throw new \SimpleSAML\Error\BadRequest('Missing authentication source id in metadata URL');
 }
 
-$config = SimpleSAML_Configuration::getInstance();
+$config = \SimpleSAML\Configuration::getInstance();
 if ($config->getBoolean('admin.protectmetadata', false)) {
-    SimpleSAML\Utils\Auth::requireAdmin();
+    \SimpleSAML\Utils\Auth::requireAdmin();
 }
 $sourceId = substr($_SERVER['PATH_INFO'], 1);
-$source = SimpleSAML_Auth_Source::getById($sourceId);
+$source = \SimpleSAML\Auth\Source::getById($sourceId);
 if ($source === null) {
-    throw new SimpleSAML_Error_AuthSource($sourceId, 'Could not find authentication source.');
+    throw new \SimpleSAML\Error\AuthSource($sourceId, 'Could not find authentication source.');
 }
 
-if (!($source instanceof sspmod_saml_Auth_Source_SP)) {
-    throw new SimpleSAML_Error_AuthSource($sourceId,
+if (!($source instanceof \SimpleSAML\Module\saml\Auth\Source\SP)) {
+    throw new \SimpleSAML\Error\AuthSource($sourceId,
         'The authentication source is not a SAML Service Provider.');
 }
 
@@ -31,7 +31,7 @@ $slosvcdefault = array(
 );
 
 $slob = $spconfig->getArray('SingleLogoutServiceBinding', $slosvcdefault);
-$slol = SimpleSAML\Module::getModuleURL('saml/sp/saml2-logout.php/'.$sourceId);
+$slol = \SimpleSAML\Module::getModuleURL('saml/sp/saml2-logout.php/'.$sourceId);
 
 foreach ($slob as $binding) {
     if ($binding == \SAML2\Constants::BINDING_SOAP && !($store instanceof \SimpleSAML\Store\SQL)) {
@@ -59,30 +59,46 @@ $assertionsconsumerservices = $spconfig->getArray('acs.Bindings', $assertionscon
 
 $index = 0;
 $eps = array();
+$supported_protocols = array();
 foreach ($assertionsconsumerservices as $services) {
 
     $acsArray = array('index' => $index);
     switch ($services) {
         case 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST':
             $acsArray['Binding'] = \SAML2\Constants::BINDING_HTTP_POST;
-            $acsArray['Location'] = SimpleSAML\Module::getModuleURL('saml/sp/saml2-acs.php/'.$sourceId);
+            $acsArray['Location'] = \SimpleSAML\Module::getModuleURL('saml/sp/saml2-acs.php/'.$sourceId);
+            if (!in_array(\SAML2\Constants::NS_SAMLP, $supported_protocols, true)) {
+                $supported_protocols[] = \SAML2\Constants::NS_SAMLP;
+            }
             break;
         case 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post':
             $acsArray['Binding'] = 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post';
-            $acsArray['Location'] = SimpleSAML\Module::getModuleURL('saml/sp/saml1-acs.php/'.$sourceId);
+            $acsArray['Location'] = \SimpleSAML\Module::getModuleURL('saml/sp/saml1-acs.php/'.$sourceId);
+            if (!in_array('urn:oasis:names:tc:SAML:1.1:protocol', $supported_protocols, true)) {
+                $supported_protocols[] = 'urn:oasis:names:tc:SAML:1.1:protocol';
+            }
             break;
         case 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact':
             $acsArray['Binding'] = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact';
-            $acsArray['Location'] = SimpleSAML\Module::getModuleURL('saml/sp/saml2-acs.php/'.$sourceId);
+            $acsArray['Location'] = \SimpleSAML\Module::getModuleURL('saml/sp/saml2-acs.php/'.$sourceId);
+            if (!in_array(\SAML2\Constants::NS_SAMLP, $supported_protocols, true)) {
+                $supported_protocols[] = \SAML2\Constants::NS_SAMLP;
+            }
             break;
         case 'urn:oasis:names:tc:SAML:1.0:profiles:artifact-01':
             $acsArray['Binding'] = 'urn:oasis:names:tc:SAML:1.0:profiles:artifact-01';
-            $acsArray['Location'] = SimpleSAML\Module::getModuleURL('saml/sp/saml1-acs.php/'.$sourceId.'/artifact');
+            $acsArray['Location'] = \SimpleSAML\Module::getModuleURL('saml/sp/saml1-acs.php/'.$sourceId.'/artifact');
+            if (!in_array('urn:oasis:names:tc:SAML:1.1:protocol', $supported_protocols, true)) {
+                $supported_protocols[] = 'urn:oasis:names:tc:SAML:1.1:protocol';
+            }
             break;
         case 'urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser':
             $acsArray['Binding'] = 'urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser';
-            $acsArray['Location'] = SimpleSAML\Module::getModuleURL('saml/sp/saml2-acs.php/'.$sourceId);
+            $acsArray['Location'] = \SimpleSAML\Module::getModuleURL('saml/sp/saml2-acs.php/'.$sourceId);
             $acsArray['hoksso:ProtocolBinding'] = \SAML2\Constants::BINDING_HTTP_REDIRECT;
+            if (!in_array(\SAML2\Constants::NS_SAMLP, $supported_protocols, true)) {
+                $supported_protocols[] = \SAML2\Constants::NS_SAMLP;
+            }
             break;
     }
     $eps[] = $acsArray;
@@ -92,7 +108,7 @@ foreach ($assertionsconsumerservices as $services) {
 $metaArray20['AssertionConsumerService'] = $eps;
 
 $keys = array();
-$certInfo = SimpleSAML\Utils\Crypto::loadPublicKey($spconfig, false, 'new_');
+$certInfo = \SimpleSAML\Utils\Crypto::loadPublicKey($spconfig, false, 'new_');
 if ($certInfo !== null && array_key_exists('certData', $certInfo)) {
     $hasNewCert = true;
 
@@ -108,7 +124,7 @@ if ($certInfo !== null && array_key_exists('certData', $certInfo)) {
     $hasNewCert = false;
 }
 
-$certInfo = SimpleSAML\Utils\Crypto::loadPublicKey($spconfig);
+$certInfo = \SimpleSAML\Utils\Crypto::loadPublicKey($spconfig);
 if ($certInfo !== null && array_key_exists('certData', $certInfo)) {
     $certData = $certInfo['certData'];
 
@@ -148,6 +164,14 @@ if ($name !== null && !empty($attributes)) {
     if ($nameFormat !== null) {
         $metaArray20['attributes.NameFormat'] = $nameFormat;
     }
+
+    if ($spconfig->hasValue('attributes.index')) {
+        $metaArray20['attributes.index'] = $spconfig->getInteger('attributes.index', 0);
+    }
+
+    if ($spconfig->hasValue('attributes.isDefault')) {
+        $metaArray20['attributes.isDefault'] = $spconfig->getBoolean('attributes.isDefault', false);
+    }
 }
 
 // add organization info
@@ -162,7 +186,7 @@ if ($orgName !== null) {
 
     $metaArray20['OrganizationURL'] = $spconfig->getLocalizedString('OrganizationURL', null);
     if ($metaArray20['OrganizationURL'] === null) {
-        throw new SimpleSAML_Error_Exception('If OrganizationName is set, OrganizationURL must also be set.');
+        throw new \SimpleSAML\Error\Exception('If OrganizationName is set, OrganizationURL must also be set.');
     }
 }
 
@@ -174,7 +198,7 @@ if ($spconfig->hasValue('contacts')) {
 }
 
 // add technical contact
-$email = $config->getString('technicalcontact_email', 'na@example.org', false);
+$email = $config->getString('technicalcontact_email', 'na@example.org');
 if ($email && $email !== 'na@example.org') {
     $techcontact['emailAddress'] = $email;
     $techcontact['name'] = $config->getString('technicalcontact_name', null);
@@ -214,12 +238,10 @@ if ($spconfig->hasValue('redirect.sign')) {
     $metaArray20['validate.authnrequest'] = $spconfig->getBoolean('sign.authnrequest');
 }
 
-$supported_protocols = array('urn:oasis:names:tc:SAML:1.1:protocol', \SAML2\Constants::NS_SAMLP);
-
 $metaArray20['metadata-set'] = 'saml20-sp-remote';
 $metaArray20['entityid'] = $entityId;
 
-$metaBuilder = new SimpleSAML_Metadata_SAMLBuilder($entityId);
+$metaBuilder = new \SimpleSAML\Metadata\SAMLBuilder($entityId);
 $metaBuilder->addMetadataSP20($metaArray20, $supported_protocols);
 $metaBuilder->addOrganizationInfo($metaArray20);
 
@@ -235,11 +257,11 @@ if (isset($metaArray20['attributes']) && is_array($metaArray20['attributes'])) {
 }
 
 // sign the metadata if enabled
-$xml = SimpleSAML_Metadata_Signer::sign($xml, $spconfig->toArray(), 'SAML 2 SP');
+$xml = \SimpleSAML\Metadata\Signer::sign($xml, $spconfig->toArray(), 'SAML 2 SP');
 
 if (array_key_exists('output', $_REQUEST) && $_REQUEST['output'] == 'xhtml') {
 
-    $t = new SimpleSAML_XHTML_Template($config, 'metadata.php', 'admin');
+    $t = new \SimpleSAML\XHTML\Template($config, 'metadata.php', 'admin');
 
     $t->data['clipboard.js'] = true;
     $t->data['header'] = 'saml20-sp'; // TODO: Replace with headerString in 2.0
diff --git a/modules/saml/www/sp/saml1-acs.php b/modules/saml/www/sp/saml1-acs.php
index fa1a0efb4e47803738899545578d87ec1dcba31f..0e607eb53ccbc5e969cb3726ae07b3f0d6e642d4 100644
--- a/modules/saml/www/sp/saml1-acs.php
+++ b/modules/saml/www/sp/saml1-acs.php
@@ -3,66 +3,66 @@
 use SimpleSAML\Bindings\Shib13\Artifact;
 
 if (!array_key_exists('SAMLResponse', $_REQUEST) && !array_key_exists('SAMLart', $_REQUEST)) {
-	throw new SimpleSAML_Error_BadRequest('Missing SAMLResponse or SAMLart parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing SAMLResponse or SAMLart parameter.');
 }
 
 if (!array_key_exists('TARGET', $_REQUEST)) {
-	throw new SimpleSAML_Error_BadRequest('Missing TARGET parameter.');
+    throw new \SimpleSAML\Error\BadRequest('Missing TARGET parameter.');
 }
 
 if (!array_key_exists('PATH_INFO', $_SERVER)) {
-    throw new SimpleSAML_Error_BadRequest('Missing authentication source ID in assertion consumer service URL');
+    throw new \SimpleSAML\Error\BadRequest('Missing authentication source ID in assertion consumer service URL');
 }
 
 $sourceId = $_SERVER['PATH_INFO'];
 $end = strpos($sourceId, '/', 1);
-if ($end === FALSE) {
-	$end = strlen($sourceId);
+if ($end === false) {
+    $end = strlen($sourceId);
 }
 $sourceId = substr($sourceId, 1, $end - 1);
 
-$source = SimpleSAML_Auth_Source::getById($sourceId, 'sspmod_saml_Auth_Source_SP');
+$source = \SimpleSAML\Auth\Source::getById($sourceId, '\SimpleSAML\Module\saml\Auth\Source\SP');
 
 SimpleSAML\Logger::debug('Received SAML1 response');
 
 $target = (string)$_REQUEST['TARGET'];
 
 if (preg_match('@^https?://@i', $target)) {
-	// Unsolicited response
-	$state = array(
-		'saml:sp:isUnsolicited' => TRUE,
-		'saml:sp:AuthId' => $sourceId,
-		'saml:sp:RelayState' => \SimpleSAML\Utils\HTTP::checkURLAllowed($target),
-	);
+    // Unsolicited response
+    $state = array(
+        'saml:sp:isUnsolicited' => true,
+        'saml:sp:AuthId' => $sourceId,
+        'saml:sp:RelayState' => \SimpleSAML\Utils\HTTP::checkURLAllowed($target),
+    );
 } else {
-	$state = SimpleSAML_Auth_State::loadState($_REQUEST['TARGET'], 'saml:sp:sso');
+    $state = \SimpleSAML\Auth\State::loadState($_REQUEST['TARGET'], 'saml:sp:sso');
 
-	// Check that the authentication source is correct.
-	assert(array_key_exists('saml:sp:AuthId', $state));
-	if ($state['saml:sp:AuthId'] !== $sourceId) {
-		throw new SimpleSAML_Error_Exception('The authentication source id in the URL does not match the authentication source which sent the request.');
-	}
+    // Check that the authentication source is correct.
+    assert(array_key_exists('saml:sp:AuthId', $state));
+    if ($state['saml:sp:AuthId'] !== $sourceId) {
+        throw new \SimpleSAML\Error\Exception('The authentication source id in the URL does not match the authentication source which sent the request.');
+    }
 
-	assert(isset($state['saml:idp']));
+    assert(isset($state['saml:idp']));
 }
 
 $spMetadata = $source->getMetadata();
 
 if (array_key_exists('SAMLart', $_REQUEST)) {
-	if (!isset($state['saml:idp'])) {
-		/* Unsolicited response. */
-		throw new SimpleSAML_Error_Exception('IdP initiated authentication not supported with the SAML 1.1 SAMLart protocol.');
-	}
-	$idpMetadata = $source->getIdPMetadata($state['saml:idp']);
-
-	$responseXML = Artifact::receive($spMetadata, $idpMetadata);
-	$isValidated = TRUE; /* Artifact binding validated with ssl certificate. */
+    if (!isset($state['saml:idp'])) {
+        /* Unsolicited response. */
+        throw new \SimpleSAML\Error\Exception('IdP initiated authentication not supported with the SAML 1.1 SAMLart protocol.');
+    }
+    $idpMetadata = $source->getIdPMetadata($state['saml:idp']);
+
+    $responseXML = Artifact::receive($spMetadata, $idpMetadata);
+    $isValidated = true; /* Artifact binding validated with ssl certificate. */
 } elseif (array_key_exists('SAMLResponse', $_REQUEST)) {
-	$responseXML = $_REQUEST['SAMLResponse'];
-	$responseXML = base64_decode($responseXML);
-	$isValidated = FALSE; /* Must check signature on response. */
+    $responseXML = $_REQUEST['SAMLResponse'];
+    $responseXML = base64_decode($responseXML);
+    $isValidated = false; /* Must check signature on response. */
 } else {
-	assert(false);
+    assert(false);
 }
 
 $response = new \SimpleSAML\XML\Shib13\AuthnResponse();
@@ -75,12 +75,12 @@ $responseIssuer = $response->getIssuer();
 $attributes = $response->getAttributes();
 
 if (isset($state['saml:idp']) && $responseIssuer !== $state['saml:idp']) {
-	throw new SimpleSAML_Error_Exception('The issuer of the response wasn\'t the destination of the request.');
+    throw new \SimpleSAML\Error\Exception('The issuer of the response wasn\'t the destination of the request.');
 }
 
 $logoutState = array(
-	'saml:logout:Type' => 'saml1'
-	);
+    'saml:logout:Type' => 'saml1'
+    );
 $state['LogoutState'] = $logoutState;
 
 $state['saml:sp:NameID'] = $response->getNameID();
diff --git a/modules/saml/www/sp/saml2-acs.php b/modules/saml/www/sp/saml2-acs.php
index 518650ed1bca9de32e6e5ccb5ece6fba9a085aa0..d897129807aedbd29b4f94077852bb4159860c1f 100644
--- a/modules/saml/www/sp/saml2-acs.php
+++ b/modules/saml/www/sp/saml2-acs.php
@@ -5,11 +5,11 @@
  */
 
 if (!array_key_exists('PATH_INFO', $_SERVER)) {
-    throw new SimpleSAML_Error_BadRequest('Missing authentication source ID in assertion consumer service URL');
+    throw new \SimpleSAML\Error\BadRequest('Missing authentication source ID in assertion consumer service URL');
 }
 
 $sourceId = substr($_SERVER['PATH_INFO'], 1);
-$source = SimpleSAML_Auth_Source::getById($sourceId, 'sspmod_saml_Auth_Source_SP');
+$source = \SimpleSAML\Auth\Source::getById($sourceId, '\SimpleSAML\Module\saml\Auth\Source\SP');
 $spMetadata = $source->getMetadata();
 
 try {
@@ -18,7 +18,7 @@ try {
     // This is dirty. Instead of checking the message of the exception, \SAML2\Binding::getCurrentBinding() should throw
     // an specific exception when the binding is unknown, and we should capture that here
     if ($e->getMessage() === 'Unable to find the current binding.') {
-        throw new SimpleSAML_Error_Error('ACSPARAMS', $e, 400);
+        throw new \SimpleSAML\Error\Error('ACSPARAMS', $e, 400);
     } else {
         throw $e; // do not ignore other exceptions!
     }
@@ -30,7 +30,7 @@ if ($b instanceof \SAML2\HTTPArtifact) {
 
 $response = $b->receive();
 if (!($response instanceof \SAML2\Response)) {
-    throw new SimpleSAML_Error_BadRequest('Invalid message received to AssertionConsumerService endpoint.');
+    throw new \SimpleSAML\Error\BadRequest('Invalid message received to AssertionConsumerService endpoint.');
 }
 
 $idp = $response->getIssuer();
@@ -49,7 +49,7 @@ if ($idp === null) {
     }
 }
 
-$session = SimpleSAML_Session::getSessionFromRequest();
+$session = \SimpleSAML\Session::getSessionFromRequest();
 $prevAuth = $session->getAuthData($sourceId, 'saml:sp:prevAuth');
 if ($prevAuth !== null && $prevAuth['id'] === $response->getId() && $prevAuth['issuer'] === $idp) {
     /* OK, it looks like this message has the same issuer
@@ -67,7 +67,7 @@ if ($prevAuth !== null && $prevAuth['id'] === $response->getId() && $prevAuth['i
     }
 
     SimpleSAML\Logger::info('No RelayState or ReturnURL available, cannot redirect.');
-    throw new SimpleSAML_Error_Exception('Duplicate assertion received.');
+    throw new \SimpleSAML\Error\Exception('Duplicate assertion received.');
 }
 
 $idpMetadata = array();
@@ -77,10 +77,10 @@ $stateId = $response->getInResponseTo();
 if (!empty($stateId)) {
     // this should be a response to a request we sent earlier
     try {
-        $state = SimpleSAML_Auth_State::loadState($stateId, 'saml:sp:sso');
+        $state = \SimpleSAML\Auth\State::loadState($stateId, 'saml:sp:sso');
     } catch (Exception $e) {
         // something went wrong,
-        SimpleSAML_Logger::warning('Could not load state specified by InResponseTo: '.$e->getMessage().
+        SimpleSAML\Logger::warning('Could not load state specified by InResponseTo: '.$e->getMessage().
             ' Processing response as unsolicited.');
     }
 }
@@ -89,7 +89,7 @@ if ($state) {
     // check that the authentication source is correct
     assert(array_key_exists('saml:sp:AuthId', $state));
     if ($state['saml:sp:AuthId'] !== $sourceId) {
-        throw new SimpleSAML_Error_Exception(
+        throw new \SimpleSAML\Error\Exception(
             'The authentication source id in the URL does not match the authentication source which sent the request.'
         );
     }
@@ -100,7 +100,7 @@ if ($state) {
         $idpMetadata = $source->getIdPMetadata($idp);
         $idplist = $idpMetadata->getArrayize('IDPList', array());
         if (!in_array($state['ExpectedIssuer'], $idplist, true)) {
-            throw new SimpleSAML_Error_Exception(
+            throw new \SimpleSAML\Error\Exception(
                 'The issuer of the response does not match to the identity provider we sent the request to.'
             );
         }
@@ -126,11 +126,11 @@ if (empty($idpMetadata)) {
 }
 
 try {
-    $assertions = sspmod_saml_Message::processResponse($spMetadata, $idpMetadata, $response);
-} catch (sspmod_saml_Error $e) {
+    $assertions = \SimpleSAML\Module\saml\Message::processResponse($spMetadata, $idpMetadata, $response);
+} catch (\SimpleSAML\Module\saml\Error $e) {
     // the status of the response wasn't "success"
     $e = $e->toException();
-    SimpleSAML_Auth_State::throwException($state, $e);
+    \SimpleSAML\Auth\State::throwException($state, $e);
 }
 
 
@@ -147,8 +147,8 @@ foreach ($assertions as $assertion) {
     if ($store !== false) {
         $aID = $assertion->getId();
         if ($store->get('saml.AssertionReceived', $aID) !== null) {
-            $e = new SimpleSAML_Error_Exception('Received duplicate assertion.');
-            SimpleSAML_Auth_State::throwException($state, $e);
+            $e = new \SimpleSAML\Error\Exception('Received duplicate assertion.');
+            \SimpleSAML\Auth\State::throwException($state, $e);
         }
 
         $notOnOrAfter = $assertion->getNotOnOrAfter();
@@ -184,8 +184,8 @@ foreach ($assertions as $assertion) {
 }
 
 if (!$foundAuthnStatement) {
-    $e = new SimpleSAML_Error_Exception('No AuthnStatement found in assertion(s).');
-    SimpleSAML_Auth_State::throwException($state, $e);
+    $e = new \SimpleSAML\Error\Exception('No AuthnStatement found in assertion(s).');
+    \SimpleSAML\Auth\State::throwException($state, $e);
 }
 
 if ($expire !== null) {
@@ -197,7 +197,7 @@ if ($expire !== null) {
 
 if (!empty($nameId)) {
     // register this session in the logout store
-    sspmod_saml_SP_LogoutStore::addSession($sourceId, $nameId, $sessionIndex, $logoutExpire);
+    \SimpleSAML\Module\saml\SP\LogoutStore::addSession($sourceId, $nameId, $sessionIndex, $logoutExpire);
 
     // we need to save the NameID and SessionIndex for logout
     $logoutState = array(
@@ -247,8 +247,8 @@ $state['saml:sp:prevAuth'] = array(
     'id'     => $response->getId(),
     'issuer' => $idp,
 );
-if (isset($state['SimpleSAML_Auth_Source.ReturnURL'])) {
-    $state['saml:sp:prevAuth']['redirect'] = $state['SimpleSAML_Auth_Source.ReturnURL'];
+if (isset($state['\SimpleSAML\Auth\Source.ReturnURL'])) {
+    $state['saml:sp:prevAuth']['redirect'] = $state['\SimpleSAML\Auth\Source.ReturnURL'];
 } elseif (isset($state['saml:sp:RelayState'])) {
     $state['saml:sp:prevAuth']['redirect'] = $state['saml:sp:RelayState'];
 }
diff --git a/modules/saml/www/sp/saml2-logout.php b/modules/saml/www/sp/saml2-logout.php
index 6fa5a0081791bc2d3588095822fc4c9a8eecfe8c..1ab456692a18bf47befda330f98dfa21f18c8240 100644
--- a/modules/saml/www/sp/saml2-logout.php
+++ b/modules/saml/www/sp/saml2-logout.php
@@ -7,26 +7,26 @@
  */
 
 if (!array_key_exists('PATH_INFO', $_SERVER)) {
-	throw new SimpleSAML_Error_BadRequest('Missing authentication source ID in logout URL');
+    throw new \SimpleSAML\Error\BadRequest('Missing authentication source ID in logout URL');
 }
 
 $sourceId = substr($_SERVER['PATH_INFO'], 1);
 
-$source = SimpleSAML_Auth_Source::getById($sourceId);
-if ($source === NULL) {
-	throw new Exception('Could not find authentication source with id ' . $sourceId);
+$source = \SimpleSAML\Auth\Source::getById($sourceId);
+if ($source === null) {
+    throw new \Exception('Could not find authentication source with id ' . $sourceId);
 }
-if (!($source instanceof sspmod_saml_Auth_Source_SP)) {
-	throw new SimpleSAML_Error_Exception('Source type changed?');
+if (!($source instanceof \SimpleSAML\Module\saml\Auth\Source\SP)) {
+    throw new \SimpleSAML\Error\Exception('Source type changed?');
 }
 
 try {
     $binding = \SAML2\Binding::getCurrentBinding();
-} catch (Exception $e) { // TODO: look for a specific exception
+} catch (\Exception $e) { // TODO: look for a specific exception
     // This is dirty. Instead of checking the message of the exception, \SAML2\Binding::getCurrentBinding() should throw
     // an specific exception when the binding is unknown, and we should capture that here
     if ($e->getMessage() === 'Unable to find the current binding.') {
-        throw new SimpleSAML_Error_Error('SLOSERVICEPARAMS', $e, 400);
+        throw new \SimpleSAML\Error\Error('SLOSERVICEPARAMS', $e, 400);
     } else {
         throw $e; // do not ignore other exceptions!
     }
@@ -34,107 +34,107 @@ try {
 $message = $binding->receive();
 
 $idpEntityId = $message->getIssuer();
-if ($idpEntityId === NULL) {
-	// Without an issuer we have no way to respond to the message.
-	throw new SimpleSAML_Error_BadRequest('Received message on logout endpoint without issuer.');
+if ($idpEntityId === null) {
+    // Without an issuer we have no way to respond to the message.
+    throw new \SimpleSAML\Error\BadRequest('Received message on logout endpoint without issuer.');
 }
 
 $spEntityId = $source->getEntityId();
 
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 $idpMetadata = $source->getIdPMetadata($idpEntityId);
 $spMetadata = $source->getMetadata();
 
-sspmod_saml_Message::validateMessage($idpMetadata, $spMetadata, $message);
+\SimpleSAML\Module\saml\Message::validateMessage($idpMetadata, $spMetadata, $message);
 
 $destination = $message->getDestination();
-if ($destination !== NULL && $destination !== \SimpleSAML\Utils\HTTP::getSelfURLNoQuery()) {
-	throw new SimpleSAML_Error_Exception('Destination in logout message is wrong.');
+if ($destination !== null && $destination !== \SimpleSAML\Utils\HTTP::getSelfURLNoQuery()) {
+    throw new \SimpleSAML\Error\Exception('Destination in logout message is wrong.');
 }
 
 if ($message instanceof \SAML2\LogoutResponse) {
 
-	$relayState = $message->getRelayState();
-	if ($relayState === NULL) {
-		// Somehow, our RelayState has been lost.
-		throw new SimpleSAML_Error_BadRequest('Missing RelayState in logout response.');
-	}
+    $relayState = $message->getRelayState();
+    if ($relayState === null) {
+        // Somehow, our RelayState has been lost.
+        throw new \SimpleSAML\Error\BadRequest('Missing RelayState in logout response.');
+    }
 
-	if (!$message->isSuccess()) {
-		SimpleSAML\Logger::warning('Unsuccessful logout. Status was: ' . sspmod_saml_Message::getResponseError($message));
-	}
+    if (!$message->isSuccess()) {
+        \SimpleSAML\Logger::warning('Unsuccessful logout. Status was: ' . \SimpleSAML\Module\saml\Message::getResponseError($message));
+    }
 
-	$state = SimpleSAML_Auth_State::loadState($relayState, 'saml:slosent');
-	$state['saml:sp:LogoutStatus'] = $message->getStatus();
-	SimpleSAML_Auth_Source::completeLogout($state);
+    $state = \SimpleSAML\Auth\State::loadState($relayState, 'saml:slosent');
+    $state['saml:sp:LogoutStatus'] = $message->getStatus();
+    \SimpleSAML\Auth\Source::completeLogout($state);
 
 } elseif ($message instanceof \SAML2\LogoutRequest) {
 
-	SimpleSAML\Logger::debug('module/saml2/sp/logout: Request from ' . $idpEntityId);
-	SimpleSAML\Logger::stats('saml20-idp-SLO idpinit ' . $spEntityId . ' ' . $idpEntityId);
-
-	if ($message->isNameIdEncrypted()) {
-		try {
-			$keys = sspmod_saml_Message::getDecryptionKeys($idpMetadata, $spMetadata);
-		} catch (Exception $e) {
-			throw new SimpleSAML_Error_Exception('Error decrypting NameID: ' . $e->getMessage());
-		}
-
-		$blacklist = sspmod_saml_Message::getBlacklistedAlgorithms($idpMetadata, $spMetadata);
-
-		$lastException = NULL;
-		foreach ($keys as $i => $key) {
-			try {
-				$message->decryptNameId($key, $blacklist);
-				SimpleSAML\Logger::debug('Decryption with key #' . $i . ' succeeded.');
-				$lastException = NULL;
-				break;
-			} catch (Exception $e) {
-				SimpleSAML\Logger::debug('Decryption with key #' . $i . ' failed with exception: ' . $e->getMessage());
-				$lastException = $e;
-			}
-		}
-		if ($lastException !== NULL) {
-			throw $lastException;
-		}
-	}
-
-	$nameId = $message->getNameId();
-	$sessionIndexes = $message->getSessionIndexes();
-
-	$numLoggedOut = sspmod_saml_SP_LogoutStore::logoutSessions($sourceId, $nameId, $sessionIndexes);
-	if ($numLoggedOut === FALSE) {
-		/* This type of logout was unsupported. Use the old method. */
-		$source->handleLogout($idpEntityId);
-		$numLoggedOut = count($sessionIndexes);
-	}
-
-	/* Create an send response. */
-	$lr = sspmod_saml_Message::buildLogoutResponse($spMetadata, $idpMetadata);
-	$lr->setRelayState($message->getRelayState());
-	$lr->setInResponseTo($message->getId());
-
-	if ($numLoggedOut < count($sessionIndexes)) {
-		SimpleSAML\Logger::warning('Logged out of ' . $numLoggedOut  . ' of ' . count($sessionIndexes) . ' sessions.');
-	}
-
-	$dst = $idpMetadata->getEndpointPrioritizedByBinding('SingleLogoutService', array(
-		\SAML2\Constants::BINDING_HTTP_REDIRECT,
-		\SAML2\Constants::BINDING_HTTP_POST)
-	);
-
-	if (!$binding instanceof \SAML2\SOAP) {
-		$binding = \SAML2\Binding::getBinding($dst['Binding']);
-		if (isset($dst['ResponseLocation'])) {
-			$dst = $dst['ResponseLocation'];
-		} else {
-			$dst = $dst['Location'];
-		}
-		$binding->setDestination($dst);
-	}
-	$lr->setDestination($dst);
-
-	$binding->send($lr);
+    \SimpleSAML\Logger::debug('module/saml2/sp/logout: Request from ' . $idpEntityId);
+    \SimpleSAML\Logger::stats('saml20-idp-SLO idpinit ' . $spEntityId . ' ' . $idpEntityId);
+
+    if ($message->isNameIdEncrypted()) {
+        try {
+            $keys = \SimpleSAML\Module\saml\Message::getDecryptionKeys($idpMetadata, $spMetadata);
+        } catch (\Exception $e) {
+            throw new \SimpleSAML\Error\Exception('Error decrypting NameID: ' . $e->getMessage());
+        }
+
+        $blacklist = \SimpleSAML\Module\saml\Message::getBlacklistedAlgorithms($idpMetadata, $spMetadata);
+
+        $lastException = null;
+        foreach ($keys as $i => $key) {
+            try {
+                $message->decryptNameId($key, $blacklist);
+                \SimpleSAML\Logger::debug('Decryption with key #' . $i . ' succeeded.');
+                $lastException = null;
+                break;
+            } catch (\Exception $e) {
+                \SimpleSAML\Logger::debug('Decryption with key #' . $i . ' failed with exception: ' . $e->getMessage());
+                $lastException = $e;
+            }
+        }
+        if ($lastException !== null) {
+            throw $lastException;
+        }
+    }
+
+    $nameId = $message->getNameId();
+    $sessionIndexes = $message->getSessionIndexes();
+
+    $numLoggedOut = \SimpleSAML\Module\saml\SP\LogoutStore::logoutSessions($sourceId, $nameId, $sessionIndexes);
+    if ($numLoggedOut === false) {
+        /* This type of logout was unsupported. Use the old method. */
+        $source->handleLogout($idpEntityId);
+        $numLoggedOut = count($sessionIndexes);
+    }
+
+    /* Create and send response. */
+    $lr = \SimpleSAML\Module\saml\Message::buildLogoutResponse($spMetadata, $idpMetadata);
+    $lr->setRelayState($message->getRelayState());
+    $lr->setInResponseTo($message->getId());
+
+    if ($numLoggedOut < count($sessionIndexes)) {
+        \SimpleSAML\Logger::warning('Logged out of ' . $numLoggedOut  . ' of ' . count($sessionIndexes) . ' sessions.');
+    }
+
+    $dst = $idpMetadata->getEndpointPrioritizedByBinding('SingleLogoutService', array(
+        \SAML2\Constants::BINDING_HTTP_REDIRECT,
+        \SAML2\Constants::BINDING_HTTP_POST)
+    );
+
+    if (!$binding instanceof \SAML2\SOAP) {
+        $binding = \SAML2\Binding::getBinding($dst['Binding']);
+        if (isset($dst['ResponseLocation'])) {
+            $dst = $dst['ResponseLocation'];
+        } else {
+            $dst = $dst['Location'];
+        }
+        $binding->setDestination($dst);
+    }
+    $lr->setDestination($dst);
+
+    $binding->send($lr);
 } else {
-	throw new SimpleSAML_Error_BadRequest('Unknown message received on logout endpoint: ' . get_class($message));
+    throw new \SimpleSAML\Error\BadRequest('Unknown message received on logout endpoint: ' . get_class($message));
 }
diff --git a/modules/saml/www/sp/wrong_authncontextclassref.php b/modules/saml/www/sp/wrong_authncontextclassref.php
index 18e17617d5ca97c8c9b0d60884d2c74fd31043d8..9cb93bf70dbfeffbe30c113b323f9c834c9d6cce 100644
--- a/modules/saml/www/sp/wrong_authncontextclassref.php
+++ b/modules/saml/www/sp/wrong_authncontextclassref.php
@@ -1,5 +1,5 @@
 <?php
 
-$globalConfig = SimpleSAML_Configuration::getInstance();
-$t = new SimpleSAML_XHTML_Template($globalConfig, 'saml:sp/wrong_authncontextclassref.tpl.php');
+$globalConfig = \SimpleSAML\Configuration::getInstance();
+$t = new \SimpleSAML\XHTML\Template($globalConfig, 'saml:sp/wrong_authncontextclassref.tpl.php');
 $t->show();
diff --git a/modules/sanitycheck/hooks/hook_cron.php b/modules/sanitycheck/hooks/hook_cron.php
index abb2b0ce45cbc37dc690343244eb27cc7ecbcb8e..5b6a93869df0329e08e929db7dc077e46f31215e 100644
--- a/modules/sanitycheck/hooks/hook_cron.php
+++ b/modules/sanitycheck/hooks/hook_cron.php
@@ -10,10 +10,10 @@ function sanitycheck_hook_cron(&$croninfo)
     assert(array_key_exists('summary', $croninfo));
     assert(array_key_exists('tag', $croninfo));
 
-    SimpleSAML\Logger::info('cron [sanitycheck]: Running cron in cron tag [' . $croninfo['tag'] . '] ');
+    \SimpleSAML\Logger::info('cron [sanitycheck]: Running cron in cron tag [' . $croninfo['tag'] . '] ');
 
     try {
-        $sconfig = SimpleSAML_Configuration::getOptionalConfig('config-sanitycheck.php');
+        $sconfig = \SimpleSAML\Configuration::getOptionalConfig('config-sanitycheck.php');
 
         $cronTag = $sconfig->getString('cron_tag', null);
         if ($cronTag === null || $cronTag !== $croninfo['tag']) {
diff --git a/modules/sanitycheck/www/index.php b/modules/sanitycheck/www/index.php
index e365db28d57a98282e3abe0528d0c0d8604fa42c..d7302529e7d3aa9437c2e13a7949f13e2f696e4e 100644
--- a/modules/sanitycheck/www/index.php
+++ b/modules/sanitycheck/www/index.php
@@ -1,6 +1,6 @@
 <?php
 
-$config = SimpleSAML_Configuration::getInstance();
+$config = \SimpleSAML\Configuration::getInstance();
 
 $info = array();
 $errors = array();
@@ -8,7 +8,7 @@ $hookinfo = array(
     'info' => &$info,
     'errors' => &$errors,
 );
-SimpleSAML\Module::callHooks('sanitycheck', $hookinfo);
+\SimpleSAML\Module::callHooks('sanitycheck', $hookinfo);
 
 if (isset($_REQUEST['output']) && $_REQUEST['output'] == 'text') {
 
@@ -20,7 +20,7 @@ if (isset($_REQUEST['output']) && $_REQUEST['output'] == 'text') {
     exit;
 }
 
-$t = new SimpleSAML_XHTML_Template($config, 'sanitycheck:check.tpl.php');
+$t = new \SimpleSAML\XHTML\Template($config, 'sanitycheck:check.tpl.php');
 $t->data['pageid'] = 'sanitycheck';
 $t->data['errors'] = $errors;
 $t->data['info'] = $info;
diff --git a/modules/smartattributes/docs/smartattributes.md b/modules/smartattributes/docs/smartattributes.md
index 0c2c8c1369d950130a79d2784702405b47b02d19..f6015259ad84b24383befef73c1420956ae0ea4b 100644
--- a/modules/smartattributes/docs/smartattributes.md
+++ b/modules/smartattributes/docs/smartattributes.md
@@ -21,7 +21,6 @@ The filter has the following configuration options:
 	* facebook_targetedID
 	* twitter_targetedID
 	* windowslive_targetedID
-	* myspace_targetedID
 	* linkedin_targetedID
 * `id_attribute`. A string to use as the name of the newly added attribute. Defaults to `smart_id`.
 * `add_authority`. A boolean to indicate whether or not to append the SAML AuthenticatingAuthority to the resulting identifier. This can be useful to indicate what SAML IdP was used, in case the original identifier is not scoped. Defaults to `TRUE`.
diff --git a/modules/smartattributes/lib/Auth/Process/SmartID.php b/modules/smartattributes/lib/Auth/Process/SmartID.php
index 67dba450b972ea3b4ee86f97342a5571a4057085..2dbde82f9a3da941421b7e3b87b7837cf97126fe 100644
--- a/modules/smartattributes/lib/Auth/Process/SmartID.php
+++ b/modules/smartattributes/lib/Auth/Process/SmartID.php
@@ -1,117 +1,122 @@
 <?php
 
-class sspmod_smartattributes_Auth_Process_SmartID extends SimpleSAML_Auth_ProcessingFilter {
-
-	/**
-	 * Which attributes to use as identifiers?
-	 *
-	 * IMPORTANT: If you use the (default) attributemaps (twitter2name, facebook2name,
-	 * etc., be sure to comment out the entries that map xxx_targetedID to
-	 * eduPersonTargetedID, or there will be no way to see its origin any more.
-	 */
-	private $_candidates = array(
-		'eduPersonTargetedID',
-		'eduPersonPrincipalName',
-		'openid',
-		'facebook_targetedID',
-		'twitter_targetedID',
-		'windowslive_targetedID',
-		'myspace_targetedID',
-		'linkedin_targetedID',
-	);
-
-	/**
-	 * The name of the generated ID attribute.
-	 */
-	private $_id_attribute = 'smart_id';
-
-	/**
-	 * Whether to append the AuthenticatingAuthority, separated by '!'
-	 * This only works when SSP is used as a gateway.
-	 */
-	private $_add_authority = true;
-
-	/**
-	 * Whether to prepend the CandidateID, separated by ':'
-	 */
-	private $_add_candidate = true;
-
-	/**
-	 * Attributes which should be added/appended.
-	 *
-	 * Associative array of arrays.
-	 */
-	private $attributes = array();
-
-
-	public function __construct($config, $reserved) {
-		parent::__construct($config, $reserved);
-
-		assert(is_array($config));
-
-		if (array_key_exists('candidates', $config)) {
-			$this->_candidates = $config['candidates'];
-			if (!is_array($this->_candidates)) {
-				throw new Exception('SmartID authproc configuration error: \'candidates\' should be an array.');
-			}
-		}
-
-		if (array_key_exists('id_attribute', $config)) {
-			$this->_id_attribute = $config['id_attribute'];
-			if (!is_string($this->_id_attribute)) {
-				throw new Exception('SmartID authproc configuration error: \'id_attribute\' should be a string.');
-			}
-		}
-
-		if (array_key_exists('add_authority', $config)) {
-			$this->_add_authority = $config['add_authority'];
-			if (!is_bool($this->_add_authority)) {
-				throw new Exception('SmartID authproc configuration error: \'add_authority\' should be a boolean.');
-			}
-		}
-
-		if (array_key_exists('add_candidate', $config)) {
-			$this->_add_candidate = $config['add_candidate'];
-			if (!is_bool($this->_add_candidate)) {
-				throw new Exception('SmartID authproc configuration error: \'add_candidate\' should be a boolean.');
-			}
-		}
-
-	}
-
-	private function addID($attributes, $request) {
-		foreach ($this->_candidates as $idCandidate) {
-			if (isset($attributes[$idCandidate][0])) {
-				if(($this->_add_authority) && (isset($request['saml:AuthenticatingAuthority'][0]))) {
-					return ($this->_add_candidate ? $idCandidate.':' : '').$attributes[$idCandidate][0] . '!' . $request['saml:AuthenticatingAuthority'][0];
-				} else {
-					return ($this->_add_candidate ? $idCandidate.':' : '').$attributes[$idCandidate][0];
-				}
-			}
-		}
-		/*
-		* At this stage no usable id_candidate has been detected.
-		*/
-		throw new SimpleSAML_Error_Exception('This service needs at least one of the following
-		attributes to identity users: '.implode(', ', $this->_candidates).'. Unfortunately not
-		one of them was detected. Please ask your institution administrator to release one of
-		them, or try using another identity provider.');
-	}
-
-
-	/**
-	 * Apply filter to add or replace attributes.
-	 *
-	 * Add or replace existing attributes with the configured values.
-	 *
-	 * @param array &$request  The current request
-	 */
-	public function process(&$request) {
-		assert(is_array($request));
-		assert(array_key_exists('Attributes', $request));
-
-		$ID = $this->addID($request['Attributes'], $request);
-
-		if(isset($ID)) $request['Attributes'][$this->_id_attribute] = array($ID);
-	}
+namespace SimpleSAML\Module\smartattributes\Auth\Process;
+
+class SmartID extends \SimpleSAML\Auth\ProcessingFilter
+{
+    /**
+     * Which attributes to use as identifiers?
+     *
+     * IMPORTANT: If you use the (default) attributemaps (twitter2name, facebook2name,
+     * etc., be sure to comment out the entries that map xxx_targetedID to
+     * eduPersonTargetedID, or there will be no way to see its origin any more.
+     */
+    private $_candidates = array(
+        'eduPersonTargetedID',
+        'eduPersonPrincipalName',
+        'openid',
+        'facebook_targetedID',
+        'twitter_targetedID',
+        'windowslive_targetedID',
+        'linkedin_targetedID',
+    );
+
+    /**
+     * The name of the generated ID attribute.
+     */
+    private $_id_attribute = 'smart_id';
+
+    /**
+     * Whether to append the AuthenticatingAuthority, separated by '!'
+     * This only works when SSP is used as a gateway.
+     */
+    private $_add_authority = true;
+
+    /**
+     * Whether to prepend the CandidateID, separated by ':'
+     */
+    private $_add_candidate = true;
+
+    /**
+     * Attributes which should be added/appended.
+     *
+     * Associative array of arrays.
+     */
+    private $attributes = array();
+
+
+    public function __construct($config, $reserved)
+    {
+        parent::__construct($config, $reserved);
+
+        assert(is_array($config));
+
+        if (array_key_exists('candidates', $config)) {
+            $this->_candidates = $config['candidates'];
+            if (!is_array($this->_candidates)) {
+                throw new \Exception('SmartID authproc configuration error: \'candidates\' should be an array.');
+            }
+        }
+
+        if (array_key_exists('id_attribute', $config)) {
+            $this->_id_attribute = $config['id_attribute'];
+            if (!is_string($this->_id_attribute)) {
+                throw new \Exception('SmartID authproc configuration error: \'id_attribute\' should be a string.');
+            }
+        }
+
+        if (array_key_exists('add_authority', $config)) {
+            $this->_add_authority = $config['add_authority'];
+            if (!is_bool($this->_add_authority)) {
+                throw new \Exception('SmartID authproc configuration error: \'add_authority\' should be a boolean.');
+            }
+        }
+
+        if (array_key_exists('add_candidate', $config)) {
+            $this->_add_candidate = $config['add_candidate'];
+            if (!is_bool($this->_add_candidate)) {
+                throw new \Exception('SmartID authproc configuration error: \'add_candidate\' should be a boolean.');
+            }
+        }
+    }
+
+    private function addID($attributes, $request)
+    {
+        $state = $request['saml:sp:State'];
+        foreach ($this->_candidates as $idCandidate) {
+            if (isset($attributes[$idCandidate][0])) {
+                if (($this->_add_authority) && (isset($state['saml:AuthenticatingAuthority'][0]))) {
+                    return ($this->_add_candidate ? $idCandidate.':' : '').$attributes[$idCandidate][0].'!'.$state['saml:AuthenticatingAuthority'][0];
+                } else {
+                    return ($this->_add_candidate ? $idCandidate.':' : '').$attributes[$idCandidate][0];
+                }
+            }
+        }
+        /*
+         * At this stage no usable id_candidate has been detected.
+         */
+        throw new \SimpleSAML\Error\Exception('This service needs at least one of the following
+            attributes to identity users: '.implode(', ', $this->_candidates).'. Unfortunately not
+            one of them was detected. Please ask your institution administrator to release one of
+            them, or try using another identity provider.');
+    }
+
+    /**
+     * Apply filter to add or replace attributes.
+     *
+     * Add or replace existing attributes with the configured values.
+     *
+     * @param array &$request  The current request
+     */
+    public function process(&$request)
+    {
+        assert(is_array($request));
+        assert(array_key_exists('Attributes', $request));
+
+        $id = $this->addID($request['Attributes'], $request);
+
+        if (isset($id)) {
+            $request['Attributes'][$this->_id_attribute] = array($id);
+        }
+    }
 }
diff --git a/modules/smartattributes/lib/Auth/Process/SmartName.php b/modules/smartattributes/lib/Auth/Process/SmartName.php
index 44323f9196a22ab4ae2597eb76a117e95c493162..6d86a229760cf4cfde58891a6c4dc639ae72004f 100644
--- a/modules/smartattributes/lib/Auth/Process/SmartName.php
+++ b/modules/smartattributes/lib/Auth/Process/SmartName.php
@@ -1,76 +1,92 @@
 <?php
 
+namespace SimpleSAML\Module\smartattributes\Auth\Process;
+
 /**
  * Filter to set name in a smart way, based on available name attributes.
  *
  * @author Andreas Ă…kre Solberg, UNINETT AS.
  * @package SimpleSAMLphp
  */
-class sspmod_smartattributes_Auth_Process_SmartName extends SimpleSAML_Auth_ProcessingFilter {
-
-	/**
-	 * Attributes which should be added/appended.
-	 *
-	 * Assiciative array of arrays.
-	 */
-	private $attributes = array();
-
-
-	private function getFullName($attributes) {
-		if (isset($attributes['displayName']))
-			return $attributes['displayName'][0];
-		
-		if (isset($attributes['cn'])) {
-			if (count(explode(' ', $attributes['cn'][0])) > 1)
-				return $attributes['cn'][0];
-		}
-		
-		if (isset($attributes['sn']) && isset($attributes['givenName']))
-			return $attributes['givenName'][0] . ' ' . $attributes['sn'][0];
-
-		if (isset($attributes['cn']))
-			return $attributes['cn'][0];
-
-		if (isset($attributes['sn']))
-			return $attributes['sn'][0];
-
-		if (isset($attributes['givenName']))
-			return $attributes['givenName'][0];
-		
-		if (isset($attributes['eduPersonPrincipalName'])) {
-			$localname = $this->getLocalUser($attributes['eduPersonPrincipalName'][0]);
-			if (isset($localname)) return $localname;
-		}		
-		
-		return NULL;
-	}
-	
-	private function getLocalUser($userid) {
-		if (strpos($userid, '@') === FALSE) return NULL;
-		$decomposed = explode('@', $userid);
-		if(count($decomposed) === 2) {
-			return $decomposed[0];
-		}
-		return NULL;
-	}
-
-	/**
-	 * Apply filter to add or replace attributes.
-	 *
-	 * Add or replace existing attributes with the configured values.
-	 *
-	 * @param array &$request  The current request
-	 */
-	public function process(&$request) {
-		assert(is_array($request));
-		assert(array_key_exists('Attributes', $request));
-
-		$attributes =& $request['Attributes'];
-		
-		$fullname = $this->getFullName($attributes);
-		
-		if(isset($fullname)) $request['Attributes']['smartname-fullname'] = array($fullname);
-		
-	}
 
+class SmartName extends \SimpleSAML\Auth\ProcessingFilter
+{
+    /**
+     * Attributes which should be added/appended.
+     *
+     * Assiciative array of arrays.
+     */
+    private $attributes = array();
+
+
+    private function getFullName($attributes)
+    {
+        if (isset($attributes['displayName'])) {
+            return $attributes['displayName'][0];
+        }
+
+        if (isset($attributes['cn'])) {
+            if (count(explode(' ', $attributes['cn'][0])) > 1) {
+                return $attributes['cn'][0];
+            }
+        }
+
+        if (isset($attributes['sn']) && isset($attributes['givenName'])) {
+            return $attributes['givenName'][0].' '.$attributes['sn'][0];
+        }
+
+        if (isset($attributes['cn'])) {
+            return $attributes['cn'][0];
+        }
+
+        if (isset($attributes['sn'])) {
+            return $attributes['sn'][0];
+        }
+
+        if (isset($attributes['givenName'])) {
+            return $attributes['givenName'][0];
+        }
+
+        if (isset($attributes['eduPersonPrincipalName'])) {
+            $localname = $this->getLocalUser($attributes['eduPersonPrincipalName'][0]);
+            if (isset($localname)) {
+                return $localname;
+            }
+        }		
+
+        return null;
+    }
+
+    private function getLocalUser($userid)
+    {
+        if (strpos($userid, '@') === false) {
+            return null;
+        }
+        $decomposed = explode('@', $userid);
+        if (count($decomposed) === 2) {
+            return $decomposed[0];
+        }
+        return null;
+    }
+
+    /**
+     * Apply filter to add or replace attributes.
+     *
+     * Add or replace existing attributes with the configured values.
+     *
+     * @param array &$request  The current request
+     */
+    public function process(&$request)
+    {
+        assert(is_array($request));
+        assert(array_key_exists('Attributes', $request));
+
+        $attributes =& $request['Attributes'];
+
+        $fullname = $this->getFullName($attributes);
+
+        if (isset($fullname)) {
+            $request['Attributes']['smartname-fullname'] = array($fullname);
+        }
+    }
 }
diff --git a/modules/sqlauth/lib/Auth/Source/SQL.php b/modules/sqlauth/lib/Auth/Source/SQL.php
index 10f0081ee8028eda9e345571c4ac72edda013478..713c69c322ed0c7180b509fc43455dd3ec614f10 100644
--- a/modules/sqlauth/lib/Auth/Source/SQL.php
+++ b/modules/sqlauth/lib/Auth/Source/SQL.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace SimpleSAML\Module\sqlauth\Auth\Source;
+
 /**
  * Simple SQL authentication source
  *
@@ -8,186 +10,191 @@
  *
  * @package SimpleSAMLphp
  */
-class sspmod_sqlauth_Auth_Source_SQL extends sspmod_core_Auth_UserPassBase {
-
-
-	/**
-	 * The DSN we should connect to.
-	 */
-	private $dsn;
-
-
-	/**
-	 * The username we should connect to the database with.
-	 */
-	private $username;
-
-
-	/**
-	 * The password we should connect to the database with.
-	 */
-	private $password;
-
-
-	/**
-	 * The query we should use to retrieve the attributes for the user.
-	 *
-	 * The username and password will be available as :username and :password.
-	 */
-	private $query;
-
-
-	/**
-	 * Constructor for this authentication source.
-	 *
-	 * @param array $info  Information about this authentication source.
-	 * @param array $config  Configuration.
-	 */
-	public function __construct($info, $config) {
-		assert(is_array($info));
-		assert(is_array($config));
-
-		// Call the parent constructor first, as required by the interface
-		parent::__construct($info, $config);
-
-		// Make sure that all required parameters are present.
-		foreach (array('dsn', 'username', 'password', 'query') as $param) {
-			if (!array_key_exists($param, $config)) {
-				throw new Exception('Missing required attribute \'' . $param .
-					'\' for authentication source ' . $this->authId);
-			}
-
-			if (!is_string($config[$param])) {
-				throw new Exception('Expected parameter \'' . $param .
-					'\' for authentication source ' . $this->authId .
-					' to be a string. Instead it was: ' .
-					var_export($config[$param], TRUE));
-			}
-		}
-
-		$this->dsn = $config['dsn'];
-		$this->username = $config['username'];
-		$this->password = $config['password'];
-		$this->query = $config['query'];
-	}
-
-
-	/**
-	 * Create a database connection.
-	 *
-	 * @return PDO  The database connection.
-	 */
-	private function connect() {
-		try {
-			$db = new PDO($this->dsn, $this->username, $this->password);
-		} catch (PDOException $e) {
-			throw new Exception('sqlauth:' . $this->authId . ': - Failed to connect to \'' .
-				$this->dsn . '\': '. $e->getMessage());
-		}
-
-		$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
-
-
-		$driver = explode(':', $this->dsn, 2);
-		$driver = strtolower($driver[0]);
-
-		/* Driver specific initialization. */
-		switch ($driver) {
-		case 'mysql':
-			/* Use UTF-8. */
-			$db->exec("SET NAMES 'utf8'");
-			break;
-		case 'pgsql':
-			/* Use UTF-8. */
-			$db->exec("SET NAMES 'UTF8'");
-			break;
-		}
-
-		return $db;
-	}
-
-
-	/**
-	 * Attempt to log in using the given username and password.
-	 *
-	 * On a successful login, this function should return the users attributes. On failure,
-	 * it should throw an exception. If the error was caused by the user entering the wrong
-	 * username or password, a SimpleSAML_Error_Error('WRONGUSERPASS') should be thrown.
-	 *
-	 * Note that both the username and the password are UTF-8 encoded.
-	 *
-	 * @param string $username  The username the user wrote.
-	 * @param string $password  The password the user wrote.
-	 * @return array  Associative array with the users attributes.
-	 */
-	protected function login($username, $password) {
-		assert(is_string($username));
-		assert(is_string($password));
-
-		$db = $this->connect();
-
-		try {
-			$sth = $db->prepare($this->query);
-		} catch (PDOException $e) {
-			throw new Exception('sqlauth:' . $this->authId .
-				': - Failed to prepare query: ' . $e->getMessage());
-		}
-
-		try {
-			$res = $sth->execute(array('username' => $username, 'password' => $password));
-		} catch (PDOException $e) {
-			throw new Exception('sqlauth:' . $this->authId .
-				': - Failed to execute query: ' . $e->getMessage());
-		}
-
-		try {
-			$data = $sth->fetchAll(PDO::FETCH_ASSOC);
-		} catch (PDOException $e) {
-			throw new Exception('sqlauth:' . $this->authId .
-				': - Failed to fetch result set: ' . $e->getMessage());
-		}
-
-		SimpleSAML\Logger::info('sqlauth:' . $this->authId . ': Got ' . count($data) .
-			' rows from database');
-
-		if (count($data) === 0) {
-			/* No rows returned - invalid username/password. */
-			SimpleSAML\Logger::error('sqlauth:' . $this->authId .
-				': No rows in result set. Probably wrong username/password.');
-			throw new SimpleSAML_Error_Error('WRONGUSERPASS');
-		}
-
-		/* Extract attributes. We allow the resultset to consist of multiple rows. Attributes
-		 * which are present in more than one row will become multivalued. NULL values and
-		 * duplicate values will be skipped. All values will be converted to strings.
-		 */
-		$attributes = array();
-		foreach ($data as $row) {
-			foreach ($row as $name => $value) {
-
-				if ($value === NULL) {
-					continue;
-				}
-
-				$value = (string)$value;
-
-				if (!array_key_exists($name, $attributes)) {
-					$attributes[$name] = array();
-				}
-
-				if (in_array($value, $attributes[$name], TRUE)) {
-					/* Value already exists in attribute. */
-					continue;
-				}
-
-				$attributes[$name][] = $value;
-			}
-		}
-
-		SimpleSAML\Logger::info('sqlauth:' . $this->authId . ': Attributes: ' .
-			implode(',', array_keys($attributes)));
-
-		return $attributes;
-	}
 
+class SQL extends \SimpleSAML\Module\core\Auth\UserPassBase
+{
+    /**
+     * The DSN we should connect to.
+     */
+    private $dsn;
+
+    /**
+     * The username we should connect to the database with.
+     */
+    private $username;
+
+    /**
+     * The password we should connect to the database with.
+     */
+    private $password;
+
+    /**
+     * The options that we should connect to the database with.
+     */
+    private $options;
+
+    /**
+     * The query we should use to retrieve the attributes for the user.
+     *
+     * The username and password will be available as :username and :password.
+     */
+    private $query;
+
+    /**
+     * Constructor for this authentication source.
+     *
+     * @param array $info  Information about this authentication source.
+     * @param array $config  Configuration.
+     */
+    public function __construct($info, $config)
+    {
+        assert(is_array($info));
+        assert(is_array($config));
+
+        // Call the parent constructor first, as required by the interface
+        parent::__construct($info, $config);
+
+        // Make sure that all required parameters are present.
+        foreach (array('dsn', 'username', 'password', 'query') as $param) {
+            if (!array_key_exists($param, $config)) {
+                throw new \Exception('Missing required attribute \'' . $param .
+                    '\' for authentication source ' . $this->authId);
+            }
+
+            if (!is_string($config[$param])) {
+                throw new \Exception('Expected parameter \'' . $param .
+                    '\' for authentication source ' . $this->authId .
+                    ' to be a string. Instead it was: ' .
+                    var_export($config[$param], true));
+            }
+        }
+
+        $this->dsn = $config['dsn'];
+        $this->username = $config['username'];
+        $this->password = $config['password'];
+        $this->query = $config['query'];
+        if (isset($config['options'])) {
+            $this->options = $config['options'];
+        }
+    }
+
+
+    /**
+     * Create a database connection.
+     *
+     * @return \PDO  The database connection.
+     */
+    private function connect()
+    {
+        try {
+            $db = new \PDO($this->dsn, $this->username, $this->password, $this->options);
+        } catch (\PDOException $e) {
+            throw new \Exception('sqlauth:' . $this->authId . ': - Failed to connect to \'' .
+                $this->dsn . '\': '. $e->getMessage());
+        }
+
+        $db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+
+        $driver = explode(':', $this->dsn, 2);
+        $driver = strtolower($driver[0]);
+
+        /* Driver specific initialization. */
+        switch ($driver) {
+        case 'mysql':
+            /* Use UTF-8. */
+            $db->exec("SET NAMES 'utf8mb4'");
+            break;
+        case 'pgsql':
+            /* Use UTF-8. */
+            $db->exec("SET NAMES 'UTF8'");
+            break;
+        }
+
+        return $db;
+    }
+
+
+    /**
+     * Attempt to log in using the given username and password.
+     *
+     * On a successful login, this function should return the users attributes. On failure,
+     * it should throw an exception. If the error was caused by the user entering the wrong
+     * username or password, a \SimpleSAML\Error\Error('WRONGUSERPASS') should be thrown.
+     *
+     * Note that both the username and the password are UTF-8 encoded.
+     *
+     * @param string $username  The username the user wrote.
+     * @param string $password  The password the user wrote.
+     * @return array  Associative array with the users attributes.
+     */
+    protected function login($username, $password)
+    {
+        assert(is_string($username));
+        assert(is_string($password));
+
+        $db = $this->connect();
+
+        try {
+            $sth = $db->prepare($this->query);
+        } catch (\PDOException $e) {
+            throw new \Exception('sqlauth:' . $this->authId .
+                ': - Failed to prepare query: ' . $e->getMessage());
+        }
+
+        try {
+            $sth->execute(array('username' => $username, 'password' => $password));
+        } catch (\PDOException $e) {
+            throw new \Exception('sqlauth:' . $this->authId .
+                ': - Failed to execute query: ' . $e->getMessage());
+        }
+
+        try {
+            $data = $sth->fetchAll(\PDO::FETCH_ASSOC);
+        } catch (\PDOException $e) {
+            throw new \Exception('sqlauth:' . $this->authId .
+                ': - Failed to fetch result set: ' . $e->getMessage());
+        }
+
+        \SimpleSAML\Logger::info('sqlauth:' . $this->authId . ': Got ' . count($data) .
+            ' rows from database');
+
+        if (count($data) === 0) {
+            /* No rows returned - invalid username/password. */
+            \SimpleSAML\Logger::error('sqlauth:' . $this->authId .
+                ': No rows in result set. Probably wrong username/password.');
+            throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
+        }
+
+        /* Extract attributes. We allow the resultset to consist of multiple rows. Attributes
+         * which are present in more than one row will become multivalued. null values and
+         * duplicate values will be skipped. All values will be converted to strings.
+         */
+        $attributes = array();
+        foreach ($data as $row) {
+            foreach ($row as $name => $value) {
+
+                if ($value === null) {
+                    continue;
+                }
+
+                $value = (string)$value;
+
+                if (!array_key_exists($name, $attributes)) {
+                    $attributes[$name] = array();
+                }
+
+                if (in_array($value, $attributes[$name], true)) {
+                    /* Value already exists in attribute. */
+                    continue;
+                }
+
+                $attributes[$name][] = $value;
+            }
+        }
+
+        \SimpleSAML\Logger::info('sqlauth:' . $this->authId . ': Attributes: ' .
+            implode(',', array_keys($attributes)));
+
+        return $attributes;
+    }
 }
diff --git a/modules/statistics/bin/loganalyzer.php b/modules/statistics/bin/loganalyzer.php
index bf9a1641893d805a55aaacc93cc0e892ccecddd4..0186477c6d072fc016eb5b7ce6e1cb3c4b9da554 100755
--- a/modules/statistics/bin/loganalyzer.php
+++ b/modules/statistics/bin/loganalyzer.php
@@ -8,9 +8,9 @@ $baseDir = dirname(dirname(dirname(dirname(__FILE__))));
 require_once($baseDir . '/lib/_autoload.php');
 
 // Initialize the configuration.
-$configdir = SimpleSAML\Utils\Config::getConfigDir();
-SimpleSAML_Configuration::setConfigDir($configdir);
-SimpleSAML\Utils\Time::initTimezone();
+$configdir = \SimpleSAML\Utils\Config::getConfigDir();
+\SimpleSAML\Configuration::setConfigDir($configdir);
+\SimpleSAML\Utils\Time::initTimezone();
 
 $progName = array_shift($argv);
 $debug = false;
@@ -50,7 +50,7 @@ foreach($argv as $a) {
     }
 }
 
-$aggregator = new sspmod_statistics_Aggregator(true);
+$aggregator = new \SimpleSAML\Module\statistics\Aggregator(true);
 $aggregator->dumpConfig();
 $aggregator->debugInfo();
 $results = $aggregator->aggregate($debug);
diff --git a/modules/statistics/bin/logcleaner.php b/modules/statistics/bin/logcleaner.php
index b845a139602c756e9b28cde423fcba30057639f5..5a84c2a5e3f1366795193c586c963bedf99bde67 100755
--- a/modules/statistics/bin/logcleaner.php
+++ b/modules/statistics/bin/logcleaner.php
@@ -8,8 +8,8 @@ $baseDir = dirname(dirname(dirname(dirname(__FILE__))));
 require_once($baseDir . '/lib/_autoload.php');
 
 // Initialize the configuration.
-$configdir = SimpleSAML\Utils\Config::getConfigDir();
-SimpleSAML_Configuration::setConfigDir($configdir);
+$configdir = \SimpleSAML\Utils\Config::getConfigDir();
+\SimpleSAML\Configuration::setConfigDir($configdir);
 
 $progName = array_shift($argv);
 $debug = false;
@@ -58,7 +58,7 @@ foreach ($argv as $a) {
     }
 }
 
-$cleaner = new sspmod_statistics_LogCleaner($infile);
+$cleaner = new \SimpleSAML\Module\statistics\LogCleaner($infile);
 $cleaner->dumpConfig();
 $todelete = $cleaner->clean($debug);
 
diff --git a/modules/statistics/hooks/hook_cron.php b/modules/statistics/hooks/hook_cron.php
index 31d85a8b913443abcaabfbf2e300a92e5da40d07..7df92b8ddfc5bc8da4bbc3d5fb2f5041beb4451e 100644
--- a/modules/statistics/hooks/hook_cron.php
+++ b/modules/statistics/hooks/hook_cron.php
@@ -1,18 +1,20 @@
 <?php
+
 /**
  * Hook to run a cron job.
  *
  * @param array &$croninfo  Output
  */
+
 function statistics_hook_cron(&$croninfo)
 {
     assert(is_array($croninfo));
     assert(array_key_exists('summary', $croninfo));
     assert(array_key_exists('tag', $croninfo));
 
-    $statconfig = SimpleSAML_Configuration::getConfig('module_statistics.php');
+    $statconfig = \SimpleSAML\Configuration::getConfig('module_statistics.php');
 	
-    if (is_null($statconfig->getValue('cron_tag', nul))) {
+    if (is_null($statconfig->getValue('cron_tag', null))) {
         return;
     }
     if ($statconfig->getValue('cron_tag', null) !== $croninfo['tag']) {
@@ -25,16 +27,16 @@ function statistics_hook_cron(&$croninfo)
     }
 	
     try {
-        $aggregator = new sspmod_statistics_Aggregator();
+        $aggregator = new \SimpleSAML\Module\statistics\Aggregator();
         $results = $aggregator->aggregate();
         if (empty($results)) {
-            SimpleSAML\Logger::notice('Output from statistics aggregator was empty.');
+            \SimpleSAML\Logger::notice('Output from statistics aggregator was empty.');
         } else {
             $aggregator->store($results);
         }
-    } catch (Exception $e) {
+    } catch (\Exception $e) {
         $message = 'Loganalyzer threw exception: ' . $e->getMessage();
-        SimpleSAML\Logger::warning($message);
+        \SimpleSAML\Logger::warning($message);
         $croninfo['summary'][] = $message;
     }
 }
diff --git a/modules/statistics/hooks/hook_sanitycheck.php b/modules/statistics/hooks/hook_sanitycheck.php
index 9936379c54a3bb88349a3b3e19ba34cde431150c..1c3783925a728f263f41551f9dc71c4e38c8e533 100644
--- a/modules/statistics/hooks/hook_sanitycheck.php
+++ b/modules/statistics/hooks/hook_sanitycheck.php
@@ -11,7 +11,7 @@ function statistics_hook_sanitycheck(&$hookinfo)
     assert(array_key_exists('info', $hookinfo));
 
     try {
-        $statconfig = SimpleSAML_Configuration::getConfig('module_statistics.php');
+        $statconfig = \SimpleSAML\Configuration::getConfig('module_statistics.php');
     } catch(Exception $e) {
         $hookinfo['errors'][] = '[statistics] Could not get configuration: ' . $e->getMessage(); return;
     }
diff --git a/modules/statistics/lib/AccessCheck.php b/modules/statistics/lib/AccessCheck.php
index f742b51d1f47d799091744deba096d26af79a8f1..5b7967f1cb2f062a3e52f62c0fdd72484d041bef 100644
--- a/modules/statistics/lib/AccessCheck.php
+++ b/modules/statistics/lib/AccessCheck.php
@@ -1,18 +1,21 @@
 <?php
 
+namespace SimpleSAML\Module\statistics;
+
 /**
  * Class implementing the access checker function for the statistics module.
  *
  * @package SimpleSAMLphp
  */
-class sspmod_statistics_AccessCheck
+
+class AccessCheck
 {
     /**
      * Check that the user has access to the statistics.
      *
      * If the user doesn't have access, send the user to the login page.
      */
-    public static function checkAccess(SimpleSAML_Configuration $statconfig)
+    public static function checkAccess(\SimpleSAML\Configuration $statconfig)
     {
         $protected = $statconfig->getBoolean('protected', false);
         $authsource = $statconfig->getString('auth', null);
@@ -21,22 +24,22 @@ class sspmod_statistics_AccessCheck
 
         $acl = $statconfig->getValue('acl', null);
         if ($acl !== null && !is_string($acl) && !is_array($acl)) {
-            throw new SimpleSAML_Error_Exception('Invalid value for \'acl\'-option. Should be an array or a string.');
+            throw new \SimpleSAML\Error\Exception('Invalid value for \'acl\'-option. Should be an array or a string.');
         }
 
         if (!$protected) {
             return;
         }
 
-        if (SimpleSAML\Utils\Auth::isAdmin()) {
+        if (\SimpleSAML\Utils\Auth::isAdmin()) {
             // User logged in as admin. OK.
-            SimpleSAML\Logger::debug('Statistics auth - logged in as admin, access granted');
+            \SimpleSAML\Logger::debug('Statistics auth - logged in as admin, access granted');
             return;
         }
 
         if (!isset($authsource)) {
             // If authsource is not defined, init admin login.
-            SimpleSAML\Utils\Auth::requireAdmin();
+            \SimpleSAML\Utils\Auth::requireAdmin();
         }
 
         // We are using an authsource for login.
@@ -45,7 +48,7 @@ class sspmod_statistics_AccessCheck
         $as->requireAuth();
 
         // User logged in with auth source.
-        SimpleSAML\Logger::debug('Statistics auth - valid login with auth source [' . $authsource . ']');
+        \SimpleSAML\Logger::debug('Statistics auth - valid login with auth source [' . $authsource . ']');
 
         // Retrieving attributes
         $attributes = $as->getAttributes();
@@ -53,29 +56,29 @@ class sspmod_statistics_AccessCheck
         if (!empty($allowedusers)) {
             // Check if userid exists
             if (!isset($attributes[$useridattr][0])) {
-                throw new Exception('User ID is missing');
+                throw new \Exception('User ID is missing');
             }
 
             // Check if userid is allowed access..
             if (in_array($attributes[$useridattr][0], $allowedusers, true)) {
-                SimpleSAML\Logger::debug('Statistics auth - User granted access by user ID [' . $attributes[$useridattr][0] . ']');
+                \SimpleSAML\Logger::debug('Statistics auth - User granted access by user ID [' . $attributes[$useridattr][0] . ']');
                 return;
             }
-            SimpleSAML\Logger::debug('Statistics auth - User denied access by user ID [' . $attributes[$useridattr][0] . ']');
+            \SimpleSAML\Logger::debug('Statistics auth - User denied access by user ID [' . $attributes[$useridattr][0] . ']');
         } else {
-            SimpleSAML\Logger::debug('Statistics auth - no allowedUsers list.');
+            \SimpleSAML\Logger::debug('Statistics auth - no allowedUsers list.');
         }
 
         if (!is_null($acl)) {
-            $acl = new sspmod_core_ACL($acl);
+            $acl = new \SimpleSAML\Module\core\ACL($acl);
             if ($acl->allows($attributes)) {
-                SimpleSAML\Logger::debug('Statistics auth - allowed access by ACL.');
+                \SimpleSAML\Logger::debug('Statistics auth - allowed access by ACL.');
                 return;
             }
-            SimpleSAML\Logger::debug('Statistics auth - denied access by ACL.');
+            \SimpleSAML\Logger::debug('Statistics auth - denied access by ACL.');
         } else {
-            SimpleSAML\Logger::debug('Statistics auth - no ACL configured.');
+            \SimpleSAML\Logger::debug('Statistics auth - no ACL configured.');
         }
-        throw new SimpleSAML_Error_Exception('Access denied to the current user.');
+        throw new \SimpleSAML\Error\Exception('Access denied to the current user.');
     }
 }
diff --git a/modules/statistics/lib/Aggregator.php b/modules/statistics/lib/Aggregator.php
index 4ec74019c94df52cc7422193470678ac560cfc9d..eae6ab5c564d259b51bf853fb326da78a5baf54a 100644
--- a/modules/statistics/lib/Aggregator.php
+++ b/modules/statistics/lib/Aggregator.php
@@ -1,9 +1,13 @@
 <?php
+
+namespace SimpleSAML\Module\statistics;
+
 /*
  * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
  * @package SimpleSAMLphp
  */
-class sspmod_statistics_Aggregator
+
+class Aggregator
 {
     private $statconfig;
     private $statdir;
@@ -13,6 +17,7 @@ class sspmod_statistics_Aggregator
     private $metadata;
     private $fromcmdline;
     private $starttime;
+    private $timeres;
 
     /**
      * Constructor
@@ -20,7 +25,7 @@ class sspmod_statistics_Aggregator
     public function __construct($fromcmdline = false)
     {
         $this->fromcmdline = $fromcmdline;
-        $this->statconfig = SimpleSAML_Configuration::getConfig('module_statistics.php');
+        $this->statconfig = \SimpleSAML\Configuration::getConfig('module_statistics.php');
 
         $this->statdir = $this->statconfig->getValue('statdir');
         $this->inputfile = $this->statconfig->getValue('inputfile');
@@ -73,25 +78,25 @@ class sspmod_statistics_Aggregator
         $this->loadMetadata();
 
         if (!is_dir($this->statdir)) {
-            throw new Exception('Statistics module: output dir do not exists [' . $this->statdir . ']');
+            throw new \Exception('Statistics module: output dir do not exists [' . $this->statdir . ']');
         }
 
         if (!file_exists($this->inputfile)) {
-            throw new Exception('Statistics module: input file do not exists [' . $this->inputfile . ']');
+            throw new \Exception('Statistics module: input file do not exists [' . $this->inputfile . ']');
         }
 
         $file = fopen($this->inputfile, 'r');
 
         if ($file === false) {
-            throw new Exception('Statistics module: unable to open file [' . $this->inputfile . ']');
+            throw new \Exception('Statistics module: unable to open file [' . $this->inputfile . ']');
         }
 
-        $logparser = new sspmod_statistics_LogParser(
+        $logparser = new LogParser(
             $this->statconfig->getValue('datestart', 0), $this->statconfig->getValue('datelength', 15), $this->statconfig->getValue('offsetspan', 44)
         );
         $datehandler = array(
-            'default' => new sspmod_statistics_DateHandler($this->offset),
-            'month' => new  sspmod_statistics_DateHandlerMonth($this->offset),
+            'default' => new DateHandler($this->offset),
+            'month' => new  DateHandlerMonth($this->offset),
         );
 
         $notBefore = 0;
@@ -168,7 +173,7 @@ class sspmod_statistics_Aggregator
                     continue;
                 }
 
-                foreach ($this->timeres AS $tres => $tresconfig ) {
+                foreach ($this->timeres as $tres => $tresconfig ) {
                     $dh = 'default';
                     if (isset($tresconfig['customDateHandler'])) {
                         $dh = $tresconfig['customDateHandler'];
@@ -219,26 +224,17 @@ class sspmod_statistics_Aggregator
     private function cummulateData($previous, $newdata)
     {
         $dataset = array();
-        foreach ($previous as $slot => $dataarray) {
-            if (!array_key_exists($slot, $dataset)) {
-                $dataset[$slot] = array();
-            }
-            foreach ($dataarray as $key => $data) {
-                if (!array_key_exists($key, $dataset[$slot])) {
-                    $dataset[$slot][$key] = 0;
+        foreach (func_get_args() as $item) {
+            foreach ($item as $slot => $dataarray) {
+                if (!array_key_exists($slot, $dataset)) {
+                    $dataset[$slot] = array();
                 }
-                $dataset[$slot][$key] += $data;
-            }
-        }
-        foreach ($newdata as $slot => $dataarray) {
-            if (!array_key_exists($slot, $dataset)) {
-                $dataset[$slot] = array();
-            }
-            foreach ($dataarray as $key => $data) {
-                if (!array_key_exists($key, $dataset[$slot])) {
-                    $dataset[$slot][$key] = 0;
+                foreach ($dataarray as $key => $data) {
+                    if (!array_key_exists($key, $dataset[$slot])) {
+                        $dataset[$slot][$key] = 0;
+                    }
+                    $dataset[$slot][$key] += $data;
                 }
-                $dataset[$slot][$key] += $data;
             }
         }
         return $dataset;
@@ -247,8 +243,8 @@ class sspmod_statistics_Aggregator
     public function store($results)
     {
         $datehandler = array(
-            'default' => new sspmod_statistics_DateHandler($this->offset),
-            'month' => new  sspmod_statistics_DateHandlerMonth($this->offset),
+            'default' => new DateHandler($this->offset),
+            'month' => new DateHandlerMonth($this->offset),
         );
 
         // Iterate the first level of results, which is per rule, as defined in the config.
diff --git a/modules/statistics/lib/DateHandler.php b/modules/statistics/lib/DateHandler.php
index 13ed07c7f5dd5b8d25d40d1fca87ad4da784100a..b35d07ab3f7427a8e7e60cc19e35746d9e59df43 100644
--- a/modules/statistics/lib/DateHandler.php
+++ b/modules/statistics/lib/DateHandler.php
@@ -1,9 +1,13 @@
 <?php
+
+namespace SimpleSAML\Module\statistics;
+
 /*
  * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
  * @package SimpleSAMLphp
  */
-class sspmod_statistics_DateHandler
+
+class DateHandler
 {
     protected $offset;
 
diff --git a/modules/statistics/lib/DateHandlerMonth.php b/modules/statistics/lib/DateHandlerMonth.php
index 33f9762d91a3c707fb9be1410f879d957125144e..979e1838b99fd888c6649e45dba9fca500366a0b 100644
--- a/modules/statistics/lib/DateHandlerMonth.php
+++ b/modules/statistics/lib/DateHandlerMonth.php
@@ -1,14 +1,18 @@
 <?php
+
+namespace SimpleSAML\Module\statistics;
+
 /*
  * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
  * @package SimpleSAMLphp
  */
-class sspmod_statistics_DateHandlerMonth extends sspmod_statistics_DateHandler
+
+class DateHandlerMonth extends DateHandler
 {
     /**
      * Constructor
      *
-     * @param array $offset 	Date offset
+     * @param integer $offset 	Date offset
      */
     public function __construct($offset)
     {
diff --git a/modules/statistics/lib/Graph/GoogleCharts.php b/modules/statistics/lib/Graph/GoogleCharts.php
index 9a1126188387d359513bcef798b0011ebc5c8057..db3df14463ce7585749abc5a4645ecbd7017c76d 100644
--- a/modules/statistics/lib/Graph/GoogleCharts.php
+++ b/modules/statistics/lib/Graph/GoogleCharts.php
@@ -1,22 +1,34 @@
 <?php
+
+namespace SimpleSAML\Module\statistics\Graph;
+
 /*
- * sspmod_statistics_Graph_GoogleCharts will help you to create a Google Chart
+ * \SimpleSAML\Module\statistics\Graph\GoogleCharts will help you to create a Google Chart
  * using the Google Charts API. 
  *
  * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
  * @package SimpleSAMLphp
  */
-class sspmod_statistics_Graph_GoogleCharts
+
+class GoogleCharts
 {
-    private $x, $y;
+    /**
+     * @var integer
+     */
+    private $x;
+
+    /**
+     * @var integer
+     */
+    private $y;
 
     /**
      * Constructor.
      *
      * Takes dimension of graph as parameters. X and Y.
      *
-     * @param $x    X dimension. Default 800.
-     * @param $y    Y dimension. Default 350.
+     * @param integer $x    X dimension. Default 800.
+     * @param integer $y    Y dimension. Default 350.
      */
     public function __construct($x = 800, $y = 350)
     {
@@ -58,40 +70,22 @@ class sspmod_statistics_Graph_GoogleCharts
         return($chardata); 
     }
 
-    /**
-     * Return colors between multiple graphs...
-     */
-    private function getFillArea($datasets)
-    {
-        if (count($datasets) < 2) {
-            return '';
-        }
-
-        $colors = array('eeeeee', 'cccccc', 'aaaaaa', '99eecc');
-        $num = count($datasets) ;
-        $colstr = array();
-        for ($i = 0; $i < $num; $i++) {
-            $colstr[] = 'b' . ',' . $colors[$i] . ',' . ($i) . ',' . ($i+1) . ',0';
-        }
-        return '&chm=' . join('|', $colstr);
-    }
-
     /**
      * Generate a Google Charts URL which points to a generated image.
      * More documentation on Google Charts here: 
      *   http://code.google.com/apis/chart/
      *
-     * @param $axis        Axis
-     * @param $axpis       Axis positions
-     * @param $datasets    Datasets values
-     * @param $max         Max value. Will be the topmost value on the Y-axis.
+     * @param string $axis        Axis
+     * @param string $axpis       Axis positions
+     * @param array $datasets    Datasets values
+     * @param integer $max         Max value. Will be the topmost value on the Y-axis.
      */
     public function show($axis, $axispos, $datasets, $maxes)
     {
         $labeld = '&chxt=x,y' . '&chxr=0,0,1|1,0,' . $maxes[0];
         if (count($datasets) > 1) {
             if (count($datasets) !== count($maxes)) {
-                throw new Exception('Incorrect number of max calculations for graph plotting.');
+                throw new \Exception('Incorrect number of max calculations for graph plotting.');
             }
             $labeld = '&chxt=x,y,r' . '&chxr=0,0,1|1,0,' . $maxes[0] . '|2,0,' . $maxes[1];
         }
@@ -145,11 +139,11 @@ class sspmod_statistics_Graph_GoogleCharts
      * <code>
      * 	    $foo = array(0, 2, 2.3, 2.6, 6, 10, 15, 98, 198, 256, 487, 563, 763, 801, 899, 999, 987, 198234.485, 283746);
      *	    foreach ($foo AS $f) {
-     *	        echo '<p>' . $f . ' => ' . sspmod_statistics_Graph_GoogleCharts::roof($f);
+     *	        echo '<p>' . $f . ' => ' . \SimpleSAML\Module\statistics\Graph\GoogleCharts::roof($f);
      *	    }
      * </code>
      * 
-     * @param $max    Input value.
+     * @param integer $max    Input value.
      */
     public static function roof($max)
     {
diff --git a/modules/statistics/lib/LogCleaner.php b/modules/statistics/lib/LogCleaner.php
index 40915f2554f686aa2239fca62e2de7d94ee0c83e..77ceeaaa4b9f1e46e2ed2631a813a08f45992838 100644
--- a/modules/statistics/lib/LogCleaner.php
+++ b/modules/statistics/lib/LogCleaner.php
@@ -1,9 +1,13 @@
 <?php
+
+namespace SimpleSAML\Module\statistics;
+
 /*
  * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
  * @package SimpleSAMLphp
  */
-class sspmod_statistics_LogCleaner
+
+class LogCleaner
 {
     private $statconfig;
     private $statdir;
@@ -16,7 +20,7 @@ class sspmod_statistics_LogCleaner
      */
     public function __construct($inputfile = null)
     {
-        $this->statconfig = SimpleSAML_Configuration::getConfig('module_statistics.php');
+        $this->statconfig = \SimpleSAML\Configuration::getConfig('module_statistics.php');
 
         $this->statdir = $this->statconfig->getValue('statdir');
         $this->inputfile = $this->statconfig->getValue('inputfile');
@@ -28,6 +32,9 @@ class sspmod_statistics_LogCleaner
         }
     }
 
+    /*
+     * @return void
+     */
     public function dumpConfig()
     {
         echo 'Statistics directory   : ' . $this->statdir . "\n";
@@ -35,23 +42,27 @@ class sspmod_statistics_LogCleaner
         echo 'Offset                 : ' . $this->offset . "\n";
     }
 
-    public function clean($debug = false) {
+
+    /*
+     * @param bool $debug
+     * @return array
+     */
+    public function clean($debug = false)
+    {
         if (!is_dir($this->statdir)) {
-            throw new Exception('Statistics module: output dir do not exists [' . $this->statdir . ']');
+            throw new \Exception('Statistics module: output dir do not exists [' . $this->statdir . ']');
         }
 
         if (!file_exists($this->inputfile)) {
-            throw new Exception('Statistics module: input file do not exists [' . $this->inputfile . ']');
+            throw new \Exception('Statistics module: input file do not exists [' . $this->inputfile . ']');
         }
 
         $file = fopen($this->inputfile, 'r');
 
-        $logparser = new sspmod_statistics_LogParser(
+        $logparser = new LogParser(
             $this->statconfig->getValue('datestart', 0), $this->statconfig->getValue('datelength', 15), $this->statconfig->getValue('offsetspan', 44)
         );
-        $datehandler = new sspmod_statistics_DateHandler($this->offset);
 
-        $results = array();
         $sessioncounter = array();
 
         $i = 0;
@@ -68,7 +79,6 @@ class sspmod_statistics_LogCleaner
             // Parse log, and extract epoch time and rest of content.
             $epoch = $logparser->parseEpoch($logline);
             $content = $logparser->parseContent($logline);
-            $action = trim($content[5]);
 
             if (($i % 10000) == 0) {
                 echo("Read line " . $i . "\n");
@@ -111,16 +121,22 @@ class sspmod_statistics_LogCleaner
         return $todelete;
     }
 
+
+    /*
+     * @param array $todelete
+     * @param string $outputfile
+     * @return void
+     */
     public function store($todelete, $outputfile)
     {
         echo "Preparing to delete [" .count($todelete) . "] trackids\n";
 
         if (!is_dir($this->statdir)) {
-            throw new Exception('Statistics module: output dir do not exists [' . $this->statdir . ']');
+            throw new \Exception('Statistics module: output dir do not exists [' . $this->statdir . ']');
         }
 
         if (!file_exists($this->inputfile)) {
-            throw new Exception('Statistics module: input file do not exists [' . $this->inputfile . ']');
+            throw new \Exception('Statistics module: input file do not exists [' . $this->inputfile . ']');
         }
 
         $file = fopen($this->inputfile, 'r');
@@ -132,7 +148,7 @@ class sspmod_statistics_LogCleaner
         }
         $outfile = fopen($outputfile, 'x'); /* Create the output file. */
 
-        $logparser = new sspmod_statistics_LogParser(
+        $logparser = new LogParser(
             $this->statconfig->getValue('datestart', 0), $this->statconfig->getValue('datelength', 15), $this->statconfig->getValue('offsetspan', 44)
         );
 
@@ -148,7 +164,6 @@ class sspmod_statistics_LogCleaner
             $i++;
 
             $content = $logparser->parseContent($logline);
-            $action = trim($content[5]);
 
             if (($i % 10000) == 0) {
                 echo("Read line " . $i . "\n");
diff --git a/modules/statistics/lib/LogParser.php b/modules/statistics/lib/LogParser.php
index 6ca677a38c5b2d624141c9105fa7746bf8aaa825..e4cf72a15747f4d2dee40dc893d7883678925c44 100644
--- a/modules/statistics/lib/LogParser.php
+++ b/modules/statistics/lib/LogParser.php
@@ -1,20 +1,35 @@
 <?php
+
+namespace SimpleSAML\Module\statistics;
+
 /*
  * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
  * @package SimpleSAMLphp
  */
-class sspmod_statistics_LogParser
+
+class LogParser
 {
+    /**
+     * @var integer
+     */
     private $datestart;
+
+    /**
+     * @var integer
+     */
     private $datelength;
+
+    /**
+     * @var integer
+     */
     private $offset;
 
     /**
      * Constructor
      *
-     * @param $datestart   At which char is the date starting
-     * @param $datelength  How many characters is the date (on the b
-     * @param $offset      At which char is the rest of the entries starting
+     * @param integer $datestart   At which char is the date starting
+     * @param integer $datelength  How many characters is the date (on the b
+     * @param integer $offset      At which char is the rest of the entries starting
      */
     public function __construct($datestart, $datelength, $offset)
     {
@@ -23,6 +38,12 @@ class sspmod_statistics_LogParser
         $this->offset = $offset;
     }
 
+
+    /**
+     * @param string $line
+     *
+     * @return integer
+     */
     public function parseEpoch($line)
     {
         $epoch = strtotime(substr($line, 0, $this->datelength));
@@ -43,24 +64,16 @@ class sspmod_statistics_LogParser
         return $epoch;
     }
 
-    public function parseContent($line) {
+
+    /**
+     * @param string $line
+     *
+     * @return array
+     */
+    public function parseContent($line)
+    {
         $contentstr = substr($line, $this->offset);
         $content = explode(' ', $contentstr);
         return $content;
     }
-
-    // Aug 27 12:54:25 ssp 5 STAT [5416262207] saml20-sp-SSO urn:mace:feide.no:services:no.uninett.wiki-feide sam.feide.no NA
-    // 
-    // Oct 30 11:07:14 www1 simplesamlphp-foodle[12677]: 5 STAT [200b4679af] saml20-sp-SLO spinit urn:mace:feide.no:services:no.feide.foodle sam.feide.no
-
-    function parse15($str) {
-        $di = date_parse($str);
-        $datestamp = mktime($di['hour'], $di['minute'], $di['second'], $di['month'], $di['day']);	
-        return $datestamp;
-    }
-
-    function parse23($str) {
-        $timestamp = strtotime($str);
-        return $timestamp;
-    }
 }
diff --git a/modules/statistics/lib/RatioDataset.php b/modules/statistics/lib/RatioDataset.php
index a88573c65697df752766edc1fa8bf1c42e8dd570..da9f5d055d5e3b6b379b556931f66f20ea683e7c 100644
--- a/modules/statistics/lib/RatioDataset.php
+++ b/modules/statistics/lib/RatioDataset.php
@@ -1,9 +1,13 @@
 <?php
+
+namespace SimpleSAML\Module\statistics;
+
 /*
  * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
  * @package SimpleSAMLphp
  */
-class sspmod_statistics_RatioDataset extends sspmod_statistics_StatDataset
+
+class RatioDataset extends StatDataset
 {
     public function aggregateSummary()
     {
diff --git a/modules/statistics/lib/Ruleset.php b/modules/statistics/lib/Ruleset.php
index 45f6ecdfddfc6761620a90321f346fef0f65bda5..679dd368e928594bcdda080059a9d8384af82800 100644
--- a/modules/statistics/lib/Ruleset.php
+++ b/modules/statistics/lib/Ruleset.php
@@ -1,9 +1,13 @@
 <?php
+
+namespace SimpleSAML\Module\statistics;
+
 /*
  * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
  * @package SimpleSAMLphp
  */
-class sspmod_statistics_Ruleset
+
+class Ruleset
 {
     private $statconfig;
     private $availrulenames;
@@ -22,7 +26,6 @@ class sspmod_statistics_Ruleset
     private function init()
     {
         $statdir = $this->statconfig->getValue('statdir');
-        $inputfile = $this->statconfig->getValue('inputfile');
         $statrules = $this->statconfig->getValue('statrules');
         $timeres = $this->statconfig->getValue('timeres');
 
@@ -30,7 +33,7 @@ class sspmod_statistics_Ruleset
          * Walk through file lists, and get available [rule][fileslot]...
          */
         if (!is_dir($statdir)) {
-            throw new Exception('Statisics output directory [' . $statdir . '] does not exists.');
+            throw new \Exception('Statisics output directory [' . $statdir . '] does not exists.');
         }
         $filelist = scandir($statdir);
         $this->available = array();
@@ -43,7 +46,7 @@ class sspmod_statistics_Ruleset
             }
         }
         if (empty($this->available)) {
-            throw new Exception('No aggregated statistics files found in [' . $statdir . ']');
+            throw new \Exception('No aggregated statistics files found in [' . $statdir . ']');
         }
 
         /*
@@ -87,7 +90,7 @@ class sspmod_statistics_Ruleset
         $statrulesConfig = $this->statconfig->getConfigItem('statrules');
         $statruleConfig = $statrulesConfig->getConfigItem($rule);
 
-        $presenterClass = SimpleSAML\Module::resolveClass($statruleConfig->getValue('presenter', 'statistics:BaseRule'), 'Statistics_Rulesets');
+        $presenterClass = \SimpleSAML\Module::resolveClass($statruleConfig->getValue('presenter', 'statistics:BaseRule'), 'Statistics_Rulesets');
         $statrule = new $presenterClass($this->statconfig, $statruleConfig, $rule, $this->available);
         return $statrule;
     }
diff --git a/modules/statistics/lib/StatDataset.php b/modules/statistics/lib/StatDataset.php
index e21c78ad8caa23c3b89d2855ffe978cefbb1aa6e..7d890848c81863672acff24e629a18121790f53b 100644
--- a/modules/statistics/lib/StatDataset.php
+++ b/modules/statistics/lib/StatDataset.php
@@ -1,11 +1,13 @@
 <?php
 
+namespace SimpleSAML\Module\statistics;
 
 /**
  * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
  * @package SimpleSAMLphp
  */
-class sspmod_statistics_StatDataset
+
+class StatDataset
 {
     protected $statconfig;
     protected $ruleconfig;
@@ -29,8 +31,8 @@ class sspmod_statistics_StatDataset
      */
     public function __construct($statconfig, $ruleconfig, $ruleid, $timeres, $fileslot)
     {
-        assert($statconfig instanceof SimpleSAML_Configuration);
-        assert($ruleconfig instanceof SimpleSAML_Configuration);
+        assert($statconfig instanceof \SimpleSAML\Configuration);
+        assert($ruleconfig instanceof \SimpleSAML\Configuration);
         $this->statconfig = $statconfig;
         $this->ruleconfig = $ruleconfig;
 
@@ -44,9 +46,9 @@ class sspmod_statistics_StatDataset
         $this->delimiter = '_';
         $this->max = 0;
 
-        $this->datehandlerTick = new sspmod_statistics_DateHandler($this->statconfig->getValue('offset', 0));
+        $this->datehandlerTick = new DateHandler($this->statconfig->getValue('offset', 0));
         if ($this->timeresconfig->getValue('customDateHandler', 'default') === 'month') {
-            $this->datehandlerFile = new sspmod_statistics_DateHandlerMonth(0);
+            $this->datehandlerFile = new DateHandlerMonth(0);
         } else {
             $this->datehandlerFile = $this->datehandlerTick;
         }
@@ -89,7 +91,7 @@ class sspmod_statistics_StatDataset
             }
             $maxvalue = max($res[$this->delimiter], $maxvalue);
         }
-        $this->max = sspmod_statistics_Graph_GoogleCharts::roof($maxvalue);
+        $this->max = Graph\GoogleCharts::roof($maxvalue);
     }
 
     public function getDebugData()
@@ -183,7 +185,6 @@ class sspmod_statistics_StatDataset
     public function getAxis()
     {
         $slotsize = $this->timeresconfig->getValue('slot');
-        $dateformat_period = $this->timeresconfig->getValue('dateformat-period');
         $dateformat_intra = $this->timeresconfig->getValue('dateformat-intra');
         $axislabelint = $this->timeresconfig->getValue('axislabelint');
 
@@ -233,20 +234,20 @@ class sspmod_statistics_StatDataset
 
     public function getDelimiterPresentation()
     {
-        $config = SimpleSAML_Configuration::getInstance();
-        $t = new SimpleSAML_XHTML_Template($config, 'statistics:statistics.tpl.php');
+        $config = \SimpleSAML\Configuration::getInstance();
+        $t = new \SimpleSAML\XHTML\Template($config, 'statistics:statistics.tpl.php');
 
         $availdelimiters = $this->availDelimiters();
 
         // create a delimiter presentation filter for this rule...
         if ($this->ruleconfig->hasValue('fieldPresentation')) {
             $fieldpresConfig = $this->ruleconfig->getConfigItem('fieldPresentation');
-            $classname = SimpleSAML\Module::resolveClass(
+            $classname = \SimpleSAML\Module::resolveClass(
                 $fieldpresConfig->getValue('class'),
                 'Statistics_FieldPresentation'
             );
             if (!class_exists($classname)) {
-                throw new Exception('Could not find field presentation plugin ['.$classname.']: No class found');
+                throw new \Exception('Could not find field presentation plugin ['.$classname.']: No class found');
             }
             $presentationHandler = new $classname($availdelimiters, $fieldpresConfig->getValue('config'), $t);
 
@@ -277,20 +278,20 @@ class sspmod_statistics_StatDataset
     {
         $statdir = $this->statconfig->getValue('statdir');
         $resarray = array();
-        $rules = SimpleSAML\Utils\Arrays::arrayize($this->ruleid);
+        $rules = \SimpleSAML\Utils\Arrays::arrayize($this->ruleid);
         foreach ($rules as $rule) {
             // Get file and extract results.
             $resultFileName = $statdir.'/'.$rule.'-'.$this->timeres.'-'.$this->fileslot.'.stat';
             if (!file_exists($resultFileName)) {
-                throw new Exception('Aggregated statitics file ['.$resultFileName.'] not found.');
+                throw new \Exception('Aggregated statitics file ['.$resultFileName.'] not found.');
             }
             if (!is_readable($resultFileName)) {
-                throw new Exception('Could not read statitics file ['.$resultFileName.']. Bad file permissions?');
+                throw new \Exception('Could not read statitics file ['.$resultFileName.']. Bad file permissions?');
             }
             $resultfile = file_get_contents($resultFileName);
             $newres = unserialize($resultfile);
             if (empty($newres)) {
-                throw new Exception('Aggregated statistics in file ['.$resultFileName.'] was empty.');
+                throw new \Exception('Aggregated statistics in file ['.$resultFileName.'] was empty.');
             }
             $resarray[] = $newres;
         }
@@ -304,6 +305,5 @@ class sspmod_statistics_StatDataset
         }
         $this->results = $combined;
     }
-
 }
 
diff --git a/modules/statistics/lib/Statistics/FieldPresentation/Base.php b/modules/statistics/lib/Statistics/FieldPresentation/Base.php
index e02300094bccf70260f34f27eafac8b0382c443a..591892b79871192d787c38acb4577ff8605bb49b 100644
--- a/modules/statistics/lib/Statistics/FieldPresentation/Base.php
+++ b/modules/statistics/lib/Statistics/FieldPresentation/Base.php
@@ -1,12 +1,14 @@
 <?php
 
-class sspmod_statistics_Statistics_FieldPresentation_Base
+namespace SimpleSAML\Module\statistics\Statistics\FieldPresentation;
+
+class Base
 {
     protected $fields;
     protected $template;
     protected $config;
 
-    function __construct($fields, $config, $template)
+    public function __construct($fields, $config, $template)
     {
         $this->fields = $fields;
         $this->template = $template;
diff --git a/modules/statistics/lib/Statistics/FieldPresentation/Entity.php b/modules/statistics/lib/Statistics/FieldPresentation/Entity.php
index 6a71fa5a76758f71feee5eca6f8002c68d3e5d7c..15b4809cb068e5ee09a6fb8cfbe6fd8a741abe5a 100644
--- a/modules/statistics/lib/Statistics/FieldPresentation/Entity.php
+++ b/modules/statistics/lib/Statistics/FieldPresentation/Entity.php
@@ -1,10 +1,12 @@
 <?php
 
-class sspmod_statistics_Statistics_FieldPresentation_Entity extends sspmod_statistics_Statistics_FieldPresentation_Base
+namespace SimpleSAML\Module\statistics\Statistics\FieldPresentation;
+
+class Entity extends Base
 {
     public function getPresentation()
     {
-        $mh = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+        $mh = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
         $metadata = $mh->getList($this->config);
 
         $translation = array('_' => 'All services');
diff --git a/modules/statistics/lib/Statistics/Rulesets/BaseRule.php b/modules/statistics/lib/Statistics/Rulesets/BaseRule.php
index 99b2254fdaca026704a513d2fef0c9af7c248d7b..6841861ba82c159fa05f7e4b9900100ed5e23ed1 100644
--- a/modules/statistics/lib/Statistics/Rulesets/BaseRule.php
+++ b/modules/statistics/lib/Statistics/Rulesets/BaseRule.php
@@ -1,9 +1,13 @@
 <?php
+
+namespace SimpleSAML\Module\statistics\Statistics\Rulesets;
+
 /*
  * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
  * @package SimpleSAMLphp
  */
-class sspmod_statistics_Statistics_Rulesets_BaseRule
+
+class BaseRule
 {
     protected $statconfig;
     protected $ruleconfig;
@@ -15,8 +19,8 @@ class sspmod_statistics_Statistics_Rulesets_BaseRule
      */
     public function __construct($statconfig, $ruleconfig, $ruleid, $available)
     {
-        assert($statconfig instanceof SimpleSAML_Configuration);
-        assert($ruleconfig instanceof SimpleSAML_Configuration);
+        assert($statconfig instanceof \SimpleSAML\Configuration);
+        assert($ruleconfig instanceof \SimpleSAML\Configuration);
         $this->statconfig = $statconfig;
         $this->ruleconfig = $ruleconfig;
         $this->ruleid = $ruleid;
@@ -49,9 +53,9 @@ class sspmod_statistics_Statistics_Rulesets_BaseRule
         $timeresConfig = $timeresConfigs[$timeres];
 
         if (isset($timeresConfig['customDateHandler']) && $timeresConfig['customDateHandler'] == 'month') {
-            $datehandler = new sspmod_statistics_DateHandlerMonth(0);
+            $datehandler = new \SimpleSAML\Module\statistics\DateHandlerMonth(0);
         } else {
-            $datehandler = new sspmod_statistics_DateHandler($this->statconfig->getValue('offset', 0));
+            $datehandler = new \SimpleSAML\Module\statistics\DateHandler($this->statconfig->getValue('offset', 0));
         }
 
         /*
@@ -112,7 +116,7 @@ class sspmod_statistics_Statistics_Rulesets_BaseRule
     {
         $timeres = $this->resolveTimeRes($preferTimeRes);
         $fileslot = $this->resolveFileSlot($timeres, $preferTime);
-        $dataset = new sspmod_statistics_StatDataset($this->statconfig, $this->ruleconfig, $this->ruleid, $timeres, $fileslot);
+        $dataset = new \SimpleSAML\Module\statistics\StatDataset($this->statconfig, $this->ruleconfig, $this->ruleid, $timeres, $fileslot);
         return $dataset;
     }
 }
diff --git a/modules/statistics/lib/Statistics/Rulesets/Ratio.php b/modules/statistics/lib/Statistics/Rulesets/Ratio.php
index ceb0ff3d42ed773c205608ecac7d7a65cdcd9c56..89d9f1c78fbeaf796627e3e110b2150361f4d8b0 100644
--- a/modules/statistics/lib/Statistics/Rulesets/Ratio.php
+++ b/modules/statistics/lib/Statistics/Rulesets/Ratio.php
@@ -1,9 +1,13 @@
 <?php
+
+namespace SimpleSAML\Module\statistics\Statistics\Rulesets;
+
 /*
  * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
  * @package SimpleSAMLphp
  */
-class sspmod_statistics_Statistics_Rulesets_Ratio extends sspmod_statistics_Statistics_Rulesets_BaseRule
+
+class Ratio extends BaseRule
 {
     protected $refrule1;
     protected $refrule2;
@@ -13,8 +17,8 @@ class sspmod_statistics_Statistics_Rulesets_Ratio extends sspmod_statistics_Stat
      */
     public function __construct($statconfig, $ruleconfig, $ruleid, $available)
     {
-        assert($statconfig instanceof SimpleSAML_Configuration);
-        assert($ruleconfig instanceof SimpleSAML_Configuration);
+        assert($statconfig instanceof \SimpleSAML\Configuration);
+        assert($ruleconfig instanceof \SimpleSAML\Configuration);
 
         parent::__construct($statconfig, $ruleconfig, $ruleid, $available);
 
@@ -25,8 +29,8 @@ class sspmod_statistics_Statistics_Rulesets_Ratio extends sspmod_statistics_Stat
         $statruleConfig1 = $statrulesConfig->getConfigItem($refNames[0]);
         $statruleConfig2 = $statrulesConfig->getConfigItem($refNames[1]);
 
-        $this->refrule1 = new sspmod_statistics_Statistics_Rulesets_BaseRule($this->statconfig, $statruleConfig1, $refNames[0], $available);
-        $this->refrule2 = new sspmod_statistics_Statistics_Rulesets_BaseRule($this->statconfig, $statruleConfig2, $refNames[1], $available);
+        $this->refrule1 = new BaseRule($this->statconfig, $statruleConfig1, $refNames[0], $available);
+        $this->refrule2 = new BaseRule($this->statconfig, $statruleConfig2, $refNames[1], $available);
     }
 
     public function availableTimeRes()
@@ -61,7 +65,7 @@ class sspmod_statistics_Statistics_Rulesets_Ratio extends sspmod_statistics_Stat
 
         $refNames = $this->ruleconfig->getArray('ref');
 
-        $dataset = new sspmod_statistics_RatioDataset($this->statconfig, $this->ruleconfig, $refNames, $timeres, $fileslot);
+        $dataset = new \SimpleSAML\Module\statistics\RatioDataset($this->statconfig, $this->ruleconfig, $refNames, $timeres, $fileslot);
         return $dataset;
     }
 }
diff --git a/modules/statistics/templates/statistics.tpl.php b/modules/statistics/templates/statistics.tpl.php
index fa7e1f4e93a8c31c8d0fabbf8f76047a4d9455a9..673070d79e83de5b8b713d72a48655c6ca503b1b 100644
--- a/modules/statistics/templates/statistics.tpl.php
+++ b/modules/statistics/templates/statistics.tpl.php
@@ -19,38 +19,42 @@ echo '<tr><td class="selecttime_icon"><img src="' . SimpleSAML\Utils\HTTP::getBa
 echo '<td>';
 echo '<form action="#">';
 echo $this->data['post_rule'];
-echo '<select onchange="submit();" name="rule">';
-foreach ($this->data['available.rules'] as $key => $rule) {
-    if ($key === $this->data['selected.rule']) {
-        echo '<option selected="selected" value="' . $key . '">' . $rule['name'] . '</option>';
-    } else {
-        echo '<option value="' . $key . '">' . $rule['name'] . '</option>';
+if (!empty($this->data['available.rules'])) {
+    echo '<select onchange="submit();" name="rule">';
+    foreach ($this->data['available.rules'] as $key => $rule) {
+        if ($key === $this->data['selected.rule']) {
+            echo '<option selected="selected" value="' . $key . '">' . $rule['name'] . '</option>';
+        } else {
+            echo '<option value="' . $key . '">' . $rule['name'] . '</option>';
+        }
     }
+    echo '</select>';
 }
-echo '</select></form>';
-echo '</td>';
+echo '</form></td>';
 
 // Select delimiter
 echo '<td class="td_right">';
 echo '<form action="#">';
 echo $this->data['post_d'];
-echo '<select onchange="submit();" name="d">';
-foreach ($this->data['availdelimiters'] as $key => $delim) {
-    $delimName = $delim;
-    if (array_key_exists($delim, $this->data['delimiterPresentation'])) {
-        $delimName = $this->data['delimiterPresentation'][$delim];
-    }
-
-    if ($key == '_') {
-        echo '<option value="_">Total</option>';
-    } elseif (isset($_REQUEST['d']) && $delim == $_REQUEST['d']) {
-        echo '<option selected="selected" value="' . htmlspecialchars($delim) . '">' . htmlspecialchars($delimName) . '</option>';
-    } else {
-        echo '<option  value="' . htmlspecialchars($delim) . '">' . htmlspecialchars($delimName) . '</option>';
+if(!empty($this->data['availdelimiters'])) {
+    echo '<select onchange="submit();" name="d">';
+    foreach ($this->data['availdelimiters'] as $key => $delim) {
+        $delimName = $delim;
+        if (array_key_exists($delim, $this->data['delimiterPresentation'])) {
+            $delimName = $this->data['delimiterPresentation'][$delim];
+        }
+
+        if ($key == '_') {
+            echo '<option value="_">Total</option>';
+        } elseif (isset($_REQUEST['d']) && $delim == $_REQUEST['d']) {
+            echo '<option selected="selected" value="' . htmlspecialchars($delim) . '">' . htmlspecialchars($delimName) . '</option>';
+        } else {
+            echo '<option  value="' . htmlspecialchars($delim) . '">' . htmlspecialchars($delimName) . '</option>';
+        }
     }
+    echo '</select>';
 }
-echo '</select></form>';
-echo '</td></tr>';
+echo '</form></td></tr>';
 
 echo '</table>';
 
@@ -70,30 +74,34 @@ if (isset($this->data['available.times.prev'])) {
 echo '<td class="td_right">';
 echo '<form action="#">';
 echo $this->data['post_res'];
-echo '<select onchange="submit();" name="res">';
-foreach ($this->data['available.timeres'] as $key => $timeresname) {
-    if ($key == $this->data['selected.timeres']) {
-        echo '<option selected="selected" value="' . $key . '">' . $timeresname . '</option>';
-    } else {
-        echo '<option  value="' . $key . '">' . $timeresname . '</option>';
+if (!empty($this->data['available.timeres'])) {
+    echo '<select onchange="submit();" name="res">';
+    foreach ($this->data['available.timeres'] as $key => $timeresname) {
+        if ($key == $this->data['selected.timeres']) {
+            echo '<option selected="selected" value="' . $key . '">' . $timeresname . '</option>';
+        } else {
+            echo '<option  value="' . $key . '">' . $timeresname . '</option>';
+        }
     }
+    echo '</select>';
 }
-echo '</select></form>';
-echo '</td>';
+echo '</form></td>';
 
 echo '<td class="td_left">';
 echo '<form action="#">';
 echo $this->data['post_time'];
-echo '<select onchange="submit();" name="time">';
-foreach ($this->data['available.times'] as $key => $timedescr) {
-    if ($key == $this->data['selected.time']) {
-        echo '<option selected="selected" value="' . $key . '">' . $timedescr . '</option>';
-    } else {
-        echo '<option  value="' . $key . '">' . $timedescr . '</option>';
+if (!empty($this->data['available.times'])) {
+    echo '<select onchange="submit();" name="time">';
+    foreach ($this->data['available.times'] as $key => $timedescr) {
+        if ($key == $this->data['selected.time']) {
+            echo '<option selected="selected" value="' . $key . '">' . $timedescr . '</option>';
+        } else {
+            echo '<option  value="' . $key . '">' . $timedescr . '</option>';
+        }
     }
+    echo '</select>';
 }
-echo '</select></form>';
-echo '</td>';
+echo '</form></td>';
 
 if (isset($this->data['available.times.next'])) {
     echo '<td class="td_right td_next_right"><a href="' . $this->data['get_times_next'] . '">Next »</a></td>';
@@ -102,94 +110,96 @@ if (isset($this->data['available.times.next'])) {
 }
 
 echo '</tr></table>';
-
-
-echo '<div id="tabdiv"><ul class="tabset_tabs">
-   <li><a href="#graph">Graph</a></li>
-   <li><a href="#table">Summary table</a></li>
-   <li><a href="#debug">Time serie</a></li>
-</ul>';
-echo '
-
-<div id="graph" class="tabset_content">';
-
-echo '<img src="' . htmlspecialchars($this->data['imgurl']) . '" alt="Graph" />';
-
-echo '<form action="#">';
-echo '<p class="p_right">Compare with total from this dataset ';
-echo $this->data['post_rule2'];
-echo '<select onchange="submit();" name="rule2">';
-echo '	<option value="_">None</option>';
-foreach ($this->data['available.rules'] as $key => $rule) {
-    if ($key === $this->data['selected.rule2']) {
-        echo '<option selected="selected" value="' . $key . '">' . $rule['name'] . '</option>';
-    } else {
-        echo '<option value="' . $key . '">' . $rule['name'] . '</option>';
+echo '<div id="tabdiv">';
+if (!empty($this->data['results'])){
+    echo '<ul class="tabset_tabs">
+       <li><a href="#graph">Graph</a></li>
+       <li><a href="#table">Summary table</a></li>
+       <li><a href="#debug">Time serie</a></li>
+    </ul>';
+    echo '
+
+    <div id="graph" class="tabset_content">';
+
+    echo '<img src="' . htmlspecialchars($this->data['imgurl']) . '" alt="Graph" />';
+
+    echo '<form action="#">';
+    echo '<p class="p_right">Compare with total from this dataset ';
+    echo $this->data['post_rule2'];
+    echo '<select onchange="submit();" name="rule2">';
+    echo '	<option value="_">None</option>';
+    foreach ($this->data['available.rules'] as $key => $rule) {
+        if ($key === $this->data['selected.rule2']) {
+            echo '<option selected="selected" value="' . $key . '">' . $rule['name'] . '</option>';
+        } else {
+            echo '<option value="' . $key . '">' . $rule['name'] . '</option>';
+        }
     }
-}
-echo '</select></p></form>';
+    echo '</select></p></form>';
 
-echo '</div>'; // end graph content.
+    echo '</div>'; // end graph content.
 
+    /**
+     * Handle table view - - - - - - 
+     */
+    $classint = array('odd', 'even'); $i = 0;
+    echo '<div id="table" class="tabset_content">';
 
-/**
- * Handle table view - - - - - - 
- */
-$classint = array('odd', 'even'); $i = 0;
-echo '<div id="table" class="tabset_content">';
-
-if (isset($this->data['pieimgurl'])) {
-    echo '<img src="' . $this->data['pieimgurl'] . '" alt="Pie chart" />';
-}
-echo '<table class="tableview"><tr><th class="value">Value</th><th class="category">Data range</th></tr>';
-
-foreach ($this->data['summaryDataset'] as $key => $value) {
-    $clint = $classint[$i++ % 2];
-
-    $keyName = $key;
-    if (array_key_exists($key, $this->data['delimiterPresentation'])) {
-        $keyName = $this->data['delimiterPresentation'][$key];
+    if (isset($this->data['pieimgurl'])) {
+        echo '<img src="' . $this->data['pieimgurl'] . '" alt="Pie chart" />';
     }
+    echo '<table class="tableview"><tr><th class="value">Value</th><th class="category">Data range</th></tr>';
 
-    if ($key === '_') {
-        echo '<tr class="total '  . $clint . '"><td  class="value">' . $value . '</td><td class="category">' . $keyName . '</td></tr>';
-    } else {
-        echo '<tr class="' . $clint . '"><td  class="value">' . $value . '</td><td class="category">' . $keyName . '</td></tr>';
-    }
-}
+    foreach ($this->data['summaryDataset'] as $key => $value) {
+        $clint = $classint[$i++ % 2];
 
-echo '</table></div>';
-//  - - - - - - - End table view - - - - - - - 
+        $keyName = $key;
+        if (array_key_exists($key, $this->data['delimiterPresentation'])) {
+            $keyName = $this->data['delimiterPresentation'][$key];
+        }
 
-echo '<div id="debug" >';
-echo '<table class="timeseries">';
-echo '<tr><th>Time</th><th>Total</th>';
-foreach ($this->data['topdelimiters'] as $key) {
-    $keyName = $key;
-    if (array_key_exists($key, $this->data['delimiterPresentation'])) {
-        $keyName = $this->data['delimiterPresentation'][$key];
+        if ($key === '_') {
+            echo '<tr class="total '  . $clint . '"><td  class="value">' . $value . '</td><td class="category">' . $keyName . '</td></tr>';
+        } else {
+            echo '<tr class="' . $clint . '"><td  class="value">' . $value . '</td><td class="category">' . $keyName . '</td></tr>';
+        }
     }
-    echo'<th>' . $keyName . '</th>';
-}
-echo '</tr>';
-
 
-$i = 0;
-foreach ($this->data['debugdata'] as $slot => $dd) {
-    echo '<tr class="' . ((++$i % 2) == 0 ? 'odd' : 'even') . '">';
-    echo '<td>' . $dd[0] . '</td>';
-    echo '<td class="datacontent">' . $dd[1] . '</td>';
+    echo '</table></div>';
+    //  - - - - - - - End table view - - - - - - - 
 
+    echo '<div id="debug" >';
+    echo '<table class="timeseries">';
+    echo '<tr><th>Time</th><th>Total</th>';
     foreach ($this->data['topdelimiters'] as $key) {
-        echo '<td class="datacontent">' . (array_key_exists($key, $this->data['results'][$slot]) ?
-            $this->data['results'][$slot][$key] : '&nbsp;') . '</td>';
+        $keyName = $key;
+        if (array_key_exists($key, $this->data['delimiterPresentation'])) {
+            $keyName = $this->data['delimiterPresentation'][$key];
+        }
+        echo'<th>' . $keyName . '</th>';
     }
     echo '</tr>';
-}
-echo '</table>';
+
+    $i = 0;
+    foreach ($this->data['debugdata'] as $slot => $dd) {
+        echo '<tr class="' . ((++$i % 2) == 0 ? 'odd' : 'even') . '">';
+        echo '<td>' . $dd[0] . '</td>';
+        echo '<td class="datacontent">' . $dd[1] . '</td>';
+
+        foreach ($this->data['topdelimiters'] as $key) {
+            echo '<td class="datacontent">' . (array_key_exists($key, $this->data['results'][$slot]) ?
+                $this->data['results'][$slot][$key] : '&nbsp;') . '</td>';
+        }
+        echo '</tr>';
+    }
+    echo '</table>';
 
 
-echo '</div>'; // End debug tab content
+    echo '</div>'; // End debug tab content
+} else {
+    echo '<h4 align="center">'.$this->data['error'].'</h4>';
+    echo '<p align="center"><a href="showstats.php">Clear selection</a></p>';
+}
 echo '</div>'; // End tab div
 
 $this->includeAtTemplateBase('includes/footer.php');
diff --git a/modules/statistics/www/showstats.php b/modules/statistics/www/showstats.php
index 559d35afbde7f8144434ecee9aad9f35833d4288..c160026d2035e9510897e58d7d468fc71375dbe0 100644
--- a/modules/statistics/www/showstats.php
+++ b/modules/statistics/www/showstats.php
@@ -1,10 +1,10 @@
 <?php
 
-$config = SimpleSAML_Configuration::getInstance();
-$statconfig = SimpleSAML_Configuration::getConfig('module_statistics.php');
-$session = SimpleSAML_Session::getSessionFromRequest();
+$config = \SimpleSAML\Configuration::getInstance();
+$statconfig = \SimpleSAML\Configuration::getConfig('module_statistics.php');
+$session = \SimpleSAML\Session::getSessionFromRequest();
 
-sspmod_statistics_AccessCheck::checkAccess($statconfig);
+\SimpleSAML\Module\statistics\AccessCheck::checkAccess($statconfig);
 
 /*
  * Check input parameters
@@ -39,12 +39,39 @@ if ($preferRule2 === '_') {
 /*
  * Create statistics data.
  */
-$ruleset = new sspmod_statistics_Ruleset($statconfig);
+$ruleset = new \SimpleSAML\Module\statistics\Ruleset($statconfig);
 $statrule = $ruleset->getRule($preferRule);
 $rule = $statrule->getRuleID();
 
-$dataset = $statrule->getDataset($preferTimeRes, $preferTime);
-$dataset->setDelimiter($delimiter);
+$t = new \SimpleSAML\XHTML\Template($config, 'statistics:statistics.tpl.php');
+$t->data['pageid'] = 'statistics';
+$t->data['header'] = 'stat';
+$t->data['available.rules'] = $ruleset->availableRulesNames();
+$t->data['selected.rule'] = $rule;
+$t->data['selected.rule2'] = $preferRule2;
+
+try {
+    $dataset = $statrule->getDataset($preferTimeRes, $preferTime);
+    $dataset->setDelimiter($delimiter);
+    $dataset->aggregateSummary();
+    $dataset->calculateMax();
+
+    if (array_key_exists('output', $_REQUEST) && $_REQUEST['output'] === 'csv') {
+        header('Content-type: text/csv');
+        header('Content-Disposition: attachment; filename="simplesamlphp-data.csv"');
+        $data = $dataset->getDebugData();
+        foreach ($data as $de) {
+            if (isset($de[1])) {
+                echo '"'.$de[0].'",'.$de[1]."\n";
+            }
+        }
+        exit;
+    }
+} catch (\Exception $e) {
+    $t->data['error'] = "No data available";
+    $t->show();
+    exit;
+}
 
 $delimiter = $dataset->getDelimiter();
 
@@ -54,9 +81,6 @@ $availableFileSlots = $statrule->availableFileSlots($timeres);
 
 $timeNavigation = $statrule->getTimeNavigation($timeres, $preferTime);
 
-$dataset->aggregateSummary();
-$dataset->calculateMax();
-
 $piedata = $dataset->getPieData();
 
 $datasets = array();
@@ -70,37 +94,29 @@ $maxes[] = $dataset->getMax();
 
 if (isset($preferRule2)) {
     $statrule = $ruleset->getRule($preferRule2);
-    $dataset2 = $statrule->getDataset($preferTimeRes, $preferTime);
-    $dataset2->aggregateSummary();
-    $dataset2->calculateMax();
-
-    $datasets[] = $dataset2->getPercentValues();
-    $maxes[] = $dataset2->getMax();
+    try {
+        $dataset2 = $statrule->getDataset($preferTimeRes, $preferTime);
+        $dataset2->aggregateSummary();
+        $dataset2->calculateMax();
+
+        $datasets[] = $dataset2->getPercentValues();
+        $maxes[] = $dataset2->getMax();
+    } catch (\Exception $e) {
+        $t->data['error'] = "No data available to compare";
+        $t->show();
+        exit;
+    }
 }
 
 $dimx = $statconfig->getValue('dimension.x', 800);
 $dimy = $statconfig->getValue('dimension.y', 350);
-$grapher = new sspmod_statistics_Graph_GoogleCharts($dimx, $dimy);
-
-if (array_key_exists('output', $_REQUEST) && $_REQUEST['output'] === 'csv') {
-    header('Content-type: text/csv');
-    header('Content-Disposition: attachment; filename="simplesamlphp-data.csv"');
-    $data = $dataset->getDebugData();
-    foreach ($data as $de) {
-        if (isset($de[1])) {
-            echo '"' . $de[0] . '",' . $de[1] . "\n";
-        }
-    }
-    exit;
-}
+$grapher = new \SimpleSAML\Module\statistics\Graph\GoogleCharts($dimx, $dimy);
 
-$t = new SimpleSAML_XHTML_Template($config, 'statistics:statistics.tpl.php');
-$t->data['pageid'] = 'statistics';
-$t->data['header'] = 'stat';
 $t->data['imgurl'] = $grapher->show($axis['axis'], $axis['axispos'], $datasets, $maxes);
 if (isset($piedata)) {
-    $t->data['pieimgurl'] = $grapher->showPie( $dataset->getDelimiterPresentationPie(), $piedata);
+    $t->data['pieimgurl'] = $grapher->showPie($dataset->getDelimiterPresentationPie(), $piedata);
 }
+
 $t->data['available_rules'] = $ruleset->availableRulesNames();
 $t->data['available_times'] = $statrule->availableFileSlots($timeres);
 $t->data['available_timeres'] = $statrule->availableTimeRes();
@@ -122,6 +138,7 @@ $t->data['topdelimiters'] = $dataset->getTopDelimiters();
 $t->data['availdelimiters'] = $dataset->availDelimiters();
 
 $t->data['delimiterPresentation'] = $dataset->getDelimiterPresentation();
+
 $t->data['post_rule'] = getBaseURL($t, 'post', 'rule');
 $t->data['post_rule2'] = getBaseURL($t, 'post', 'rule2');
 $t->data['post_d'] = getBaseURL($t, 'post', 'd');
@@ -158,7 +175,7 @@ function getBaseURL($t, $type = 'get', $key = null, $value = null)
     }
 
     if ($type === 'get') {
-        return SimpleSAML\Module::getModuleURL("statistics/showstats.php") . '?' . http_build_query($vars, '', '&');
+        return \SimpleSAML\Module::getModuleURL("statistics/showstats.php").'?'.http_build_query($vars, '', '&amp;');
     }
     return $vars;
 }
diff --git a/modules/statistics/www/statmeta.php b/modules/statistics/www/statmeta.php
index 91a5fe4aa4ad7bdb04884594f1b671250864c7f5..442723d0bd8961c0ab94b85bc2db59167fed57a8 100644
--- a/modules/statistics/www/statmeta.php
+++ b/modules/statistics/www/statmeta.php
@@ -1,15 +1,15 @@
 <?php
 
-$config = SimpleSAML_Configuration::getInstance();
-$statconfig = SimpleSAML_Configuration::getConfig('module_statistics.php');
+$config = \SimpleSAML\Configuration::getInstance();
+$statconfig = \SimpleSAML\Configuration::getConfig('module_statistics.php');
 
-sspmod_statistics_AccessCheck::checkAccess($statconfig);
+\SimpleSAML\Module\statistics\AccessCheck::checkAccess($statconfig);
 
-$aggr = new sspmod_statistics_Aggregator();
+$aggr = new \SimpleSAML\Module\statistics\Aggregator();
 $aggr->loadMetadata();
 $metadata = $aggr->getMetadata();
 
-$t = new SimpleSAML_XHTML_Template($config, 'statistics:statmeta.tpl.php');
+$t = new \SimpleSAML\XHTML\Template($config, 'statistics:statmeta.tpl.php');
 
 if ($metadata !== null) {
     if (in_array('lastrun', $metadata, true)) {
diff --git a/psalm.xml b/psalm.xml
index 575f74033ee2f2ee3b0c63ed984e962d179ac302..0ccc8b80b8654966efad5c3df94f7d520c6dc7d9 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -23,6 +23,8 @@
 
         <PropertyNotSetInConstructor errorLevel="info" />
         <MissingConstructor errorLevel="info" />
+        <MissingClosureParamType errorLevel="info" />
+        <MissingParamType errorLevel="info" />
         <UnusedClass errorLevel="info" />
         <PossiblyUnusedMethod errorLevel="info" />
         <UntypedParam errorLevel="info" />
diff --git a/templates/includes/attributes.php b/templates/includes/attributes.php
index 79aae3130d4579957302e6f23983a796c63a7ec4..98e6abe3147b2decc9e89918a7bede70b3ac32f5 100644
--- a/templates/includes/attributes.php
+++ b/templates/includes/attributes.php
@@ -51,7 +51,7 @@ function present_eptid(\SimpleSAML\Locale\Translate $t, \SAML2\XML\saml\NameID $
     return '<td class="attrvalue">'.present_assoc($eptid);
 }
 
-function present_attributes(SimpleSAML_XHTML_Template $t, $attributes, $nameParent)
+function present_attributes(\SimpleSAML\XHTML\Template $t, $attributes, $nameParent)
 {
     $alternate = array('odd', 'even');
     $i = 0;
@@ -100,11 +100,11 @@ function present_attributes(SimpleSAML_XHTML_Template $t, $attributes, $namePare
                         '" /></td></tr>';
                 } elseif (is_a($value[0], 'DOMNodeList')) {
                     // try to see if we have a NameID here
-                    /** @var DOMNodeList $value [0] */
+                    /** @var \DOMNodeList $value [0] */
                     $n = $value[0]->length;
                     for ($idx = 0; $idx < $n; $idx++) {
                         $elem = $value[0]->item($idx);
-                        /* @var DOMElement $elem */
+                        /* @var \DOMElement $elem */
                         if (!($elem->localName === 'NameID' && $elem->namespaceURI === \SAML2\Constants::NS_SAML)) {
                             continue;
                         }
diff --git a/templates/includes/footer.php b/templates/includes/footer.php
index 0ca7e12c1166440517eb477a77f83541b26e6987..94e62f7c0fbae60fd42d5ecb092a4327e2cc26e7 100644
--- a/templates/includes/footer.php
+++ b/templates/includes/footer.php
@@ -10,7 +10,7 @@ if(!empty($this->data['htmlinject']['htmlContentPost'])) {
 		<hr />
 
 		<img src="/<?php echo $this->data['baseurlpath']; ?>resources/icons/ssplogo-fish-small.png" alt="Small fish logo" style="float: right" />		
-		Copyright &copy; 2007-2017 <a href="http://uninett.no/">UNINETT AS</a>
+		Copyright &copy; 2007-2018 <a href="http://uninett.no/">UNINETT AS</a>
 		
 		<br style="clear: right" />
 	
diff --git a/templates/includes/header.php b/templates/includes/header.php
index f95e6c62dbc70cc1d2440bf4b50612d0307337d3..1144bcd6e1b38050e706c853de3f457c143f0142 100644
--- a/templates/includes/header.php
+++ b/templates/includes/header.php
@@ -5,26 +5,28 @@
 /**
  * Support the htmlinject hook, which allows modules to change header, pre and post body on all pages.
  */
-$this->data['htmlinject'] = array(
-	'htmlContentPre' => array(),
-	'htmlContentPost' => array(),
-	'htmlContentHead' => array(),
-);
+$this->data['htmlinject'] = [
+    'htmlContentPre' => [],
+    'htmlContentPost' => [],
+    'htmlContentHead' => [],
+];
 
 
-$jquery = array();
-if (array_key_exists('jquery', $this->data)) $jquery = $this->data['jquery'];
+$jquery = [];
+if (array_key_exists('jquery', $this->data)) {
+    $jquery = $this->data['jquery'];
+}
 
 if (array_key_exists('pageid', $this->data)) {
-	$hookinfo = array(
-		'pre' => &$this->data['htmlinject']['htmlContentPre'], 
-		'post' => &$this->data['htmlinject']['htmlContentPost'], 
-		'head' => &$this->data['htmlinject']['htmlContentHead'], 
-		'jquery' => &$jquery, 
-		'page' => $this->data['pageid']
-	);
-		
-	SimpleSAML\Module::callHooks('htmlinject', $hookinfo);
+    $hookinfo = [
+        'pre' => &$this->data['htmlinject']['htmlContentPre'],
+        'post' => &$this->data['htmlinject']['htmlContentPost'],
+        'head' => &$this->data['htmlinject']['htmlContentHead'],
+        'jquery' => &$jquery,
+        'page' => $this->data['pageid']
+    ];
+        
+    SimpleSAML\Module::callHooks('htmlinject', $hookinfo);
 }
 // - o - o - o - o - o - o - o - o - o - o - o - o -
 
@@ -46,170 +48,180 @@ header('X-Frame-Options: SAMEORIGIN');
 <meta name="viewport" content="initial-scale=1.0" />
 <script type="text/javascript" src="/<?php echo $this->data['baseurlpath']; ?>assets/js/src/script.js"></script>
 <title><?php
-if(array_key_exists('header', $this->data)) {
-	echo $this->data['header'];
+if (array_key_exists('header', $this->data)) {
+    echo $this->data['header'];
 } else {
-	echo 'SimpleSAMLphp';
+    echo 'SimpleSAMLphp';
 }
 ?></title>
 
-	<link rel="stylesheet" type="text/css" href="/<?php echo $this->data['baseurlpath']; ?>resources/default.css" />
-	<link rel="icon" type="image/icon" href="/<?php echo $this->data['baseurlpath']; ?>resources/icons/favicon.ico" />
+    <link rel="stylesheet" type="text/css" href="/<?php echo $this->data['baseurlpath']; ?>resources/default.css" />
+    <link rel="icon" type="image/icon" href="/<?php echo $this->data['baseurlpath']; ?>resources/icons/favicon.ico" />
 
 <?php
 
-if(!empty($jquery)) {
-	$version = '1.8';
-	if (array_key_exists('version', $jquery))
-		$version = $jquery['version'];
-		
-	if ($version == '1.8') {
-		if (isset($jquery['core']) && $jquery['core'])
-			echo('<script type="text/javascript" src="/' . $this->data['baseurlpath'] . 'resources/jquery-1.8.js"></script>' . "\n");
-	
-		if (isset($jquery['ui']) && $jquery['ui'])
-			echo('<script type="text/javascript" src="/' . $this->data['baseurlpath'] . 'resources/jquery-ui-1.8.js"></script>' . "\n");
-	
-		if (isset($jquery['css']) && $jquery['css'])
-			echo('<link rel="stylesheet" media="screen" type="text/css" href="/' . $this->data['baseurlpath'] . 
-				'resources/uitheme1.8/jquery-ui.css" />' . "\n");
-	}
+if (!empty($jquery)) {
+    $version = '1.8';
+    if (array_key_exists('version', $jquery)) {
+        $version = $jquery['version'];
+    }
+
+    if ($version == '1.8') {
+        if (isset($jquery['core']) && $jquery['core']) {
+            echo('<script type="text/javascript" src="/' . $this->data['baseurlpath'] . 'resources/jquery-1.8.js"></script>' . "\n");
+        }
+
+        if (isset($jquery['ui']) && $jquery['ui']) {
+            echo('<script type="text/javascript" src="/' . $this->data['baseurlpath'] . 'resources/jquery-ui-1.8.js"></script>' . "\n");
+        }
+
+        if (isset($jquery['css']) && $jquery['css']) {
+            echo('<link rel="stylesheet" media="screen" type="text/css" href="/' . $this->data['baseurlpath'] .
+                'resources/uitheme1.8/jquery-ui.css" />' . "\n");
+        }
+    }
 }
 
-if (isset($this->data['clipboard.js'])) {
-	echo '<script type="text/javascript" src="/'. $this->data['baseurlpath'] .
-		 'assets/js/lib/clipboard.min.js"></script>'."\n";
+if (isset($this->data['clipboard.js'])) { =======
+    echo '<script type="text/javascript" src="/' . $this->data['baseurlpath'] .
+         'resources/clipboard.min.js"></script>' . "\n";
 }
 
-if(!empty($this->data['htmlinject']['htmlContentHead'])) {
-	foreach($this->data['htmlinject']['htmlContentHead'] AS $c) {
-		echo $c;
-	}
+if (!empty($this->data['htmlinject']['htmlContentHead'])) {
+    foreach ($this->data['htmlinject']['htmlContentHead'] as $c) {
+        echo $c;
+    }
 }
 
 
 
 
 if ($this->isLanguageRTL()) {
-?>
-	<link rel="stylesheet" type="text/css" href="/<?php echo $this->data['baseurlpath']; ?>assets/css/src/default-rtl.css" />
-<?php	
+    ?>
+    <link rel="stylesheet" type="text/css" href="/<?php echo $this->data['baseurlpath']; ?>resources/default-rtl.css" />
+<?php
 }
 ?>
 
-	
-	<meta name="robots" content="noindex, nofollow" />
-	
 
-<?php	
-if(array_key_exists('head', $this->data)) {
-	echo '<!-- head -->' . $this->data['head'] . '<!-- /head -->';
+    <meta name="robots" content="noindex, nofollow" />
+
+
+<?php
+if (array_key_exists('head', $this->data)) {
+    echo '<!-- head -->' . $this->data['head'] . '<!-- /head -->';
 }
 ?>
 </head>
 <?php
 $onLoad = '';
-if(array_key_exists('autofocus', $this->data)) {
-	$onLoad .= 'SimpleSAML_focus(\'' . $this->data['autofocus'] . '\');';
+if (array_key_exists('autofocus', $this->data)) {
+    $onLoad .= 'SimpleSAML_focus(\'' . $this->data['autofocus'] . '\');';
 }
 if (isset($this->data['onLoad'])) {
-	$onLoad .= $this->data['onLoad']; 
+    $onLoad .= $this->data['onLoad'];
 }
 
-if($onLoad !== '') {
-	$onLoad = ' onload="' . $onLoad . '"';
+if ($onLoad !== '') {
+    $onLoad = ' onload="' . $onLoad . '"';
 }
 ?>
 <body<?php echo $onLoad; ?>>
 
 <div id="wrap">
-	
-	<div id="header">
-		<h1><a href="/<?php echo $this->data['baseurlpath']; ?>"><?php
-			echo (isset($this->data['header']) ? $this->data['header'] : 'SimpleSAMLphp');
-		?></a></h1>
-	</div>
-
-	
-	<?php 
-	
-	$includeLanguageBar = TRUE;
-	if (!empty($_POST)) 
-		$includeLanguageBar = FALSE;
-	if (isset($this->data['hideLanguageBar']) && $this->data['hideLanguageBar'] === TRUE) 
-		$includeLanguageBar = FALSE;
-	
-	if ($includeLanguageBar) {
-		
-		$languages = $this->getLanguageList();
-		if ( count($languages) > 1 ) {
-			echo '<div id="languagebar">';
-			$langnames = array(
-						'no' => 'BokmĂĄl', // Norwegian BokmĂĄl
-						'nn' => 'Nynorsk', // Norwegian Nynorsk
-						'se' => 'Sámegiella', // Northern Sami
-						'da' => 'Dansk', // Danish
-						'en' => 'English',
-						'de' => 'Deutsch', // German
-						'sv' => 'Svenska', // Swedish
-						'fi' => 'Suomeksi', // Finnish
-						'es' => 'Español', // Spanish
-						'fr' => 'Français', // French
-						'it' => 'Italiano', // Italian
-						'nl' => 'Nederlands', // Dutch
-						'lb' => 'Lëtzebuergesch', // Luxembourgish
-						'cs' => 'Čeština', // Czech
-						'sl' => 'Slovenščina', // Slovensk
-						'lt' => 'LietuviĹł kalba', // Lithuanian
-						'hr' => 'Hrvatski', // Croatian
-						'hu' => 'Magyar', // Hungarian
-						'pl' => 'Język polski', // Polish
-						'pt' => 'PortuguĂŞs', // Portuguese
-						'pt-br' => 'PortuguĂŞs brasileiro', // Portuguese
-						'ru' => 'русский язык', // Russian
-						'et' => 'eesti keel', // Estonian
-						'tr' => 'Türkçe', // Turkish
-						'el' => 'ελληνικά', // Greek
-						'ja' => '日本語', // Japanese
-						'zh' => '简体中文', // Chinese (simplified)
-						'zh-tw' => '繁體中文', // Chinese (traditional)
-						'ar' => 'العربية', // Arabic
-						'he' => 'עִבְרִית', // Hebrew
-						'id' => 'Bahasa Indonesia', // Indonesian
-						'sr' => 'Srpski', // Serbian
-						'lv' => 'Latviešu', // Latvian
-						'ro' => 'Românește', // Romanian
-						'eu' => 'Euskara', // Basque
-						'af' => 'Afrikaans', // Afrikaans
-			);
-			
-			$textarray = array();
-			foreach ($languages AS $lang => $current) {
-				$lang = strtolower($lang);
-				if ($current) {
-					$textarray[] = $langnames[$lang];
-				} else {
-					$textarray[] = '<a href="' . htmlspecialchars(\SimpleSAML\Utils\HTTP::addURLParameters(\SimpleSAML\Utils\HTTP::getSelfURL(), array($this->getTranslator()->getLanguage()->getLanguageParameterName() => $lang))) . '">' .
-						$langnames[$lang] . '</a>';
-				}
-			}
-			echo join(' | ', $textarray);
-			echo '</div>';
-		}
-
-	}
-
-
-
-	?>
-	<div id="content">
+
+    <div id="header">
+        <h1><a href="/<?php echo $this->data['baseurlpath']; ?>"><?php
+            echo(isset($this->data['header']) ? $this->data['header'] : 'SimpleSAMLphp');
+        ?></a></h1>
+    </div>
+
+
+    <?php
+
+    $includeLanguageBar = true;
+    if (!empty($_POST)) {
+        $includeLanguageBar = false;
+    }
+    if (isset($this->data['hideLanguageBar']) && $this->data['hideLanguageBar'] === true) {
+        $includeLanguageBar = false;
+    }
+
+    if ($includeLanguageBar) {
+        $languages = $this->getLanguageList();
+        ksort($languages);
+        if (count($languages) > 1) {
+            echo '<div id="languagebar">';
+            $langnames = [
+                'no' => 'BokmĂĄl', // Norwegian BokmĂĄl
+                'nn' => 'Nynorsk', // Norwegian Nynorsk
+                'se' => 'Sámegiella', // Northern Sami
+                'da' => 'Dansk', // Danish
+                'en' => 'English',
+                'de' => 'Deutsch', // German
+                'sv' => 'Svenska', // Swedish
+                'fi' => 'Suomeksi', // Finnish
+                'es' => 'Español', // Spanish
+                'fr' => 'Français', // French
+                'it' => 'Italiano', // Italian
+                'nl' => 'Nederlands', // Dutch
+                'lb' => 'Lëtzebuergesch', // Luxembourgish
+                'cs' => 'Čeština', // Czech
+                'sl' => 'Slovenščina', // Slovensk
+                'lt' => 'LietuviĹł kalba', // Lithuanian
+                'hr' => 'Hrvatski', // Croatian
+                'hu' => 'Magyar', // Hungarian
+                'pl' => 'Język polski', // Polish
+                'pt' => 'PortuguĂŞs', // Portuguese
+                'pt-br' => 'PortuguĂŞs brasileiro', // Portuguese
+                'ru' => 'русский язык', // Russian
+                'et' => 'eesti keel', // Estonian
+                'tr' => 'Türkçe', // Turkish
+                'el' => 'ελληνικά', // Greek
+                'ja' => '日本語', // Japanese
+                'zh' => '简体中文', // Chinese (simplified)
+                'zh-tw' => '繁體中文', // Chinese (traditional)
+                'ar' => 'العربية', // Arabic
+                'he' => 'עִבְרִית', // Hebrew
+                'id' => 'Bahasa Indonesia', // Indonesian
+                'sr' => 'Srpski', // Serbian
+                'lv' => 'Latviešu', // Latvian
+                'ro' => 'Românește', // Romanian
+                'eu' => 'Euskara', // Basque
+                'af' => 'Afrikaans', // Afrikaans
+            ];
+
+            $textarray = [];
+            foreach ($languages as $lang => $current) {
+                $lang = strtolower($lang);
+                if ($current) {
+                    $textarray[] = $langnames[$lang];
+                } else {
+                    $textarray[] = '<a href="' . htmlspecialchars(
+                        \SimpleSAML\Utils\HTTP::addURLParameters(
+                            \SimpleSAML\Utils\HTTP::getSelfURL(),
+                            [$this->getTranslator()->getLanguage()->getLanguageParameterName() => $lang]
+                        )
+                    ) . '">' .
+                        $langnames[$lang] . '</a>';
+                }
+            }
+            echo join(' | ', $textarray);
+            echo '</div>';
+        }
+    }
+
+
+
+    ?>
+    <div id="content">
 
 
 
 <?php
 
-if(!empty($this->data['htmlinject']['htmlContentPre'])) {
-	foreach($this->data['htmlinject']['htmlContentPre'] AS $c) {
-		echo $c;
-	}
+if (!empty($this->data['htmlinject']['htmlContentPre'])) {
+    foreach ($this->data['htmlinject']['htmlContentPre'] as $c) {
+        echo $c;
+    }
 }
diff --git a/templates/index.twig b/templates/index.twig
index 2a6004aa06f112da48320488c242a7ad286dd17c..6f6f0518063bf61bd837f9295fcf36af0761f21d 100644
--- a/templates/index.twig
+++ b/templates/index.twig
@@ -2,10 +2,9 @@
 {% block content %}
     <div id="portalmenu" class="ui-tabs ui-widget ui-widget-content ui-corner-all">
         <ul class="tabset_tabs ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all">
-            <li class="ui-state-default ui-corner-top"><a href="http://simplesaml.arrakis.uninett.no/simplesaml/module.php/core/frontpage_welcome.php">Welcome</a></li>
             <li class="ui-state-default ui-corner-top ui-tabs-selected ui-state-active"><a href="#">Configuration</a></li>
-            <li class="ui-state-default ui-corner-top"><a href="http://simplesaml.arrakis.uninett.no/simplesaml/module.php/core/frontpage_auth.php">Authentication</a></li>
-            <li class="ui-state-default ui-corner-top"><a href="http://simplesaml.arrakis.uninett.no/simplesaml/module.php/core/frontpage_federation.php">Federation</a></li>
+            <li class="ui-state-default ui-corner-top"><a href="/{{ baseurlpath }}module.php/core/frontpage_auth.php">Authentication</a></li>
+            <li class="ui-state-default ui-corner-top"><a href="/{{ baseurlpath }}module.php/core/frontpage_federation.php">Federation</a></li>
         </ul>
         <div id="portalcontent" class="ui-tabs-panel ui-widget-content ui-corner-bottom">
 
diff --git a/templates/status.php b/templates/status.php
index 798b546acc9bac0ce198e7e412b643675636e36a..7fb5ba09ff94175b0ab0d07f98c6a904b5d91e16 100644
--- a/templates/status.php
+++ b/templates/status.php
@@ -60,6 +60,13 @@ if ($nameid !== false) {
     echo(present_attributes($this, $list, ''));
 }
 
+$authData = $this->data['authData'];
+if (!empty($authData)) {
+    echo "<h2>".$this->t('{status:authData_header}')."</h2>";
+    echo '<details><summary>' . $this->t('{status:authData_summary}') . '</summary>'; 
+    echo('<pre>' . htmlspecialchars(json_encode($this->data['authData'], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)) . '</pre>');
+    echo '</details>';
+}
 if (isset($this->data['logout'])) {
     echo('<h2>'.$this->t('{status:logout}').'</h2>');
     echo('<p>'.$this->data['logout'].'</p>');
diff --git a/tests/Utils/ReduceSpillOverTest.php b/tests/Utils/ReduceSpillOverTest.php
index 3c1022209bb38225ad37e6042e82001b2d274839..2f474576dd040e59e543cbfd05b1b8798221a12a 100644
--- a/tests/Utils/ReduceSpillOverTest.php
+++ b/tests/Utils/ReduceSpillOverTest.php
@@ -15,8 +15,8 @@ class ReduceSpillOverTest extends ClearStateTestCase
     public function testSetState()
     {
         $_SERVER['QUERY_STRING'] = 'a=b';
-        \SimpleSAML_Configuration::loadFromArray(array('a' => 'b'), '[ARRAY]', 'simplesaml');
-        $this->assertEquals('b', \SimpleSAML_Configuration::getInstance()->getString('a'));
+        \SimpleSAML\Configuration::loadFromArray(array('a' => 'b'), '[ARRAY]', 'simplesaml');
+        $this->assertEquals('b', \SimpleSAML\Configuration::getInstance()->getString('a'));
         putenv('SIMPLESAMLPHP_CONFIG_DIR=' . __DIR__);
     }
 
@@ -29,7 +29,7 @@ class ReduceSpillOverTest extends ClearStateTestCase
         $this->assertArrayNotHasKey('QUERY_STRING', $_SERVER);
         $this->assertFalse(getenv('SIMPLESAMLPHP_CONFIG_DIR'));
         try {
-            \SimpleSAML_Configuration::getInstance();
+            \SimpleSAML\Configuration::getInstance();
             $this->fail('Expected config configured in other tests to no longer be valid');
         } catch (\SimpleSAML\Error\ConfigurationError $error) {
             // Expected error
diff --git a/tests/Utils/StateClearer.php b/tests/Utils/StateClearer.php
index 7d074d5b1a861a0b1e149a6fa1cf5ee94183352e..db32db8e780bed71d522243d26ce4bfef8e9fcfd 100644
--- a/tests/Utils/StateClearer.php
+++ b/tests/Utils/StateClearer.php
@@ -1,4 +1,5 @@
 <?php
+
 namespace SimpleSAML\Test\Utils;
 
 /**
@@ -17,7 +18,7 @@ class StateClearer
      * Class that implement \SimpleSAML\Utils\ClearableState and should have clearInternalState called between tests
      * @var array
      */
-    private $clearableState = array('SimpleSAML_Configuration');
+    private $clearableState = array('SimpleSAML\Configuration');
 
     /**
      * Environmental variables to unset
diff --git a/tests/lib/SimpleSAML/Auth/SimpleTest.php b/tests/lib/SimpleSAML/Auth/SimpleTest.php
index 8bd5cf8fdd5f1770ba1b1477a1e15908803f3259..e0543b44be4d4ee8dae270ab564815e2d0f96ce5 100644
--- a/tests/lib/SimpleSAML/Auth/SimpleTest.php
+++ b/tests/lib/SimpleSAML/Auth/SimpleTest.php
@@ -8,7 +8,6 @@ namespace SimpleSAML\Test\Auth;
  */
 class SimpleTest extends \SimpleSAML\Test\Utils\ClearStateTestCase
 {
-
     /**
      * @test
      */
@@ -22,7 +21,7 @@ class SimpleTest extends \SimpleSAML\Test\Utils\ClearStateTestCase
         $_SERVER['REQUEST_URI'] = '/';
 
         // test merging configuration option with passed URL
-        \SimpleSAML_Configuration::loadFromArray(array(
+        \SimpleSAML\Configuration::loadFromArray(array(
             'application' => array(
                 'baseURL' => 'https://example.org'
             )
@@ -50,7 +49,7 @@ class SimpleTest extends \SimpleSAML\Test\Utils\ClearStateTestCase
         $this->assertEquals('https://example.org/foo/bar?a=b#fragment', $method->invokeArgs($s, array(null)));
 
         // test config option with ending with / and port
-        \SimpleSAML_Configuration::loadFromArray(array(
+        \SimpleSAML\Configuration::loadFromArray(array(
             'application' => array(
                 'baseURL' => 'http://example.org:8080/'
             )
@@ -66,7 +65,7 @@ class SimpleTest extends \SimpleSAML\Test\Utils\ClearStateTestCase
 
         // now test with no configuration
         $_SERVER['SERVER_NAME'] = 'example.org';
-        \SimpleSAML_Configuration::loadFromArray(array(), '[ARRAY]', 'simplesaml');
+        \SimpleSAML\Configuration::loadFromArray(array(), '[ARRAY]', 'simplesaml');
         $s = new \SimpleSAML\Auth\Simple('');
         $this->assertEquals('http://example.org:1234/foo/bar?a=b#fragment', $method->invokeArgs($s, array(null)));
 
diff --git a/tests/lib/SimpleSAML/Auth/SourceTest.php b/tests/lib/SimpleSAML/Auth/SourceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e51781d72d6392c98eff242d00a2a2c630b0e7b4
--- /dev/null
+++ b/tests/lib/SimpleSAML/Auth/SourceTest.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace SimpleSAML\Test\Auth;
+
+use SimpleSAML\Auth\SourceFactory;
+use SimpleSAML\Test\Utils\ClearStateTestCase;
+
+/**
+ * Tests for \SimpleSAML\Auth\Source
+ */
+
+class SourceTest extends ClearStateTestCase
+{
+    public function testParseAuthSource()
+    {
+        $class = new \ReflectionClass('\SimpleSAML\Auth\Source');
+        $method = $class->getMethod('parseAuthSource');
+        $method->setAccessible(true);
+
+        // test direct instantiation of the auth source object
+        $authSource = $method->invokeArgs(null, ['test', ['SimpleSAML\Test\Auth\TestAuthSource']]);
+        $this->assertInstanceOf('SimpleSAML\Test\Auth\TestAuthSource', $authSource);
+
+        // test instantiation via an auth source factory
+        $authSource = $method->invokeArgs(null, ['test', ['SimpleSAML\Test\Auth\TestAuthSourceFactory']]);
+        $this->assertInstanceOf('SimpleSAML\Test\Auth\TestAuthSource', $authSource);
+    }
+}
+
+class TestAuthSource extends \SimpleSAML\Auth\Source
+{
+    public function authenticate(&$state)
+    {
+    }
+}
+
+class TestAuthSourceFactory implements SourceFactory
+{
+    public function create(array $info, array $config)
+    {
+        return new TestAuthSource($info, $config);
+    }
+}
diff --git a/tests/lib/SimpleSAML/Auth/StateTest.php b/tests/lib/SimpleSAML/Auth/StateTest.php
index 0edb0b20ec8b2a94549f2e4a09aba1776b0d79fd..b9bc2b5c4bb62ee399d0319546e13deb0a11e7a2 100644
--- a/tests/lib/SimpleSAML/Auth/StateTest.php
+++ b/tests/lib/SimpleSAML/Auth/StateTest.php
@@ -3,12 +3,10 @@
 use PHPUnit\Framework\TestCase;
 
 /**
- * Tests for SimpleSAML_Auth_State
+ * Tests for \SimpleSAML\Auth\State
  */
 class Auth_StateTest extends TestCase
 {
-
-
     /**
      * Test the getPersistentAuthData() function.
      */
@@ -29,7 +27,7 @@ class Auth_StateTest extends TestCase
         $expected = $mandatory;
         $this->assertEquals(
             $expected,
-            SimpleSAML_Auth_State::getPersistentAuthData($state),
+            \SimpleSAML\Auth\State::getPersistentAuthData($state),
             'Mandatory state attributes did not survive as expected'.print_r($expected, true)
         );
 
@@ -39,7 +37,7 @@ class Auth_StateTest extends TestCase
         $expected = $state;
         $this->assertEquals(
             $expected,
-            SimpleSAML_Auth_State::getPersistentAuthData($state),
+            \SimpleSAML\Auth\State::getPersistentAuthData($state),
             'Some error occurred with missing mandatory parameters'
         );
 
@@ -52,7 +50,7 @@ class Auth_StateTest extends TestCase
         $expected = $mandatory;
         $this->assertEquals(
             $expected,
-            SimpleSAML_Auth_State::getPersistentAuthData($state),
+            \SimpleSAML\Auth\State::getPersistentAuthData($state),
             'Additional parameters survived'
         );
 
@@ -64,7 +62,7 @@ class Auth_StateTest extends TestCase
         unset($expected['PersistentAuthData']);
         $this->assertEquals(
             $expected,
-            SimpleSAML_Auth_State::getPersistentAuthData($state),
+            \SimpleSAML\Auth\State::getPersistentAuthData($state),
             'Some error occurred with additional, persistent parameters'
         );
 
@@ -75,7 +73,7 @@ class Auth_StateTest extends TestCase
         unset($expected['PersistentAuthData']);
         $this->assertEquals(
             $expected,
-            SimpleSAML_Auth_State::getPersistentAuthData($state),
+            \SimpleSAML\Auth\State::getPersistentAuthData($state),
             'Some error occurred with additional, persistent parameters, and no mandatory ones'
         );
     }
diff --git a/tests/lib/SimpleSAML/Auth/TimeLimitedTokenTest.php b/tests/lib/SimpleSAML/Auth/TimeLimitedTokenTest.php
index 2666fb68b7369a3d84a245f1a7317f95e3895bf9..782de37be6874d98132ae57f9ee3322da84860e0 100644
--- a/tests/lib/SimpleSAML/Auth/TimeLimitedTokenTest.php
+++ b/tests/lib/SimpleSAML/Auth/TimeLimitedTokenTest.php
@@ -6,13 +6,12 @@ use SimpleSAML\Auth\TimeLimitedToken;
 
 class TimeLimitedTokenTest extends \SimpleSAML\Test\Utils\ClearStateTestCase
 {
-
     /**
      * Test for malformed tokens.
      */
     public function testMalformedToken()
     {
-        \SimpleSAML_Configuration::loadFromArray(array('secretsalt' => 'random'), '[ARRAY]', 'simplesaml');
+        \SimpleSAML\Configuration::loadFromArray(array('secretsalt' => 'random'), '[ARRAY]', 'simplesaml');
 
         $token = new TimeLimitedToken();
         $this->assertFalse($token->validate('malformed'));
@@ -26,7 +25,7 @@ class TimeLimitedTokenTest extends \SimpleSAML\Test\Utils\ClearStateTestCase
      */
     public function testValidToken()
     {
-        \SimpleSAML_Configuration::loadFromArray(array('secretsalt' => 'random'), '[ARRAY]', 'simplesaml');
+        \SimpleSAML\Configuration::loadFromArray(array('secretsalt' => 'random'), '[ARRAY]', 'simplesaml');
 
         $token = new TimeLimitedToken();
         $t = $token->generate();
@@ -39,7 +38,7 @@ class TimeLimitedTokenTest extends \SimpleSAML\Test\Utils\ClearStateTestCase
      */
     public function testValidTokenWithData()
     {
-        \SimpleSAML_Configuration::loadFromArray(array('secretsalt' => 'random'), '[ARRAY]', 'simplesaml');
+        \SimpleSAML\Configuration::loadFromArray(array('secretsalt' => 'random'), '[ARRAY]', 'simplesaml');
 
         $tokenWithData = new TimeLimitedToken();
         $tokenWithData->addVerificationData('some more random data');
@@ -56,7 +55,7 @@ class TimeLimitedTokenTest extends \SimpleSAML\Test\Utils\ClearStateTestCase
      */
     public function testExpiredToken()
     {
-        \SimpleSAML_Configuration::loadFromArray(array('secretsalt' => 'random'), '[ARRAY]', 'simplesaml');
+        \SimpleSAML\Configuration::loadFromArray(array('secretsalt' => 'random'), '[ARRAY]', 'simplesaml');
 
         $token = new TimeLimitedToken();
         $this->assertFalse($token->validate('7-c0803e76fff1df0ceb222dee80aa1d73f35d84dd'));
@@ -68,7 +67,7 @@ class TimeLimitedTokenTest extends \SimpleSAML\Test\Utils\ClearStateTestCase
      */
     public function testManipulatedToken()
     {
-        \SimpleSAML_Configuration::loadFromArray(array('secretsalt' => 'random'), '[ARRAY]', 'simplesaml');
+        \SimpleSAML\Configuration::loadFromArray(array('secretsalt' => 'random'), '[ARRAY]', 'simplesaml');
 
         $token = new TimeLimitedToken(1);
         $t = $token->generate();
diff --git a/tests/lib/SimpleSAML/ConfigurationTest.php b/tests/lib/SimpleSAML/ConfigurationTest.php
index fced577efb64dd1cf96700502e4939de9d402276..ea421b952d4ce7803c18836c39c013616fda8177 100644
--- a/tests/lib/SimpleSAML/ConfigurationTest.php
+++ b/tests/lib/SimpleSAML/ConfigurationTest.php
@@ -1,16 +1,18 @@
 <?php
 
+use \SimpleSAML\Configuration;
+
 /**
- * Tests for SimpleSAML_Configuration
+ * Tests for \SimpleSAML\Configuration
  */
-class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTestCase
+class Test_Configuration extends SimpleSAML\Test\Utils\ClearStateTestCase
 {
-
     /**
-     * Test SimpleSAML_Configuration::getVersion()
+     * Test \SimpleSAML\Configuration::getVersion()
      */
-    public function testGetVersion() {
-        $c = SimpleSAML_Configuration::getOptionalConfig();
+    public function testGetVersion()
+    {
+        $c = Configuration::getOptionalConfig();
         $this->assertTrue(is_string($c->getVersion()));
     }
 
@@ -20,8 +22,8 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
      */
     public function testLoadDefaultInstance()
     {
-        SimpleSAML_Configuration::loadFromArray(array('key' => 'value'), '', 'dummy');
-        SimpleSAML_Configuration::getInstance();
+        Configuration::loadFromArray(array('key' => 'value'), '', 'dummy');
+        Configuration::getInstance();
     }
 
 
@@ -32,7 +34,7 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
     public function testCriticalConfigurationError()
     {
         try {
-            SimpleSAML_Configuration::getInstance();
+            Configuration::getInstance();
             $this->fail('Exception expected');
         } catch (\SimpleSAML\Error\CriticalConfigurationError $var) {
             // This exception is expected.
@@ -41,18 +43,19 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
          * After the above failure an emergency configuration is create to allow core SSP components to function and
          * possibly log/display the error.
          */
-        $c = SimpleSAML_Configuration::getInstance();
+        $c = Configuration::getInstance();
         $this->assertNotEmpty($c->toArray());
     }
 
     /**
-     * Test SimpleSAML_Configuration::getValue()
+     * Test \SimpleSAML\Configuration::getValue()
      */
-    public function testGetValue() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetValue()
+    {
+        $c = Configuration::loadFromArray([
             'exists_true' => true,
             'exists_null' => null,
-        ));
+        ]);
         $this->assertEquals($c->getValue('missing'), null);
         $this->assertEquals($c->getValue('missing', true), true);
         $this->assertEquals($c->getValue('missing', true), true);
@@ -64,19 +67,21 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
     }
 
     /**
-     * Test SimpleSAML_Configuration::getValue(), REQUIRED_OPTION flag.
+     * Test \SimpleSAML\Configuration::getValue(), REQUIRED_OPTION flag.
      * @expectedException Exception
      */
-    public function testGetValueRequired() {
-        $c = SimpleSAML_Configuration::loadFromArray(array());
-        $c->getValue('missing', SimpleSAML_Configuration::REQUIRED_OPTION);
+    public function testGetValueRequired()
+    {
+        $c = Configuration::loadFromArray(array());
+        $c->getValue('missing', Configuration::REQUIRED_OPTION);
     }
 
     /**
-     * Test SimpleSAML_Configuration::hasValue()
+     * Test \SimpleSAML\Configuration::hasValue()
      */
-    public function testHasValue() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testHasValue()
+    {
+        $c = Configuration::loadFromArray(array(
             'exists_true' => true,
             'exists_null' => null,
         ));
@@ -86,10 +91,11 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
     }
 
     /**
-     * Test SimpleSAML_Configuration::hasValue()
+     * Test \SimpleSAML\Configuration::hasValue()
      */
-    public function testHasValueOneOf() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testHasValueOneOf()
+    {
+        $c = Configuration::loadFromArray(array(
             'exists_true' => true,
             'exists_null' => null,
         ));
@@ -104,109 +110,111 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
     }
 
     /**
-     * Test SimpleSAML_Configuration::getBaseURL()
+     * Test \SimpleSAML\Configuration::getBaseURL()
      */
-    public function testGetBaseURL() {
-
+    public function testGetBaseURL()
+    {
         // Need to set a default configuration because the SSP Logger attempts to use it.
-        SimpleSAML_Configuration::loadFromArray(array(), '[ARRAY]', 'simplesaml');
-        $c = SimpleSAML_Configuration::loadFromArray(array());
+        Configuration::loadFromArray(array(), '[ARRAY]', 'simplesaml');
+        $c = Configuration::loadFromArray(array());
         $this->assertEquals($c->getBaseURL(), 'simplesaml/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'simplesaml/'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => 'simplesaml/'));
         $this->assertEquals($c->getBaseURL(), 'simplesaml/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => '/simplesaml/'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => '/simplesaml/'));
         $this->assertEquals($c->getBaseURL(), 'simplesaml/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'path/to/simplesaml/'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => 'path/to/simplesaml/'));
         $this->assertEquals($c->getBaseURL(), 'path/to/simplesaml/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => '/path/to/simplesaml/'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => '/path/to/simplesaml/'));
         $this->assertEquals($c->getBaseURL(), 'path/to/simplesaml/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'https://example.org/ssp/'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => 'https://example.org/ssp/'));
         $this->assertEquals($c->getBaseURL(), 'ssp/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'https://example.org/'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => 'https://example.org/'));
         $this->assertEquals($c->getBaseURL(), '');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'http://example.org/ssp/'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => 'http://example.org/ssp/'));
         $this->assertEquals($c->getBaseURL(), 'ssp/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => ''));
+        $c = Configuration::loadFromArray(array('baseurlpath' => ''));
         $this->assertEquals($c->getBaseURL(), '');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => '/'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => '/'));
         $this->assertEquals($c->getBaseURL(), '');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'simplesaml'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => 'simplesaml'));
         $this->assertEquals($c->getBaseURL(), 'simplesaml/');
     }
 
     /**
-     * Test SimpleSAML_Configuration::getBasePath()
+     * Test \SimpleSAML\Configuration::getBasePath()
      */
-    public function testGetBasePath() {
-        $c = SimpleSAML_Configuration::loadFromArray(array());
+    public function testGetBasePath()
+    {
+        $c = Configuration::loadFromArray(array());
         $this->assertEquals($c->getBasePath(), '/simplesaml/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'simplesaml/'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => 'simplesaml/'));
         $this->assertEquals($c->getBasePath(), '/simplesaml/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => '/simplesaml/'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => '/simplesaml/'));
         $this->assertEquals($c->getBasePath(), '/simplesaml/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'simplesaml'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => 'simplesaml'));
         $this->assertEquals($c->getBasePath(), '/simplesaml/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => '/simplesaml'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => '/simplesaml'));
         $this->assertEquals($c->getBasePath(), '/simplesaml/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'path/to/simplesaml/'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => 'path/to/simplesaml/'));
         $this->assertEquals($c->getBasePath(), '/path/to/simplesaml/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => '/path/to/simplesaml/'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => '/path/to/simplesaml/'));
         $this->assertEquals($c->getBasePath(), '/path/to/simplesaml/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => '/path/to/simplesaml'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => '/path/to/simplesaml'));
         $this->assertEquals($c->getBasePath(), '/path/to/simplesaml/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'https://example.org/ssp/'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => 'https://example.org/ssp/'));
         $this->assertEquals($c->getBasePath(), '/ssp/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'https://example.org/'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => 'https://example.org/'));
         $this->assertEquals($c->getBasePath(), '/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'http://example.org/ssp/'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => 'http://example.org/ssp/'));
         $this->assertEquals($c->getBasePath(), '/ssp/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'http://example.org/ssp/simplesaml'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => 'http://example.org/ssp/simplesaml'));
         $this->assertEquals($c->getBasePath(), '/ssp/simplesaml/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'http://example.org/ssp/simplesaml/'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => 'http://example.org/ssp/simplesaml/'));
         $this->assertEquals($c->getBasePath(), '/ssp/simplesaml/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => ''));
+        $c = Configuration::loadFromArray(array('baseurlpath' => ''));
         $this->assertEquals($c->getBasePath(), '/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => '/'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => '/'));
         $this->assertEquals($c->getBasePath(), '/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'https://example.org:8443'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => 'https://example.org:8443'));
         $this->assertEquals($c->getBasePath(), '/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array('baseurlpath' => 'https://example.org:8443/'));
+        $c = Configuration::loadFromArray(array('baseurlpath' => 'https://example.org:8443/'));
         $this->assertEquals($c->getBasePath(), '/');
     }
 
     /**
-     * Test SimpleSAML_Configuration::resolvePath()
+     * Test \SimpleSAML\Configuration::resolvePath()
      */
-    public function testResolvePath() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testResolvePath()
+    {
+        $c = Configuration::loadFromArray([
             'basedir' => '/basedir/',
-        ));
+        ]);
 
         $this->assertEquals($c->resolvePath(null), null);
         $this->assertEquals($c->resolvePath('/otherdir'), '/otherdir');
@@ -214,17 +222,21 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
 
         $this->assertEquals($c->resolvePath('slash/'), '/basedir/slash');
         $this->assertEquals($c->resolvePath('slash//'), '/basedir/slash');
+
+        $this->assertEquals($c->resolvePath('C:\\otherdir'), 'C:/otherdir');
+        $this->assertEquals($c->resolvePath('C:/otherdir'), 'C:/otherdir');
     }
 
     /**
-     * Test SimpleSAML_Configuration::getPathValue()
+     * Test \SimpleSAML\Configuration::getPathValue()
      */
-    public function testGetPathValue() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetPathValue()
+    {
+        $c = Configuration::loadFromArray([
             'basedir' => '/basedir/',
             'path_opt' => 'path',
             'slashes_opt' => 'slashes//',
-        ));
+        ]);
 
         $this->assertEquals($c->getPathValue('missing'), null);
         $this->assertEquals($c->getPathValue('path_opt'), '/basedir/path/');
@@ -232,156 +244,169 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
     }
 
     /**
-     * Test SimpleSAML_Configuration::getBaseDir()
+     * Test \SimpleSAML\Configuration::getBaseDir()
      */
-    public function testGetBaseDir() {
-        $c = SimpleSAML_Configuration::loadFromArray(array());
+    public function testGetBaseDir()
+    {
+        $c = Configuration::loadFromArray([]);
         $this->assertEquals($c->getBaseDir(), dirname(dirname(dirname(dirname(__FILE__)))) . '/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+        $c = Configuration::loadFromArray([
             'basedir' => '/basedir',
-        ));
+        ]);
         $this->assertEquals($c->getBaseDir(), '/basedir/');
 
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+        $c = Configuration::loadFromArray(array(
             'basedir' => '/basedir/',
         ));
         $this->assertEquals($c->getBaseDir(), '/basedir/');
     }
 
     /**
-     * Test SimpleSAML_Configuration::getBoolean()
+     * Test \SimpleSAML\Configuration::getBoolean()
      */
-    public function testGetBoolean() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetBoolean()
+    {
+        $c = Configuration::loadFromArray([
             'true_opt' => true,
             'false_opt' => false,
-        ));
+        ]);
         $this->assertEquals($c->getBoolean('missing_opt', '--missing--'), '--missing--');
         $this->assertEquals($c->getBoolean('true_opt', '--missing--'), true);
         $this->assertEquals($c->getBoolean('false_opt', '--missing--'), false);
     }
 
     /**
-     * Test SimpleSAML_Configuration::getBoolean() missing option
+     * Test \SimpleSAML\Configuration::getBoolean() missing option
      * @expectedException Exception
      */
-    public function testGetBooleanMissing() {
-        $c = SimpleSAML_Configuration::loadFromArray(array());
+    public function testGetBooleanMissing()
+    {
+        $c = Configuration::loadFromArray([]);
         $c->getBoolean('missing_opt');
     }
 
     /**
-     * Test SimpleSAML_Configuration::getBoolean() wrong option
+     * Test \SimpleSAML\Configuration::getBoolean() wrong option
      * @expectedException Exception
      */
-    public function testGetBooleanWrong() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetBooleanWrong()
+    {
+        $c = Configuration::loadFromArray([
             'wrong' => 'true',
-        ));
+        ]);
         $c->getBoolean('wrong');
     }
 
     /**
-     * Test SimpleSAML_Configuration::getString()
+     * Test \SimpleSAML\Configuration::getString()
      */
-    public function testGetString() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetString()
+    {
+        $c = Configuration::loadFromArray([
             'str_opt' => 'Hello World!',
-        ));
+        ]);
         $this->assertEquals($c->getString('missing_opt', '--missing--'), '--missing--');
         $this->assertEquals($c->getString('str_opt', '--missing--'), 'Hello World!');
     }
 
     /**
-     * Test SimpleSAML_Configuration::getString() missing option
+     * Test \SimpleSAML\Configuration::getString() missing option
      * @expectedException Exception
      */
-    public function testGetStringMissing() {
-        $c = SimpleSAML_Configuration::loadFromArray(array());
+    public function testGetStringMissing()
+    {
+        $c = Configuration::loadFromArray([]);
         $c->getString('missing_opt');
     }
 
     /**
-     * Test SimpleSAML_Configuration::getString() wrong option
+     * Test \SimpleSAML\Configuration::getString() wrong option
      * @expectedException Exception
      */
-    public function testGetStringWrong() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetStringWrong()
+    {
+        $c = Configuration::loadFromArray([
             'wrong' => false,
-        ));
+        ]);
         $c->getString('wrong');
     }
 
     /**
-     * Test SimpleSAML_Configuration::getInteger()
+     * Test \SimpleSAML\Configuration::getInteger()
      */
-    public function testGetInteger() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetInteger()
+    {
+        $c = Configuration::loadFromArray([
             'int_opt' => 42,
-        ));
+        ]);
         $this->assertEquals($c->getInteger('missing_opt', '--missing--'), '--missing--');
         $this->assertEquals($c->getInteger('int_opt', '--missing--'), 42);
     }
 
     /**
-     * Test SimpleSAML_Configuration::getInteger() missing option
+     * Test \SimpleSAML\Configuration::getInteger() missing option
      * @expectedException Exception
      */
-    public function testGetIntegerMissing() {
-        $c = SimpleSAML_Configuration::loadFromArray(array());
+    public function testGetIntegerMissing()
+    {
+        $c = Configuration::loadFromArray([]);
         $c->getInteger('missing_opt');
     }
 
     /**
-     * Test SimpleSAML_Configuration::getInteger() wrong option
+     * Test \SimpleSAML\Configuration::getInteger() wrong option
      * @expectedException Exception
      */
-    public function testGetIntegerWrong() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetIntegerWrong()
+    {
+        $c = Configuration::loadFromArray([
             'wrong' => '42',
-        ));
+        ]);
         $c->getInteger('wrong');
     }
 
     /**
-     * Test SimpleSAML_Configuration::getIntegerRange()
+     * Test \SimpleSAML\Configuration::getIntegerRange()
      */
-    public function testGetIntegerRange() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetIntegerRange()
+    {
+        $c = Configuration::loadFromArray([
             'int_opt' => 42,
-        ));
+        ]);
         $this->assertEquals($c->getIntegerRange('missing_opt', 0, 100, '--missing--'), '--missing--');
         $this->assertEquals($c->getIntegerRange('int_opt', 0, 100), 42);
     }
 
     /**
-     * Test SimpleSAML_Configuration::getIntegerRange() below limit
+     * Test \SimpleSAML\Configuration::getIntegerRange() below limit
      * @expectedException Exception
      */
-    public function testGetIntegerRangeBelow() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetIntegerRangeBelow()
+    {
+        $c = Configuration::loadFromArray([
             'int_opt' => 9,
-        ));
+        ]);
         $this->assertEquals($c->getIntegerRange('int_opt', 10, 100), 42);
     }
 
     /**
-     * Test SimpleSAML_Configuration::getIntegerRange() above limit
+     * Test \SimpleSAML\Configuration::getIntegerRange() above limit
      * @expectedException Exception
      */
-    public function testGetIntegerRangeAbove() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetIntegerRangeAbove()
+    {
+        $c = Configuration::loadFromArray([
             'int_opt' => 101,
-        ));
+        ]);
         $this->assertEquals($c->getIntegerRange('int_opt', 10, 100), 42);
     }
 
     /**
-     * Test SimpleSAML_Configuration::getValueValidate()
+     * Test \SimpleSAML\Configuration::getValueValidate()
      */
     public function testGetValueValidate() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+        $c = Configuration::loadFromArray(array(
             'opt' => 'b',
         ));
         $this->assertEquals($c->getValueValidate('missing_opt', array('a', 'b', 'c'), '--missing--'), '--missing--');
@@ -389,47 +414,51 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
     }
 
     /**
-     * Test SimpleSAML_Configuration::getValueValidate() wrong option
+     * Test \SimpleSAML\Configuration::getValueValidate() wrong option
      * @expectedException Exception
      */
-    public function testGetValueValidateWrong() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetValueValidateWrong()
+    {
+        $c = Configuration::loadFromArray([
             'opt' => 'd',
-        ));
+        ]);
         $c->getValueValidate('opt', array('a', 'b', 'c'));
     }
 
     /**
-     * Test SimpleSAML_Configuration::getArray()
+     * Test \SimpleSAML\Configuration::getArray()
      */
-    public function testGetArray() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetArray()
+    {
+        $c = Configuration::loadFromArray([
             'opt' => array('a', 'b', 'c'),
-        ));
+        ]);
         $this->assertEquals($c->getArray('missing_opt', '--missing--'), '--missing--');
         $this->assertEquals($c->getArray('opt'), array('a', 'b', 'c'));
     }
 
     /**
-     * Test SimpleSAML_Configuration::getArray() wrong option
+     * Test \SimpleSAML\Configuration::getArray() wrong option
      * @expectedException Exception
      */
-    public function testGetArrayWrong() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetArrayWrong()
+    {
+        $c = Configuration::loadFromArray([
             'opt' => 'not_an_array',
-        ));
+        ]);
         $c->getArray('opt');
     }
 
     /**
-     * Test SimpleSAML_Configuration::getArrayize()
+     * Test \SimpleSAML\Configuration::getArrayize()
      */
-    public function testGetArrayize() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetArrayize()
+    {
+        $c = Configuration::loadFromArray([
             'opt' => array('a', 'b', 'c'),
             'opt_int' => 42,
             'opt_str' => 'string',
-        ));
+        ]);
         $this->assertEquals($c->getArrayize('missing_opt', '--missing--'), '--missing--');
         $this->assertEquals($c->getArrayize('opt'), array('a', 'b', 'c'));
         $this->assertEquals($c->getArrayize('opt_int'), array(42));
@@ -437,126 +466,134 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
     }
 
     /**
-     * Test SimpleSAML_Configuration::getArrayizeString()
+     * Test \SimpleSAML\Configuration::getArrayizeString()
      */
-    public function testGetArrayizeString() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetArrayizeString()
+    {
+        $c = Configuration::loadFromArray([
             'opt' => array('a', 'b', 'c'),
             'opt_str' => 'string',
-        ));
+        ]);
         $this->assertEquals($c->getArrayizeString('missing_opt', '--missing--'), '--missing--');
         $this->assertEquals($c->getArrayizeString('opt'), array('a', 'b', 'c'));
         $this->assertEquals($c->getArrayizeString('opt_str'), array('string'));
     }
 
     /**
-     * Test SimpleSAML_Configuration::getArrayizeString() option with an array that contains something that isn't a string.
+     * Test \SimpleSAML\Configuration::getArrayizeString() option with an array that contains something that isn't a string.
      * @expectedException Exception
      */
-    public function testGetArrayizeStringWrongValue() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetArrayizeStringWrongValue()
+    {
+        $c = Configuration::loadFromArray([
             'opt' => array('a', 'b', 42),
-        ));
+        ]);
         $c->getArrayizeString('opt');
     }
 
     /**
-     * Test SimpleSAML_Configuration::getConfigItem()
+     * Test \SimpleSAML\Configuration::getConfigItem()
      */
-    public function testGetConfigItem() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetConfigItem()
+    {
+        $c = Configuration::loadFromArray([
             'opt' => array('a' => 42),
-        ));
+        ]);
         $this->assertEquals($c->getConfigItem('missing_opt', '--missing--'), '--missing--');
         $opt = $c->getConfigItem('opt');
-        $this->assertInstanceOf('SimpleSAML_Configuration', $opt);
+        $this->assertInstanceOf('SimpleSAML\Configuration', $opt);
         $this->assertEquals($opt->getValue('a'), 42);
     }
 
     /**
-     * Test SimpleSAML_Configuration::getConfigItem() wrong option
+     * Test \SimpleSAML\Configuration::getConfigItem() wrong option
      * @expectedException Exception
      */
-    public function testGetConfigItemWrong() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetConfigItemWrong()
+    {
+        $c = Configuration::loadFromArray([
             'opt' => 'not_an_array',
-        ));
+        ]);
         $c->getConfigItem('opt');
     }
 
     /**
-     * Test SimpleSAML_Configuration::getConfigList()
+     * Test \SimpleSAML\Configuration::getConfigList()
      */
-    public function testGetConfigList() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetConfigList()
+    {
+        $c = Configuration::loadFromArray([
             'opts' => array(
                'a' => array('opt1' => 'value1'),
                'b' => array('opt2' => 'value2'),
             ),
-        ));
+        ]);
         $this->assertEquals($c->getConfigList('missing_opt', '--missing--'), '--missing--');
         $opts = $c->getConfigList('opts');
         $this->assertInternalType('array', $opts);
         $this->assertEquals(array_keys($opts), array('a', 'b'));
-        $this->assertInstanceOf('SimpleSAML_Configuration', $opts['a']);
+        $this->assertInstanceOf('SimpleSAML\Configuration', $opts['a']);
         $this->assertEquals($opts['a']->getValue('opt1'), 'value1');
-        $this->assertInstanceOf('SimpleSAML_Configuration', $opts['b']);
+        $this->assertInstanceOf('SimpleSAML\Configuration', $opts['b']);
         $this->assertEquals($opts['b']->getValue('opt2'), 'value2');
     }
 
     /**
-     * Test SimpleSAML_Configuration::getConfigList() wrong option
+     * Test \SimpleSAML\Configuration::getConfigList() wrong option
      * @expectedException Exception
      */
-    public function testGetConfigListWrong() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetConfigListWrong()
+    {
+        $c = Configuration::loadFromArray([
             'opt' => 'not_an_array',
-        ));
+        ]);
         $c->getConfigList('opt');
     }
 
 
     /**
-     * Test SimpleSAML_Configuration::getConfigList() with an array of wrong options.
+     * Test \SimpleSAML\Configuration::getConfigList() with an array of wrong options.
      * @expectedException Exception
      */
     public function testGetConfigListWrongArrayValues()
     {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+        $c = Configuration::loadFromArray([
             'opts' => array(
                 'a',
                 'b',
             ),
-        ));
+        ]);
         $c->getConfigList('opts');
     }
 
 
     /**
-     * Test SimpleSAML_Configuration::getOptions()
+     * Test \SimpleSAML\Configuration::getOptions()
      */
-    public function testGetOptions() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetOptions()
+    {
+        $c = Configuration::loadFromArray([
             'a' => true,
             'b' => null,
-        ));
+        ]);
         $this->assertEquals($c->getOptions(), array('a', 'b'));
     }
 
     /**
-     * Test SimpleSAML_Configuration::toArray()
+     * Test \SimpleSAML\Configuration::toArray()
      */
-    public function testToArray() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testToArray()
+    {
+        $c = Configuration::loadFromArray([
             'a' => true,
             'b' => null,
-        ));
+        ]);
         $this->assertEquals($c->toArray(), array('a' => true, 'b' => null));
     }
 
 
     /**
-     * Test SimpleSAML_Configuration::getDefaultEndpoint().
+     * Test \SimpleSAML\Configuration::getDefaultEndpoint().
      *
      * Iterate over all different valid definitions of endpoints and check if the expected output is produced.
      */
@@ -697,7 +734,7 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
         // run all general tests with AssertionConsumerService endpoint type
         foreach ($acs_eps as $i => $ep) {
             $a['AssertionConsumerService'] = $ep;
-            $c = SimpleSAML_Configuration::loadFromArray($a);
+            $c = Configuration::loadFromArray($a);
             $this->assertEquals($acs_expected_eps[$i], $c->getDefaultEndpoint(
                 'AssertionConsumerService',
                 $valid_bindings
@@ -706,7 +743,7 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
 
         // now make sure SingleSignOnService, SingleLogoutService and ArtifactResolutionService works fine
         $a['metadata-set'] = 'shib13-idp-remote';
-        $c = SimpleSAML_Configuration::loadFromArray($a);
+        $c = Configuration::loadFromArray($a);
         $this->assertEquals(
             array(
                 'Location' => 'https://example.com/sso',
@@ -715,7 +752,7 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
             $c->getDefaultEndpoint('SingleSignOnService')
         );
         $a['metadata-set'] = 'saml20-idp-remote';
-        $c = SimpleSAML_Configuration::loadFromArray($a);
+        $c = Configuration::loadFromArray($a);
         $this->assertEquals(
             array(
                 'Location' => 'https://example.com/ars',
@@ -734,7 +771,7 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
         // test for old shib1.3 AssertionConsumerService
         $a['metadata-set'] = 'shib13-sp-remote';
         $a['AssertionConsumerService'] = 'https://example.com/endpoint.php';
-        $c = SimpleSAML_Configuration::loadFromArray($a);
+        $c = Configuration::loadFromArray($a);
         $this->assertEquals(
             array(
                 'Location' => 'https://example.com/endpoint.php',
@@ -751,7 +788,7 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
                 'isDefault' => true,
             ),
         );
-        $c = SimpleSAML_Configuration::loadFromArray($a);
+        $c = Configuration::loadFromArray($a);
         try {
             $c->getDefaultEndpoint('SingleLogoutService', $valid_bindings);
             $this->fail('Failed to detect invalid endpoint binding.');
@@ -762,7 +799,7 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
             );
         }
         $a['metadata-set'] = 'foo';
-        $c = SimpleSAML_Configuration::loadFromArray($a);
+        $c = Configuration::loadFromArray($a);
         try {
             $c->getDefaultEndpoint('SingleSignOnService');
             $this->fail('No valid metadata set specified.');
@@ -773,12 +810,12 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
 
 
     /**
-     * Test SimpleSAML_Configuration::getEndpoints().
+     * Test \SimpleSAML\Configuration::getEndpoints().
      */
     public function testGetEndpoints()
     {
         // test response location for old-style configurations
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+        $c = Configuration::loadFromArray(array(
             'metadata-set' => 'saml20-idp-remote',
             'SingleSignOnService' => 'https://example.com/endpoint.php',
             'SingleSignOnServiceResponse' => 'https://example.com/response.php',
@@ -866,7 +903,7 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
         // now run all the tests expecting the correct exception message
         foreach ($tests as $i => $test) {
             $a['SingleSignOnService'] = $test;
-            $c = SimpleSAML_Configuration::loadFromArray($a);
+            $c = Configuration::loadFromArray($a);
             try {
                 $c->getEndpoints('SingleSignOnService');
             } catch (Exception $e) {
@@ -877,54 +914,81 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
 
 
     /**
-     * Test SimpleSAML_Configuration::getLocalizedString()
+     * Test \SimpleSAML\Configuration::getLocalizedString()
      */
-    public function testGetLocalizedString() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetLocalizedString()
+    {
+        $c = Configuration::loadFromArray([
             'str_opt' => 'Hello World!',
             'str_array' => array(
                 'en' => 'Hello World!',
                 'no' => 'Hei Verden!',
             ),
-        ));
+        ]);
         $this->assertEquals($c->getLocalizedString('missing_opt', '--missing--'), '--missing--');
         $this->assertEquals($c->getLocalizedString('str_opt'), array('en' => 'Hello World!'));
         $this->assertEquals($c->getLocalizedString('str_array'), array('en' => 'Hello World!', 'no' => 'Hei Verden!'));
     }
 
     /**
-     * Test SimpleSAML_Configuration::getLocalizedString() not array nor simple string
+     * Test \SimpleSAML\Configuration::getLocalizedString() not array nor simple string
      * @expectedException Exception
      */
-    public function testGetLocalizedStringNotArray() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetLocalizedStringNotArray()
+    {
+        $c = Configuration::loadFromArray([
             'opt' => 42,
-        ));
+        ]);
         $c->getLocalizedString('opt');
     }
 
     /**
-     * Test SimpleSAML_Configuration::getLocalizedString() not string key
+     * Test \SimpleSAML\Configuration::getLocalizedString() not string key
      * @expectedException Exception
      */
-    public function testGetLocalizedStringNotStringKey() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetLocalizedStringNotStringKey()
+    {
+        $c = Configuration::loadFromArray([
             'opt' => array(42 => 'text'),
-        ));
+        ]);
         $c->getLocalizedString('opt');
     }
 
     /**
-     * Test SimpleSAML_Configuration::getLocalizedString() not string value
+     * Test \SimpleSAML\Configuration::getLocalizedString() not string value
      * @expectedException Exception
      */
-    public function testGetLocalizedStringNotStringValue() {
-        $c = SimpleSAML_Configuration::loadFromArray(array(
+    public function testGetLocalizedStringNotStringValue()
+    {
+        $c = Configuration::loadFromArray([
             'opt' => array('en' => 42),
-        ));
+        ]);
         $c->getLocalizedString('opt');
     }
 
+    /**
+     * Test \SimpleSAML\Configuration::getConfig() nonexistent file
+     * @expectedException Exception
+     */
+    public function testGetConfigNonexistentFile()
+    {
+        Configuration::getConfig('nonexistent-nopreload.php');
+    }
+
+    /**
+     * Test \SimpleSAML\Configuration::getConfig() preloaded nonexistent file
+     */
+    public function testGetConfigNonexistentFilePreload()
+    {
+        $c = Configuration::loadFromArray([
+            'key' => 'value'
+        ]);
+        $virtualFile = 'nonexistent-preload.php';
+        Configuration::setPreLoadedConfig($c, $virtualFile);
+        $nc = Configuration::getConfig($virtualFile);
+        $this->assertEquals('value', $nc->getValue('key', null));
+    }
+
     /**
      * Test that Configuration objects can be initialized from an array.
      *
@@ -936,11 +1000,11 @@ class Test_SimpleSAML_Configuration extends SimpleSAML\Test\Utils\ClearStateTest
             'key' => 'value'
         );
         // test loading a custom instance
-        SimpleSAML_Configuration::loadFromArray($c, '', 'dummy');
-        $this->assertEquals('value', SimpleSAML_Configuration::getInstance('dummy')->getValue('key', null));
+        Configuration::loadFromArray($c, '', 'dummy');
+        $this->assertEquals('value', Configuration::getInstance('dummy')->getValue('key', null));
 
         // test loading the default instance
-        SimpleSAML_Configuration::loadFromArray($c, '', 'simplesaml');
-        $this->assertEquals('value', SimpleSAML_Configuration::getInstance()->getValue('key', null));
+        Configuration::loadFromArray($c, '', 'simplesaml');
+        $this->assertEquals('value', Configuration::getInstance()->getValue('key', null));
     }
 }
diff --git a/tests/lib/SimpleSAML/DatabaseTest.php b/tests/lib/SimpleSAML/DatabaseTest.php
index 5f04dd87b9bf3e0322ccc3da6c367f57212e6bf3..b99575b66c556c191c0e198e5d05831adf91c36f 100644
--- a/tests/lib/SimpleSAML/DatabaseTest.php
+++ b/tests/lib/SimpleSAML/DatabaseTest.php
@@ -3,7 +3,7 @@
 use PHPUnit\Framework\TestCase;
 
 /**
- * This test ensures that the SimpleSAML_Database class can properly
+ * This test ensures that the \SimpleSAML\Database class can properly
  * query a database.
  *
  * It currently uses sqlite to test, but an alternate config.php file
@@ -13,16 +13,16 @@ use PHPUnit\Framework\TestCase;
  * @author Tyler Antonio, University of Alberta. <tantonio@ualberta.ca>
  * @package SimpleSAMLphp
  */
-class SimpleSAML_DatabaseTest extends TestCase
-{
 
+class DatabaseTest extends TestCase
+{
     /**
-     * @var SimpleSAML_Configuration
+     * @var \SimpleSAML\Configuration
      */
     protected $config;
 
     /**
-     * @var SimpleSAML\Database
+     * @var \SimpleSAML\Database
      */
     protected $db;
 
@@ -59,10 +59,10 @@ class SimpleSAML_DatabaseTest extends TestCase
             'database.slaves'     => array(),
         );
 
-        $this->config = new SimpleSAML_Configuration($config, "test/SimpleSAML/DatabaseTest.php");
+        $this->config = new \SimpleSAML\Configuration($config, "test/SimpleSAML/DatabaseTest.php");
 
         // Ensure that we have a functional configuration class
-        $this->assertInstanceOf('SimpleSAML_Configuration', $this->config);
+        $this->assertInstanceOf('SimpleSAML\Configuration', $this->config);
         $this->assertEquals($config['database.dsn'], $this->config->getString('database.dsn'));
 
         $this->db = SimpleSAML\Database::getInstance($this->config);
@@ -91,7 +91,7 @@ class SimpleSAML_DatabaseTest extends TestCase
             'database.slaves'     => array(),
         );
 
-        $this->config = new SimpleSAML_Configuration($config, "test/SimpleSAML/DatabaseTest.php");
+        $this->config = new \SimpleSAML\Configuration($config, "test/SimpleSAML/DatabaseTest.php");
         $db = SimpleSAML\Database::getInstance($this->config);
     }
 
@@ -122,13 +122,13 @@ class SimpleSAML_DatabaseTest extends TestCase
             'database.slaves'     => array(),
         );
 
-        $config1 = new SimpleSAML_Configuration($config, "test/SimpleSAML/DatabaseTest.php");
-        $config2 = new SimpleSAML_Configuration($config2, "test/SimpleSAML/DatabaseTest.php");
-        $config3 = new SimpleSAML_Configuration($config, "test/SimpleSAML/DatabaseTest.php");
+        $config1 = new \SimpleSAML\Configuration($config, "test/SimpleSAML/DatabaseTest.php");
+        $config2 = new \SimpleSAML\Configuration($config2, "test/SimpleSAML/DatabaseTest.php");
+        $config3 = new \SimpleSAML\Configuration($config, "test/SimpleSAML/DatabaseTest.php");
 
-        $db1 = SimpleSAML\Database::getInstance($config1);
-        $db2 = SimpleSAML\Database::getInstance($config2);
-        $db3 = SimpleSAML\Database::getInstance($config3);
+        $db1 = \SimpleSAML\Database::getInstance($config1);
+        $db2 = \SimpleSAML\Database::getInstance($config2);
+        $db3 = \SimpleSAML\Database::getInstance($config3);
 
         $generateInstanceId = self::getMethod('generateInstanceId');
 
@@ -196,8 +196,8 @@ class SimpleSAML_DatabaseTest extends TestCase
             ),
         );
 
-        $sspConfiguration = new SimpleSAML_Configuration($config, "test/SimpleSAML/DatabaseTest.php");
-        $msdb = SimpleSAML\Database::getInstance($sspConfiguration);
+        $sspConfiguration = new \SimpleSAML\Configuration($config, "test/SimpleSAML/DatabaseTest.php");
+        $msdb = \SimpleSAML\Database::getInstance($sspConfiguration);
 
         $slaves = PHPUnit_Framework_Assert::readAttribute($msdb, 'dbSlaves');
         $gotSlave = spl_object_hash($getSlave->invokeArgs($msdb, array()));
diff --git a/tests/lib/SimpleSAML/Locale/LanguageTest.php b/tests/lib/SimpleSAML/Locale/LanguageTest.php
index 4b76c09d6187570990a2e4e0e45419a0f05e179c..09c53d760375c51d9c1fbb134580062b405bf711 100644
--- a/tests/lib/SimpleSAML/Locale/LanguageTest.php
+++ b/tests/lib/SimpleSAML/Locale/LanguageTest.php
@@ -3,24 +3,23 @@
 namespace SimpleSAML\Test\Locale;
 
 use PHPUnit\Framework\TestCase;
+use SimpleSAML\Configuration;
 use SimpleSAML\Locale\Language;
 
 class LanguageTest extends TestCase
 {
-
-
     /**
      * Test SimpleSAML\Locale\Language::getDefaultLanguage().
      */
     public function testGetDefaultLanguage()
     {
         // test default
-        $c = \SimpleSAML_Configuration::loadFromArray(array());
+        $c = Configuration::loadFromArray(array());
         $l = new Language($c);
         $this->assertEquals('en', $l->getDefaultLanguage());
 
         // test defaults coming from configuration
-        $c = \SimpleSAML_Configuration::loadFromArray(array(
+        $c = Configuration::loadFromArray(array(
             'language.available' => array('en', 'es', 'nn'),
             'language.default' => 'es',
         ));
@@ -35,16 +34,16 @@ class LanguageTest extends TestCase
     public function testGetLanguageCookie()
     {
         // test it works when no cookie is set
-        \SimpleSAML_Configuration::loadFromArray(array(), '', 'simplesaml');
+        Configuration::loadFromArray(array(), '', 'simplesaml');
         $this->assertNull(Language::getLanguageCookie());
 
         // test that it works fine with defaults
-        \SimpleSAML_Configuration::loadFromArray(array(), '', 'simplesaml');
+        Configuration::loadFromArray(array(), '', 'simplesaml');
         $_COOKIE['language'] = 'en';
         $this->assertEquals('en', Language::getLanguageCookie());
 
         // test that it works with non-defaults
-        \SimpleSAML_Configuration::loadFromArray(array(
+        Configuration::loadFromArray(array(
             'language.available' => array('en', 'es', 'nn'),
             'language.cookie.name' => 'xyz'
         ), '', 'simplesaml');
@@ -58,8 +57,8 @@ class LanguageTest extends TestCase
      */
     public function testGetLanguageListNoConfig()
     {
-        // test defaults
-        $c = \SimpleSAML_Configuration::loadFromArray(array(), '', 'simplesaml');
+        // test default
+        $c = Configuration::loadFromArray(array(), '', 'simplesaml');
         $l = new Language($c);
         $l->setLanguage('en');
         $this->assertEquals(array('en' => true), $l->getLanguageList());
@@ -72,7 +71,7 @@ class LanguageTest extends TestCase
     public function testGetLanguageListCorrectConfig()
     {
         // test langs from from language_names
-        $c = \SimpleSAML_Configuration::loadFromArray(array(
+        $c = Configuration::loadFromArray(array(
             'language.available' => array('en', 'nn', 'es'),
         ), '', 'simplesaml');
         $l = new Language($c);
@@ -91,7 +90,7 @@ class LanguageTest extends TestCase
     public function testGetLanguageListIncorrectConfig()
     {
         // test non-existent langs
-        $c = \SimpleSAML_Configuration::loadFromArray(array(
+        $c = Configuration::loadFromArray(array(
             'language.available' => array('foo', 'bar'),
         ), '', 'simplesaml');
         $l = new Language($c);
@@ -106,12 +105,12 @@ class LanguageTest extends TestCase
     public function testGetLanguageParameterName()
     {
         // test for default configuration
-        $c = \SimpleSAML_Configuration::loadFromArray(array(), '', 'simplesaml');
+        $c = Configuration::loadFromArray(array(), '', 'simplesaml');
         $l = new Language($c);
         $this->assertEquals('language', $l->getLanguageParameterName());
 
         // test for valid configuration
-        $c = \SimpleSAML_Configuration::loadFromArray(array(
+        $c = Configuration::loadFromArray(array(
             'language.parameter.name' => 'xyz'
         ), '', 'simplesaml');
         $l = new Language($c);
@@ -125,13 +124,13 @@ class LanguageTest extends TestCase
     public function testIsLanguageRTL()
     {
         // test defaults
-        $c = \SimpleSAML_Configuration::loadFromArray(array(), '', 'simplesaml');
+        $c = Configuration::loadFromArray(array(), '', 'simplesaml');
         $l = new Language($c);
         $l->setLanguage('en');
         $this->assertFalse($l->isLanguageRTL());
 
         // test non-defaults, non-RTL
-        $c = \SimpleSAML_Configuration::loadFromArray(array(
+        $c = Configuration::loadFromArray(array(
             'language.rtl' => array('foo', 'bar'),
         ), '', 'simplesaml');
         $l = new Language($c);
@@ -139,7 +138,7 @@ class LanguageTest extends TestCase
         $this->assertFalse($l->isLanguageRTL());
 
         // test non-defaults, RTL
-        $c = \SimpleSAML_Configuration::loadFromArray(array(
+        $c = Configuration::loadFromArray(array(
             'language.available' => array('en', 'nn', 'es'),
             'language.rtl' => array('nn', 'es'),
         ), '', 'simplesaml');
@@ -155,7 +154,7 @@ class LanguageTest extends TestCase
     public function testSetLanguage()
     {
         // test with valid configuration, no cookies set
-        $c = \SimpleSAML_Configuration::loadFromArray(array(
+        $c = Configuration::loadFromArray(array(
             'language.available' => array('en', 'nn', 'es'),
             'language.parameter.name' => 'xyz',
             'language.parameter.setcookie' => false,
diff --git a/tests/lib/SimpleSAML/Locale/LocalizationTest.php b/tests/lib/SimpleSAML/Locale/LocalizationTest.php
index d38af4add61227531ff0710238450c7c8a1e7c56..c45eb0974f32b60651c45bfeae38fc1358957d72 100644
--- a/tests/lib/SimpleSAML/Locale/LocalizationTest.php
+++ b/tests/lib/SimpleSAML/Locale/LocalizationTest.php
@@ -4,8 +4,7 @@ namespace SimpleSAML\Test\Locale;
 
 use PHPUnit\Framework\TestCase;
 use SimpleSAML\Locale\Localization;
-use \SimpleSAML_Configuration as Configuration;
-
+use \SimpleSAML\Configuration;
 
 class LocalizationTest extends TestCase
 {
@@ -22,7 +21,7 @@ class LocalizationTest extends TestCase
     public function testLocalization()
     {
         // The constructor should activate the default domain
-        $c = \SimpleSAML_Configuration::loadFromArray(
+        $c = Configuration::loadFromArray(
             array('language.i18n.backend' => 'SimpleSAMLphp')
         );
         $l = new Localization($c);
@@ -35,7 +34,7 @@ class LocalizationTest extends TestCase
      */
     public function testAddDomain()
     {
-        $c = \SimpleSAML_Configuration::loadFromArray(
+        $c = Configuration::loadFromArray(
             array('language.i18n.backend' => 'gettext/gettext')
         );
         $l = new Localization($c);
diff --git a/tests/lib/SimpleSAML/Locale/TranslateTest.php b/tests/lib/SimpleSAML/Locale/TranslateTest.php
index 93d6c441ba830b160c79f06925426331ccb082ff..48d92377d19d942bd7ee5e9efc814ac4315a6843 100644
--- a/tests/lib/SimpleSAML/Locale/TranslateTest.php
+++ b/tests/lib/SimpleSAML/Locale/TranslateTest.php
@@ -14,7 +14,7 @@ class TranslateTest extends TestCase
     public function testNoop()
     {
         // test default
-        $c = \SimpleSAML_Configuration::loadFromArray(array());
+        $c = \SimpleSAML\Configuration::loadFromArray(array());
         $t = new Translate($c);
         $testString = 'Blablabla';
         $this->assertEquals($testString, $t->noop($testString));
@@ -25,7 +25,7 @@ class TranslateTest extends TestCase
      */
     public function testTFallback()
     {
-        $c = \SimpleSAML_Configuration::loadFromArray(array());
+        $c = \SimpleSAML\Configuration::loadFromArray(array());
         $t = new Translate($c);
         $testString = 'Blablabla';
 
diff --git a/tests/lib/SimpleSAML/Metadata/MetaDataStorageSourceTest.php b/tests/lib/SimpleSAML/Metadata/MetaDataStorageSourceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ce301db53d5c21324ebd4a9b7486810e54cddf3d
--- /dev/null
+++ b/tests/lib/SimpleSAML/Metadata/MetaDataStorageSourceTest.php
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * Class MetaDataStorageSourceTest
+ */
+
+class MetaDataStorageSourceTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test \SimpleSAML\Metadata\MetaDataStorageSourceTest::getConfig XML bad source
+     * @expectedException \Exception
+     */
+    public function testBadXMLSource() {
+        \SimpleSAML\Metadata\MetaDataStorageSource::getSource(["type"=>"xml", "foo"=>"baa"]);
+    }
+
+    /**
+     * Test \SimpleSAML\Metadata\MetaDataStorageSourceTest::getConfig invalid static XML source
+     * @expectedException Exception
+     */
+    public function testInvalidStaticXMLSource() {
+        $strTestXML = "
+<EntityDescriptor ID=\"_12345678-90ab-cdef-1234-567890abcdef\" entityID=\"https://saml.idp/entityid\" xmlns=\"urn:oasis:names:tc:SAML:2.0:metadata\">
+</EntityDescriptor>
+";
+        \SimpleSAML\Metadata\MetaDataStorageSource::getSource(["type"=>"xml", "xml"=>$strTestXML]);
+    }
+
+    /**
+     * Test \SimpleSAML\Metadata\MetaDataStorageSourceTest::getConfig XML static XML source
+     */
+    public function testStaticXMLSource() {
+        $testEntityId = "https://saml.idp/entityid";
+        $strTestXML = "
+<EntityDescriptor ID=\"_12345678-90ab-cdef-1234-567890abcdef\" entityID=\"$testEntityId\" xmlns=\"urn:oasis:names:tc:SAML:2.0:metadata\">
+<RoleDescriptor xsi:type=\"fed:ApplicationServiceType\"
+protocolSupportEnumeration=\"http://docs.oasis-open.org/ws-sx/ws-trust/200512 http://schemas.xmlsoap.org/ws/2005/02/trust http://docs.oasis-open.org/wsfed/federation/200706\"
+ServiceDisplayName=\"SimpleSAMLphp Test\"
+xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
+xmlns:fed=\"http://docs.oasis-open.org/wsfed/federation/200706\">
+<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
+<SingleSignOnService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect\" Location=\"https://saml.idp/sso/\"/>
+<SingleLogoutService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect\" Location=\"https://saml.idp/logout/\"/>
+</RoleDescriptor>
+<IDPSSODescriptor protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol\"/>
+</EntityDescriptor>
+";
+        // The primary test here is that - in contrast to the others above - this loads without error
+        // As a secondary thing, check that the entity ID from the static source provided can be extracted
+        $source = \SimpleSAML\Metadata\MetaDataStorageSource::getSource(["type"=>"xml", "xml"=>$strTestXML]);
+        $idpSet = $source->getMetadataSet("saml20-idp-remote");
+        $this->assertArrayHasKey($testEntityId, $idpSet,  "Did not extract expected IdP entity ID from static XML source");
+	// Finally verify that a different entity ID does not get loaded
+        $this->assertCount(1, $idpSet, "Unexpectedly got metadata for an alternate entity than that defined");
+    }
+}
diff --git a/tests/lib/SimpleSAML/Metadata/SAMLBuilderTest.php b/tests/lib/SimpleSAML/Metadata/SAMLBuilderTest.php
index d9aa96a5a60c8d9778655eb78f0769c300b96aff..1a57bbab0a5bafaba0b752ad9a25ad3d461520e1 100644
--- a/tests/lib/SimpleSAML/Metadata/SAMLBuilderTest.php
+++ b/tests/lib/SimpleSAML/Metadata/SAMLBuilderTest.php
@@ -1,13 +1,14 @@
 <?php
 
 use PHPUnit\Framework\TestCase;
+use SimpleSAML\Metadata\SAMLBuilder;
 
 /**
- * Class SimpleSAML_Metadata_SAMLBuilderTest
+ * Class SAMLBuilderTest
  */
-class SimpleSAML_Metadata_SAMLBuilderTest extends TestCase
-{
 
+class SAMLBuilderTest extends TestCase
+{
     /**
      * Test the requested attributes are valued correctly.
      */
@@ -29,7 +30,7 @@ class SimpleSAML_Metadata_SAMLBuilderTest extends TestCase
             ),
         );
 
-        $samlBuilder = new SimpleSAML_Metadata_SAMLBuilder($entityId);
+        $samlBuilder = new SAMLBuilder($entityId);
         $samlBuilder->addMetadata($set, $metadata);
 
         $spDesc = $samlBuilder->getEntityDescriptor();
@@ -58,7 +59,7 @@ class SimpleSAML_Metadata_SAMLBuilderTest extends TestCase
             ),
         );
 
-        $samlBuilder = new SimpleSAML_Metadata_SAMLBuilder($entityId);
+        $samlBuilder = new SAMLBuilder($entityId);
         $samlBuilder->addMetadata($set, $metadata);
 
         $spDesc = $samlBuilder->getEntityDescriptor();
@@ -89,7 +90,7 @@ class SimpleSAML_Metadata_SAMLBuilderTest extends TestCase
             ),
         );
 
-        $samlBuilder = new SimpleSAML_Metadata_SAMLBuilder($entityId);
+        $samlBuilder = new SAMLBuilder($entityId);
         $samlBuilder->addMetadata($set, $metadata);
 
         $spDesc = $samlBuilder->getEntityDescriptor();
@@ -118,7 +119,7 @@ class SimpleSAML_Metadata_SAMLBuilderTest extends TestCase
             ),
         );
 
-        $samlBuilder = new SimpleSAML_Metadata_SAMLBuilder($entityId);
+        $samlBuilder = new SAMLBuilder($entityId);
         $samlBuilder->addMetadata($set, $metadata);
 
         $spDesc = $samlBuilder->getEntityDescriptor();
@@ -136,6 +137,92 @@ class SimpleSAML_Metadata_SAMLBuilderTest extends TestCase
         }
     }
 
+    /**
+     * Test the working of the isDefault config option
+     */
+    public function testAttributeConsumingServiceDefault()
+    {
+        $entityId = 'https://entity.example.com/id';
+        $set = 'saml20-sp-remote';
+
+        $metadata = array(
+            'entityid'     => $entityId,
+            'name'         => array('en' => 'Test SP'),
+            'metadata-set' => $set,
+            'attributes'   => array(
+                'eduPersonTargetedID'    => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.10',
+                'eduPersonPrincipalName' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6',
+            ),
+        );
+
+        $samlBuilder = new SAMLBuilder($entityId);
+        $samlBuilder->addMetadata($set, $metadata);
+
+        $spDesc = $samlBuilder->getEntityDescriptor();
+        $acs = $spDesc->getElementsByTagName("AttributeConsumingService");
+	$acs1 = $acs->item(0);
+        $this->assertFalse($acs1->hasAttribute("isDefault"));
+
+	$metadata['attributes.isDefault'] = true;
+
+        $samlBuilder = new SAMLBuilder($entityId);
+        $samlBuilder->addMetadata($set, $metadata);
+        $spDesc = $samlBuilder->getEntityDescriptor();
+        $acs = $spDesc->getElementsByTagName("AttributeConsumingService");
+	$acs1 = $acs->item(0);
+        $this->assertTrue($acs1->hasAttribute("isDefault"));
+        $this->assertEquals("true", $acs1->getAttribute("isDefault"));
+
+	$metadata['attributes.isDefault'] = false;
+
+        $samlBuilder = new SAMLBuilder($entityId);
+        $samlBuilder->addMetadata($set, $metadata);
+        $spDesc = $samlBuilder->getEntityDescriptor();
+        $acs = $spDesc->getElementsByTagName("AttributeConsumingService");
+	$acs1 = $acs->item(0);
+        $this->assertTrue($acs1->hasAttribute("isDefault"));
+        $this->assertEquals("false", $acs1->getAttribute("isDefault"));
+    }
+
+    /**
+     * Test the index option is used correctly.
+     */
+    public function testAttributeConsumingServiceIndex()
+    {
+        $entityId = 'https://entity.example.com/id';
+        $set = 'saml20-sp-remote';
+
+        $metadata = array(
+            'entityid'     => $entityId,
+            'name'         => array('en' => 'Test SP'),
+            'metadata-set' => $set,
+            'attributes'   => array(
+                'eduPersonTargetedID'    => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.10',
+                'eduPersonPrincipalName' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6',
+            ),
+        );
+
+        $samlBuilder = new SAMLBuilder($entityId);
+        $samlBuilder->addMetadata($set, $metadata);
+
+        $spDesc = $samlBuilder->getEntityDescriptor();
+        $acs = $spDesc->getElementsByTagName("AttributeConsumingService");
+	$acs1 = $acs->item(0);
+        $this->assertTrue($acs1->hasAttribute("index"));
+        $this->assertEquals("0", $acs1->getAttribute("index"));
+
+	$metadata['attributes.index'] = 15;
+
+        $samlBuilder = new SAMLBuilder($entityId);
+        $samlBuilder->addMetadata($set, $metadata);
+
+        $spDesc = $samlBuilder->getEntityDescriptor();
+        $acs = $spDesc->getElementsByTagName("AttributeConsumingService");
+	$acs1 = $acs->item(0);
+        $this->assertTrue($acs1->hasAttribute("index"));
+        $this->assertEquals("15", $acs1->getAttribute("index"));
+    }
+
     /**
      * Test the required protocolSupportEnumeration in AttributeAuthorityDescriptor
      */
@@ -159,7 +246,7 @@ class SimpleSAML_Metadata_SAMLBuilderTest extends TestCase
                 ),
             );
 
-        $samlBuilder = new SimpleSAML_Metadata_SAMLBuilder($entityId);
+        $samlBuilder = new SAMLBuilder($entityId);
         $samlBuilder->addMetadata($set, $metadata);
         $entityDescriptorXml = $samlBuilder->getEntityDescriptorText();
 
@@ -174,7 +261,7 @@ class SimpleSAML_Metadata_SAMLBuilderTest extends TestCase
                 0 => 'urn:oasis:names:tc:SAML:1.1:protocol',
                 1 => 'urn:oasis:names:tc:SAML:2.0:protocol',
             );
-        $samlBuilder = new SimpleSAML_Metadata_SAMLBuilder($entityId);
+        $samlBuilder = new SAMLBuilder($entityId);
         $samlBuilder->addMetadata($set, $metadata);
         $entityDescriptorXml = $samlBuilder->getEntityDescriptorText();
 
diff --git a/tests/lib/SimpleSAML/Metadata/SAMLParserTest.php b/tests/lib/SimpleSAML/Metadata/SAMLParserTest.php
index 0e34ad063e006f336fe978f7178a51a516eea086..0a82545981280a71cde2e2f4917b0e911c08947f 100644
--- a/tests/lib/SimpleSAML/Metadata/SAMLParserTest.php
+++ b/tests/lib/SimpleSAML/Metadata/SAMLParserTest.php
@@ -1,4 +1,5 @@
 <?php
+
 namespace SimpleSAML\Metadata;
 
 use PHPUnit\Framework\TestCase;
@@ -32,7 +33,7 @@ XML
         );
 
 
-        $entities = \SimpleSAML_Metadata_SAMLParser::parseDescriptorsElement($document->documentElement);
+        $entities = \SimpleSAML\Metadata\SAMLParser::parseDescriptorsElement($document->documentElement);
         $this->assertArrayHasKey('theEntityID', $entities);
         // RegistrationInfo is accessible in the SP or IDP metadata accessors
         $metadata = $entities['theEntityID']->getMetadata20SP();
@@ -74,7 +75,7 @@ XML
 XML
         );
 
-        $entities = \SimpleSAML_Metadata_SAMLParser::parseDescriptorsElement($document->documentElement);
+        $entities = \SimpleSAML\Metadata\SAMLParser::parseDescriptorsElement($document->documentElement);
         $this->assertArrayHasKey('theEntityID', $entities);
         $this->assertArrayHasKey('subEntityId', $entities);
         // RegistrationInfo is accessible in the SP or IDP metadata accessors
@@ -116,7 +117,7 @@ XML
 XML
         );
 
-        $entities = \SimpleSAML_Metadata_SAMLParser::parseDescriptorsElement($document->documentElement);
+        $entities = \SimpleSAML\Metadata\SAMLParser::parseDescriptorsElement($document->documentElement);
         $this->assertArrayHasKey('theEntityID', $entities);
 
         $metadata = $entities['theEntityID']->getMetadata20SP();
diff --git a/tests/lib/SimpleSAML/ModuleTest.php b/tests/lib/SimpleSAML/ModuleTest.php
index 00cff258cabf8d7246cbcebedca1ebd80cc27968..8cb330896613f2ac69410072e5155007b871d6d2 100644
--- a/tests/lib/SimpleSAML/ModuleTest.php
+++ b/tests/lib/SimpleSAML/ModuleTest.php
@@ -1,4 +1,5 @@
 <?php
+
 namespace SimpleSAML\Test;
 
 use PHPUnit\Framework\TestCase;
@@ -6,8 +7,6 @@ use SimpleSAML\Module;
 
 class ModuleTest extends TestCase
 {
-
-
     /**
      * Test for SimpleSAML\Module::isModuleEnabled().
      */
@@ -36,7 +35,7 @@ class ModuleTest extends TestCase
      */
     public function testGetModuleURL()
     {
-        \SimpleSAML_Configuration::loadFromArray(array(
+        \SimpleSAML\Configuration::loadFromArray(array(
             'baseurlpath' => 'https://example.com/simplesaml/'
         ), '', 'simplesaml');
         $this->assertEquals(
@@ -113,8 +112,8 @@ class ModuleTest extends TestCase
         // test for valid subclasses
         $this->assertEquals('sspmod_core_Auth_Process_PHP', Module::resolveClass(
             'core:PHP',
-            'Auth_Process',
-            'SimpleSAML_Auth_ProcessingFilter'
+            'Auth\Process',
+            '\SimpleSAML\Auth\ProcessingFilter'
         ));
     }
 }
diff --git a/tests/lib/SimpleSAML/Store/RedisTest.php b/tests/lib/SimpleSAML/Store/RedisTest.php
index d17f4473a3f99b48db61f1e2b52f76aebbc23f0b..fbe770522eabb591172cd33abbab108d6e6e5a1e 100644
--- a/tests/lib/SimpleSAML/Store/RedisTest.php
+++ b/tests/lib/SimpleSAML/Store/RedisTest.php
@@ -3,7 +3,7 @@
 namespace SimpleSAML\Test\Store;
 
 use PHPUnit\Framework\TestCase;
-use \SimpleSAML_Configuration as Configuration;
+use \SimpleSAML\Configuration;
 use \SimpleSAML\Store;
 
 /**
@@ -84,7 +84,7 @@ class RedisTest extends TestCase
 
         $this->assertInstanceOf('SimpleSAML\Store\Redis', $store);
 
-        $this->clearInstance($config, '\SimpleSAML_Configuration');
+        $this->clearInstance($config, '\SimpleSAML\Configuration');
         $this->clearInstance($store, '\SimpleSAML\Store');
     }
 
diff --git a/tests/lib/SimpleSAML/Store/SQLTest.php b/tests/lib/SimpleSAML/Store/SQLTest.php
index 143632f9060f5ccfa4d992883ff68191bc7d4b34..1321726d3493da40d3a2f7b23cccc4f1ae833c81 100644
--- a/tests/lib/SimpleSAML/Store/SQLTest.php
+++ b/tests/lib/SimpleSAML/Store/SQLTest.php
@@ -3,7 +3,7 @@
 namespace SimpleSAML\Test\Store;
 
 use PHPUnit\Framework\TestCase;
-use \SimpleSAML_Configuration as Configuration;
+use \SimpleSAML\Configuration;
 use \SimpleSAML\Store;
 
 /**
@@ -19,7 +19,7 @@ class SQLTest extends TestCase
 {
     protected function setUp()
     {
-        \SimpleSAML_Configuration::loadFromArray(array(
+        Configuration::loadFromArray(array(
             'store.type'                    => 'sql',
             'store.sql.dsn'                 => 'sqlite::memory:',
             'store.sql.prefix'              => 'phpunit_',
@@ -50,7 +50,7 @@ class SQLTest extends TestCase
 
         $version = $store->getTableVersion('kvstore');
 
-        $this->assertEquals(1, $version);
+        $this->assertEquals(2, $version);
     }
 
     /**
@@ -176,7 +176,7 @@ class SQLTest extends TestCase
         $config = Configuration::getInstance();
         $store = Store::getInstance();
 
-        $this->clearInstance($config, '\SimpleSAML_Configuration');
+        $this->clearInstance($config, '\SimpleSAML\Configuration');
         $this->clearInstance($store, '\SimpleSAML\Store');
     }
 
diff --git a/tests/lib/SimpleSAML/StoreTest.php b/tests/lib/SimpleSAML/StoreTest.php
index 22641681dcd9143f351226d9d55797854ed811f9..61f0fe8237d291507390d1d4a58dee9c8b8d4cb9 100644
--- a/tests/lib/SimpleSAML/StoreTest.php
+++ b/tests/lib/SimpleSAML/StoreTest.php
@@ -3,7 +3,7 @@
 namespace SimpleSAML\Test;
 
 use PHPUnit\Framework\TestCase;
-use \SimpleSAML_Configuration as Configuration;
+use \SimpleSAML\Configuration;
 use \SimpleSAML\Store;
 
 /**
@@ -121,7 +121,7 @@ class StoreTest extends TestCase
         $config = Configuration::getInstance();
         $store = Store::getInstance();
 
-        $this->clearInstance($config, '\SimpleSAML_Configuration');
+        $this->clearInstance($config, '\SimpleSAML\Configuration');
         $this->clearInstance($store, '\SimpleSAML\Store');
     }
 
diff --git a/tests/lib/SimpleSAML/Utils/ArraysTest.php b/tests/lib/SimpleSAML/Utils/ArraysTest.php
index 0ec3e29bdf74250eb7a098fa230647db0e54f96f..5bed975d1d2d90ceb0742ae307e8d252ef7f92d5 100644
--- a/tests/lib/SimpleSAML/Utils/ArraysTest.php
+++ b/tests/lib/SimpleSAML/Utils/ArraysTest.php
@@ -10,7 +10,6 @@ use SimpleSAML\Utils\Arrays;
  */
 class ArraysTest extends TestCase
 {
-
     /**
      * Test the arrayize() function.
      */
diff --git a/tests/lib/SimpleSAML/Utils/AttributesTest.php b/tests/lib/SimpleSAML/Utils/AttributesTest.php
index 271b506848b0b76a1bcf4d6a94bac2d0b994fc09..0c1c8dba58c34472c556f9338cb207bb41247a4e 100644
--- a/tests/lib/SimpleSAML/Utils/AttributesTest.php
+++ b/tests/lib/SimpleSAML/Utils/AttributesTest.php
@@ -74,7 +74,7 @@ class AttributesTest extends TestCase
         );
         $expected = 'missing';
         $this->setExpectedException(
-            'SimpleSAML_Error_Exception',
+            '\SimpleSAML\Error\Exception',
             "No such attribute '".$expected."' found."
         );
         Attributes::getExpectedAttribute($attributes, $expected);
@@ -92,7 +92,7 @@ class AttributesTest extends TestCase
         );
         $expected = 'attribute';
         $this->setExpectedException(
-            'SimpleSAML_Error_Exception',
+            '\SimpleSAML\Error\Exception',
             "Empty attribute '".$expected."'.'"
         );
         Attributes::getExpectedAttribute($attributes, $expected);
@@ -113,7 +113,7 @@ class AttributesTest extends TestCase
         );
         $expected = 'attribute';
         $this->setExpectedException(
-            'SimpleSAML_Error_Exception',
+            '\SimpleSAML\Error\Exception',
             'More than one value found for the attribute, multiple values not allowed.'
         );
         Attributes::getExpectedAttribute($attributes, $expected);
diff --git a/tests/lib/SimpleSAML/Utils/ConfigTest.php b/tests/lib/SimpleSAML/Utils/ConfigTest.php
index 262fbfd801837ef611fb738c69424fa5caaa41ea..43525cf30c356a9fbdd4697352cd3f3814524ac9 100644
--- a/tests/lib/SimpleSAML/Utils/ConfigTest.php
+++ b/tests/lib/SimpleSAML/Utils/ConfigTest.php
@@ -35,6 +35,29 @@ class ConfigTest extends TestCase
         $this->assertEquals($configDir, __DIR__);
     }
 
+    /**
+     * Test valid dir specified by env redirect var overrides default config dir
+     */
+    public function testEnvRedirectVariableConfigDir()
+    {
+        putenv('REDIRECT_SIMPLESAMLPHP_CONFIG_DIR=' . __DIR__);
+        $configDir = Config::getConfigDir();
+
+        $this->assertEquals($configDir, __DIR__);
+    }
+
+    /**
+     * Test which directory takes precedence
+     */
+    public function testEnvRedirectPriorityVariableConfigDir()
+    {
+        putenv('SIMPLESAMLPHP_CONFIG_DIR=' . dirname(__DIR__));
+        putenv('REDIRECT_SIMPLESAMLPHP_CONFIG_DIR=' . __DIR__);
+        $configDir = Config::getConfigDir();
+
+        $this->assertEquals($configDir, dirname(__DIR__));
+    }
+
 
     /**
      * Test invalid dir specified by env var results in a thrown exception
diff --git a/tests/lib/SimpleSAML/Utils/CryptoTest.php b/tests/lib/SimpleSAML/Utils/CryptoTest.php
index a47d0d432c938fe3001a6a0c2a4fb059937d77a0..b5a0b500a966350542632a5b9f18035f623eaee1 100644
--- a/tests/lib/SimpleSAML/Utils/CryptoTest.php
+++ b/tests/lib/SimpleSAML/Utils/CryptoTest.php
@@ -4,7 +4,7 @@ namespace SimpleSAML\Test\Utils;
 
 use PHPUnit\Framework\TestCase;
 use SimpleSAML\Utils\Crypto;
-use \SimpleSAML_Configuration as Configuration;
+use \SimpleSAML\Configuration;
 
 use \org\bovigo\vfs\vfsStream;
 
@@ -70,7 +70,7 @@ class CryptoTest extends TestCase
     public function testAesDecrypt()
     {
         if (!extension_loaded('openssl')) {
-            $this->setExpectedException('\SimpleSAML_Error_Exception');
+            $this->setExpectedException('\SimpleSAML\Error\Exception');
         }
 
         $secret = 'SUPER_SECRET_SALT';
@@ -92,7 +92,7 @@ class CryptoTest extends TestCase
     public function testAesEncrypt()
     {
         if (!extension_loaded('openssl')) {
-            $this->setExpectedException('\SimpleSAML_Error_Exception');
+            $this->setExpectedException('\SimpleSAML\Error\Exception');
         }
 
         $secret = 'SUPER_SECRET_SALT';
@@ -195,7 +195,7 @@ PHP;
     }
 
     /**
-     * @expectedException \SimpleSAML_Error_Exception
+     * @expectedException \SimpleSAML\Error\Exception
      *
      * @covers \SimpleSAML\Utils\Crypto::pwHash
      */
@@ -237,7 +237,7 @@ PHP;
     }
 
     /**
-     * @expectedException \SimpleSAML_Error_Exception
+     * @expectedException \SimpleSAML\Error\Exception
      *
      * @covers \SimpleSAML\Utils\Crypto::pwValid
      */
@@ -271,7 +271,7 @@ PHP;
     }
 
     /**
-     * @expectedException \SimpleSAML_Error_Exception
+     * @expectedException \SimpleSAML\Error\Exception
      *
      * @covers \SimpleSAML\Utils\Crypto::loadPrivateKey
      */
@@ -297,7 +297,7 @@ PHP;
     }
 
     /**
-     * @expectedException \SimpleSAML_Error_Exception
+     * @expectedException \SimpleSAML\Error\Exception
      *
      * @covers \SimpleSAML\Utils\Crypto::loadPrivateKey
      */
@@ -378,7 +378,7 @@ PHP;
     }
 
     /**
-     * @expectedException \SimpleSAML_Error_Exception
+     * @expectedException \SimpleSAML\Error\Exception
      *
      * @covers \SimpleSAML\Utils\Crypto::loadPublicKey
      */
diff --git a/tests/lib/SimpleSAML/Utils/HTTPTest.php b/tests/lib/SimpleSAML/Utils/HTTPTest.php
index 073073c9378b12d1ca2b306fdf5392304adf6ca3..917a16290bbb2b5ebd0bd8872b11ce05f3e79a55 100644
--- a/tests/lib/SimpleSAML/Utils/HTTPTest.php
+++ b/tests/lib/SimpleSAML/Utils/HTTPTest.php
@@ -3,11 +3,10 @@ namespace SimpleSAML\Test\Utils;
 
 use PHPUnit\Framework\TestCase;
 use SimpleSAML\Utils\HTTP;
+use SimpleSAML\Configuration;
 
 class HTTPTest extends TestCase
 {
-
-
     /**
      * Set up the environment ($_SERVER) populating the typical variables from a given URL.
      *
@@ -120,7 +119,6 @@ class HTTPTest extends TestCase
         $_SERVER = $original;
     }
 
-
     /**
      * Test SimpleSAML\Utils\HTTP::getSelfHost() with and without custom port.
      */
@@ -128,7 +126,7 @@ class HTTPTest extends TestCase
     {
         $original = $_SERVER;
 
-        \SimpleSAML_Configuration::loadFromArray(array(
+        Configuration::loadFromArray(array(
             'baseurlpath' => '',
         ), '[ARRAY]', 'simplesaml');
         $_SERVER['SERVER_PORT'] = '80';
@@ -146,7 +144,7 @@ class HTTPTest extends TestCase
     {
         $original = $_SERVER;
 
-        \SimpleSAML_Configuration::loadFromArray(array(
+        Configuration::loadFromArray(array(
             'baseurlpath' => '',
         ), '[ARRAY]', 'simplesaml');
 
@@ -166,7 +164,6 @@ class HTTPTest extends TestCase
         $_SERVER = $original;
     }
 
-
     /**
      * Test SimpleSAML\Utils\HTTP::getSelfURL().
      */
@@ -178,7 +175,7 @@ class HTTPTest extends TestCase
          * Test a URL pointing to a script that's not part of the public interface. This allows us to test calls to
          * getSelfURL() from scripts outside of SimpleSAMLphp
          */
-        \SimpleSAML_Configuration::loadFromArray(array(
+        Configuration::loadFromArray(array(
             'baseurlpath' => 'http://example.com/simplesaml/',
         ), '[ARRAY]', 'simplesaml');
         $url = 'https://example.com/app/script.php/some/path?foo=bar';
@@ -191,7 +188,7 @@ class HTTPTest extends TestCase
         $this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
 
         // test a request URI that doesn't match the current script
-        $cfg = \SimpleSAML_Configuration::loadFromArray(array(
+        $cfg = Configuration::loadFromArray(array(
             'baseurlpath' => 'https://example.org/simplesaml/',
         ), '[ARRAY]', 'simplesaml');
         $baseDir = $cfg->getBaseDir();
@@ -205,7 +202,7 @@ class HTTPTest extends TestCase
         $this->assertEquals('http://www.example.com', HTTP::getSelfURLHost());
 
         // test a valid, full URL, based on a full URL in the configuration
-        \SimpleSAML_Configuration::loadFromArray(array(
+        Configuration::loadFromArray(array(
             'baseurlpath' => 'https://example.com/simplesaml/',
         ), '[ARRAY]', 'simplesaml');
         $this->setupEnvFromURL('http://www.example.org/module.php/module/file.php?foo=bar');
@@ -219,7 +216,7 @@ class HTTPTest extends TestCase
         $this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
 
         // test a valid, full URL, based on a full URL *without* a trailing slash in the configuration
-        \SimpleSAML_Configuration::loadFromArray(array(
+        Configuration::loadFromArray(array(
             'baseurlpath' => 'https://example.com/simplesaml',
         ), '[ARRAY]', 'simplesaml');
         $this->assertEquals(
@@ -232,7 +229,7 @@ class HTTPTest extends TestCase
         $this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
 
         // test a valid, full URL, based on a full URL *without* a path in the configuration
-        \SimpleSAML_Configuration::loadFromArray(array(
+        Configuration::loadFromArray(array(
             'baseurlpath' => 'https://example.com',
         ), '[ARRAY]', 'simplesaml');
         $this->assertEquals(
@@ -245,7 +242,7 @@ class HTTPTest extends TestCase
         $this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
 
         // test a valid, full URL, based on a relative path in the configuration
-        \SimpleSAML_Configuration::loadFromArray(array(
+        Configuration::loadFromArray(array(
             'baseurlpath' => '/simplesaml/',
         ), '[ARRAY]', 'simplesaml');
         $this->setupEnvFromURL('http://www.example.org/simplesaml/module.php/module/file.php?foo=bar');
@@ -259,7 +256,7 @@ class HTTPTest extends TestCase
         $this->assertEquals('http://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
 
         // test a valid, full URL, based on a relative path in the configuration and a non standard port
-        \SimpleSAML_Configuration::loadFromArray(array(
+        Configuration::loadFromArray(array(
             'baseurlpath' => '/simplesaml/',
         ), '[ARRAY]', 'simplesaml');
         $this->setupEnvFromURL('http://example.org:8080/simplesaml/module.php/module/file.php?foo=bar');
@@ -273,7 +270,7 @@ class HTTPTest extends TestCase
         $this->assertEquals('http://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
 
         // test a valid, full URL, based on a relative path in the configuration, a non standard port and HTTPS
-        \SimpleSAML_Configuration::loadFromArray(array(
+        Configuration::loadFromArray(array(
             'baseurlpath' => '/simplesaml/',
         ), '[ARRAY]', 'simplesaml');
         $this->setupEnvFromURL('https://example.org:8080/simplesaml/module.php/module/file.php?foo=bar');
@@ -292,7 +289,6 @@ class HTTPTest extends TestCase
         $_SERVER = $original;
     }
 
-
     /**
      * Test SimpleSAML\Utils\HTTP::checkURLAllowed(), without regex.
      */
@@ -300,7 +296,7 @@ class HTTPTest extends TestCase
     {
         $original = $_SERVER;
 
-        \SimpleSAML_Configuration::loadFromArray(array(
+        Configuration::loadFromArray(array(
             'trusted.url.domains' => array('sp.example.com', 'app.example.com'),
             'trusted.url.regex' => false,
         ), '[ARRAY]', 'simplesaml');
@@ -317,7 +313,7 @@ class HTTPTest extends TestCase
             $this->assertEquals(HTTP::checkURLAllowed($url), $url);
         }
 
-        $this->setExpectedException('SimpleSAML_Error_Exception');
+        $this->setExpectedException('\SimpleSAML\Error\Exception');
         HTTP::checkURLAllowed('https://evil.com');
 
         $_SERVER = $original;
@@ -330,7 +326,7 @@ class HTTPTest extends TestCase
     {
         $original = $_SERVER;
 
-        \SimpleSAML_Configuration::loadFromArray(array(
+        Configuration::loadFromArray(array(
             'trusted.url.domains' => array('.*\.example\.com'),
             'trusted.url.regex' => true,
         ), '[ARRAY]', 'simplesaml');
@@ -349,12 +345,56 @@ class HTTPTest extends TestCase
             $this->assertEquals(HTTP::checkURLAllowed($url), $url);
         }
 
-        $this->setExpectedException('SimpleSAML_Error_Exception');
+        $this->setExpectedException('\SimpleSAML\Error\Exception');
         HTTP::checkURLAllowed('https://evil.com');
 
         $_SERVER = $original;
     }
 
+    /**
+     * Test SimpleSAML\Utils\HTTP::getServerPort().
+     */
+    public function testGetServerPort()
+    {
+        $original = $_SERVER;
+
+        // Test HTTP + non-standard port
+        $_SERVER['HTTPS'] = 'off';
+        $_SERVER['SERVER_PORT'] = '3030';
+        $this->assertEquals(HTTP::getServerPort(), ':3030');
+
+        // Test HTTP + standard port
+        $_SERVER['SERVER_PORT'] = '80';
+        $this->assertEquals(HTTP::getServerPort(), '');
+
+        // Test HTTP + standard integer port
+        $_SERVER['SERVER_PORT'] = 80;
+        $this->assertEquals(HTTP::getServerPort(), '');
+
+        // Test HTTP + without port
+        unset($_SERVER['SERVER_PORT']);
+        $this->assertEquals(HTTP::getServerPort(), '');
+
+        // Test HTTPS + non-standard port
+        $_SERVER['HTTPS'] = 'on';
+        $_SERVER['SERVER_PORT'] = '3030';
+        $this->assertEquals(HTTP::getServerPort(), ':3030');
+
+        // Test HTTPS + non-standard integer port
+        $_SERVER['SERVER_PORT'] = 3030;
+        $this->assertEquals(HTTP::getServerPort(), ':3030');
+
+        // Test HTTPS + standard port
+        $_SERVER['SERVER_PORT'] = '443';
+        $this->assertEquals(HTTP::getServerPort(), '');
+
+        // Test HTTPS + without port
+        unset($_SERVER['SERVER_PORT']);
+        $this->assertEquals(HTTP::getServerPort(), '');
+
+        $_SERVER = $original;
+    }
+
     /**
      * Test SimpleSAML\Utils\HTTP::checkURLAllowed(), with the regex as a
      * subdomain of an evil domain.
@@ -363,14 +403,14 @@ class HTTPTest extends TestCase
     {
         $original = $_SERVER;
 
-        \SimpleSAML_Configuration::loadFromArray(array(
+        Configuration::loadFromArray(array(
             'trusted.url.domains' => array('app\.example\.com'),
             'trusted.url.regex' => true,
         ), '[ARRAY]', 'simplesaml');
 
         $_SERVER['REQUEST_URI'] = '/module.php';
 
-        $this->setExpectedException('SimpleSAML_Error_Exception');
+        $this->setExpectedException('\SimpleSAML\Error\Exception');
         HTTP::checkURLAllowed('https://app.example.com.evil.com');
 
         $_SERVER = $original;
diff --git a/tests/lib/SimpleSAML/Utils/NetTest.php b/tests/lib/SimpleSAML/Utils/NetTest.php
index 8e7e29e5453794f34bce483ee921279dd37b845e..8b23bb44aaf709e7993195bffadc8aeb40d17fa3 100644
--- a/tests/lib/SimpleSAML/Utils/NetTest.php
+++ b/tests/lib/SimpleSAML/Utils/NetTest.php
@@ -10,8 +10,6 @@ use SimpleSAML\Utils\Net;
  */
 class NetTest extends TestCase
 {
-
-
     /**
      * Test the function that checks for IPs belonging to a CIDR.
      *
diff --git a/tests/lib/SimpleSAML/Utils/RandomTest.php b/tests/lib/SimpleSAML/Utils/RandomTest.php
index ff05ed0243f2ceb09104ee59b2b3deb6f529e401..6067faf070830ba24ac26745cb08d278ba07b134 100644
--- a/tests/lib/SimpleSAML/Utils/RandomTest.php
+++ b/tests/lib/SimpleSAML/Utils/RandomTest.php
@@ -10,7 +10,6 @@ use SimpleSAML\Utils\Random;
  */
 class RandomTest extends TestCase
 {
-
     /**
      * Test for SimpleSAML\Utils\Random::generateID().
      *
diff --git a/tests/lib/SimpleSAML/Utils/SystemTest.php b/tests/lib/SimpleSAML/Utils/SystemTest.php
index 897f8a3d9d68b6c7f011c3f0fddb1f06464e4572..e39370e941d4a5b41154fb5fbc559d0c43509be6 100644
--- a/tests/lib/SimpleSAML/Utils/SystemTest.php
+++ b/tests/lib/SimpleSAML/Utils/SystemTest.php
@@ -3,7 +3,7 @@
 namespace SimpleSAML\Test\Utils;
 
 use PHPUnit\Framework\TestCase;
-use \SimpleSAML_Configuration as Configuration;
+use \SimpleSAML\Configuration;
 use \SimpleSAML\Utils\System;
 
 use \org\bovigo\vfs\vfsStream;
@@ -124,7 +124,7 @@ class SystemTest extends TestCase
 
         $this->assertFileExists($filename);
 
-        $this->clearInstance($config, '\SimpleSAML_Configuration');
+        $this->clearInstance($config, '\SimpleSAML\Configuration');
     }
 
     /**
@@ -146,7 +146,7 @@ class SystemTest extends TestCase
 
         $this->assertEquals($expected, $res);
 
-        $this->clearInstance($config, '\SimpleSAML_Configuration');
+        $this->clearInstance($config, '\SimpleSAML\Configuration');
     }
 
     /**
@@ -168,7 +168,7 @@ class SystemTest extends TestCase
 
         $this->assertEquals($expected, $res);
 
-        $this->clearInstance($config, '\SimpleSAML_Configuration');
+        $this->clearInstance($config, '\SimpleSAML\Configuration');
     }
 
     /**
@@ -186,7 +186,7 @@ class SystemTest extends TestCase
         $this->assertEquals($expected, $res);
         $this->assertFileExists($res);
 
-        $this->clearInstance($config, '\SimpleSAML_Configuration');
+        $this->clearInstance($config, '\SimpleSAML\Configuration');
     }
 
     /**
@@ -204,7 +204,7 @@ class SystemTest extends TestCase
         $this->assertEquals($expected, $res);
         $this->assertFileExists($res);
 
-        $this->clearInstance($config, '\SimpleSAML_Configuration');
+        $this->clearInstance($config, '\SimpleSAML\Configuration');
     }
 
     /**
@@ -221,10 +221,10 @@ class SystemTest extends TestCase
 
         chown($tempdir, $bad_uid);
 
-        $this->setExpectedException('\SimpleSAML_Error_Exception');
+        $this->setExpectedException('\SimpleSAML\Error\Exception');
         $res = System::getTempDir();
 
-        $this->clearInstance($config, '\SimpleSAML_Configuration');
+        $this->clearInstance($config, '\SimpleSAML\Configuration');
     }
 
     private function setConfigurationTempDir($directory)
diff --git a/tests/lib/SimpleSAML/Utils/TimeTest.php b/tests/lib/SimpleSAML/Utils/TimeTest.php
index 043aefbe52d4bec5519bda67216e5086fb4e79ff..ebe99b9c8091bf6d2f09fcdf9bfa062c554e28ca 100644
--- a/tests/lib/SimpleSAML/Utils/TimeTest.php
+++ b/tests/lib/SimpleSAML/Utils/TimeTest.php
@@ -7,7 +7,6 @@ use SimpleSAML\Utils\Time;
 
 class TimeTest extends TestCase
 {
-
     /**
      * Test the SimpleSAML\Utils\Time::generateTimestamp() method.
      *
@@ -37,7 +36,7 @@ class TimeTest extends TestCase
         }
 
         // test guessing timezone from the OS
-        \SimpleSAML_Configuration::loadFromArray(array('timezone' => null), '[ARRAY]', 'simplesaml');
+        \SimpleSAML\Configuration::loadFromArray(array('timezone' => null), '[ARRAY]', 'simplesaml');
         @Time::initTimezone();
         $this->assertEquals($os, @date_default_timezone_get());
 
@@ -47,21 +46,21 @@ class TimeTest extends TestCase
         $c->setValue(false);
 
         // test unknown timezone
-        \SimpleSAML_Configuration::loadFromArray(array('timezone' => 'INVALID'), '[ARRAY]', 'simplesaml');
+        \SimpleSAML\Configuration::loadFromArray(array('timezone' => 'INVALID'), '[ARRAY]', 'simplesaml');
         try {
             @Time::initTimezone();
             $this->fail('Failed to recognize an invalid timezone.');
-        } catch (\SimpleSAML_Error_Exception $e) {
+        } catch (\SimpleSAML\Error\Exception $e) {
             $this->assertEquals('Invalid timezone set in the "timezone" option in config.php.', $e->getMessage());
         }
 
         // test a valid timezone
-        \SimpleSAML_Configuration::loadFromArray(array('timezone' => $tz), '[ARRAY]', 'simplesaml');
+        \SimpleSAML\Configuration::loadFromArray(array('timezone' => $tz), '[ARRAY]', 'simplesaml');
         @Time::initTimezone();
         $this->assertEquals($tz, @date_default_timezone_get());
 
         // make sure initialization happens only once
-        \SimpleSAML_Configuration::loadFromArray(array('timezone' => 'Europe/Madrid'), '[ARRAY]', 'simplesaml');
+        \SimpleSAML\Configuration::loadFromArray(array('timezone' => 'Europe/Madrid'), '[ARRAY]', 'simplesaml');
         @Time::initTimezone();
         $this->assertEquals($tz, @date_default_timezone_get());
     }
diff --git a/tests/lib/SimpleSAML/Utils/XMLTest.php b/tests/lib/SimpleSAML/Utils/XMLTest.php
index 7660487956ba79e9449342b26380896d7641041f..4f820a9efa2855fe8dc1a8c625ee17a98825f175 100644
--- a/tests/lib/SimpleSAML/Utils/XMLTest.php
+++ b/tests/lib/SimpleSAML/Utils/XMLTest.php
@@ -3,7 +3,7 @@
 namespace SimpleSAML\Test\Utils;
 
 use PHPUnit\Framework\TestCase;
-use \SimpleSAML_Configuration as Configuration;
+use \SimpleSAML\Configuration;
 use \SimpleSAML\Utils\XML;
 
 /**
@@ -141,7 +141,7 @@ class XMLTest extends TestCase
     }
 
     /**
-     * @expectedException \SimpleSAML_Error_Exception
+     * @expectedException \SimpleSAML\Error\Exception
      *
      * @covers \SimpleSAML\Utils\XML::getDOMText
      * @test
@@ -357,7 +357,7 @@ NOWDOC;
      */
     public function testIsValidMetadata()
     {
-        \SimpleSAML_Configuration::loadFromArray(array(), '[ARRAY]', 'simplesaml');
+        Configuration::loadFromArray(array(), '[ARRAY]', 'simplesaml');
 
         $schema = 'saml-schema-metadata-2.0.xsd';
 
diff --git a/tests/lib/SimpleSAML/XML/SignerTest.php b/tests/lib/SimpleSAML/XML/SignerTest.php
index 77edff09d1d1291fef61af531b5988d5b41ac04a..65b0f81cc8606ee640377b54e71bc59371d09706 100644
--- a/tests/lib/SimpleSAML/XML/SignerTest.php
+++ b/tests/lib/SimpleSAML/XML/SignerTest.php
@@ -3,7 +3,7 @@
 namespace SimpleSAML\Test\Utils;
 
 use PHPUnit\Framework\TestCase;
-use \SimpleSAML_Configuration as Configuration;
+use \SimpleSAML\Configuration;
 use \SimpleSAML\XML\Signer;
 
 use \org\bovigo\vfs\vfsStream;
@@ -127,7 +127,7 @@ NOWDOC;
 
     public function tearDown()
     {
-        $this->clearInstance($this->config, '\SimpleSAML_Configuration', array());
+        $this->clearInstance($this->config, '\SimpleSAML\Configuration', array());
     }
 
     public function testSignerBasic()
diff --git a/tests/lib/SimpleSAML/XML/ValidatorTest.php b/tests/lib/SimpleSAML/XML/ValidatorTest.php
index 8dc2179f45986bfc4c287dc1a54c7c31f252e721..7887886129c27bd36cd41e7681fb364ca10609f3 100644
--- a/tests/lib/SimpleSAML/XML/ValidatorTest.php
+++ b/tests/lib/SimpleSAML/XML/ValidatorTest.php
@@ -3,7 +3,7 @@
 namespace SimpleSAML\Test\XML;
 
 use PHPUnit\Framework\TestCase;
-use \SimpleSAML_Configuration as Configuration;
+use \SimpleSAML\Configuration;
 use \SimpleSAML\XML\Signer;
 use \SimpleSAML\XML\Validator;
 
@@ -171,7 +171,7 @@ NOWDOC;
 
     public function tearDown()
     {
-        $this->clearInstance($this->config, '\SimpleSAML_Configuration', array());
+        $this->clearInstance($this->config, '\SimpleSAML\Configuration', array());
     }
 
     public function testValidatorMissingSignature()
diff --git a/tests/modules/consent/lib/Auth/Process/ConsentTest.php b/tests/modules/consent/lib/Auth/Process/ConsentTest.php
index 887e11b433e8daffa88fdef506339124d9622685..1e06862d3e8684deca263d92e8879e07c8d736fd 100644
--- a/tests/modules/consent/lib/Auth/Process/ConsentTest.php
+++ b/tests/modules/consent/lib/Auth/Process/ConsentTest.php
@@ -9,7 +9,7 @@
 namespace SimpleSAML\Test\Module\consent\Auth\Process;
 
 use PHPUnit\Framework\TestCase;
-use \SimpleSAML_Configuration as Configuration;
+use \SimpleSAML\Configuration;
 
 class ConsentTest extends TestCase
 {
@@ -27,7 +27,7 @@ class ConsentTest extends TestCase
      */
     private function processFilter(array $config, array $request)
     {
-        $filter = new \sspmod_consent_Auth_Process_Consent($config, null);
+        $filter = new \SimpleSAML\Module\consent\Auth\Process\Consent($config, null);
         $filter->process($request);
         return $request;
     }
@@ -120,4 +120,98 @@ class ConsentTest extends TestCase
         // the state should NOT have changed because NO consent should be necessary (match)
         $this->assertEquals($request, $result);
     }
+
+    public function testAttributeHashIsConsistentWhenOrderOfValuesChange()
+    {
+        $attributes1 = array(
+            'attribute1' => array('val1', 'val2'),
+            'attribute2' => array('val1', 'val2')
+        );
+        $attributeHash1 = \SimpleSAML\Module\consent\Auth\Process\Consent::getAttributeHash($attributes1, true);
+
+        $attributes2 = array(
+            'attribute1' => array('val1', 'val2'),
+            'attribute2' => array('val2', 'val1')
+        );
+        $attributeHash2 = \SimpleSAML\Module\consent\Auth\Process\Consent::getAttributeHash($attributes2, true);
+
+        $this->assertEquals($attributeHash1, $attributeHash2, "Hash is not the same when the order of values changes");
+    }
+
+    public function testAttributeHashIsConsistentWhenOrderOfAttributesChange()
+    {
+        $attributes1 = array(
+            'attribute2' => array('val1', 'val2'),
+            'attribute1' => array('val1', 'val2')
+        );
+        $attributeHash1 = \SimpleSAML\Module\consent\Auth\Process\Consent::getAttributeHash($attributes1, true);
+
+        $attributes2 = array(
+            'attribute1' => array('val1', 'val2'),
+            'attribute2' => array('val1', 'val2')
+        );
+        $attributeHash2 = \SimpleSAML\Module\consent\Auth\Process\Consent::getAttributeHash($attributes2, true);
+
+        $this->assertEquals(
+            $attributeHash1,
+            $attributeHash2,
+            "Hash is not the same when the order of the attributs changes"
+        );
+    }
+
+    public function testAttributeHashIsConsistentWithoutValuesWhenOrderOfAttributesChange()
+    {
+        $attributes1 = array(
+            'attribute2' => array('val1', 'val2'),
+            'attribute1' => array('val1', 'val2')
+        );
+        $attributeHash1 = \SimpleSAML\Module\consent\Auth\Process\Consent::getAttributeHash($attributes1);
+
+        $attributes2 = array(
+            'attribute1' => array('val1', 'val2'),
+            'attribute2' => array('val1', 'val2')
+        );
+        $attributeHash2 = \SimpleSAML\Module\consent\Auth\Process\Consent::getAttributeHash($attributes2);
+
+        $this->assertEquals(
+            $attributeHash1,
+            $attributeHash2,
+            "Hash is not the same when the order of the attributs changes and the values are not included"
+        );
+    }
+
+    public function testConstructorSetsInstancePrivateVars()
+    {
+        $reflection = new \ReflectionClass('\SimpleSAML\Module\consent\Auth\Process\Consent');
+
+        foreach (array(
+            '_includeValues', '_checked', '_focus', '_hiddenAttributes', '_noconsentattributes', '_showNoConsentAboutService'
+        ) as $v) {
+            $instanceVars[$v] = $reflection->getProperty($v);
+            $instanceVars[$v]->setAccessible(true);
+        }
+
+        /* these just need to be different to the default values */
+        $config = array(
+            'includeValues' => true,
+            'checked' => true,
+            'focus' => 'yes',
+            'hiddenAttributes' => array('attribute1', 'attribute2'),
+            'attributes.exclude' => array('attribute1', 'attribute2'),
+            'showNoConsentAboutService' => false,
+        );
+
+        $testcase = $reflection->newInstance($config, null);
+
+        $this->assertEquals($instanceVars['_includeValues']->getValue($testcase), $config['includeValues']);
+        $this->assertEquals($instanceVars['_checked']->getValue($testcase), $config['checked']);
+        $this->assertEquals($instanceVars['_focus']->getValue($testcase), $config['focus']);
+        $this->assertEquals($instanceVars['_hiddenAttributes']->getValue($testcase), $config['hiddenAttributes']);
+        $this->assertEquals($instanceVars['_noconsentattributes']->getValue($testcase), $config['attributes.exclude']);
+        $this->assertEquals($instanceVars['_showNoConsentAboutService']->getValue($testcase), $config['showNoConsentAboutService']);
+
+        $deprecated = $reflection->newInstance(array('noconsentattributes' => $config['attributes.exclude'],), null);
+        $this->assertEquals($instanceVars['_noconsentattributes']->getValue($deprecated), $config['attributes.exclude']);
+
+    }
 }
diff --git a/tests/modules/core/lib/Auth/Process/AttributeAddTest.php b/tests/modules/core/lib/Auth/Process/AttributeAddTest.php
index 1fd9fc72bc67ccfdefcb3ee23822be1afddf8333..deabdd3d210f596678284e80806dbac91275d422 100644
--- a/tests/modules/core/lib/Auth/Process/AttributeAddTest.php
+++ b/tests/modules/core/lib/Auth/Process/AttributeAddTest.php
@@ -17,7 +17,7 @@ class Test_Core_Auth_Process_AttributeAdd extends TestCase
      */
     private static function processFilter(array $config, array $request)
     {
-        $filter = new sspmod_core_Auth_Process_AttributeAdd($config, NULL);
+        $filter = new \SimpleSAML\Module\core\Auth\Process\AttributeAdd($config, null);
         $filter->process($request);
         return $request;
     }
diff --git a/tests/modules/core/lib/Auth/Process/AttributeAlterTest.php b/tests/modules/core/lib/Auth/Process/AttributeAlterTest.php
index 8260c04e487e3c9d345ac9391604589d194bd941..d59522cba870bb66f6ac551e7575745137c86ad5 100644
--- a/tests/modules/core/lib/Auth/Process/AttributeAlterTest.php
+++ b/tests/modules/core/lib/Auth/Process/AttributeAlterTest.php
@@ -17,7 +17,7 @@ class Test_Core_Auth_Process_AttributeAlter extends TestCase
      */
     private static function processFilter(array $config, array $request)
     {
-        $filter = new sspmod_core_Auth_Process_AttributeAlter($config, NULL);
+        $filter = new \SimpleSAML\Module\core\Auth\Process\AttributeAlter($config, null);
         $filter->process($request);
         return $request;
     }
diff --git a/tests/modules/core/lib/Auth/Process/AttributeCopyTest.php b/tests/modules/core/lib/Auth/Process/AttributeCopyTest.php
index d960c379f764e9b0db635a8f8aa44253daaa52c5..52f03613cffebdcc1eee49bf3b4b6504d0d3aa59 100644
--- a/tests/modules/core/lib/Auth/Process/AttributeCopyTest.php
+++ b/tests/modules/core/lib/Auth/Process/AttributeCopyTest.php
@@ -17,7 +17,7 @@ class Test_Core_Auth_Process_AttributeCopy extends TestCase
      */
     private static function processFilter(array $config, array $request)
     {
-        $filter = new sspmod_core_Auth_Process_AttributeCopy($config, NULL);
+        $filter = new \SimpleSAML\Module\core\Auth\Process\AttributeCopy($config, NULL);
         $filter->process($request);
         return $request;
     }
diff --git a/tests/modules/core/lib/Auth/Process/AttributeLimitTest.php b/tests/modules/core/lib/Auth/Process/AttributeLimitTest.php
index 57e912e88cdf993f143e9240e79acd455b8738a3..fc55240f9f9e1b88cf71390973b06eb773346b98 100644
--- a/tests/modules/core/lib/Auth/Process/AttributeLimitTest.php
+++ b/tests/modules/core/lib/Auth/Process/AttributeLimitTest.php
@@ -7,7 +7,6 @@ use PHPUnit\Framework\TestCase;
  */
 class Test_Core_Auth_Process_AttributeLimitTest extends TestCase
 {
-
     /**
      * Helper function to run the filter with a given configuration.
      *
@@ -17,7 +16,7 @@ class Test_Core_Auth_Process_AttributeLimitTest extends TestCase
      */
     private static function processFilter(array $config, array $request)
     {
-        $filter = new sspmod_core_Auth_Process_AttributeLimit($config, NULL);
+        $filter = new \SimpleSAML\Module\core\Auth\Process\AttributeLimit($config, NULL);
         $filter->process($request);
         return $request;
     }
@@ -267,6 +266,175 @@ class Test_Core_Auth_Process_AttributeLimitTest extends TestCase
         $this->assertCount(0, $attributes);
     }
 
+    public function testBadOptionsNotTreatedAsValidValues() {
+
+        // Ensure really misconfigured ignoreCase and regex options are not interpretted as valid valus
+        $config = array(
+            'eduPersonAffiliation' => array('ignoreCase' => 'member', 'nomatch'),
+            'mail' => array('regex' => 'user@example.org', 'nomatch')
+        );
+        $result = self::processFilter($config, self::$request);
+        $attributes = $result['Attributes'];
+        $this->assertCount(0, $attributes);
+    }
+
+    /**
+     * Verify that the true value for ignoreCase doesn't get converted into a string ('1') by
+     * php and matched against an attribute value of '1'
+     */
+    public function testThatIgnoreCaseOptionNotMatchBooleanAsStringValue() {
+        $config = array(
+            'someAttribute' => array('ignoreCase' => true, 'someValue')
+        );
+
+        $request = array(
+            'Attributes' => array(
+                'someAttribute' => array('1'), //boolean true as a string
+
+            ),
+        );
+        $result = self::processFilter($config, $request);
+        $attributes = $result['Attributes'];
+        $this->assertCount(0, $attributes);
+    }
+
+    /**
+     * Test for attribute value matching ignore case
+     */
+    public function testMatchAttributeValuesIgnoreCase()
+    {
+        $config = array(
+            'eduPersonAffiliation' => array('ignoreCase' => true, 'meMber')
+        );
+
+        $result = self::processFilter($config, self::$request);
+        $attributes = $result['Attributes'];
+        $this->assertCount(1, $attributes);
+        $this->assertArrayHasKey('eduPersonAffiliation', $attributes);
+        $this->assertEquals($attributes['eduPersonAffiliation'], array('member'));
+
+        $config = array(
+            'eduPersonAffiliation' => array('ignoreCase' => true, 'membeR','sTaff')
+        );
+
+        $result = self::processFilter($config, self::$request);
+        $attributes = $result['Attributes'];
+        $this->assertCount(1, $attributes);
+        $this->assertArrayHasKey('eduPersonAffiliation', $attributes);
+        $this->assertEquals($attributes['eduPersonAffiliation'], array('member'));
+
+        $config = array(
+            'eduPersonAffiliation' => array('ignoreCase' => true, 'Student')
+        );
+        $result = self::processFilter($config, self::$request);
+        $attributes = $result['Attributes'];
+        $this->assertCount(0, $attributes);
+
+        $config = array(
+            'eduPersonAffiliation' => array('ignoreCase' => true, 'studeNt','sTaff')
+        );
+        $result = self::processFilter($config, self::$request);
+        $attributes = $result['Attributes'];
+        $this->assertCount(0, $attributes);
+    }
+
+    /**
+     * Test for attribute value matching
+     */
+    public function testMatchAttributeValuesRegex()
+    {
+        // SSP Logger requires a configuration to be set.
+        \SimpleSAML\Configuration::loadFromArray(array(), '[ARRAY]', 'simplesaml');
+        $state = self::$request;
+        $state['Attributes']['eduPersonEntitlement'] = array(
+            'urn:mace:example.terena.org:tcs:personal-user',
+            'urn:x-surfnet:surfdomeinen.nl:role:dnsadmin',
+            'urn:x-surfnet:surf.nl:surfdrive:quota:100',
+            '1' //boolean true as a string
+        );
+
+        $config = array(
+            'eduPersonEntitlement' => array(
+                'regex' => true,
+                '/^urn:x-surfnet:surf/'
+            )
+        );
+
+        $result = self::processFilter($config, $state);
+        $attributes = $result['Attributes'];
+        $this->assertCount(1, $attributes);
+        $this->assertArrayHasKey('eduPersonEntitlement', $attributes);
+        $this->assertEquals(
+            array('urn:x-surfnet:surfdomeinen.nl:role:dnsadmin', 'urn:x-surfnet:surf.nl:surfdrive:quota:100'),
+            $attributes['eduPersonEntitlement']
+        );
+
+        // Matching multiple lines shouldn't duplicate the attribute
+        $config = array(
+            'eduPersonEntitlement' => array(
+                'regex' => true,
+                '/urn:x-surfnet:surf/',
+                '/urn:x-surfnet/'
+
+            )
+        );
+
+        $result = self::processFilter($config, $state);
+        $attributes = $result['Attributes'];
+        $this->assertCount(1, $attributes);
+        $this->assertArrayHasKey('eduPersonEntitlement', $attributes);
+        $this->assertEquals(
+            array('urn:x-surfnet:surfdomeinen.nl:role:dnsadmin', 'urn:x-surfnet:surf.nl:surfdrive:quota:100'),
+            $attributes['eduPersonEntitlement']
+        );
+
+        // Invalid and no-match regex expressions should not stop a valid regex from matching
+        $config = array(
+            'eduPersonEntitlement' => array(
+                'regex' => true,
+                '/urn:mace:example.terena.org:tcs:no-match/',
+                '$invalidRegex[',
+                '/^URN:x-surf.*SURF.*n$/i'
+            )
+        );
+
+        $result = self::processFilter($config, $state);
+        $attributes = $result['Attributes'];
+        $this->assertCount(1, $attributes);
+        $this->assertArrayHasKey('eduPersonEntitlement', $attributes);
+        $this->assertEquals(
+            array('urn:x-surfnet:surfdomeinen.nl:role:dnsadmin'),
+            $attributes['eduPersonEntitlement']
+        );
+
+        // No matches should remove attribute
+        $config = array(
+            'eduPersonEntitlement' => array(
+                'regex' => true,
+                '/urn:x-no-match/'
+            )
+        );
+        $result = self::processFilter($config, $state);
+        $attributes = $result['Attributes'];
+        $this->assertCount(0, $attributes);
+
+        // A regex that matches an input value multiple times should work.
+        $config = array(
+            'eduPersonEntitlement' => array(
+                'regex' => true,
+                '/surf/'
+            )
+        );
+        $result = self::processFilter($config, $state);
+        $attributes = $result['Attributes'];
+        $this->assertCount(1, $attributes);
+        $this->assertArrayHasKey('eduPersonEntitlement', $attributes);
+        $this->assertEquals(
+            array('urn:x-surfnet:surfdomeinen.nl:role:dnsadmin', 'urn:x-surfnet:surf.nl:surfdrive:quota:100'),
+            $attributes['eduPersonEntitlement']
+        );
+    }
+
     /**
      * Test for allowed attributes not an array.
      *
diff --git a/tests/modules/core/lib/Auth/Process/AttributeMapTest.php b/tests/modules/core/lib/Auth/Process/AttributeMapTest.php
index 719ad54cf222f10215dad485d6fb5c2b010ed5ce..5c50f59bd533ddad04c7299028717dae6ade71eb 100644
--- a/tests/modules/core/lib/Auth/Process/AttributeMapTest.php
+++ b/tests/modules/core/lib/Auth/Process/AttributeMapTest.php
@@ -16,7 +16,7 @@ class Test_Core_Auth_Process_AttributeMap extends TestCase
      */
     private static function processFilter(array $config, array $request)
     {
-        $filter = new sspmod_core_Auth_Process_AttributeMap($config, null);
+        $filter = new \SimpleSAML\Module\core\Auth\Process\AttributeMap($config, null);
         $filter->process($request);
         return $request;
     }
@@ -108,6 +108,51 @@ class Test_Core_Auth_Process_AttributeMap extends TestCase
         $this->assertEquals($expected, $result);
     }
 
+    public function testCircular()
+    {
+        $config = [
+            'attribute1' => 'attribute1',
+            'attribute2' => 'attribute2',
+        ];
+        $request = [
+            'Attributes' => [
+                'attribute1' => ['value'],
+                'attribute2' => ['value'],
+            ],
+        ];
+
+        $processed = self::processFilter($config, $request);
+        $result = $processed['Attributes'];
+        $expected = [
+            'attribute1' => ['value'],
+            'attribute2' => ['value'],
+        ];
+
+        $this->assertEquals($expected, $result);
+    }
+
+    public function testMissingMap()
+    {
+        $config = [
+            'attribute1' => 'attribute3',
+        ];
+        $request = [
+            'Attributes' => [
+                'attribute1' => ['value'],
+                'attribute2' => ['value'],
+            ],
+        ];
+
+        $processed = self::processFilter($config, $request);
+        $result = $processed['Attributes'];
+        $expected = [
+            'attribute2' => ['value'],
+            'attribute3' => ['value'],
+        ];
+
+        $this->assertEquals($expected, $result);
+    }
+
     public function testInvalidOriginalAttributeType()
     {
         $config = [
diff --git a/tests/modules/core/lib/Auth/Process/AttributeRealmTest.php b/tests/modules/core/lib/Auth/Process/AttributeRealmTest.php
index 915475d17d559b7eb163eff0dd6242e38f034978..75ea9441a31e7a4b78db68cbc45e4bea17030b0f 100644
--- a/tests/modules/core/lib/Auth/Process/AttributeRealmTest.php
+++ b/tests/modules/core/lib/Auth/Process/AttributeRealmTest.php
@@ -17,7 +17,7 @@ class Test_Core_Auth_Process_AttributeRealm extends TestCase
      */
     private static function processFilter(array $config, array $request)
     {
-        $filter = new sspmod_core_Auth_Process_AttributeRealm($config, NULL);
+        $filter = new \SimpleSAML\Module\core\Auth\Process\AttributeRealm($config, NULL);
         $filter->process($request);
         return $request;
     }
diff --git a/tests/modules/core/lib/Auth/Process/CardinalitySingleTest.php b/tests/modules/core/lib/Auth/Process/CardinalitySingleTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0c04b777b2dcf9f54c6776a06a5a32828eb59280
--- /dev/null
+++ b/tests/modules/core/lib/Auth/Process/CardinalitySingleTest.php
@@ -0,0 +1,148 @@
+<?php
+// Alias the PHPUnit 6.0 ancestor if available, else fall back to legacy ancestor
+if (class_exists('\PHPUnit\Framework\TestCase', true) and !class_exists('\PHPUnit_Framework_TestCase', true)) {
+    class_alias('\PHPUnit\Framework\TestCase', '\PHPUnit_Framework_TestCase', true);
+}
+
+/**
+ * Test for the core:CardinalitySingle filter.
+ */
+class Test_Core_Auth_Process_CardinalitySingleTest extends \PHPUnit_Framework_TestCase
+{
+    private $http;
+
+    /**
+     * Helper function to run the filter with a given configuration.
+     *
+     * @param  array $config The filter configuration.
+     * @param  array $request The request state.
+     * @return array  The state array after processing.
+     */
+    private function processFilter(array $config, array $request)
+    {
+        $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.1';
+        $_SERVER['REQUEST_METHOD'] = 'GET';
+        $filter = new \SimpleSAML\Module\core\Auth\Process\CardinalitySingle($config, null, $this->http);
+        $filter->process($request);
+        return $request;
+    }
+
+    protected function setUp()
+    {
+        \SimpleSAML\Configuration::loadFromArray(array(), '[ARRAY]', 'simplesaml');
+        $this->http = $this->getMockBuilder('SimpleSAML\Utils\HTTPAdapter')
+                           ->setMethods(array('redirectTrustedURL'))
+                           ->getMock();
+    }
+
+    /**
+     * Test singleValued
+     */
+    public function testSingleValuedUnchanged()
+    {
+        $config = array(
+            'singleValued' => array('eduPersonPrincipalName')
+        );
+        $request = array(
+            'Attributes' => array(
+                'eduPersonPrincipalName' => array('joe@example.com'),
+            ),
+        );
+        $result = $this->processFilter($config, $request);
+        $attributes = $result['Attributes'];
+        $expectedData = array('eduPersonPrincipalName' => array('joe@example.com'));
+        $this->assertEquals($expectedData, $attributes, "Assertion values should not have changed");
+    }
+
+    /**
+     * Test first value extraction
+     */
+    public function testFirstValue()
+    {
+        $config = array(
+            'firstValue' => array('eduPersonPrincipalName')
+        );
+        $request = array(
+            'Attributes' => array(
+                'eduPersonPrincipalName' => array('joe@example.com', 'bob@example.net'),
+            ),
+        );
+        $result = $this->processFilter($config, $request);
+        $attributes = $result['Attributes'];
+        $expectedData = array('eduPersonPrincipalName' => array('joe@example.com'));
+        $this->assertEquals($expectedData, $attributes, "Only first value should be returned");
+    }
+
+    public function testFirstValueUnchanged()
+    {
+        $config = array(
+            'firstValue' => array('eduPersonPrincipalName')
+        );
+        $request = array(
+            'Attributes' => array(
+                'eduPersonPrincipalName' => array('joe@example.com'),
+            ),
+        );
+        $result = $this->processFilter($config, $request);
+        $attributes = $result['Attributes'];
+        $expectedData = array('eduPersonPrincipalName' => array('joe@example.com'));
+        $this->assertEquals($expectedData, $attributes, "Assertion values should not have changed");
+    }
+
+    /**
+     * Test flattening
+     */
+    public function testFlatten()
+    {
+        $config = array(
+            'flatten' => array('eduPersonPrincipalName'),
+            'flattenWith' => '|',
+        );
+        $request = array(
+            'Attributes' => array(
+                'eduPersonPrincipalName' => array('joe@example.com', 'bob@example.net'),
+            ),
+        );
+        $result = $this->processFilter($config, $request);
+        $attributes = $result['Attributes'];
+        $expectedData = array('eduPersonPrincipalName' => array('joe@example.com|bob@example.net'));
+        $this->assertEquals($expectedData, $attributes, "Flattened string should be returned");
+    }
+
+    public function testFlattenUnchanged()
+    {
+        $config = array(
+            'flatten' => array('eduPersonPrincipalName'),
+            'flattenWith' => '|',
+        );
+        $request = array(
+            'Attributes' => array(
+                'eduPersonPrincipalName' => array('joe@example.com'),
+            ),
+        );
+        $result = $this->processFilter($config, $request);
+        $attributes = $result['Attributes'];
+        $expectedData = array('eduPersonPrincipalName' => array('joe@example.com'));
+        $this->assertEquals($expectedData, $attributes, "Assertion values should not have changed");
+    }
+
+    /**
+     * Test abort
+     */
+    public function testAbort()
+    {
+        $config = array(
+            'singleValued' => array('eduPersonPrincipalName'),
+        );
+        $request = array(
+            'Attributes' => array(
+                'eduPersonPrincipalName' => array('joe@example.com', 'bob@example.net'),
+            ),
+        );
+
+        $this->http->expects($this->once())
+                   ->method('redirectTrustedURL');
+
+        $this->processFilter($config, $request);
+    }
+}
diff --git a/tests/modules/core/lib/Auth/Process/CardinalityTest.php b/tests/modules/core/lib/Auth/Process/CardinalityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8d94754445a17de1a02691f11daff701fe0e9ca2
--- /dev/null
+++ b/tests/modules/core/lib/Auth/Process/CardinalityTest.php
@@ -0,0 +1,247 @@
+<?php
+
+// Alias the PHPUnit 6.0 ancestor if available, else fall back to legacy ancestor
+if (class_exists('\PHPUnit\Framework\TestCase', true) and !class_exists('\PHPUnit_Framework_TestCase', true)) {
+    class_alias('\PHPUnit\Framework\TestCase', '\PHPUnit_Framework_TestCase', true);
+}
+
+/**
+ * Test for the core:Cardinality filter.
+ */
+class Test_Core_Auth_Process_CardinalityTest extends \PHPUnit_Framework_TestCase
+{
+    private $http;
+
+    /**
+     * Helper function to run the filter with a given configuration.
+     *
+     * @param  array $config The filter configuration.
+     * @param  array $request The request state.
+     * @return array  The state array after processing.
+     */
+    private function processFilter(array $config, array $request)
+    {
+        $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.1';
+        $_SERVER['REQUEST_METHOD'] = 'GET';
+        $filter = new \SimpleSAML\Module\core\Auth\Process\Cardinality($config, null, $this->http);
+        $filter->process($request);
+        return $request;
+    }
+
+    protected function setUp()
+    {
+        \SimpleSAML\Configuration::loadFromArray(array(), '[ARRAY]', 'simplesaml');
+        $this->http = $this->getMockBuilder('SimpleSAML\Utils\HTTPAdapter')
+                           ->setMethods(array('redirectTrustedURL'))
+                           ->getMock();
+    }
+
+    /*
+     * Test where a minimum is set but no maximum
+     */
+    public function testMinNoMax()
+    {
+        $config = array(
+            'mail' => array('min' => 1),
+        );
+        $request = array(
+            'Attributes' => array(
+                'mail' => array('joe@example.com', 'bob@example.com'),
+            ),
+        );
+        $result = $this->processFilter($config, $request);
+        $attributes = $result['Attributes'];
+        $expectedData = array('mail' => array('joe@example.com', 'bob@example.com'));
+        $this->assertEquals($expectedData, $attributes, "Assertion values should not have changed");
+    }
+
+    /*
+     * Test where a maximum is set but no minimum
+     */
+    public function testMaxNoMin()
+    {
+        $config = array(
+            'mail' => array('max' => 2),
+        );
+        $request = array(
+            'Attributes' => array(
+                'mail' => array('joe@example.com', 'bob@example.com'),
+            ),
+        );
+        $result = $this->processFilter($config, $request);
+        $attributes = $result['Attributes'];
+        $expectedData = array('mail' => array('joe@example.com', 'bob@example.com'));
+        $this->assertEquals($expectedData, $attributes, "Assertion values should not have changed");
+    }
+
+    /*
+     * Test in bounds within a maximum an minimum
+     */
+    public function testMaxMin()
+    {
+        $config = array(
+            'mail' => array('min' => 1, 'max' => 2),
+        );
+        $request = array(
+            'Attributes' => array(
+                'mail' => array('joe@example.com', 'bob@example.com'),
+            ),
+        );
+        $result = $this->processFilter($config, $request);
+        $attributes = $result['Attributes'];
+        $expectedData = array('mail' => array('joe@example.com', 'bob@example.com'));
+        $this->assertEquals($expectedData, $attributes, "Assertion values should not have changed");
+    }
+
+    /**
+     * Test maximum is out of bounds results in redirect
+     */
+    public function testMaxOutOfBounds()
+    {
+        $config = array(
+            'mail' => array('max' => 2),
+        );
+        $request = array(
+            'Attributes' => array(
+                'mail' => array('joe@example.com', 'bob@example.com', 'fred@example.com'),
+            ),
+        );
+
+        $this->http->expects($this->once())
+                   ->method('redirectTrustedURL');
+
+        $this->processFilter($config, $request);
+    }
+
+    /**
+     * Test minimum is out of bounds results in redirect
+     */
+    public function testMinOutOfBounds()
+    {
+        $config = array(
+            'mail' => array('min' => 3),
+        );
+        $request = array(
+            'Attributes' => array(
+                'mail' => array('joe@example.com', 'bob@example.com'),
+            ),
+        );
+
+        $this->http->expects($this->once())
+                   ->method('redirectTrustedURL');
+
+        $this->processFilter($config, $request);
+    }
+
+    /**
+     * Test missing attribute results in redirect
+     */
+    public function testMissingAttribute()
+    {
+        $config = array(
+            'mail' => array('min' => 1),
+        );
+        $request = array(
+            'Attributes' => array( ),
+        );
+
+        $this->http->expects($this->once())
+                   ->method('redirectTrustedURL');
+
+        $this->processFilter($config, $request);
+    }
+
+    /*
+     * Configuration errors
+     */
+
+    /**
+     * Test invalid minimum values
+     * @expectedException \SimpleSAML\Error\Exception
+     * @expectedExceptionMessageRegExp /Minimum/
+     */
+    public function testMinInvalid()
+    {
+        $config = array(
+            'mail' => array('min' => false),
+        );
+        $request = array(
+            'Attributes' => array(
+                'mail' => array('joe@example.com', 'bob@example.com'),
+            ),
+        );
+        $this->processFilter($config, $request);
+    }
+
+    /**
+     * Test invalid minimum values
+     * @expectedException \SimpleSAML\Error\Exception
+     * @expectedExceptionMessageRegExp /Minimum/
+     */
+    public function testMinNegative()
+    {
+        $config = array(
+            'mail' => array('min' => -1),
+        );
+        $request = array(
+            'Attributes' => array(
+                'mail' => array('joe@example.com', 'bob@example.com'),
+            ),
+        );
+        $this->processFilter($config, $request);
+    }
+
+    /**
+     * Test invalid maximum values
+     * @expectedException \SimpleSAML\Error\Exception
+     * @expectedExceptionMessageRegExp /Maximum/
+     */
+    public function testMaxInvalid()
+    {
+        $config = array(
+            'mail' => array('max' => false),
+        );
+        $request = array(
+            'Attributes' => array(
+                'mail' => array('joe@example.com', 'bob@example.com'),
+            ),
+        );
+        $this->processFilter($config, $request);
+    }
+
+    /**
+     * Test maximum < minimum
+     * @expectedException \SimpleSAML\Error\Exception
+     * @expectedExceptionMessageRegExp /less than/
+     */
+    public function testMinGreaterThanMax()
+    {
+        $config = array(
+            'mail' => array('min' => 2, 'max' => 1),
+        );
+        $request = array(
+            'Attributes' => array(
+                'mail' => array('joe@example.com', 'bob@example.com'),
+            ),
+        );
+        $this->processFilter($config, $request);
+    }
+
+    /**
+     * Test invalid attribute name
+     * @expectedException \SimpleSAML\Error\Exception
+     * @expectedExceptionMessageRegExp /Invalid attribute/
+     */
+    public function testInvalidAttributeName()
+    {
+        $config = array(
+            array('min' => 2, 'max' => 1),
+        );
+        $request = array(
+            'Attributes' => array(
+                'mail' => array('joe@example.com', 'bob@example.com'),
+            ),
+        );
+        self::processFilter($config, $request);
+    }
+}
diff --git a/tests/modules/core/lib/Auth/Process/PHPTest.php b/tests/modules/core/lib/Auth/Process/PHPTest.php
index 0e18e9bcd9f10b052fa934a950369b222c9035e4..c7331397389ddb73748e6a2b78bab8e243ad6f03 100644
--- a/tests/modules/core/lib/Auth/Process/PHPTest.php
+++ b/tests/modules/core/lib/Auth/Process/PHPTest.php
@@ -7,7 +7,6 @@ use PHPUnit\Framework\TestCase;
  */
 class Test_Core_Auth_Process_PHP extends TestCase
 {
-
     /**
      * Helper function to run the filter with a given configuration.
      *
@@ -18,7 +17,7 @@ class Test_Core_Auth_Process_PHP extends TestCase
      */
     private static function processFilter(array $config, array $request)
     {
-        $filter = new sspmod_core_Auth_Process_PHP($config, null);
+        $filter = new \SimpleSAML\Module\core\Auth\Process\PHP($config, null);
         @$filter->process($request);
         return $request;
     }
@@ -26,13 +25,15 @@ class Test_Core_Auth_Process_PHP extends TestCase
 
     /**
      * Test the configuration of the filter.
-     *
-     * @expectedException SimpleSAML_Error_Exception
      */
     public function testInvalidConfiguration()
     {
         $config = array();
-        new sspmod_core_Auth_Process_PHP($config, null);
+        $this->setExpectedException(
+            "\SimpleSAML\Error\Exception",
+            "core:PHP: missing mandatory configuration option 'code'."
+        );
+        new \SimpleSAML\Module\core\Auth\Process\PHP($config, null);
     }
 
 
@@ -43,16 +44,71 @@ class Test_Core_Auth_Process_PHP extends TestCase
     {
         $config = array(
             'code' => '
-                $attributes["key"] = "value";
+                $attributes["key"] = array("value");
             ',
         );
         $request = array('Attributes' => array());
         $expected = array(
             'Attributes' => array(
-                'key' => 'value',
+                'key' => array('value'),
             ),
         );
 
         $this->assertEquals($expected, $this->processFilter($config, $request));
     }
+
+    /**
+     * Check that the incoming attributes are also available after processing
+     */
+    public function testPreserveIncomingAttributes()
+    {
+        $config = array(
+            'code' => '
+                $attributes["orig2"] = array("value0");
+            ',
+        );
+        $request = array(
+            'Attributes' => array(
+                'orig1' => array('value1', 'value2'),
+                'orig2' => array('value3'),
+                'orig3' => array('value4')
+            )
+        );
+        $expected = array(
+            'Attributes' => array(
+                'orig1' => array('value1', 'value2'),
+                'orig2' => array('value0'),
+                'orig3' => array('value4')
+            ),
+        );
+
+        $this->assertEquals($expected, $this->processFilter($config, $request));
+    }
+
+    /**
+     * Check that throwing an Exception inside the PHP code of the
+     * filter (a documented use case) works.
+     */
+    public function testThrowExceptionFromFilter()
+    {
+        $config = array(
+            'code' => '
+                 if (empty($attributes["uid"])) {
+                     throw new Exception("Missing uid attribute.");
+                 }
+                 $attributes["uid"][0] = strtoupper($attributes["uid"][0]);
+            ',
+        );
+        $request = array(
+            'Attributes' => array(
+                'orig1' => array('value1', 'value2'),
+            )
+        );
+
+        $this->setExpectedException(
+            "Exception",
+            "Missing uid attribute."
+        );
+        $this->processFilter($config, $request);
+    }
 }
diff --git a/tests/modules/core/lib/Auth/Process/ScopeAttributeTest.php b/tests/modules/core/lib/Auth/Process/ScopeAttributeTest.php
index 866fc1a641a60db42eaffa27365e8664957b6197..843492678a7de14a8a8b1943a2d02c351e4af365 100644
--- a/tests/modules/core/lib/Auth/Process/ScopeAttributeTest.php
+++ b/tests/modules/core/lib/Auth/Process/ScopeAttributeTest.php
@@ -17,7 +17,7 @@ class Test_Core_Auth_Process_ScopeAttribute extends TestCase
      */
     private static function processFilter(array $config, array $request)
     {
-        $filter = new sspmod_core_Auth_Process_ScopeAttribute($config, NULL);
+        $filter = new \SimpleSAML\Module\core\Auth\Process\ScopeAttribute($config, NULL);
         $filter->process($request);
         return $request;
     }
diff --git a/tests/modules/core/lib/Auth/Process/ScopeFromAttributeTest.php b/tests/modules/core/lib/Auth/Process/ScopeFromAttributeTest.php
index 545093124dbe74709ed2b8fec9fd98eb90d212e1..1d24c38e90f358861d737f2d2c22d70dc53c99fa 100644
--- a/tests/modules/core/lib/Auth/Process/ScopeFromAttributeTest.php
+++ b/tests/modules/core/lib/Auth/Process/ScopeFromAttributeTest.php
@@ -17,7 +17,7 @@ class Test_Core_Auth_Process_ScopeFromAttribute extends TestCase
      */
     private static function processFilter(array $config, array $request)
     {
-        $filter = new sspmod_core_Auth_Process_ScopeFromAttribute($config, NULL);
+        $filter = new \SimpleSAML\Module\core\Auth\Process\ScopeFromAttribute($config, NULL);
         $filter->process($request);
         return $request;
     }
@@ -102,8 +102,6 @@ class Test_Core_Auth_Process_ScopeFromAttribute extends TestCase
 
     /*
      * When the source attribute doesn't have a scope, a warning is emitted
-     * NOTE: currently disabled: this triggers a warning and a warning
-     * wants to start a session which we cannot do in phpunit. How to fix?
      */
     public function testNoAt()
     {
diff --git a/tests/modules/core/lib/Auth/Process/TargetedIDTest.php b/tests/modules/core/lib/Auth/Process/TargetedIDTest.php
index 7cfc1abe3e222bf193a8514e1a10f3179914db66..e828db7795514618ddfe422514f95d59f57344f6 100644
--- a/tests/modules/core/lib/Auth/Process/TargetedIDTest.php
+++ b/tests/modules/core/lib/Auth/Process/TargetedIDTest.php
@@ -16,7 +16,7 @@ class Test_Core_Auth_Process_TargetedID extends TestCase
      */
     private static function processFilter(array $config, array $request)
     {
-        $filter = new sspmod_core_Auth_Process_TargetedID($config, NULL);
+        $filter = new \SimpleSAML\Module\core\Auth\Process\TargetedID($config, NULL);
         $filter->process($request);
         return $request;
     }
diff --git a/tests/modules/core/lib/Auth/UserPassBaseTest.php b/tests/modules/core/lib/Auth/UserPassBaseTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d70616800b1561327d3c716b9cde90b43aef474b
--- /dev/null
+++ b/tests/modules/core/lib/Auth/UserPassBaseTest.php
@@ -0,0 +1,52 @@
+<?php
+
+class UserPassBaseTest extends \PHPUnit_Framework_TestCase
+{
+    public function testAuthenticateECPCallsLoginAndSetsAttributes()
+    {
+        $state = array();
+        $attributes = array('attrib' => 'val');
+
+        $username = $state['core:auth:username'] = 'username';
+        $password = $state['core:auth:password'] = 'password';
+
+        $stub = $this->getMockBuilder('\SimpleSAML\Module\core\Auth\UserPassBase')
+            ->disableOriginalConstructor()
+            ->setMethods(array('login'))
+            ->getMockForAbstractClass();
+
+        $stub->expects($this->once())
+            ->method('login')
+            ->with($username, $password)
+            ->will($this->returnValue($attributes));
+
+        $stub->authenticate($state);
+
+        $this->assertSame($attributes, $state['Attributes']);
+    }
+
+    public function testAuthenticateECPCallsLoginWithForcedUsername()
+    {
+        $state = array();
+        $attributes = array();
+
+        $forcedUsername = 'forcedUsername';
+
+        $state['core:auth:username'] = 'username';
+        $password = $state['core:auth:password'] = 'password';
+
+        $stub = $this->getMockBuilder('\SimpleSAML\Module\core\Auth\UserPassBase')
+            ->disableOriginalConstructor()
+            ->setMethods(array('login'))
+            ->getMockForAbstractClass();
+
+        $stub->expects($this->once())
+            ->method('login')
+            ->with($forcedUsername, $password)
+            ->will($this->returnValue($attributes));
+
+        $stub->setForcedUsername($forcedUsername);
+
+        $stub->authenticate($state);
+    }
+}
diff --git a/tests/modules/core/lib/Storage/SQLPermanentStorageTest.php b/tests/modules/core/lib/Storage/SQLPermanentStorageTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..49b17fd611d9180e7b33838f406e92a9a46bccf1
--- /dev/null
+++ b/tests/modules/core/lib/Storage/SQLPermanentStorageTest.php
@@ -0,0 +1,86 @@
+<?php
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * Test for the SQLPermanentStorage class.
+ */
+class Test_Core_Storage_SQLPermanentStorage extends TestCase
+{
+    private static $sql;
+
+    public static function setUpBeforeClass()
+    {
+        // Create instance
+        $config = \SimpleSAML\Configuration::loadFromArray([
+            'datadir' => sys_get_temp_dir(),
+        ]);
+        self::$sql = new \SimpleSAML\Module\core\Storage\SQLPermanentStorage('test', $config);
+    }
+
+    public static function tearDownAfterClass()
+    {
+        self::$sql = null;
+        unlink(sys_get_temp_dir().'/sqllite/test.sqlite');
+    }
+
+    public function testSet()
+    {
+        // Set a new value
+        self::$sql->set('testtype', 'testkey1', 'testkey2', 'testvalue', 2);
+
+        // Test getCondition
+        $result = self::$sql->get();
+        $this->assertEquals('testvalue', $result['value']);
+    }
+
+    public function testSetOverwrite()
+    {
+        // Overwrite existing value
+        self::$sql->set('testtype', 'testkey1', 'testkey2', 'testvaluemodified', 2);
+
+        // Test that the value was actually overwriten
+        $result = self::$sql->getValue('testtype', 'testkey1', 'testkey2');
+        $this->assertEquals('testvaluemodified', $result);
+
+        $result = self::$sql->getList('testtype', 'testkey1', 'testkey2');
+        $this->assertEquals('testvaluemodified', $result[0]['value']);
+    }
+
+    public function testNonexistentKey()
+    {
+        // Test that getting some non-existing key will return null
+        $result = self::$sql->getValue('testtype_nonexistent', 'testkey1_nonexistent', 'testkey2_nonexistent');
+        $this->assertNull($result);
+        $result = self::$sql->getList('testtype_nonexistent', 'testkey1_nonexistent', 'testkey2_nonexistent');
+        $this->assertNull($result);
+        $result = self::$sql->get('testtype_nonexistent', 'testkey1_nonexistent', 'testkey2_nonexistent');
+        $this->assertNull($result);
+    }
+
+    public function testExpiration()
+    {
+        // Make sure the earlier created entry has expired now
+        sleep(3);
+
+        // Make sure we can't get the expired entry anymore
+        $result = self::$sql->getValue('testtype', 'testkey1', 'testkey2');
+        $this->assertNull($result);
+
+        // Now add a second entry that never expires
+        self::$sql->set('testtype', 'testkey1_nonexpiring', 'testkey2_nonexpiring', 'testvalue_nonexpiring', null);
+
+        // Expire entries and verify that only the second one is still there
+        self::$sql->removeExpired();
+        $result = self::$sql->getValue('testtype', 'testkey1_nonexpiring', 'testkey2_nonexpiring');
+        $this->assertEquals('testvalue_nonexpiring', $result);
+    }
+
+    public function testRemove()
+    {
+        // Now remove the nonexpiring entry and make sure it's gone
+        self::$sql->remove('testtype', 'testkey1_nonexpiring', 'testkey2_nonexpiring');
+        $result = self::$sql->getValue('testtype', 'testkey1_nonexpiring', 'testkey2_nonexpiring');
+        $this->assertNull($result);
+    }
+}
diff --git a/tests/modules/ldap/lib/Auth/Process/BaseFilterTest.php b/tests/modules/ldap/lib/Auth/Process/BaseFilterTest.php
index 08dd8ea52a8b59bd177f9a8997e03fe2f7fff563..11f6efed6bbddc922a095bc6c1940529b6f5bf81 100644
--- a/tests/modules/ldap/lib/Auth/Process/BaseFilterTest.php
+++ b/tests/modules/ldap/lib/Auth/Process/BaseFilterTest.php
@@ -2,11 +2,11 @@
 
 use PHPUnit\Framework\TestCase;
 
-class sspmod_ldap_Auth_Process_BaseFilter_Test extends TestCase
+class BaseFilter_Test extends TestCase
 {
     public function testVarExportHidesLdapPassword()
     {
-        $stub = $this->getMockBuilder('sspmod_ldap_Auth_Process_BaseFilter')
+        $stub = $this->getMockBuilder('\SimpleSAML\Module\ldap\Auth\Process\BaseFilter')
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
         $class = new \ReflectionClass($stub);
diff --git a/tests/modules/saml/lib/Auth/Process/NameIDAttributeTest.php b/tests/modules/saml/lib/Auth/Process/NameIDAttributeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..84799db9e227ecb503d2ff481a8ba6f2255d2aad
--- /dev/null
+++ b/tests/modules/saml/lib/Auth/Process/NameIDAttributeTest.php
@@ -0,0 +1,141 @@
+<?php
+/**
+ * Test for the saml:NameIDAttribute filter.
+ *
+ * @author Eugene Venter <eugene@catalyst.net.nz>
+ * @package SimpleSAMLphp
+ */
+
+use PHPUnit\Framework\TestCase;
+
+class NameIDAttributeTest extends TestCase
+{
+
+    /*
+     * Helper function to run the filter with a given configuration.
+     *
+     * @param array $config  The filter configuration.
+     * @param array $request  The request state.
+     * @return array  The state array after processing.
+     */
+    private function processFilter(array $config, array $request)
+    {
+        $filter = new \SimpleSAML\Module\saml\Auth\Process\NameIDAttribute($config, null);
+        $filter->process($request);
+        return $request;
+    }
+
+
+    /**
+     * Test minimal configuration.
+     */
+    public function testMinimalConfig()
+    {
+        $config = array();
+
+        $nameId = new \SAML2\XML\saml\NameID();
+        $nameId->value = 'eugene@oombaas';
+        $nameId->Format = \SAML2\Constants::NAMEID_PERSISTENT;
+
+        $spId = 'eugeneSP';
+        $idpId = 'eugeneIdP';
+
+        $request = array(
+            'Source'     => array(
+                'entityid' => $spId,
+            ),
+            'Destination' => array(
+                'entityid' => $idpId,
+            ),
+            'saml:sp:NameID' => $nameId,
+        );
+        $result = $this->processFilter($config, $request);
+        $this->assertEquals("{$spId}!{$idpId}!{$nameId->value}", $result['Attributes']['nameid'][0]);
+    }
+
+    /**
+     * Test custom attribute name.
+     */
+    public function testCustomAttributeName()
+    {
+        $attributeName = 'eugeneNameIDAttribute';
+        $config = array('attribute' => $attributeName);
+
+        $nameId = new \SAML2\XML\saml\NameID();
+        $nameId->value = 'eugene@oombaas';
+        $nameId->Format = \SAML2\Constants::NAMEID_PERSISTENT;
+
+        $spId = 'eugeneSP';
+        $idpId = 'eugeneIdP';
+
+        $request = array(
+            'Source'     => array(
+                'entityid' => $spId,
+            ),
+            'Destination' => array(
+                'entityid' => $idpId,
+            ),
+            'saml:sp:NameID' => $nameId,
+        );
+        $result = $this->processFilter($config, $request);
+        $this->assertTrue(isset($result['Attributes'][$attributeName]));
+        $this->assertEquals("{$spId}!{$idpId}!{$nameId->value}", $result['Attributes'][$attributeName][0]);
+    }
+
+    /**
+     * Test custom format.
+     */
+    public function testFormat()
+    {
+        $config = array('format' => '%V');
+
+        $nameId = new \SAML2\XML\saml\NameID();
+        $nameId->value = 'eugene@oombaas';
+        $nameId->Format = \SAML2\Constants::NAMEID_PERSISTENT;
+
+        $spId = 'eugeneSP';
+        $idpId = 'eugeneIdP';
+
+        $request = array(
+            'Source'     => array(
+                'entityid' => $spId,
+            ),
+            'Destination' => array(
+                'entityid' => $idpId,
+            ),
+            'saml:sp:NameID' => $nameId,
+        );
+        $result = $this->processFilter($config, $request);
+        $this->assertEquals("{$nameId->value}", $result['Attributes']['nameid'][0]);
+    }
+
+
+    /**
+     * Test custom attribute name with format.
+     */
+    public function testCustomAttributeNameAndFormat()
+    {
+        $attributeName = 'eugeneNameIDAttribute';
+        $config = array('attribute' => $attributeName, 'format' => '%V');
+
+        $nameId = new \SAML2\XML\saml\NameID();
+        $nameId->value = 'eugene@oombaas';
+        $nameId->Format = \SAML2\Constants::NAMEID_PERSISTENT;
+
+        $spId = 'eugeneSP';
+        $idpId = 'eugeneIdP';
+
+        $request = array(
+            'Source'     => array(
+                'entityid' => $spId,
+            ),
+            'Destination' => array(
+                'entityid' => $idpId,
+            ),
+            'saml:sp:NameID' => $nameId,
+        );
+        $result = $this->processFilter($config, $request);
+        $this->assertTrue(isset($result['Attributes'][$attributeName]));
+        $this->assertEquals("{$nameId->value}", $result['Attributes'][$attributeName][0]);
+    }
+}
diff --git a/tests/modules/saml/lib/Auth/Source/Auth_Source_SP_Test.php b/tests/modules/saml/lib/Auth/Source/Auth_Source_SP_Test.php
index 57baff5ff06b30480f5742dc97dde3f657e614f5..502babca7e10c312d3b842f1aca4f5d3eac8a4c0 100644
--- a/tests/modules/saml/lib/Auth/Source/Auth_Source_SP_Test.php
+++ b/tests/modules/saml/lib/Auth/Source/Auth_Source_SP_Test.php
@@ -3,7 +3,7 @@
 namespace SimpleSAML\Test\Module\saml\Auth\Source;
 
 use PHPUnit\Framework\TestCase;
-use \SimpleSAML_Configuration as Configuration;
+use \SimpleSAML\Configuration;
 
 /**
  * Custom Exception to throw to terminate a TestCase.
@@ -28,11 +28,11 @@ class ExitTestException extends \Exception
 
 
 /**
- * Wrap the SSP sspmod_saml_Auth_Source_SP class
+ * Wrap the SSP \SimpleSAML\Module\saml\Auth\Source\SP class
  * - Use introspection to make startSSO2Test available
  * - Override sendSAML2AuthnRequest() to catch the AuthnRequest being sent
  */
-class SP_Tester extends \sspmod_saml_Auth_Source_SP
+class SP_Tester extends \SimpleSAML\Module\saml\Auth\Source\SP
 {
 
     public function __construct($info, $config)
@@ -41,7 +41,7 @@ class SP_Tester extends \sspmod_saml_Auth_Source_SP
     }
 
 
-    public function startSSO2Test(\SimpleSAML_Configuration $idpMetadata, array $state)
+    public function startSSO2Test(Configuration $idpMetadata, array $state)
     {
         $reflector = new \ReflectionObject($this);
         $method = $reflector->getMethod('startSSO2');
@@ -66,7 +66,7 @@ class SP_Tester extends \sspmod_saml_Auth_Source_SP
 
 
 /**
- * Set of test cases for sspmod_saml_Auth_Source_SP.
+ * Set of test cases for \SimpleSAML\Module\saml\Auth\Source\SP.
  */
 class SP_Test extends TestCase
 {
@@ -79,7 +79,7 @@ class SP_Test extends TestCase
     private function getIdpMetadata()
     {
         if (!$this->idpMetadata) {
-            $this->idpMetadata = new \SimpleSAML_Configuration(
+            $this->idpMetadata = new Configuration(
                 $this->idpConfigArray,
                 'Auth_Source_SP_Test::getIdpMetadata()'
             );
@@ -130,7 +130,7 @@ class SP_Test extends TestCase
 
 
     /**
-     * Create a SAML AuthnRequest using sspmod_saml_Auth_Source_SP
+     * Create a SAML AuthnRequest using \SimpleSAML\Module\saml\Auth\Source\SP
      *
      * @param array $state The state array to use in the test. This is an array of the parameters described in section
      * 2 of https://simplesamlphp.org/docs/development/saml:sp
diff --git a/tests/modules/saml/lib/IdP/SAML2Test.php b/tests/modules/saml/lib/IdP/SAML2Test.php
new file mode 100644
index 0000000000000000000000000000000000000000..76efcedb2316fd1c699f5d42fc642347f20c00af
--- /dev/null
+++ b/tests/modules/saml/lib/IdP/SAML2Test.php
@@ -0,0 +1,38 @@
+<?php
+
+class SAML2Test extends \PHPUnit_Framework_TestCase
+{
+    public function testProcessSOAPAuthnRequest()
+    {
+        $username = $_SERVER['PHP_AUTH_USER'] = 'username';
+        $password = $_SERVER['PHP_AUTH_PW'] = 'password';
+        $state = array();
+
+        \SimpleSAML\Module\saml\IdP\SAML2::processSOAPAuthnRequest($state);
+
+        $this->assertEquals($username, $state['core:auth:username']);
+        $this->assertEquals($password, $state['core:auth:password']);
+    }
+
+    public function testProcessSOAPAuthnRequestMissingUsername()
+    {
+        $this->setExpectedException('\SimpleSAML\Error\Error', 'WRONGUSERPASS');
+
+        $_SERVER['PHP_AUTH_PW'] = 'password';
+        unset($_SERVER['PHP_AUTH_USER']);
+        $state = array();
+
+        \SimpleSAML\Module\saml\IdP\SAML2::processSOAPAuthnRequest($state);
+    }
+
+    public function testProcessSOAPAuthnRequestMissingPassword()
+    {
+        $this->setExpectedException('\SimpleSAML\Error\Error', 'WRONGUSERPASS');
+
+        $_SERVER['PHP_AUTH_USER'] = 'username';
+        unset($_SERVER['PHP_AUTH_PW']);
+        $state = array();
+
+        \SimpleSAML\Module\saml\IdP\SAML2::processSOAPAuthnRequest($state);
+    }
+}
diff --git a/tests/routers/configLoader.php b/tests/routers/configLoader.php
index 724cada284b9ce0452a8a7cff3c56e537fe8aa84..57baa0a42f15355805609b437fac6d18c91dd009 100644
--- a/tests/routers/configLoader.php
+++ b/tests/routers/configLoader.php
@@ -33,7 +33,7 @@ require_once(dirname(__FILE__).'/../../vendor/autoload.php');
 
 // initialize configuration
 if (isset($config)) {
-    SimpleSAML_Configuration::loadFromArray($config, '[ARRAY]', 'simplesaml');
+    \SimpleSAML\Configuration::loadFromArray($config, '[ARRAY]', 'simplesaml');
 }
 
 // let the script proceed
diff --git a/tools/phpunit/phpunit.xml b/tools/phpunit/phpunit.xml
index b82bc2077bff517bf5f5c806da56498b6bf68133..eae5444c383cc978cf85035c7d5f100425ed95b2 100644
--- a/tools/phpunit/phpunit.xml
+++ b/tools/phpunit/phpunit.xml
@@ -23,6 +23,7 @@
             <exclude>
                 <directory>./../../vendor/</directory>
                 <directory>./../../tests/</directory>
+                <file>./../../lib/SimpleSAML/Utils/HttpAdapter.php</file>
             </exclude>
         </whitelist>
     </filter>
diff --git a/www/_include.php b/www/_include.php
index 7c18a2525447ec5ea88eecab9b879fc121af5822..a1bbe0e98d1d285394058fb8edea032acfdd021b 100644
--- a/www/_include.php
+++ b/www/_include.php
@@ -4,27 +4,25 @@
 require_once(dirname(dirname(__FILE__)).'/lib/_autoload.php');
 
 // enable assertion handler for all pages
-SimpleSAML_Error_Assertion::installHandler();
+\SimpleSAML\Error\Assertion::installHandler();
 
 // show error page on unhandled exceptions
 function SimpleSAML_exception_handler($exception)
 {
-    SimpleSAML\Module::callHooks('exception_handler', $exception);
+    \SimpleSAML\Module::callHooks('exception_handler', $exception);
 
-    if ($exception instanceof SimpleSAML_Error_Error) {
+    if ($exception instanceof \SimpleSAML\Error\Error) {
         $exception->show();
-    } elseif ($exception instanceof Exception) {
-        $e = new SimpleSAML_Error_Error('UNHANDLEDEXCEPTION', $exception);
+    } elseif ($exception instanceof \Exception) {
+        $e = new \SimpleSAML\Error\Error('UNHANDLEDEXCEPTION', $exception);
         $e->show();
-    } else {
-        if (class_exists('Error') && $exception instanceof Error) {
-            $code = $exception->getCode();
-            $errno = ($code > 0) ? $code : E_ERROR;
-            $errstr = $exception->getMessage();
-            $errfile = $exception->getFile();
-            $errline = $exception->getLine();
-            SimpleSAML_error_handler($errno, $errstr, $errfile, $errline);
-        }
+    } else if (class_exists('Error') && $exception instanceof \Error) {
+        $code = $exception->getCode();
+        $errno = ($code > 0) ? $code : E_ERROR;
+        $errstr = $exception->getMessage();
+        $errfile = $exception->getFile();
+        $errline = $exception->getLine();
+        SimpleSAML_error_handler($errno, $errstr, $errfile, $errline);
     }
 }
 
@@ -33,7 +31,7 @@ set_exception_handler('SimpleSAML_exception_handler');
 // log full backtrace on errors and warnings
 function SimpleSAML_error_handler($errno, $errstr, $errfile = null, $errline = 0, $errcontext = null)
 {
-    if (!class_exists('SimpleSAML\Logger')) {
+    if (!class_exists('\SimpleSAML\Logger')) {
         /* We are probably logging a deprecation-warning during parsing. Unfortunately, the autoloader is disabled at
          * this point, so we should stop here.
          *
@@ -42,7 +40,7 @@ function SimpleSAML_error_handler($errno, $errstr, $errfile = null, $errline = 0
         return false;
     }
 
-    if (SimpleSAML\Logger::isErrorMasked($errno)) {
+    if (\SimpleSAML\Logger::isErrorMasked($errno)) {
         // masked error
         return false;
     }
@@ -55,7 +53,7 @@ function SimpleSAML_error_handler($errno, $errstr, $errfile = null, $errline = 0
     }
 
     // show an error with a full backtrace
-    $e = new SimpleSAML_Error_Exception('Error '.$errno.' - '.$errstr);
+    $e = new \SimpleSAML\Error\Exception('Error '.$errno.' - '.$errstr);
     $e->logError();
 
     // resume normal error processing
@@ -65,12 +63,12 @@ function SimpleSAML_error_handler($errno, $errstr, $errfile = null, $errline = 0
 set_error_handler('SimpleSAML_error_handler');
 
 try {
-    SimpleSAML_Configuration::getInstance();
-} catch (Exception $e) {
+    \SimpleSAML\Configuration::getInstance();
+} catch (\Exception $e) {
     throw new \SimpleSAML\Error\CriticalConfigurationError(
         $e->getMessage()
     );
 }
 
 // set the timezone
-SimpleSAML\Utils\Time::initTimezone();
+\SimpleSAML\Utils\Time::initTimezone();
diff --git a/www/admin/hostnames.php b/www/admin/hostnames.php
index 90d58c3869e2dc5449c6f9b241d1d8e0fea757fd..3b24bf53124ed099fa8acaed66abc0aa78ed9bd9 100644
--- a/www/admin/hostnames.php
+++ b/www/admin/hostnames.php
@@ -2,12 +2,12 @@
 
 require_once('../_include.php');
 
-// Load SimpleSAMLphp, configuration
-$config = SimpleSAML_Configuration::getInstance();
-$session = SimpleSAML_Session::getSessionFromRequest();
+// Load SimpleSAMLphp configuration
+$config = \SimpleSAML\Configuration::getInstance();
+$session = \SimpleSAML\Session::getSessionFromRequest();
 
 // Check if valid local session exists..
-SimpleSAML\Utils\Auth::requireAdmin();
+\SimpleSAML\Utils\Auth::requireAdmin();
 
 $attributes = array();
 
@@ -25,7 +25,7 @@ $attributes['getSelfHostWithPath()'] = array(\SimpleSAML\Utils\HTTP::getSelfHost
 $attributes['getFirstPathElement()'] = array(\SimpleSAML\Utils\HTTP::getFirstPathElement());
 $attributes['selfURL()'] = array(\SimpleSAML\Utils\HTTP::getSelfURL());
 
-$template = new SimpleSAML_XHTML_Template($config, 'hostnames.php');
+$template = new \SimpleSAML\XHTML\Template($config, 'hostnames.php');
 
 $template->data['remaining']  = $session->getAuthData('admin', 'Expire') - time();
 $template->data['attributes'] = $attributes;
diff --git a/www/admin/index.php b/www/admin/index.php
index a1f9558e1446a3821ec98c9038499aaf46c4daaf..28bec413bc6c1e4bb85438eca84abd68b9ad4054 100644
--- a/www/admin/index.php
+++ b/www/admin/index.php
@@ -2,12 +2,12 @@
 
 require_once('../_include.php');
 
-// Load SimpleSAMLphp, configuration
-$config = SimpleSAML_Configuration::getInstance();
-$session = SimpleSAML_Session::getSessionFromRequest();
+// Load SimpleSAMLphp configuration
+$config = \SimpleSAML\Configuration::getInstance();
+$session = \SimpleSAML\Session::getSessionFromRequest();
 
 // Check if valid local session exists..
-//SimpleSAML\Utils\Auth::requireAdmin();
+\SimpleSAML\Utils\Auth::requireAdmin();
 
 $adminpages = array(
     'hostnames.php' => 'Diagnostics on hostname, port and protocol',
@@ -16,7 +16,7 @@ $adminpages = array(
     'sandbox.php' => 'Sandbox for testing changes to layout and css',
 );
 
-$template = new SimpleSAML_XHTML_Template($config, 'index.php');
+$template = new \SimpleSAML\XHTML\Template($config, 'index.php');
 
 $template->data['pagetitle'] = 'Admin';
 $template->data['adminpages'] = $adminpages;
diff --git a/www/admin/metadata-converter.php b/www/admin/metadata-converter.php
index 52313f1b769c7cf054af2a4ecae06aadc8fd16b5..db3114fb41c2d612af77659f2b71d8aba29f1fe6 100644
--- a/www/admin/metadata-converter.php
+++ b/www/admin/metadata-converter.php
@@ -1,10 +1,11 @@
 <?php
+
 require_once('../_include.php');
 
 // make sure that the user has admin access rights
-SimpleSAML\Utils\Auth::requireAdmin();
+\SimpleSAML\Utils\Auth::requireAdmin();
 
-$config = SimpleSAML_Configuration::getInstance();
+$config = \SimpleSAML\Configuration::getInstance();
 
 if (!empty($_FILES['xmlfile']['tmp_name'])) {
     $xmldata = trim(file_get_contents($_FILES['xmlfile']['tmp_name']));
@@ -14,7 +15,7 @@ if (!empty($_FILES['xmlfile']['tmp_name'])) {
 
 if (!empty($xmldata)) {
     \SimpleSAML\Utils\XML::checkSAMLMessage($xmldata, 'saml-meta');
-    $entities = SimpleSAML_Metadata_SAMLParser::parseDescriptorsString($xmldata);
+    $entities = \SimpleSAML\Metadata\SAMLParser::parseDescriptorsString($xmldata);
 
     // get all metadata for the entities
     foreach ($entities as &$entity) {
@@ -27,7 +28,7 @@ if (!empty($xmldata)) {
     }
 
     // transpose from $entities[entityid][type] to $output[type][entityid]
-    $output = SimpleSAML\Utils\Arrays::transpose($entities);
+    $output = \SimpleSAML\Utils\Arrays::transpose($entities);
 
     // merge all metadata of each type to a single string which should be added to the corresponding file
     foreach ($output as $type => &$entities) {
@@ -51,7 +52,7 @@ if (!empty($xmldata)) {
     $output = array();
 }
 
-$template = new SimpleSAML_XHTML_Template($config, 'metadata-converter.php', 'admin');
+$template = new \SimpleSAML\XHTML\Template($config, 'metadata-converter.php', 'admin');
 $template->data['clipboard.js'] = true;
 $template->data['xmldata'] = $xmldata;
 $template->data['output'] = $output;
diff --git a/www/admin/phpinfo.php b/www/admin/phpinfo.php
index 2b6b3d7cc5e0dfdfd6695c6d84a03581d13bc8ad..eb46c93772028d40e703798478d239a39fcfacfc 100644
--- a/www/admin/phpinfo.php
+++ b/www/admin/phpinfo.php
@@ -3,6 +3,6 @@
 require_once('../_include.php');
 
 // Make sure that the user has admin access rights
-SimpleSAML\Utils\Auth::requireAdmin();
+\SimpleSAML\Utils\Auth::requireAdmin();
 
 phpinfo();
diff --git a/www/admin/sandbox.php b/www/admin/sandbox.php
index ec77569cf8ebb875bfd47d361f52c815e2376ba3..e15d02fd7802f70f2da17506e7cc4d02e2723389 100644
--- a/www/admin/sandbox.php
+++ b/www/admin/sandbox.php
@@ -2,14 +2,14 @@
 
 require_once('../_include.php');
 
-// Load SimpleSAMLphp, configuration
-$config = SimpleSAML_Configuration::getInstance();
-$session = SimpleSAML_Session::getSessionFromRequest();
+// Load SimpleSAMLphp configuration
+$config = \SimpleSAML\Configuration::getInstance();
+$session = \SimpleSAML\Session::getSessionFromRequest();
 
 // Check if valid local session exists..
 //SimpleSAML\Utils\Auth::requireAdmin();
 
-$template = new SimpleSAML_XHTML_Template($config, 'sandbox.php');
+$template = new \SimpleSAML\XHTML\Template($config, 'sandbox.php');
 
 $template->data['pagetitle'] = 'Sandbox';
 $template->data['sometext'] = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur.';
diff --git a/www/authmemcookie.php b/www/authmemcookie.php
index d403aee138ba21a0429f5375329f369280832666..032c05f4c568d10c8c6fe50b20f249bf2ac01a99 100644
--- a/www/authmemcookie.php
+++ b/www/authmemcookie.php
@@ -16,15 +16,15 @@ require_once('_include.php');
 
 try {
     // load SimpleSAMLphp configuration
-    $globalConfig = SimpleSAML_Configuration::getInstance();
+    $globalConfig = \SimpleSAML\Configuration::getInstance();
 
     // check if this module is enabled
     if (!$globalConfig->getBoolean('enable.authmemcookie', false)) {
-        throw new SimpleSAML_Error_Error('NOACCESS');
+        throw new \SimpleSAML\Error\Error('NOACCESS');
     }
 
     // load Auth MemCookie configuration
-    $amc = SimpleSAML_AuthMemCookie::getInstance();
+    $amc = \SimpleSAML\AuthMemCookie::getInstance();
 
     $sourceId = $amc->getAuthSource();
     $s = new \SimpleSAML\Auth\Simple($sourceId);
@@ -33,7 +33,7 @@ try {
     $s->requireAuth();
 
     // generate session id and save it in a cookie
-    $sessionID = SimpleSAML\Utils\Random::generateID();
+    $sessionID = \SimpleSAML\Utils\Random::generateID();
     $cookieName = $amc->getCookieName();
     \SimpleSAML\Utils\HTTP::setCookie($cookieName, $sessionID);
 
@@ -45,7 +45,7 @@ try {
     // username
     $usernameAttr = $amc->getUsernameAttr();
     if (!array_key_exists($usernameAttr, $attributes)) {
-        throw new Exception(
+        throw new \Exception(
             "The user doesn't have an attribute named '".$usernameAttr.
             "'. This attribute is expected to contain the username."
         );
@@ -56,7 +56,7 @@ try {
     $groupsAttr = $amc->getGroupsAttr();
     if ($groupsAttr !== null) {
         if (!array_key_exists($groupsAttr, $attributes)) {
-            throw new Exception(
+            throw new \Exception(
                 "The user doesn't have an attribute named '".$groupsAttr.
                 "'. This attribute is expected to contain the groups the user is a member of."
             );
@@ -96,11 +96,11 @@ try {
     $memcache->set($sessionID, $data, 0, $expirationTime);
 
     // register logout handler
-    $session = SimpleSAML_Session::getSessionFromRequest();
-    $session->registerLogoutHandler($sourceId, 'SimpleSAML_AuthMemCookie', 'logoutHandler');
+    $session = \SimpleSAML\Session::getSessionFromRequest();
+    $session->registerLogoutHandler($sourceId, '\SimpleSAML\AuthMemCookie', 'logoutHandler');
 
     // redirect the user back to this page to signal that the login is completed
     \SimpleSAML\Utils\HTTP::redirectTrustedURL(\SimpleSAML\Utils\HTTP::getSelfURL());
-} catch (Exception $e) {
-    throw new SimpleSAML_Error_Error('CONFIG', $e);
+} catch (\Exception $e) {
+    throw new \SimpleSAML\Error\Error('CONFIG', $e);
 }
diff --git a/www/errorreport.php b/www/errorreport.php
index 569db419929568a20568bb20df012a1a67a6ede6..f04eb9eacbd4307a581a693a9f1ad883eaaf1ba4 100644
--- a/www/errorreport.php
+++ b/www/errorreport.php
@@ -2,13 +2,13 @@
 
 require_once('_include.php');
 
-$config = SimpleSAML_Configuration::getInstance();
+$config = \SimpleSAML\Configuration::getInstance();
 
 // this page will redirect to itself after processing a POST request and sending the email
 if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
     // the message has been sent. Show error report page
 
-    $t = new SimpleSAML_XHTML_Template($config, 'errorreport.php', 'errors');
+    $t = new \SimpleSAML\XHTML\Template($config, 'errorreport.php', 'errors');
     $t->show();
     exit;
 }
@@ -19,10 +19,10 @@ $text = htmlspecialchars((string) $_REQUEST['text']);
 
 $data = null;
 try {
-    $session = SimpleSAML_Session::getSessionFromRequest();
+    $session = \SimpleSAML\Session::getSessionFromRequest();
     $data = $session->getData('core:errorreport', $reportId);
-} catch (Exception $e) {
-    SimpleSAML\Logger::error('Error loading error report data: '.var_export($e->getMessage(), true));
+} catch (\Exception $e) {
+    \SimpleSAML\Logger::error('Error loading error report data: '.var_export($e->getMessage(), true));
 }
 
 if ($data === null) {
@@ -121,7 +121,7 @@ if ($from === 'no-reply@example.org' && $replyto !== null) {
 // send the email
 $toAddress = $config->getString('technicalcontact_email', 'na@example.org');
 if ($config->getBoolean('errorreporting', true) && $toAddress !== 'na@example.org') {
-    $email = new SimpleSAML_XHTML_EMail($toAddress, 'SimpleSAMLphp error report', $from);
+    $email = new \SimpleSAML\XHTML\EMail($toAddress, 'SimpleSAMLphp error report', $from);
     $email->setBody($message);
     $email->send();
     SimpleSAML\Logger::error('Report with id '.$reportId.' sent to <'.$toAddress.'>.');
diff --git a/www/logout.php b/www/logout.php
index b87ca89b77438a8002021d9ee9a9e0cadf5565c3..97c7d2b41b2c768512fc4703fb4837e70eb50969 100644
--- a/www/logout.php
+++ b/www/logout.php
@@ -2,7 +2,7 @@
 
 require_once('_include.php');
 
-$config = SimpleSAML_Configuration::getInstance();
+$config = \SimpleSAML\Configuration::getInstance();
 
 if (array_key_exists('link_href', $_REQUEST)) {
     $link = \SimpleSAML\Utils\HTTP::checkURLAllowed($_REQUEST['link_href']);
@@ -16,7 +16,7 @@ if (array_key_exists('link_text', $_REQUEST)) {
     $text = '{logout:default_link_text}';
 }
 
-$t = new SimpleSAML_XHTML_Template($config, 'logout.php');
+$t = new \SimpleSAML\XHTML\Template($config, 'logout.php');
 $t->data['link'] = $link;
 $t->data['text'] = $text;
 $t->show();
diff --git a/www/module.php b/www/module.php
index 8e122f78e335a4614f6d3054483d293349d7aa94..d8a72013d1e439d61d92bef310fbada8b044d78c 100644
--- a/www/module.php
+++ b/www/module.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Handler for module requests.
  *
@@ -39,7 +40,7 @@ $mimeTypes = array(
 );
 
 if (empty($_SERVER['PATH_INFO'])) {
-    throw new SimpleSAML_Error_NotFound('No PATH_INFO to module.php');
+    throw new \SimpleSAML\Error\NotFound('No PATH_INFO to module.php');
 }
 
 $url = $_SERVER['PATH_INFO'];
@@ -53,7 +54,7 @@ unset($_SERVER['PATH_INFO']);
 $modEnd = strpos($url, '/', 1);
 if ($modEnd === false) {
     // the path must always be on the form /module/
-    throw new SimpleSAML_Error_NotFound('The URL must at least contain a module name followed by a slash.');
+    throw new \SimpleSAML\Error\NotFound('The URL must at least contain a module name followed by a slash.');
 }
 
 $module = substr($url, 1, $modEnd - 1);
@@ -63,7 +64,7 @@ if ($url === false) {
 }
 
 if (!SimpleSAML\Module::isModuleEnabled($module)) {
-    throw new SimpleSAML_Error_NotFound('The module \''.$module.'\' was either not found, or wasn\'t enabled.');
+    throw new \SimpleSAML\Error\NotFound('The module \''.$module.'\' was either not found, or wasn\'t enabled.');
 }
 
 /* Make sure that the request isn't suspicious (contains references to current directory or parent directory or
@@ -71,9 +72,9 @@ if (!SimpleSAML\Module::isModuleEnabled($module)) {
  * attempts to use Windows-style paths.
  */
 if (strpos($url, '\\') !== false) {
-    throw new SimpleSAML_Error_BadRequest('Requested URL contained a backslash.');
+    throw new SimpleSAML\Error\BadRequest('Requested URL contained a backslash.');
 } elseif (strpos($url, './') !== false) {
-    throw new SimpleSAML_Error_BadRequest('Requested URL contained \'./\'.');
+    throw new \SimpleSAML\Error\BadRequest('Requested URL contained \'./\'.');
 }
 
 $moduleDir = SimpleSAML\Module::getModuleDir($module).'/www/';
@@ -110,13 +111,13 @@ if (is_dir($path)) {
     /* Path is a directory - maybe no index file was found in the previous step, or maybe the path didn't end with
      * a slash. Either way, we don't do directory listings.
      */
-    throw new SimpleSAML_Error_NotFound('Directory listing not available.');
+    throw new \SimpleSAML\Error\NotFound('Directory listing not available.');
 }
 
 if (!file_exists($path)) {
     // file not found
     SimpleSAML\Logger::info('Could not find file \''.$path.'\'.');
-    throw new SimpleSAML_Error_NotFound('The URL wasn\'t found in the module.');
+    throw new \SimpleSAML\Error\NotFound('The URL wasn\'t found in the module.');
 }
 
 if (preg_match('#\.php$#D', $path)) {
diff --git a/www/saml2/idp/ArtifactResolutionService.php b/www/saml2/idp/ArtifactResolutionService.php
index 39f705e657f8b01d3f54dc5768460655ddea78c0..26a4b48ffe6d1661414bd463e3840ac5e7a34d13 100644
--- a/www/saml2/idp/ArtifactResolutionService.php
+++ b/www/saml2/idp/ArtifactResolutionService.php
@@ -10,17 +10,17 @@
 
 require_once('../../_include.php');
 
-$config = SimpleSAML_Configuration::getInstance();
+$config = \SimpleSAML\Configuration::getInstance();
 if (!$config->getBoolean('enable.saml20-idp', false)) {
-    throw new SimpleSAML_Error_Error('NOACCESS');
+    throw new \SimpleSAML\Error\Error('NOACCESS');
 }
 
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 $idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
 $idpMetadata = $metadata->getMetaDataConfig($idpEntityId, 'saml20-idp-hosted');
 
 if (!$idpMetadata->getBoolean('saml20.sendartifact', false)) {
-    throw new SimpleSAML_Error_Error('NOACCESS');
+    throw new \SimpleSAML\Error\Error('NOACCESS');
 }
 
 $store = \SimpleSAML\Store::getInstance();
@@ -36,7 +36,7 @@ try {
     // an specific exception when the binding is unknown, and we should capture that here. Also note that the exception
     // message here is bogus!
     if ($e->getMessage() === 'Invalid message received to AssertionConsumerService endpoint.') {
-        throw new SimpleSAML_Error_Error('ARSPARAMS', $e, 400);
+        throw new \SimpleSAML\Error\Error('ARSPARAMS', $e, 400);
     } else {
         throw $e; // do not ignore other exceptions!
     }
@@ -64,5 +64,5 @@ $artifactResponse = new \SAML2\ArtifactResponse();
 $artifactResponse->setIssuer($idpEntityId);
 $artifactResponse->setInResponseTo($request->getId());
 $artifactResponse->setAny($responseXML);
-sspmod_saml_Message::addSign($idpMetadata, $spMetadata, $artifactResponse);
+\SimpleSAML\Module\saml\Message::addSign($idpMetadata, $spMetadata, $artifactResponse);
 $binding->send($artifactResponse);
diff --git a/www/saml2/idp/SSOService.php b/www/saml2/idp/SSOService.php
index f05e34c9c3c7adfbaa60a99c376585acbce6b3b9..5a400b854499c39bc04cf7fc62d99ede897551ed 100644
--- a/www/saml2/idp/SSOService.php
+++ b/www/saml2/idp/SSOService.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * The SSOService is part of the SAML 2.0 IdP code, and it receives incoming Authentication Requests
  * from a SAML 2.0 SP, parses, and process it, and then authenticates the user and sends the user back
@@ -10,16 +11,17 @@
 
 require_once('../../_include.php');
 
-SimpleSAML\Logger::info('SAML2.0 - IdP.SSOService: Accessing SAML 2.0 IdP endpoint SSOService');
+\SimpleSAML\Logger::info('SAML2.0 - IdP.SSOService: Accessing SAML 2.0 IdP endpoint SSOService');
 
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 $idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
-$idp = SimpleSAML_IdP::getById('saml2:' . $idpEntityId);
+$idp = \SimpleSAML\IdP::getById('saml2:' . $idpEntityId);
+
 try {
-    sspmod_saml_IdP_SAML2::receiveAuthnRequest($idp);
-} catch (Exception $e) {
+    \SimpleSAML\Module\saml\IdP\SAML2::receiveAuthnRequest($idp);
+} catch (\Exception $e) {
     if ($e->getMessage() === "Unable to find the current binding.") {
-        throw new SimpleSAML_Error_Error('SSOPARAMS', $e, 400);
+        throw new \SimpleSAML\Error\Error('SSOPARAMS', $e, 400);
     } else {
         throw $e; // do not ignore other exceptions!
     }
diff --git a/www/saml2/idp/SingleLogoutService.php b/www/saml2/idp/SingleLogoutService.php
index ab2a280229b7888ed79ca735e7dd71585331d360..402e8d5e2afbe1285aabf2c4fa9d07cc970ab9eb 100644
--- a/www/saml2/idp/SingleLogoutService.php
+++ b/www/saml2/idp/SingleLogoutService.php
@@ -10,27 +10,27 @@
 
 require_once('../../_include.php');
 
-SimpleSAML\Logger::info('SAML2.0 - IdP.SingleLogoutService: Accessing SAML 2.0 IdP endpoint SingleLogoutService');
+\SimpleSAML\Logger::info('SAML2.0 - IdP.SingleLogoutService: Accessing SAML 2.0 IdP endpoint SingleLogoutService');
 
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 $idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
-$idp = SimpleSAML_IdP::getById('saml2:'.$idpEntityId);
+$idp = \SimpleSAML\IdP::getById('saml2:'.$idpEntityId);
 
 if (isset($_REQUEST['ReturnTo'])) {
     $idp->doLogoutRedirect(\SimpleSAML\Utils\HTTP::checkURLAllowed((string) $_REQUEST['ReturnTo']));
 } else {
     try {
-        sspmod_saml_IdP_SAML2::receiveLogoutMessage($idp);
-    } catch (Exception $e) { // TODO: look for a specific exception
+        \SimpleSAML\Module\saml\IdP\SAML2::receiveLogoutMessage($idp);
+    } catch (\Exception $e) { // TODO: look for a specific exception
         /*
          * This is dirty. Instead of checking the message of the exception, \SAML2\Binding::getCurrentBinding() should
          * throw an specific exception when the binding is unknown, and we should capture that here
          */
         if ($e->getMessage() === 'Unable to find the current binding.') {
-            throw new SimpleSAML_Error_Error('SLOSERVICEPARAMS', $e, 400);
+            throw new \SimpleSAML\Error\Error('SLOSERVICEPARAMS', $e, 400);
         } else {
             throw $e; // do not ignore other exceptions!
         }
     }
 }
-assert(FALSE);
+assert(false);
diff --git a/www/saml2/idp/initSLO.php b/www/saml2/idp/initSLO.php
index 60b17fc5ff86ae9eb24b2a0ef39456c4ebd776dc..526c7cd8641e76bddd4fb18c9be19593e5ee25e1 100644
--- a/www/saml2/idp/initSLO.php
+++ b/www/saml2/idp/initSLO.php
@@ -1,14 +1,15 @@
 <?php
+
 require_once('../../_include.php');
 
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 $idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
-$idp = SimpleSAML_IdP::getById('saml2:'.$idpEntityId);
+$idp = \SimpleSAML\IdP::getById('saml2:'.$idpEntityId);
 
-SimpleSAML\Logger::info('SAML2.0 - IdP.initSLO: Accessing SAML 2.0 IdP endpoint init Single Logout');
+\SimpleSAML\Logger::info('SAML2.0 - IdP.initSLO: Accessing SAML 2.0 IdP endpoint init Single Logout');
 
 if (!isset($_GET['RelayState'])) {
-    throw new SimpleSAML_Error_Error('NORELAYSTATE');
+    throw new \SimpleSAML\Error\Error('NORELAYSTATE');
 }
 
 $idp->doLogoutRedirect(\SimpleSAML\Utils\HTTP::checkURLAllowed((string) $_GET['RelayState']));
diff --git a/www/saml2/idp/metadata.php b/www/saml2/idp/metadata.php
index e39645517cc6d3cdfb77256c7256191d6c393101..d15262f5a8ce81cf318a80e1b0305ed0a778fb0a 100644
--- a/www/saml2/idp/metadata.php
+++ b/www/saml2/idp/metadata.php
@@ -8,12 +8,12 @@ use SimpleSAML\Utils\Crypto as Crypto;
 use SimpleSAML\Utils\HTTP as HTTP;
 use SimpleSAML\Utils\Config\Metadata as Metadata;
 
-// load SimpleSAMLphp, configuration and metadata
-$config = SimpleSAML_Configuration::getInstance();
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+// load SimpleSAMLphp configuration and metadata
+$config = \SimpleSAML\Configuration::getInstance();
+$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 
 if (!$config->getBoolean('enable.saml20-idp', false)) {
-    throw new SimpleSAML_Error_Error('NOACCESS');
+    throw new \SimpleSAML\Error\Error('NOACCESS');
 }
 
 // check if valid local session exists
@@ -127,6 +127,14 @@ try {
         ));
     }
 
+    if ($idpmeta->getBoolean('saml20.ecp', false)) {
+        $metaArray['SingleSignOnService'][] = array(
+            'index' => 0,
+            'Binding'  => Constants::BINDING_SOAP,
+            'Location' => HTTP::getBaseURL().'saml2/idp/SSOService.php',
+        );
+    }
+
     $metaArray['NameIDFormat'] = $idpmeta->getString(
         'NameIDFormat',
         'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'
@@ -140,7 +148,7 @@ try {
         );
 
         if (!$idpmeta->hasValue('OrganizationURL')) {
-            throw new SimpleSAML_Error_Exception('If OrganizationName is set, OrganizationURL must also be set.');
+            throw new \SimpleSAML\Error\Exception('If OrganizationName is set, OrganizationURL must also be set.');
         }
         $metaArray['OrganizationURL'] = $idpmeta->getLocalizedString('OrganizationURL');
     }
@@ -193,7 +201,7 @@ try {
         $metaArray['contacts'][] = Metadata::getContact($techcontact);
     }
 
-    $metaBuilder = new SimpleSAML_Metadata_SAMLBuilder($idpentityid);
+    $metaBuilder = new \SimpleSAML\Metadata\SAMLBuilder($idpentityid);
     $metaBuilder->addMetadataIdP20($metaArray);
     $metaBuilder->addOrganizationInfo($metaArray);
 
@@ -202,12 +210,12 @@ try {
     $metaflat = '$metadata['.var_export($idpentityid, true).'] = '.var_export($metaArray, true).';';
 
     // sign the metadata if enabled
-    $metaxml = SimpleSAML_Metadata_Signer::sign($metaxml, $idpmeta->toArray(), 'SAML 2 IdP');
+    $metaxml = \SimpleSAML\Metadata\Signer::sign($metaxml, $idpmeta->toArray(), 'SAML 2 IdP');
 
     if (array_key_exists('output', $_GET) && $_GET['output'] == 'xhtml') {
         $defaultidp = $config->getString('default-saml20-idp', null);
 
-        $t = new SimpleSAML_XHTML_Template($config, 'metadata.php', 'admin');
+        $t = new \SimpleSAML\XHTML\Template($config, 'metadata.php', 'admin');
 
         $t->data['clipboard.js'] = true;
         $t->data['available_certs'] = $availableCerts;
@@ -233,5 +241,5 @@ try {
         exit(0);
     }
 } catch (Exception $exception) {
-    throw new SimpleSAML_Error_Error('METADATA', $exception);
+    throw new \SimpleSAML\Error\Error('METADATA', $exception);
 }
diff --git a/www/shib13/idp/SSOService.php b/www/shib13/idp/SSOService.php
index 1a65ab18f96ea6273e6a7e0c3a12b92b47322e03..2237091b8763078d7537df6ebf7aa7268b74d7a6 100644
--- a/www/shib13/idp/SSOService.php
+++ b/www/shib13/idp/SSOService.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * The SSOService is part of the Shibboleth 1.3 IdP code, and it receives incoming Authentication Requests
  * from a Shibboleth 1.3 SP, parses, and process it, and then authenticates the user and sends the user back
@@ -10,10 +11,11 @@
 
 require_once '../../_include.php';
 
-SimpleSAML\Logger::info('Shib1.3 - IdP.SSOService: Accessing Shibboleth 1.3 IdP endpoint SSOService');
+\SimpleSAML\Logger::info('Shib1.3 - IdP.SSOService: Accessing Shibboleth 1.3 IdP endpoint SSOService');
 
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 $idpEntityId = $metadata->getMetaDataCurrentEntityID('shib13-idp-hosted');
-$idp = SimpleSAML_IdP::getById('saml1:' . $idpEntityId);
-sspmod_saml_IdP_SAML1::receiveAuthnRequest($idp);
+$idp = \SimpleSAML\IdP::getById('saml1:' . $idpEntityId);
+\SimpleSAML\Module\saml\IdP\SAML1::receiveAuthnRequest($idp);
+
 assert(false);
diff --git a/www/shib13/idp/metadata.php b/www/shib13/idp/metadata.php
index 23c3f6857c3638b4b51dfdcb768e2c92bd540f31..060ba6bcd03a0a1a0692c84bafa8e6da59ede4dd 100644
--- a/www/shib13/idp/metadata.php
+++ b/www/shib13/idp/metadata.php
@@ -3,16 +3,16 @@
 require_once('../../_include.php');
 
 // load configuration and metadata
-$config = SimpleSAML_Configuration::getInstance();
-$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
+$config = \SimpleSAML\Configuration::getInstance();
+$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 
 if (!$config->getBoolean('enable.shib13-idp', false)) {
-    throw new SimpleSAML_Error_Error('NOACCESS');
+    throw new \SimpleSAML\Error\Error('NOACCESS');
 }
 
 // check if valid local session exists
 if ($config->getBoolean('admin.protectmetadata', false)) {
-    SimpleSAML\Utils\Auth::requireAdmin();
+    \SimpleSAML\Utils\Auth::requireAdmin();
 }
 
 try {
@@ -22,7 +22,7 @@ try {
     $idpmeta = $metadata->getMetaDataConfig($idpentityid, 'shib13-idp-hosted');
 
     $keys = array();
-    $certInfo = SimpleSAML\Utils\Crypto::loadPublicKey($idpmeta, false, 'new_');
+    $certInfo = \SimpleSAML\Utils\Crypto::loadPublicKey($idpmeta, false, 'new_');
     if ($certInfo !== null) {
         $keys[] = array(
             'type'            => 'X509Certificate',
@@ -32,7 +32,7 @@ try {
         );
     }
 
-    $certInfo = SimpleSAML\Utils\Crypto::loadPublicKey($idpmeta, true);
+    $certInfo = \SimpleSAML\Utils\Crypto::loadPublicKey($idpmeta, true);
     $keys[] = array(
         'type'            => 'X509Certificate',
         'signing'         => true,
@@ -62,15 +62,14 @@ try {
         );
 
         if (!$idpmeta->hasValue('OrganizationURL')) {
-            throw new SimpleSAML_Error_Exception('If OrganizationName is set, OrganizationURL must also be set.');
+            throw new \SimpleSAML\Error\Exception('If OrganizationName is set, OrganizationURL must also be set.');
         }
         $metaArray['OrganizationURL'] = $idpmeta->getLocalizedString('OrganizationURL');
     }
 
-
     $metaflat = '$metadata['.var_export($idpentityid, true).'] = '.var_export($metaArray, true).';';
 
-    $metaBuilder = new SimpleSAML_Metadata_SAMLBuilder($idpentityid);
+    $metaBuilder = new \SimpleSAML\Metadata\SAMLBuilder($idpentityid);
     $metaBuilder->addMetadataIdP11($metaArray);
     $metaBuilder->addOrganizationInfo($metaArray);
     $metaBuilder->addContact('technical', \SimpleSAML\Utils\Config\Metadata::getContact(array(
@@ -81,13 +80,12 @@ try {
     $metaxml = $metaBuilder->getEntityDescriptorText();
 
     // sign the metadata if enabled
-    $metaxml = SimpleSAML_Metadata_Signer::sign($metaxml, $idpmeta->toArray(), 'Shib 1.3 IdP');
-
+    $metaxml = \SimpleSAML\Metadata\Signer::sign($metaxml, $idpmeta->toArray(), 'Shib 1.3 IdP');
 
     if (array_key_exists('output', $_GET) && $_GET['output'] == 'xhtml') {
         $defaultidp = $config->getString('default-shib13-idp', null);
 
-        $t = new SimpleSAML_XHTML_Template($config, 'metadata.php', 'admin');
+        $t = new \SimpleSAML\XHTML\Template($config, 'metadata.php', 'admin');
 
         $t->data['clipboard.js'] = true;
         $t->data['header'] = 'shib13-idp'; // TODO: Replace with headerString in 2.0
@@ -107,6 +105,6 @@ try {
         echo $metaxml;
         exit(0);
     }
-} catch (Exception $exception) {
-    throw new SimpleSAML_Error_Error('METADATA', $exception);
+} catch (\Exception $exception) {
+    throw new \SimpleSAML\Error\Error('METADATA', $exception);
 }