diff --git a/composer.json b/composer.json
index a837f10218ea42537d30ca92852e9ab6042e7e62..77558fac6fa0c4d4757d3791abea4690e7a7d2ea 100644
--- a/composer.json
+++ b/composer.json
@@ -36,8 +36,8 @@
         "ext-hash": "*",
         "ext-json": "*",
         "ext-mbstring": "*",
-        "simplesamlphp/saml2": "~3.1.4",
-        "robrichards/xmlseclibs": "~3.0",
+        "simplesamlphp/saml2": "~3.2",
+        "robrichards/xmlseclibs": "dev-master#93f8c07976b36b6050ab341ab5850484dc897ce0 as 3.0.2",
         "whitehat101/apr1-md5": "~1.0",
         "twig/twig": "~1.0",
         "gettext/gettext": "^3.5",
diff --git a/composer.lock b/composer.lock
index c62015b7caed35608a30b7f5f5b21d0b4720b8e1..6891f27e657b7f5c4b2a24dc6b218c24c70afc20 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "429c28dc40717fc389a01b58acdbfa6b",
+    "content-hash": "221caf8ce81175f80009f06e6c1f6cc5",
     "packages": [
         {
             "name": "gettext/gettext",
@@ -68,16 +68,16 @@
         },
         {
             "name": "gettext/languages",
-            "version": "2.3.0",
+            "version": "2.4.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/mlocati/cldr-to-gettext-plural-rules.git",
-                "reference": "49c39e51569963cc917a924b489e7025bfb9d8c7"
+                "reference": "1b74377bd0c4cd87e8d72b948f5d8867e23505a5"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/mlocati/cldr-to-gettext-plural-rules/zipball/49c39e51569963cc917a924b489e7025bfb9d8c7",
-                "reference": "49c39e51569963cc917a924b489e7025bfb9d8c7",
+                "url": "https://api.github.com/repos/mlocati/cldr-to-gettext-plural-rules/zipball/1b74377bd0c4cd87e8d72b948f5d8867e23505a5",
+                "reference": "1b74377bd0c4cd87e8d72b948f5d8867e23505a5",
                 "shasum": ""
             },
             "require": {
@@ -125,7 +125,7 @@
                 "translations",
                 "unicode"
             ],
-            "time": "2017-03-23T17:02:28+00:00"
+            "time": "2018-06-21T15:58:36+00:00"
         },
         {
             "name": "jaimeperez/twig-configurable-i18n",
@@ -220,24 +220,22 @@
         },
         {
             "name": "robrichards/xmlseclibs",
-            "version": "3.0.1",
+            "version": "dev-master",
             "source": {
                 "type": "git",
                 "url": "https://github.com/robrichards/xmlseclibs.git",
-                "reference": "d937712f70f93a584eb0299ccd87dc6374003781"
+                "reference": "93f8c07976b36b6050ab341ab5850484dc897ce0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/robrichards/xmlseclibs/zipball/d937712f70f93a584eb0299ccd87dc6374003781",
-                "reference": "d937712f70f93a584eb0299ccd87dc6374003781",
+                "url": "https://api.github.com/repos/robrichards/xmlseclibs/zipball/93f8c07976b36b6050ab341ab5850484dc897ce0",
+                "reference": "93f8c07976b36b6050ab341ab5850484dc897ce0",
                 "shasum": ""
             },
             "require": {
+                "ext-openssl": "*",
                 "php": ">= 5.4"
             },
-            "suggest": {
-                "ext-openssl": "OpenSSL extension"
-            },
             "type": "library",
             "autoload": {
                 "psr-4": {
@@ -256,20 +254,20 @@
                 "xml",
                 "xmldsig"
             ],
-            "time": "2017-08-31T09:27:07+00:00"
+            "time": "2018-03-23T11:10:08+00:00"
         },
         {
             "name": "simplesamlphp/saml2",
-            "version": "v3.1.6",
+            "version": "v3.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/simplesamlphp/saml2.git",
-                "reference": "d809ffbe2aa7260a0b3e72bf5be8cd6de0325d7c"
+                "reference": "43590bc9614c1df5bd7b1639088f7d904842892b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/simplesamlphp/saml2/zipball/d809ffbe2aa7260a0b3e72bf5be8cd6de0325d7c",
-                "reference": "d809ffbe2aa7260a0b3e72bf5be8cd6de0325d7c",
+                "url": "https://api.github.com/repos/simplesamlphp/saml2/zipball/43590bc9614c1df5bd7b1639088f7d904842892b",
+                "reference": "43590bc9614c1df5bd7b1639088f7d904842892b",
                 "shasum": ""
             },
             "require": {
@@ -313,7 +311,7 @@
                 }
             ],
             "description": "SAML2 PHP library from SimpleSAMLphp",
-            "time": "2018-05-04T12:03:18+00:00"
+            "time": "2018-07-12T09:56:19+00:00"
         },
         {
             "name": "twig/extensions",
@@ -373,16 +371,16 @@
         },
         {
             "name": "twig/twig",
-            "version": "v1.35.2",
+            "version": "v1.35.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/twigphp/Twig.git",
-                "reference": "9c24f2cd39dc1906b76879e099970b7e53724601"
+                "reference": "b48680b6eb7d16b5025b9bfc4108d86f6b8af86f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/twigphp/Twig/zipball/9c24f2cd39dc1906b76879e099970b7e53724601",
-                "reference": "9c24f2cd39dc1906b76879e099970b7e53724601",
+                "url": "https://api.github.com/repos/twigphp/Twig/zipball/b48680b6eb7d16b5025b9bfc4108d86f6b8af86f",
+                "reference": "b48680b6eb7d16b5025b9bfc4108d86f6b8af86f",
                 "shasum": ""
             },
             "require": {
@@ -390,8 +388,8 @@
             },
             "require-dev": {
                 "psr/container": "^1.0",
-                "symfony/debug": "~2.7",
-                "symfony/phpunit-bridge": "~3.3@dev"
+                "symfony/debug": "^2.7",
+                "symfony/phpunit-bridge": "^3.3"
             },
             "type": "library",
             "extra": {
@@ -434,7 +432,7 @@
             "keywords": [
                 "templating"
             ],
-            "time": "2018-03-03T16:21:29+00:00"
+            "time": "2018-03-20T04:25:58+00:00"
         },
         {
             "name": "whitehat101/apr1-md5",
@@ -544,37 +542,81 @@
             ],
             "time": "2016-08-30T16:08:34+00:00"
         },
+        {
+            "name": "composer/xdebug-handler",
+            "version": "1.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/composer/xdebug-handler.git",
+                "reference": "c919dc6c62e221fc6406f861ea13433c0aa24f08"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/c919dc6c62e221fc6406f861ea13433c0aa24f08",
+                "reference": "c919dc6c62e221fc6406f861ea13433c0aa24f08",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.3.2 || ^7.0",
+                "psr/log": "^1.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Composer\\XdebugHandler\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "John Stevenson",
+                    "email": "john-stevenson@blueyonder.co.uk"
+                }
+            ],
+            "description": "Restarts a process without xdebug.",
+            "keywords": [
+                "Xdebug",
+                "performance"
+            ],
+            "time": "2018-04-11T15:42:36+00:00"
+        },
         {
             "name": "doctrine/annotations",
-            "version": "v1.4.0",
+            "version": "v1.2.7",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/annotations.git",
-                "reference": "54cacc9b81758b14e3ce750f205a393d52339e97"
+                "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/annotations/zipball/54cacc9b81758b14e3ce750f205a393d52339e97",
-                "reference": "54cacc9b81758b14e3ce750f205a393d52339e97",
+                "url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535",
+                "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535",
                 "shasum": ""
             },
             "require": {
                 "doctrine/lexer": "1.*",
-                "php": "^5.6 || ^7.0"
+                "php": ">=5.3.2"
             },
             "require-dev": {
                 "doctrine/cache": "1.*",
-                "phpunit/phpunit": "^5.7"
+                "phpunit/phpunit": "4.*"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.4.x-dev"
+                    "dev-master": "1.3.x-dev"
                 }
             },
             "autoload": {
-                "psr-4": {
-                    "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations"
+                "psr-0": {
+                    "Doctrine\\Common\\Annotations\\": "lib/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -610,7 +652,7 @@
                 "docblock",
                 "parser"
             ],
-            "time": "2017-02-24T16:22:25+00:00"
+            "time": "2015-08-31T12:32:49+00:00"
         },
         {
             "name": "doctrine/instantiator",
@@ -722,51 +764,54 @@
         },
         {
             "name": "friendsofphp/php-cs-fixer",
-            "version": "v2.10.3",
+            "version": "v2.2.20",
             "source": {
                 "type": "git",
                 "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
-                "reference": "1634a2c250bf4640f1c5c963f63b413c2d966c8a"
+                "reference": "f1631f0747ad2a9dd3de8d7873b71f6573f8d0c2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/1634a2c250bf4640f1c5c963f63b413c2d966c8a",
-                "reference": "1634a2c250bf4640f1c5c963f63b413c2d966c8a",
+                "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/f1631f0747ad2a9dd3de8d7873b71f6573f8d0c2",
+                "reference": "f1631f0747ad2a9dd3de8d7873b71f6573f8d0c2",
                 "shasum": ""
             },
             "require": {
                 "composer/semver": "^1.4",
+                "composer/xdebug-handler": "^1.0",
                 "doctrine/annotations": "^1.2",
                 "ext-json": "*",
                 "ext-tokenizer": "*",
-                "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",
+                "php": "^5.3.6 || >=7.0 <7.3",
+                "sebastian/diff": "^1.4",
+                "symfony/console": "^2.4 || ^3.0 || ^4.0",
+                "symfony/event-dispatcher": "^2.1 || ^3.0 || ^4.0",
+                "symfony/filesystem": "^2.4 || ^3.0 || ^4.0",
+                "symfony/finder": "^2.2 || ^3.0 || ^4.0",
+                "symfony/options-resolver": "^2.6 || ^3.0 || ^4.0",
+                "symfony/polyfill-php54": "^1.0",
+                "symfony/polyfill-php55": "^1.3",
                 "symfony/polyfill-php70": "^1.0",
                 "symfony/polyfill-php72": "^1.4",
-                "symfony/process": "^3.0 || ^4.0",
-                "symfony/stopwatch": "^3.0 || ^4.0"
+                "symfony/process": "^2.3 || ^3.0 || ^4.0",
+                "symfony/stopwatch": "^2.5 || ^3.0 || ^4.0"
             },
             "conflict": {
-                "hhvm": "*"
+                "hhvm": "<3.18"
             },
             "require-dev": {
-                "johnkary/phpunit-speedtrap": "^1.1 || ^2.0@dev",
+                "johnkary/phpunit-speedtrap": "^1.0.1 || ^2.0 || ^3.0",
                 "justinrainbow/json-schema": "^5.0",
-                "keradus/cli-executor": "^1.0",
+                "keradus/cli-executor": "^1.1",
                 "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",
+                "php-coveralls/php-coveralls": "^1.0.2",
+                "phpunit/phpunit": "^4.8.35 || ^5.4.3",
                 "symfony/phpunit-bridge": "^3.2.2 || ^4.0"
             },
             "suggest": {
                 "ext-mbstring": "For handling non-UTF8 characters in cache signature.",
+                "php-cs-fixer/phpunit-constraint-isidenticalstring": "For IsIdenticalString constraint.",
+                "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "For XmlMatchesXsd constraint.",
                 "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible."
             },
             "bin": [
@@ -781,8 +826,6 @@
                     "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/IntegrationCaseFactoryInterface.php",
@@ -805,7 +848,49 @@
                 }
             ],
             "description": "A tool to automatically fix PHP code style",
-            "time": "2018-02-22T16:49:33+00:00"
+            "time": "2018-06-02T17:26:04+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"
         },
         {
             "name": "mikey179/vfsStream",
@@ -855,16 +940,16 @@
         },
         {
             "name": "paragonie/random_compat",
-            "version": "v2.0.11",
+            "version": "v2.0.17",
             "source": {
                 "type": "git",
                 "url": "https://github.com/paragonie/random_compat.git",
-                "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8"
+                "reference": "29af24f25bab834fcbb38ad2a69fa93b867e070d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/paragonie/random_compat/zipball/5da4d3c796c275c55f057af5a643ae297d96b4d8",
-                "reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8",
+                "url": "https://api.github.com/repos/paragonie/random_compat/zipball/29af24f25bab834fcbb38ad2a69fa93b867e070d",
+                "reference": "29af24f25bab834fcbb38ad2a69fa93b867e070d",
                 "shasum": ""
             },
             "require": {
@@ -896,192 +981,45 @@
             "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
             "keywords": [
                 "csprng",
+                "polyfill",
                 "pseudorandom",
                 "random"
             ],
-            "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.1",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
-                "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
-                "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.5"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "^4.6"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.0.x-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "phpDocumentor\\Reflection\\": [
-                        "src"
-                    ]
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Jaap van Otterdijk",
-                    "email": "opensource@ijaap.nl"
-                }
-            ],
-            "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
-            "homepage": "http://www.phpdoc.org",
-            "keywords": [
-                "FQSEN",
-                "phpDocumentor",
-                "phpdoc",
-                "reflection",
-                "static analysis"
-            ],
-            "time": "2017-09-11T18:02:19+00:00"
+            "time": "2018-07-04T16:31:37+00:00"
         },
         {
             "name": "phpdocumentor/reflection-docblock",
-            "version": "3.3.2",
+            "version": "2.0.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
-                "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2"
+                "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bf329f6c1aadea3299f08ee804682b7c45b326a2",
-                "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e6a969a640b00d8daa3c66518b0405fb41ae0c4b",
+                "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b",
                 "shasum": ""
             },
             "require": {
-                "php": "^5.6 || ^7.0",
-                "phpdocumentor/reflection-common": "^1.0.0",
-                "phpdocumentor/type-resolver": "^0.4.0",
-                "webmozart/assert": "^1.0"
+                "php": ">=5.3.3"
             },
             "require-dev": {
-                "mockery/mockery": "^0.9.4",
-                "phpunit/phpunit": "^4.4"
-            },
-            "type": "library",
-            "autoload": {
-                "psr-4": {
-                    "phpDocumentor\\Reflection\\": [
-                        "src/"
-                    ]
-                }
+                "phpunit/phpunit": "~4.0"
             },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Mike van Riel",
-                    "email": "me@mikevanriel.com"
-                }
-            ],
-            "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-11-10T14:09:06+00:00"
-        },
-        {
-            "name": "phpdocumentor/type-resolver",
-            "version": "0.4.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/phpDocumentor/TypeResolver.git",
-                "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7",
-                "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
-                "shasum": ""
-            },
-            "require": {
-                "php": "^5.5 || ^7.0",
-                "phpdocumentor/reflection-common": "^1.0"
-            },
-            "require-dev": {
-                "mockery/mockery": "^0.9.4",
-                "phpunit/phpunit": "^5.2||^4.8.24"
+            "suggest": {
+                "dflydev/markdown": "~1.0",
+                "erusev/parsedown": "~1.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.0.x-dev"
+                    "dev-master": "2.0.x-dev"
                 }
             },
             "autoload": {
-                "psr-4": {
-                    "phpDocumentor\\Reflection\\": [
+                "psr-0": {
+                    "phpDocumentor": [
                         "src/"
                     ]
                 }
@@ -1093,30 +1031,30 @@
             "authors": [
                 {
                     "name": "Mike van Riel",
-                    "email": "me@mikevanriel.com"
+                    "email": "mike.vanriel@naenius.com"
                 }
             ],
-            "time": "2017-07-14T14:27:02+00:00"
+            "time": "2016-01-25T08:17:30+00:00"
         },
         {
             "name": "phpspec/prophecy",
-            "version": "1.7.5",
+            "version": "1.7.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpspec/prophecy.git",
-                "reference": "dfd6be44111a7c41c2e884a336cc4f461b3b2401"
+                "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/dfd6be44111a7c41c2e884a336cc4f461b3b2401",
-                "reference": "dfd6be44111a7c41c2e884a336cc4f461b3b2401",
+                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/33a7e3c4fda54e912ff6338c48823bd5c0f0b712",
+                "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712",
                 "shasum": ""
             },
             "require": {
                 "doctrine/instantiator": "^1.0.2",
                 "php": "^5.3|^7.0",
                 "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
-                "sebastian/comparator": "^1.1|^2.0",
+                "sebastian/comparator": "^1.1|^2.0|^3.0",
                 "sebastian/recursion-context": "^1.0|^2.0|^3.0"
             },
             "require-dev": {
@@ -1159,7 +1097,7 @@
                 "spy",
                 "stub"
             ],
-            "time": "2018-02-19T10:16:54+00:00"
+            "time": "2018-04-18T13:57:24+00:00"
         },
         {
             "name": "phpunit/php-code-coverage",
@@ -1911,45 +1849,37 @@
         },
         {
             "name": "symfony/console",
-            "version": "v3.4.5",
+            "version": "v2.8.42",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/console.git",
-                "reference": "067339e9b8ec30d5f19f5950208893ff026b94f7"
+                "reference": "e8e59b74ad1274714dad2748349b55e3e6e630c7"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/console/zipball/067339e9b8ec30d5f19f5950208893ff026b94f7",
-                "reference": "067339e9b8ec30d5f19f5950208893ff026b94f7",
+                "url": "https://api.github.com/repos/symfony/console/zipball/e8e59b74ad1274714dad2748349b55e3e6e630c7",
+                "reference": "e8e59b74ad1274714dad2748349b55e3e6e630c7",
                 "shasum": ""
             },
             "require": {
-                "php": "^5.5.9|>=7.0.8",
-                "symfony/debug": "~2.8|~3.0|~4.0",
+                "php": ">=5.3.9",
+                "symfony/debug": "^2.7.2|~3.0.0",
                 "symfony/polyfill-mbstring": "~1.0"
             },
-            "conflict": {
-                "symfony/dependency-injection": "<3.4",
-                "symfony/process": "<3.3"
-            },
             "require-dev": {
                 "psr/log": "~1.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"
+                "symfony/event-dispatcher": "~2.1|~3.0.0",
+                "symfony/process": "~2.1|~3.0.0"
             },
             "suggest": {
-                "psr/log": "For using the console logger",
+                "psr/log-implementation": "For using the console logger",
                 "symfony/event-dispatcher": "",
-                "symfony/lock": "",
                 "symfony/process": ""
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.4-dev"
+                    "dev-master": "2.8-dev"
                 }
             },
             "autoload": {
@@ -1976,36 +1906,37 @@
             ],
             "description": "Symfony Console Component",
             "homepage": "https://symfony.com",
-            "time": "2018-02-26T15:46:28+00:00"
+            "time": "2018-05-15T21:17:45+00:00"
         },
         {
             "name": "symfony/debug",
-            "version": "v3.4.5",
+            "version": "v2.8.42",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/debug.git",
-                "reference": "9b1071f86e79e1999b3d3675d2e0e7684268b9bc"
+                "reference": "a26ddce7fe4e884097d72435653bc7e703411f26"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/debug/zipball/9b1071f86e79e1999b3d3675d2e0e7684268b9bc",
-                "reference": "9b1071f86e79e1999b3d3675d2e0e7684268b9bc",
+                "url": "https://api.github.com/repos/symfony/debug/zipball/a26ddce7fe4e884097d72435653bc7e703411f26",
+                "reference": "a26ddce7fe4e884097d72435653bc7e703411f26",
                 "shasum": ""
             },
             "require": {
-                "php": "^5.5.9|>=7.0.8",
+                "php": ">=5.3.9",
                 "psr/log": "~1.0"
             },
             "conflict": {
                 "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|~4.0"
+                "symfony/class-loader": "~2.2|~3.0.0",
+                "symfony/http-kernel": "~2.3.24|~2.5.9|^2.6.2|~3.0.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.4-dev"
+                    "dev-master": "2.8-dev"
                 }
             },
             "autoload": {
@@ -2032,34 +1963,31 @@
             ],
             "description": "Symfony Debug Component",
             "homepage": "https://symfony.com",
-            "time": "2018-02-28T21:49:22+00:00"
+            "time": "2018-06-22T15:01:26+00:00"
         },
         {
             "name": "symfony/event-dispatcher",
-            "version": "v3.4.5",
+            "version": "v2.8.42",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher.git",
-                "reference": "58990682ac3fdc1f563b7e705452921372aad11d"
+                "reference": "9b69aad7d4c086dc94ebade2d5eb9145da5dac8c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/58990682ac3fdc1f563b7e705452921372aad11d",
-                "reference": "58990682ac3fdc1f563b7e705452921372aad11d",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9b69aad7d4c086dc94ebade2d5eb9145da5dac8c",
+                "reference": "9b69aad7d4c086dc94ebade2d5eb9145da5dac8c",
                 "shasum": ""
             },
             "require": {
-                "php": "^5.5.9|>=7.0.8"
-            },
-            "conflict": {
-                "symfony/dependency-injection": "<3.3"
+                "php": ">=5.3.9"
             },
             "require-dev": {
                 "psr/log": "~1.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"
+                "symfony/config": "^2.0.5|~3.0.0",
+                "symfony/dependency-injection": "~2.6|~3.0.0",
+                "symfony/expression-language": "~2.6|~3.0.0",
+                "symfony/stopwatch": "~2.3|~3.0.0"
             },
             "suggest": {
                 "symfony/dependency-injection": "",
@@ -2068,7 +1996,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.4-dev"
+                    "dev-master": "2.8-dev"
                 }
             },
             "autoload": {
@@ -2095,29 +2023,30 @@
             ],
             "description": "Symfony EventDispatcher Component",
             "homepage": "https://symfony.com",
-            "time": "2018-02-14T10:03:57+00:00"
+            "time": "2018-04-06T07:35:03+00:00"
         },
         {
             "name": "symfony/filesystem",
-            "version": "v3.4.5",
+            "version": "v2.8.42",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/filesystem.git",
-                "reference": "253a4490b528597aa14d2bf5aeded6f5e5e4a541"
+                "reference": "0f685c099aca7ba86bcc31850186dbfe84a4a8a1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/filesystem/zipball/253a4490b528597aa14d2bf5aeded6f5e5e4a541",
-                "reference": "253a4490b528597aa14d2bf5aeded6f5e5e4a541",
+                "url": "https://api.github.com/repos/symfony/filesystem/zipball/0f685c099aca7ba86bcc31850186dbfe84a4a8a1",
+                "reference": "0f685c099aca7ba86bcc31850186dbfe84a4a8a1",
                 "shasum": ""
             },
             "require": {
-                "php": "^5.5.9|>=7.0.8"
+                "php": ">=5.3.9",
+                "symfony/polyfill-ctype": "~1.8"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.4-dev"
+                    "dev-master": "2.8-dev"
                 }
             },
             "autoload": {
@@ -2144,29 +2073,29 @@
             ],
             "description": "Symfony Filesystem Component",
             "homepage": "https://symfony.com",
-            "time": "2018-02-22T10:48:49+00:00"
+            "time": "2018-06-21T09:24:14+00:00"
         },
         {
             "name": "symfony/finder",
-            "version": "v3.4.5",
+            "version": "v2.8.42",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/finder.git",
-                "reference": "6a615613745cef820d807443f32076bb9f5d0a38"
+                "reference": "995cd7c28a0778cece02e2133b4d813dc509dfc3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/finder/zipball/6a615613745cef820d807443f32076bb9f5d0a38",
-                "reference": "6a615613745cef820d807443f32076bb9f5d0a38",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/995cd7c28a0778cece02e2133b4d813dc509dfc3",
+                "reference": "995cd7c28a0778cece02e2133b4d813dc509dfc3",
                 "shasum": ""
             },
             "require": {
-                "php": "^5.5.9|>=7.0.8"
+                "php": ">=5.3.9"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.4-dev"
+                    "dev-master": "2.8-dev"
                 }
             },
             "autoload": {
@@ -2193,29 +2122,29 @@
             ],
             "description": "Symfony Finder Component",
             "homepage": "https://symfony.com",
-            "time": "2018-02-11T17:15:12+00:00"
+            "time": "2018-06-19T11:07:17+00:00"
         },
         {
             "name": "symfony/options-resolver",
-            "version": "v3.4.5",
+            "version": "v2.8.42",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/options-resolver.git",
-                "reference": "f3109a6aedd20e35c3a33190e932c2b063b7b50e"
+                "reference": "d9077ee91fdd64695dc754dc153fc00ada7ade97"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/options-resolver/zipball/f3109a6aedd20e35c3a33190e932c2b063b7b50e",
-                "reference": "f3109a6aedd20e35c3a33190e932c2b063b7b50e",
+                "url": "https://api.github.com/repos/symfony/options-resolver/zipball/d9077ee91fdd64695dc754dc153fc00ada7ade97",
+                "reference": "d9077ee91fdd64695dc754dc153fc00ada7ade97",
                 "shasum": ""
             },
             "require": {
-                "php": "^5.5.9|>=7.0.8"
+                "php": ">=5.3.9"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.4-dev"
+                    "dev-master": "2.8-dev"
                 }
             },
             "autoload": {
@@ -2247,20 +2176,75 @@
                 "configuration",
                 "options"
             ],
-            "time": "2018-01-11T07:56:07+00:00"
+            "time": "2018-05-30T04:18:42+00:00"
+        },
+        {
+            "name": "symfony/polyfill-ctype",
+            "version": "v1.8.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-ctype.git",
+                "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/7cc359f1b7b80fc25ed7796be7d96adc9b354bae",
+                "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.8-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Ctype\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                },
+                {
+                    "name": "Gert de Pagter",
+                    "email": "BackEndTea@gmail.com"
+                }
+            ],
+            "description": "Symfony polyfill for ctype functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "ctype",
+                "polyfill",
+                "portable"
+            ],
+            "time": "2018-04-30T19:57:29+00:00"
         },
         {
             "name": "symfony/polyfill-mbstring",
-            "version": "v1.7.0",
+            "version": "v1.8.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-mbstring.git",
-                "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b"
+                "reference": "3296adf6a6454a050679cde90f95350ad604b171"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/78be803ce01e55d3491c1397cf1c64beb9c1b63b",
-                "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b",
+                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/3296adf6a6454a050679cde90f95350ad604b171",
+                "reference": "3296adf6a6454a050679cde90f95350ad604b171",
                 "shasum": ""
             },
             "require": {
@@ -2272,7 +2256,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.7-dev"
+                    "dev-master": "1.8-dev"
                 }
             },
             "autoload": {
@@ -2306,35 +2290,34 @@
                 "portable",
                 "shim"
             ],
-            "time": "2018-01-30T19:27:44+00:00"
+            "time": "2018-04-26T10:06:28+00:00"
         },
         {
-            "name": "symfony/polyfill-php70",
-            "version": "v1.7.0",
+            "name": "symfony/polyfill-php54",
+            "version": "v1.8.0",
             "source": {
                 "type": "git",
-                "url": "https://github.com/symfony/polyfill-php70.git",
-                "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f"
+                "url": "https://github.com/symfony/polyfill-php54.git",
+                "reference": "6c3a2b84c6025e4ea3f6a19feac35408c64b22e1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/3532bfcd8f933a7816f3a0a59682fc404776600f",
-                "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f",
+                "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/6c3a2b84c6025e4ea3f6a19feac35408c64b22e1",
+                "reference": "6c3a2b84c6025e4ea3f6a19feac35408c64b22e1",
                 "shasum": ""
             },
             "require": {
-                "paragonie/random_compat": "~1.0|~2.0",
                 "php": ">=5.3.3"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.7-dev"
+                    "dev-master": "1.8-dev"
                 }
             },
             "autoload": {
                 "psr-4": {
-                    "Symfony\\Polyfill\\Php70\\": ""
+                    "Symfony\\Polyfill\\Php54\\": ""
                 },
                 "files": [
                     "bootstrap.php"
@@ -2357,7 +2340,7 @@
                     "homepage": "https://symfony.com/contributors"
                 }
             ],
-            "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions",
+            "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions",
             "homepage": "https://symfony.com",
             "keywords": [
                 "compatibility",
@@ -2365,34 +2348,35 @@
                 "portable",
                 "shim"
             ],
-            "time": "2018-01-30T19:27:44+00:00"
+            "time": "2018-04-26T10:06:28+00:00"
         },
         {
-            "name": "symfony/polyfill-php72",
-            "version": "v1.7.0",
+            "name": "symfony/polyfill-php55",
+            "version": "v1.8.0",
             "source": {
                 "type": "git",
-                "url": "https://github.com/symfony/polyfill-php72.git",
-                "reference": "8eca20c8a369e069d4f4c2ac9895144112867422"
+                "url": "https://github.com/symfony/polyfill-php55.git",
+                "reference": "a39456128377a85f2c5707fcae458678560cba46"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/8eca20c8a369e069d4f4c2ac9895144112867422",
-                "reference": "8eca20c8a369e069d4f4c2ac9895144112867422",
+                "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/a39456128377a85f2c5707fcae458678560cba46",
+                "reference": "a39456128377a85f2c5707fcae458678560cba46",
                 "shasum": ""
             },
             "require": {
+                "ircmaxell/password-compat": "~1.0",
                 "php": ">=5.3.3"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.7-dev"
+                    "dev-master": "1.8-dev"
                 }
             },
             "autoload": {
                 "psr-4": {
-                    "Symfony\\Polyfill\\Php72\\": ""
+                    "Symfony\\Polyfill\\Php55\\": ""
                 },
                 "files": [
                     "bootstrap.php"
@@ -2412,7 +2396,7 @@
                     "homepage": "https://symfony.com/contributors"
                 }
             ],
-            "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
+            "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions",
             "homepage": "https://symfony.com",
             "keywords": [
                 "compatibility",
@@ -2420,37 +2404,41 @@
                 "portable",
                 "shim"
             ],
-            "time": "2018-01-31T17:43:24+00:00"
+            "time": "2018-04-26T10:06:28+00:00"
         },
         {
-            "name": "symfony/process",
-            "version": "v3.4.5",
+            "name": "symfony/polyfill-php70",
+            "version": "v1.8.0",
             "source": {
                 "type": "git",
-                "url": "https://github.com/symfony/process.git",
-                "reference": "cc4aea21f619116aaf1c58016a944e4821c8e8af"
+                "url": "https://github.com/symfony/polyfill-php70.git",
+                "reference": "77454693d8f10dd23bb24955cffd2d82db1007a6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/process/zipball/cc4aea21f619116aaf1c58016a944e4821c8e8af",
-                "reference": "cc4aea21f619116aaf1c58016a944e4821c8e8af",
+                "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/77454693d8f10dd23bb24955cffd2d82db1007a6",
+                "reference": "77454693d8f10dd23bb24955cffd2d82db1007a6",
                 "shasum": ""
             },
             "require": {
-                "php": "^5.5.9|>=7.0.8"
+                "paragonie/random_compat": "~1.0|~2.0",
+                "php": ">=5.3.3"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.4-dev"
+                    "dev-master": "1.8-dev"
                 }
             },
             "autoload": {
                 "psr-4": {
-                    "Symfony\\Component\\Process\\": ""
+                    "Symfony\\Polyfill\\Php70\\": ""
                 },
-                "exclude-from-classmap": [
-                    "/Tests/"
+                "files": [
+                    "bootstrap.php"
+                ],
+                "classmap": [
+                    "Resources/stubs"
                 ]
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -2459,44 +2447,105 @@
             ],
             "authors": [
                 {
-                    "name": "Fabien Potencier",
-                    "email": "fabien@symfony.com"
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
                 },
                 {
                     "name": "Symfony Community",
                     "homepage": "https://symfony.com/contributors"
                 }
             ],
-            "description": "Symfony Process Component",
+            "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions",
             "homepage": "https://symfony.com",
-            "time": "2018-02-12T17:55:00+00:00"
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "time": "2018-04-26T10:06:28+00:00"
         },
         {
-            "name": "symfony/stopwatch",
-            "version": "v3.4.5",
+            "name": "symfony/polyfill-php72",
+            "version": "v1.8.0",
             "source": {
                 "type": "git",
-                "url": "https://github.com/symfony/stopwatch.git",
-                "reference": "eb17cfa072cab26537ac37e9c4ece6c0361369af"
+                "url": "https://github.com/symfony/polyfill-php72.git",
+                "reference": "a4576e282d782ad82397f3e4ec1df8e0f0cafb46"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/stopwatch/zipball/eb17cfa072cab26537ac37e9c4ece6c0361369af",
-                "reference": "eb17cfa072cab26537ac37e9c4ece6c0361369af",
+                "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/a4576e282d782ad82397f3e4ec1df8e0f0cafb46",
+                "reference": "a4576e282d782ad82397f3e4ec1df8e0f0cafb46",
                 "shasum": ""
             },
             "require": {
-                "php": "^5.5.9|>=7.0.8"
+                "php": ">=5.3.3"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.4-dev"
+                    "dev-master": "1.8-dev"
                 }
             },
             "autoload": {
                 "psr-4": {
-                    "Symfony\\Component\\Stopwatch\\": ""
+                    "Symfony\\Polyfill\\Php72\\": ""
+                },
+                "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 7.2+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "time": "2018-04-26T10:06:28+00:00"
+        },
+        {
+            "name": "symfony/process",
+            "version": "v2.8.42",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/process.git",
+                "reference": "542d88b350c42750fdc14e73860ee96dd423e95d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/process/zipball/542d88b350c42750fdc14e73860ee96dd423e95d",
+                "reference": "542d88b350c42750fdc14e73860ee96dd423e95d",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.9"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.8-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Process\\": ""
                 },
                 "exclude-from-classmap": [
                     "/Tests/"
@@ -2516,45 +2565,36 @@
                     "homepage": "https://symfony.com/contributors"
                 }
             ],
-            "description": "Symfony Stopwatch Component",
+            "description": "Symfony Process Component",
             "homepage": "https://symfony.com",
-            "time": "2018-02-17T14:55:25+00:00"
+            "time": "2018-05-27T07:40:52+00:00"
         },
         {
-            "name": "symfony/yaml",
-            "version": "v3.4.5",
+            "name": "symfony/stopwatch",
+            "version": "v2.8.42",
             "source": {
                 "type": "git",
-                "url": "https://github.com/symfony/yaml.git",
-                "reference": "6af42631dcf89e9c616242c900d6c52bd53bd1bb"
+                "url": "https://github.com/symfony/stopwatch.git",
+                "reference": "57021208ad9830f8f8390c1a9d7bb390f32be89e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/6af42631dcf89e9c616242c900d6c52bd53bd1bb",
-                "reference": "6af42631dcf89e9c616242c900d6c52bd53bd1bb",
+                "url": "https://api.github.com/repos/symfony/stopwatch/zipball/57021208ad9830f8f8390c1a9d7bb390f32be89e",
+                "reference": "57021208ad9830f8f8390c1a9d7bb390f32be89e",
                 "shasum": ""
             },
             "require": {
-                "php": "^5.5.9|>=7.0.8"
-            },
-            "conflict": {
-                "symfony/console": "<3.4"
-            },
-            "require-dev": {
-                "symfony/console": "~3.4|~4.0"
-            },
-            "suggest": {
-                "symfony/console": "For validating YAML files using the lint command"
+                "php": ">=5.3.9"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "3.4-dev"
+                    "dev-master": "2.8-dev"
                 }
             },
             "autoload": {
                 "psr-4": {
-                    "Symfony\\Component\\Yaml\\": ""
+                    "Symfony\\Component\\Stopwatch\\": ""
                 },
                 "exclude-from-classmap": [
                     "/Tests/"
@@ -2574,41 +2614,41 @@
                     "homepage": "https://symfony.com/contributors"
                 }
             ],
-            "description": "Symfony Yaml Component",
+            "description": "Symfony Stopwatch Component",
             "homepage": "https://symfony.com",
-            "time": "2018-02-16T09:50:28+00:00"
+            "time": "2018-01-03T07:36:31+00:00"
         },
         {
-            "name": "webmozart/assert",
-            "version": "1.3.0",
+            "name": "symfony/yaml",
+            "version": "v2.8.42",
             "source": {
                 "type": "git",
-                "url": "https://github.com/webmozart/assert.git",
-                "reference": "0df1908962e7a3071564e857d86874dad1ef204a"
+                "url": "https://github.com/symfony/yaml.git",
+                "reference": "51356b7a2ff7c9fd06b2f1681cc463bb62b5c1ff"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a",
-                "reference": "0df1908962e7a3071564e857d86874dad1ef204a",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/51356b7a2ff7c9fd06b2f1681cc463bb62b5c1ff",
+                "reference": "51356b7a2ff7c9fd06b2f1681cc463bb62b5c1ff",
                 "shasum": ""
             },
             "require": {
-                "php": "^5.3.3 || ^7.0"
-            },
-            "require-dev": {
-                "phpunit/phpunit": "^4.6",
-                "sebastian/version": "^1.0.1"
+                "php": ">=5.3.9",
+                "symfony/polyfill-ctype": "~1.8"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.3-dev"
+                    "dev-master": "2.8-dev"
                 }
             },
             "autoload": {
                 "psr-4": {
-                    "Webmozart\\Assert\\": "src/"
-                }
+                    "Symfony\\Component\\Yaml\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
@@ -2616,22 +2656,31 @@
             ],
             "authors": [
                 {
-                    "name": "Bernhard Schussek",
-                    "email": "bschussek@gmail.com"
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
                 }
             ],
-            "description": "Assertions to validate method input/output with nice error messages.",
-            "keywords": [
-                "assert",
-                "check",
-                "validate"
-            ],
-            "time": "2018-01-29T19:49:41+00:00"
+            "description": "Symfony Yaml Component",
+            "homepage": "https://symfony.com",
+            "time": "2018-05-01T22:52:40+00:00"
+        }
+    ],
+    "aliases": [
+        {
+            "alias": "3.0.2",
+            "alias_normalized": "3.0.2.0",
+            "version": "9999999-dev",
+            "package": "robrichards/xmlseclibs"
         }
     ],
-    "aliases": [],
     "minimum-stability": "stable",
-    "stability-flags": [],
+    "stability-flags": {
+        "robrichards/xmlseclibs": 20
+    },
     "prefer-stable": false,
     "prefer-lowest": false,
     "platform": {
diff --git a/dictionaries/login.definition.json b/dictionaries/login.definition.json
index 29ff2249d37c3a9e83de45268a75630e653e16b4..61e5dddf6c0179147997b37d6cac1c8cfea3acd7 100644
--- a/dictionaries/login.definition.json
+++ b/dictionaries/login.definition.json
@@ -1,71 +1,71 @@
 {
-	"error_header": {
-		"en": "Error"
-	},
-	"user_pass_header": {
-		"en": "Enter your username and password"
-	},
-	"user_pass_text": {
-		"en": "A service has requested you to authenticate yourself. Please enter your username and password in the form below."
-	},
-	"login_button": {
-		"en": "Login"
-	},
-	"processing": {
-		"en": "Processing..."
-	},
-	"username": {
-		"en": "Username"
-	},
-	"organization": {
-		"en": "Organization"
-	},
-	"password": {
-		"en": "Password"
-	},
-	"help_header": {
-		"en": "Help! I don't remember my password."
-	},
-	"help_text": {
-		"en": "Without your username and password you cannot authenticate yourself for access to the service. There may be someone that can help you. Consult the help desk at your organization!"
-	},
-	"error_nopassword": {
-		"en": "You sent something to the login page, but for some reason the password was not sent. Try again please."
-	},
-	"error_wrongpassword": {
-		"en": "Incorrect username or password."
-	},
-	"select_home_org": {
-		"en": "Choose your home organization"
-	},
-	"next": {
-		"en": "Next"
-	},
-	"change_home_org_title": {
-		"en": "Change your home organization"
-	},
-	"change_home_org_text": {
-		"en": "You have chosen <b>%HOMEORG%<\/b> as your home organization. If this is wrong you may choose another one."
-	},
-	"change_home_org_button": {
-		"en": "Choose home organization"
-	},
-	"help_desk_link": {
-		"en": "Help desk homepage"
-	},
-	"help_desk_email": {
-		"en": "Send e-mail to help desk"
-	},
-	"contact_info": {
-		"en": "Contact information:"
-	},
-	"remember_username": {
-		"en": "Remember my username"
-	},
-	"remember_me": {
-		"en": "Remember me"
-	},
-	"remember_organization": {
-		"en": "Remember my organization"
-	}
+    "error_header": {
+        "en": "Error"
+    },
+    "user_pass_header": {
+        "en": "Enter your username and password"
+    },
+    "user_pass_text": {
+        "en": "A service has requested you to authenticate yourself. Please enter your username and password in the form below."
+    },
+    "login_button": {
+        "en": "Login"
+    },
+    "processing": {
+        "en": "Processing..."
+    },
+    "username": {
+        "en": "Username"
+    },
+    "organization": {
+        "en": "Organization"
+    },
+    "password": {
+        "en": "Password"
+    },
+    "help_header": {
+        "en": "Help! I don't remember my password."
+    },
+    "help_text": {
+        "en": "Without your username and password you cannot authenticate yourself for access to the service. There may be someone that can help you. Consult the help desk at your organization!"
+    },
+    "error_nopassword": {
+        "en": "You sent something to the login page, but for some reason the password was not sent. Try again please."
+    },
+    "error_wrongpassword": {
+        "en": "Incorrect username or password."
+    },
+    "select_home_org": {
+        "en": "Choose your home organization"
+    },
+    "next": {
+        "en": "Next"
+    },
+    "change_home_org_title": {
+        "en": "Change your home organization"
+    },
+    "change_home_org_text": {
+        "en": "You have chosen <b>%HOMEORG%<\/b> as your home organization. If this is wrong you may choose another one."
+    },
+    "change_home_org_button": {
+        "en": "Choose home organization"
+    },
+    "help_desk_link": {
+        "en": "Help desk homepage"
+    },
+    "help_desk_email": {
+        "en": "Send e-mail to help desk"
+    },
+    "contact_info": {
+        "en": "Contact information:"
+    },
+    "remember_username": {
+        "en": "Remember my username"
+    },
+    "remember_me": {
+        "en": "Remember me"
+    },
+    "remember_organization": {
+        "en": "Remember my organization"
+    }
 }
diff --git a/docs/simplesamlphp-authproc.md b/docs/simplesamlphp-authproc.md
index be91c42071ab10070e6f8fcb3e45c19c253ef64f..d082a8255c805ad2bce82db7880956b31b4f4f3e 100644
--- a/docs/simplesamlphp-authproc.md
+++ b/docs/simplesamlphp-authproc.md
@@ -132,6 +132,8 @@ The following filters are included in the SimpleSAMLphp distribution:
 - [`core:AttributeLimit`](./core:authproc_attributelimit): Limit the attributes in the response.
 - [`core:AttributeMap`](./core:authproc_attributemap): Change the name of the attributes.
 - [`core:AttributeRealm`](./core:authproc_attributerealm): (deprecated) Create an attribute with the realm of the user.
+- [`core:Cardinality`](./core:authproc_cardinality): Ensure the number of attribute values is within the specified multiplicity.
+- [`core:CardinalitySingle`](./core:authproc_cardinalitysingle): Ensure the correct cardinality of single-valued attributes.
 - [`core:GenerateGroups`](./core:authproc_generategroups): Generate a `group` attribute for the user.
 - [`core:LanguageAdaptor`](./core:authproc_languageadaptor): Transfering language setting from IdP to SP.
 - [`core:PHP`](./core:authproc_php): Modify attributes with custom PHP code.
diff --git a/docs/simplesamlphp-changelog.md b/docs/simplesamlphp-changelog.md
index 707d1fb397a08bf3f4529d1fc8b77ddc1d566f97..699edd3920ab2049fe63beac564c725f81e36f67 100644
--- a/docs/simplesamlphp-changelog.md
+++ b/docs/simplesamlphp-changelog.md
@@ -11,16 +11,17 @@ See the upgrade notes for specific information about upgrading.
 Released TBD
 
 ### Changes
-  * Default signature algorithm is now SHA-256.
+  * Default signature algorithm is now RSA-SHA256.
   * 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.
+  * Fix edge case in getServerPort.
   * 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.
+    IdP side with HTTP Basic Authentication 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.
@@ -33,7 +34,6 @@ Released TBD
   * 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.
@@ -49,6 +49,9 @@ Released TBD
 ### cas
   * Respect all LDAP options in LDAP call.
 
+### casserver
+  * Module removed; superseded by externally hosted module.
+
 ### consent
   * Sort attribute values for consent.
   * Fix table layout for MySQL > 5.6.
@@ -70,7 +73,7 @@ Released TBD
   * AttributeMap: prevent possible infinite loop with some PHP versions.
 
 ### ldap
-  * AttributeAddUsersGroups: if attribute.groupname is set, use the
+  * 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.
 
@@ -86,15 +89,16 @@ Released TBD
 ### saml
   * AttributeConsumingService: allow to set isDefault and index options.
   * Encrypted attributes in an assertion are now decrypted correctly.
+  * Prefer the HTTP-Redirect binding for AuthnRequests if available.
 
 ### smartattributes
   * Fix to make the `add_authority` option work.
 
 ### sqlauth
-  * Changed from default-enabled to default-disabled.
+  * The module is now disabled by default.
 
 ### statistics
-  * Show decent error message when no data is available.
+  * Show a decent error message when no data is available.
 
 ## Version 1.15.4
 
diff --git a/docs/simplesamlphp-reference-idp-hosted.md b/docs/simplesamlphp-reference-idp-hosted.md
index ba558066e3e5ca226eed9ae9d80e1c1d75cbd406..fc134dded9a92947516ccd57e6054e61eccbb41c 100644
--- a/docs/simplesamlphp-reference-idp-hosted.md
+++ b/docs/simplesamlphp-reference-idp-hosted.md
@@ -50,6 +50,38 @@ Common options
 :   Certificate file which should be used by this IdP, in PEM format.
     The filename is relative to the `cert/`-directory.
 
+`contacts`
+:	Specify contacts in addition to the technical contact configured through config/config.php.
+	For example, specifying a support contact:
+
+		'contacts' => array(
+		    array(
+		        'contactType'       => 'support',
+		        'emailAddress'      => 'support@example.org',
+		        'givenName'         => 'John',
+		        'surName'           => 'Doe',
+		        'telephoneNumber'   => '+31(0)12345678',
+		        'company'           => 'Example Inc.',
+		    ),
+		),
+
+:	If you have support for a trust framework that requires extra attributes on the contact person element in your IdP metadata (for example, SIRTFI), you can specify an array of attributes on a contact.
+
+		'contacts' => array(
+		    array(
+		        'contactType'       => 'other',
+		        'emailAddress'      => 'mailto:abuse@example.org',
+		        'givenName'         => 'John',
+		        'surName'           => 'Doe',
+		        'telephoneNumber'   => '+31(0)12345678',
+		        'company'           => 'Example Inc.',
+		        'attributes'        => array(
+		            'xmlns:remd'        => 'http://refeds.org/metadata',
+		            'remd:contactType'  => 'http://refeds.org/metadata/contactType/security',
+		        ),
+		    ),
+		),
+
 `host`
 :   The hostname for this IdP. One IdP can also have the `host`-option
     set to `__DEFAULT__`, and that IdP will be used when no other
@@ -123,37 +155,6 @@ Common options
     any value in the SP-remote metadata overrides the one configured
     in the IdP metadata.
 
-`contacts`
-:	Specify contacts in addition to the technical contact configured through config/config.php.
-	For example, specifying a support contact:
-
-		'contacts' => array(
-		    array(
-		        'contactType'       => 'support',
-		        'emailAddress'      => 'support@example.org',
-		        'givenName'         => 'John',
-		        'surName'           => 'Doe',
-		        'telephoneNumber'   => '+31(0)12345678',
-		        'company'           => 'Example Inc.',
-		    ),
-		),
-
-:	If you have support for a trust framework that requires extra attributes on the contact person element in your IdP metadata (for example, SIRTFI), you can specify an array of attributes on a contact.
-
-		'contacts' => array(
-		    array(
-		        'contactType'       => 'other',
-		        'emailAddress'      => 'mailto:abuse@example.org',
-		        'givenName'         => 'John',
-		        'surName'           => 'Doe',
-		        'telephoneNumber'   => '+31(0)12345678',
-		        'company'           => 'Example Inc.',
-		        'attributes'        => array(
-		            'xmlns:remd'        => 'http://refeds.org/metadata',
-		            'remd:contactType'  => 'http://refeds.org/metadata/contactType/security',
-		        ),
-		    ),
-		), 
 
 SAML 2.0 options
 ----------------
diff --git a/docs/simplesamlphp-upgrade-notes-1.16.md b/docs/simplesamlphp-upgrade-notes-1.16.md
index 6a809cc5da66f71584a9600ea13d78005c1ec080..b7f225947acc6835d654e5fae7ba39b57be2e320 100644
--- a/docs/simplesamlphp-upgrade-notes-1.16.md
+++ b/docs/simplesamlphp-upgrade-notes-1.16.md
@@ -15,3 +15,11 @@ The class `SimpleSAML_Error_BadUserInnput` has been renamed to
 
 The `authmyspace` module has been removed since the service is no longer
 available. 
+
+The `casserver` module has been removed because it was an outdated version,
+the up to date module is maintained in the
+[simplesamlphp-module-casserver](https://github.com/simplesamlphp/simplesamlphp-module-casserver)
+repository. It can be installed with composer:
+```
+composer require simplesamlphp/simplesamlphp-module-casserver
+```
diff --git a/lib/SimpleSAML/Auth/LDAP.php b/lib/SimpleSAML/Auth/LDAP.php
index 437ff7bf3e539db801c98b86bce5b58158a929d8..08af6dacadd935c0c7d4149bdfc65f2dedff565d 100644
--- a/lib/SimpleSAML/Auth/LDAP.php
+++ b/lib/SimpleSAML/Auth/LDAP.php
@@ -2,8 +2,8 @@
 
 namespace SimpleSAML\Auth;
 
-use SimpleSAmL\Error;
-use SimpleSAMl\Logger;
+use SimpleSAML\Error;
+use SimpleSAML\Logger;
 
 /**
  * Constants defining possible errors
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php
index 47eec7be89eea4c67b371ecf3cb45bd5af74aeff..91b4d32a8493410ae7df6a5d94e82620b615546f 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php
@@ -293,7 +293,7 @@ class MetaDataStorageHandlerPdo extends MetaDataStorageSource
                 "CREATE TABLE IF NOT EXISTS $tableName (entity_id VARCHAR(255) PRIMARY KEY NOT NULL, entity_data ".
                 "TEXT NOT NULL)"
             );
-            if ($rows === 0) {
+            if ($rows === false) {
                 $fine = false;
             } else {
                 $stmt += $rows;
diff --git a/lib/SimpleSAML/Utils/HTTP.php b/lib/SimpleSAML/Utils/HTTP.php
index f840450db804c8c76f7ec1af615f7441c6b88ee8..0b1170066acea9cdce9a173f3956ad847ea0330d 100644
--- a/lib/SimpleSAML/Utils/HTTP.php
+++ b/lib/SimpleSAML/Utils/HTTP.php
@@ -809,7 +809,7 @@ class HTTP
             return $protocol.'://'.$hostname.$port.$_SERVER['REQUEST_URI'];
         }
 
-        return self::getBaseURL().$rel_path.substr($_SERVER['REQUEST_URI'], $uri_pos + strlen($url_path));
+        return self::getBaseURL().$url_path.substr($_SERVER['REQUEST_URI'], $uri_pos + strlen($url_path));
     }
 
 
diff --git a/modules/.gitignore b/modules/.gitignore
index bcf421d67f52f500e81e413b477073bad1cd8d50..063665917650c84fdff7c342704432b959a01263 100644
--- a/modules/.gitignore
+++ b/modules/.gitignore
@@ -38,3 +38,6 @@
 !/smartattributes/
 !/sqlauth/
 !/statistics/
+
+*/enable
+*/disable
diff --git a/modules/authwindowslive/docs/windowsliveid.md b/modules/authwindowslive/docs/windowsliveid.md
index a26c8fe49a51d6257104c623e1ac5b95c130c14c..b80116cf3a7ad20fc55ad1e0ceacb6999e438693 100644
--- a/modules/authwindowslive/docs/windowsliveid.md
+++ b/modules/authwindowslive/docs/windowsliveid.md
@@ -1,5 +1,7 @@
 Using the Windows Live ID authentication source with SimpleSAMLphp
 ==================================================================
+This module works around the limitation in Microsoft Online/Azure OIDC implementation of not supplying the OIDC userinfo endpoint.
+Microsoft explains the omission by suggesting that the Graph API can produce anything userinfo would have brought, in place.
 
 Remember to configure `authsources.php`, with both your Client ID and Secret key.
 
diff --git a/modules/casserver/config-templates/module_casserver.php b/modules/casserver/config-templates/module_casserver.php
deleted file mode 100644
index fab96fbbf4d3a5f6e3f6a65edcbd2d686c56b354..0000000000000000000000000000000000000000
--- a/modules/casserver/config-templates/module_casserver.php
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-/* 
- * Configuration for the module casserver.
- */
-
-$config = array (
-
-	'legal_service_urls' => array(
-		'http://test.feide.no/casclient',
-		'http://test.feide.no/cas2',
-	),
-
-	// Legal values: saml2, shib13
-	'auth' => 'saml2',
-	
-	'ticketcache' => 'ticketcache',
-
-	'attrname' => 'mail', // 'eduPersonPrincipalName',
-	#'attributes' => TRUE, // enable transfer of attributes
-	
-);
diff --git a/modules/casserver/default-disable b/modules/casserver/default-disable
deleted file mode 100644
index fa0bd82e2df7bd79d57593d35bc53c1f9d3ef71f..0000000000000000000000000000000000000000
--- a/modules/casserver/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/casserver/www/cas.php b/modules/casserver/www/cas.php
deleted file mode 100644
index 712b4f08309f1a54b499c452524799ab9b53866c..0000000000000000000000000000000000000000
--- a/modules/casserver/www/cas.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-
-/*
- * Frontend for login.php, proxy.php, validate.php and serviceValidate.php. It allows them to be called
- * as cas.php/login, cas.php/validate and cas.php/serviceValidate and is meant for clients
- * like phpCAS which expects one configured prefix which it appends login, validate and 
- * serviceValidate to.
- * 
- * This version supports CAS proxying. As SSP controls the user session (TGT in CAS parlance)
- * and the CASServer as a backend/proxy server is not aware of termination of the session the Proxy-
- * Granting-Tickets (PGT) issued have a very short ttl - pt. 60 secs.
- *
- * ServiceTickets (SP) and ProxyTickets (PT) now have a 5 secs ttl.
- *
- * Proxyed services (targetService) shall be present in the legal_service_urls config.
- * 
- */
-
- 
-$validFunctions = array(
-    '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.');
-}
-
-include($validFunctions[$function].".php");
diff --git a/modules/casserver/www/login.php b/modules/casserver/www/login.php
deleted file mode 100644
index 7b1d967fc8a3ae61369b66547007fd626c5ee379..0000000000000000000000000000000000000000
--- a/modules/casserver/www/login.php
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-require 'tickets.php';
-
-/*
- * Incoming parameters:
- *  service
- *  renew
- *  gateway
- *  
- */
-
-if (!array_key_exists('service', $_GET))
-	throw new Exception('Required URL query parameter [service] not provided. (CAS Server)');
-
-$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');
-
-$legal_service_urls = $casconfig->getValue('legal_service_urls');
-if (!checkServiceURL($service, $legal_service_urls))
-	throw new Exception('Service parameter provided to CAS server is not listed as a legal service: [service] = ' . $service);
-
-$auth = $casconfig->getValue('auth', 'saml2');
-if (!in_array($auth, array('saml2', 'shib13'), true))
- 	throw new Exception('CAS Service configured to use [auth] = ' . $auth . ' only [saml2,shib13] is legal.');
- 
-$as = new \SimpleSAML\Auth\Simple($auth);
-if (!$as->isAuthenticated()) {
-	$params = array(
-		'ForceAuthn' => $forceAuthn,
-		'isPassive' => $isPassive,
-	);
-	$as->login($params);
-}
-
-$attributes = $as->getAttributes();
-
-$path = $casconfig->resolvePath($casconfig->getValue('ticketcache', '/tmp'));
-
-$ticket = str_replace( '_', 'ST-', SimpleSAML\Utils\Random::generateID() );
-storeTicket($ticket, $path, array('service' => $service,
-	'forceAuthn' => $forceAuthn,
-	'attributes' => $attributes,
-	'proxies' => array(),
-	'validbefore' => time() + 5));
-
-\SimpleSAML\Utils\HTTP::redirectTrustedURL(
-	\SimpleSAML\Utils\HTTP::addURLParameters($service,
-		array('ticket' => $ticket)
-	)
-);
diff --git a/modules/casserver/www/proxy.php b/modules/casserver/www/proxy.php
deleted file mode 100644
index 4ae88113423f800493328ff238017ccd342d290e..0000000000000000000000000000000000000000
--- a/modules/casserver/www/proxy.php
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-require 'tickets.php';
-
-/*
- * Incoming parameters:
- *  targetService
- *  ptg
- *  
- */
-
-if (array_key_exists('targetService', $_GET)) {
-	$targetService = $_GET['targetService'];
-	$pgt = $_GET['pgt'];
-} else {
-	throw new Exception('Required URL query parameter [targetService] not provided. (CAS Server)');
-}
-
-$casconfig = \SimpleSAML\Configuration::getConfig('module_casserver.php');
-
-$legal_service_urls = $casconfig->getValue('legal_service_urls');
-
-if (!checkServiceURL($targetService, $legal_service_urls))
-	throw new Exception('Service parameter provided to CAS server is not listed as a legal service: [service] = ' . $service);
-
-$path = $casconfig->resolvePath($casconfig->getValue('ticketcache', 'ticketcache'));
-
-$ticket = retrieveTicket($pgt, $path, false);
-if ($ticket['validbefore'] > time()) {
-	$pt = str_replace( '_', 'PT-', SimpleSAML\Utils\Random::generateID() );
-	storeTicket($pt, $path, array(
-		'service' => $targetService,
-		'forceAuthn' => false,
-		'attributes' => $ticket['attributes'],
-		'proxies' => $ticket['proxies'],
-		'validbefore' => time() + 5)
-	);
-		
-print <<<eox
-<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
-    <cas:proxySuccess>
-        <cas:proxyTicket>$pt</cas:proxyTicket>
-    </cas:proxySuccess>
-</cas:serviceResponse>
-eox;
-} else {
-print <<<eox
-<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
-    <cas:proxyFailure code="INVALID_REQUEST">
-        Proxygranting ticket to old - ssp casserver only supports shortlived (30 secs) pgts.
-    </cas:proxyFailure>
-</cas:serviceResponse>
-eox;
-}
diff --git a/modules/casserver/www/serviceValidate.php b/modules/casserver/www/serviceValidate.php
deleted file mode 100644
index 9fd4fdf62dd67cd7d121eb4e25ae771dd1b44572..0000000000000000000000000000000000000000
--- a/modules/casserver/www/serviceValidate.php
+++ /dev/null
@@ -1,107 +0,0 @@
-<?php
-require('tickets.php');
-
-// set manually if called directly - ie not included from validate.php or cas.php
-if (!$function) {
-    $function = 'serviceValidate';
-}
-
-/*
- * Incoming parameters:
- *  service
- *  renew
- *  ticket
- *
- */
-if (array_key_exists('service', $_GET)) {
-    $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)');
-}
-
-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'];
-
-    $pgtiouxml = "";
-
-    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(
-	    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());
-}
-
-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>
-</cas:serviceResponse>';
-        } 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';
-        }
-    }
-}
diff --git a/modules/casserver/www/tickets.php b/modules/casserver/www/tickets.php
deleted file mode 100644
index 79498b1082d85769d1db6fe8cd945e7aa6190467..0000000000000000000000000000000000000000
--- a/modules/casserver/www/tickets.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-
-function storeTicket($ticket, $path, $value ) {
-
-	if (!is_dir($path)) 
-		throw new Exception('Directory for CAS Server ticket storage [' . $path . '] does not exists. ');
-		
-	if (!is_writable($path)) 
-		throw new Exception('Directory for CAS Server ticket storage [' . $path . '] is not writable. ');
-
-	$filename = $path . '/' . $ticket;
-	file_put_contents($filename, serialize($value));
-}
-
-function retrieveTicket($ticket, $path, $unlink = true) {
-
-	if (!preg_match('/^(ST|PT|PGT)-?[a-zA-Z0-9]+$/D', $ticket)) throw new Exception('Invalid characters in ticket');
-
-	if (!is_dir($path)) 
-		throw new Exception('Directory for CAS Server ticket storage [' . $path . '] does not exists. ');
-
-	$filename = $path . '/' . $ticket;
-
-	if (!file_exists($filename))
-		throw new Exception('Could not find ticket');
-	
-	$content = file_get_contents($filename);
-	
-	if ($unlink) {
-		unlink($filename);
-	}
-	
-	return unserialize($content);
-}
-
-function checkServiceURL($service, array $legal_service_urls) {
-	foreach ($legal_service_urls AS $legalurl) {
-		if (strpos($service, $legalurl) === 0) return TRUE;
-	}
-	return FALSE;
-}
diff --git a/modules/casserver/www/validate.php b/modules/casserver/www/validate.php
deleted file mode 100644
index 29e29a05f651c7465fb1b0cff3eb61e871ca4cb9..0000000000000000000000000000000000000000
--- a/modules/casserver/www/validate.php
+++ /dev/null
@@ -1,4 +0,0 @@
-<?php
-
-$function = 'validate';
-include("serviceValidate.php");
diff --git a/modules/core/docs/authproc_cardinality.md b/modules/core/docs/authproc_cardinality.md
index 0902bf27863dad94991aacb54d15a7a407750f63..97b73f86619cb70db8e4c104b2f8cf52e9e9fe46 100644
--- a/modules/core/docs/authproc_cardinality.md
+++ b/modules/core/docs/authproc_cardinality.md
@@ -7,6 +7,8 @@ This filter should contain a set of attribute name => rule pairs describing the
 
 The special parameter `%ignoreEntities` can be used to give an array of entity IDs that should be ignored for testing, etc purposes.
 
+A separate [`core:CardinalitySingle`](./core:authproc_cardinalitysingle) authproc filter provides additional functionality for the special case where attributes are single valued.
+
 Specifying Rules
 ----------------
 
diff --git a/modules/core/docs/authproc_cardinalitysingle.md b/modules/core/docs/authproc_cardinalitysingle.md
index 4a61bdbc5aaca4579729fc0bafec6b6976a2efea..62d2fa7998b666f9d1a0ae1ed63f0d1452e986bd 100644
--- a/modules/core/docs/authproc_cardinalitysingle.md
+++ b/modules/core/docs/authproc_cardinalitysingle.md
@@ -2,7 +2,7 @@
 ========================
 
 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
+of the more generic [`core:Cardinality`](./core:authproc_cardinality) filter that allows for optional corrective measures
 when multi-valued attributes are received where single-valued ones are expected.
 
 Parameters
diff --git a/modules/core/lib/Auth/UserPassOrgBase.php b/modules/core/lib/Auth/UserPassOrgBase.php
index 08f9b8f00cd18d294ced3ccf194c19cde7454d74..d7a718cd828724911c7007313c4db02af4d6fb2f 100644
--- a/modules/core/lib/Auth/UserPassOrgBase.php
+++ b/modules/core/lib/Auth/UserPassOrgBase.php
@@ -16,305 +16,313 @@ namespace SimpleSAML\Module\core\Auth;
 
 abstract class UserPassOrgBase extends \SimpleSAML\Auth\Source
 {
-	/**
-	 * The string used to identify our states.
-	 */
-	const STAGEID = '\SimpleSAML\Module\core\Auth\UserPassOrgBase.state';
-
-
-	/**
-	 * The key of the AuthId field in the state.
-	 */
-	const AUTHID = '\SimpleSAML\Module\core\Auth\UserPassOrgBase.AuthId';
-
-
-	/**
-	 * The key of the OrgId field in the state, identifies which org was selected.
-	 */
-	const ORGID = '\SimpleSAML\Module\core\Auth\UserPassOrgBase.SelectedOrg';
-
-
-	/**
-	 * What way do we handle the organization as part of the username.
-	 * Three values:
-	 *  'none': Force the user to select the correct organization from the dropdown box.
-	 *  'allow': Allow the user to enter the organization as part of the username.
-	 *  'force': Remove the dropdown box.
-	 */
-	private $usernameOrgMethod;
-
-	/**
-	 * Storage for authsource config option remember.username.enabled
-	 * loginuserpass.php and loginuserpassorg.php pages/templates use this option to
-	 * present users with a checkbox to save their username for the next login request.
-	 * @var bool
-	 */
-	protected $rememberUsernameEnabled = FALSE;
-
-	/**
-	 * Storage for authsource config option remember.username.checked
-	 * loginuserpass.php and loginuserpassorg.php pages/templates use this option
-	 * to default the remember username checkbox to checked or not.
-	 * @var bool
-	 */
-	protected $rememberUsernameChecked = FALSE;
-
-	/**
-	 * Storage for authsource config option remember.organization.enabled
-	 * loginuserpassorg.php page/template use this option to present users	
-	 * with a checkbox to save their organization choice for the next login request.
-	 * @var bool
- 	*/
-	protected $rememberOrganizationEnabled = false;
-
-	/**
-	 * Storage for authsource config option remember.organization.checked
-	 * loginuserpassorg.php page/template use this option to
-	 * default the remember organization checkbox to checked or not.
-	 * @var bool
-	 */
-	protected $rememberOrganizationChecked = false;
-
-
-	/**
-	 * Constructor for this authentication source.
-	 *
-	 * All subclasses who implement their own constructor must call this constructor before
-	 * using $config for anything.
-	 *
-	 * @param array $info  Information about this authentication source.
-	 * @param array &$config  Configuration for this authentication source.
-	 */
-	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);
-
-		// Get the remember username config options
-		if (isset($config['remember.username.enabled'])) {
-			$this->rememberUsernameEnabled = (bool) $config['remember.username.enabled'];
-			unset($config['remember.username.enabled']);
-		}
-		if (isset($config['remember.username.checked'])) {
-			$this->rememberUsernameChecked = (bool) $config['remember.username.checked'];
-			unset($config['remember.username.checked']);
-		}
-		// Get the remember organization config options
-		if (isset($config['remember.organization.enabled'])) {
-			$this->rememberOrganizationEnabled = (bool) $config['remember.organization.enabled'];
-			unset($config['remember.organization.enabled']);
-		}
-		if (isset($config['remember.organization.checked'])) {
-			$this->rememberOrganizationChecked = (bool) $config['remember.organization.checked'];
-			unset($config['remember.organization.checked']);
-		}
-
-		$this->usernameOrgMethod = 'none';
-	}
-
-
-	/**
-	 * Configure the way organizations as part of the username is handled.
-	 *
-	 * There are three possible values:
-	 * - 'none': Force the user to select the correct organization from the dropdown box.
-	 * - 'allow': Allow the user to enter the organization as part of the username.
-	 * - 'force': Remove the dropdown box.
-	 *
-	 * If unconfigured, the default is 'none'.
-	 *
-	 * @param string $usernameOrgMethod  The method which should be used.
-	 */
-	protected function setUsernameOrgMethod($usernameOrgMethod) {
-		assert(in_array($usernameOrgMethod, array('none', 'allow', 'force'), true));
-
-		$this->usernameOrgMethod = $usernameOrgMethod;
-	}
-
-
-	/**
-	 * Retrieve the way organizations as part of the username should be handled.
-	 *
-	 * There are three possible values:
-	 * - 'none': Force the user to select the correct organization from the dropdown box.
-	 * - 'allow': Allow the user to enter the organization as part of the username.
-	 * - 'force': Remove the dropdown box.
-	 *
-	 * @return string  The method which should be used.
-	 */
-	public function getUsernameOrgMethod() {
-		return $this->usernameOrgMethod;
-	}
-
-	/**
-	 * Getter for the authsource config option remember.username.enabled
-	 * @return bool
-	 */
-	public function getRememberUsernameEnabled() {
-		return $this->rememberUsernameEnabled;
-	}
-
-	/**
-	 * Getter for the authsource config option remember.username.checked
-	 * @return bool
-	 */
-	public function getRememberUsernameChecked()
-	{
-		return $this->rememberUsernameChecked;
-	}
-
-	/**
-	 * Getter for the authsource config option remember.organization.enabled
-	 * @return bool
-	 */
-	public function getRememberOrganizationEnabled()
-	{
-		return $this->rememberOrganizationEnabled;
-	}
-
-	/**
-	 * Getter for the authsource config option remember.organization.checked
-	 * @return bool
-	 */
-	public function getRememberOrganizationChecked() {
-		return $this->rememberOrganizationChecked;
-	}
-
-	/**
-	 * 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('core/loginuserpassorg.php');
-		$params = array('AuthState' => $id);
-		\SimpleSAML\Utils\HTTP::redirectTrustedURL($url, $params);
-	}
-
-
-	/**
-	 * Attempt to log in using the given username, password and organization.
-	 *
-	 * 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.
-	 *
-	 * 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.
-	 * @param string $organization  The id of the organization the user chose.
-	 * @return array  Associative array with the user's attributes.
-	 */
-	abstract protected function login($username, $password, $organization);
-
-
-	/**
-	 * Retrieve list of organizations.
-	 *
-	 * The list of organizations is an associative array. The key of the array is the
-	 * id of the organization, and the value is the description. The value can be another
-	 * array, in which case that array is expected to contain language-code to
-	 * description mappings.
-	 *
-	 * @return array  Associative array with the organizations.
-	 */
-	abstract protected function getOrganizations();
-
-
-	/**
-	 * Handle login request.
-	 *
-	 * This function is used by the login form (core/www/loginuserpassorg.php) when the user
-	 * enters a username and password. On success, it will not return. On wrong
-	 * username/password failure, and other errors, it will throw an exception.
-	 *
-	 * @param string $authStateId  The identifier of the authentication state.
-	 * @param string $username  The username the user wrote.
-	 * @param string $password  The password the user wrote.
-	 * @param string $organization  The id of the organization the user chose.
-	 */
-	public static function handleLogin($authStateId, $username, $password, $organization) {
-		assert(is_string($authStateId));
-		assert(is_string($username));
-		assert(is_string($password));
-		assert(is_string($organization));
-
-		/* 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]);
-		}
-
-		$orgMethod = $source->getUsernameOrgMethod();
-		if ($orgMethod !== 'none') {
-			$tmp = explode('@', $username, 2);
-			if (count($tmp) === 2) {
-				$username = $tmp[0];
-				$organization = $tmp[1];
-			} else {
-				if ($orgMethod === 'force') {
-					/* The organization should be a part of the username, but isn't. */
-					throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
-				}
-			}
-		}
-
-		/* Attempt to log in. */
-		$attributes = $source->login($username, $password, $organization);
-
-		// Add the selected Org to the state
-		$state[self::ORGID] = $organization;
-		$state['PersistentAuthData'][] = self::ORGID;
-
-		$state['Attributes'] = $attributes;
-		\SimpleSAML\Auth\Source::completeAuth($state);
-	}
-
-
-	/**
-	 * Get available organizations.
-	 *
-	 * This function is used by the login form to get the available organizations.
-	 *
-	 * @param string $authStateId  The identifier of the authentication state.
-	 * @return array|NULL  Array of organizations. NULL if the user must enter the
-	 *         organization as part of the username.
-	 */
-	public static function listOrganizations($authStateId) {
-		assert(is_string($authStateId));
-
-		/* 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]);
-		}
-
-		$orgMethod = $source->getUsernameOrgMethod();
-		if ($orgMethod === 'force') {
-			return NULL;
-		}
-
-		return $source->getOrganizations();
-	}
+    /**
+     * The string used to identify our states.
+     */
+    const STAGEID = '\SimpleSAML\Module\core\Auth\UserPassOrgBase.state';
+
+
+    /**
+     * The key of the AuthId field in the state.
+     */
+    const AUTHID = '\SimpleSAML\Module\core\Auth\UserPassOrgBase.AuthId';
+
+
+    /**
+     * The key of the OrgId field in the state, identifies which org was selected.
+     */
+    const ORGID = '\SimpleSAML\Module\core\Auth\UserPassOrgBase.SelectedOrg';
+
+
+    /**
+     * What way do we handle the organization as part of the username.
+     * Three values:
+     *  'none': Force the user to select the correct organization from the dropdown box.
+     *  'allow': Allow the user to enter the organization as part of the username.
+     *  'force': Remove the dropdown box.
+     */
+    private $usernameOrgMethod;
+
+    /**
+     * Storage for authsource config option remember.username.enabled
+     * loginuserpass.php and loginuserpassorg.php pages/templates use this option to
+     * present users with a checkbox to save their username for the next login request.
+     * @var bool
+     */
+    protected $rememberUsernameEnabled = false;
+
+    /**
+     * Storage for authsource config option remember.username.checked
+     * loginuserpass.php and loginuserpassorg.php pages/templates use this option
+     * to default the remember username checkbox to checked or not.
+     * @var bool
+     */
+    protected $rememberUsernameChecked = false;
+
+    /**
+     * Storage for authsource config option remember.organization.enabled
+     * loginuserpassorg.php page/template use this option to present users
+     * with a checkbox to save their organization choice for the next login request.
+     * @var bool
+     */
+    protected $rememberOrganizationEnabled = false;
+
+    /**
+     * Storage for authsource config option remember.organization.checked
+     * loginuserpassorg.php page/template use this option to
+     * default the remember organization checkbox to checked or not.
+     * @var bool
+     */
+    protected $rememberOrganizationChecked = false;
+
+
+    /**
+     * Constructor for this authentication source.
+     *
+     * All subclasses who implement their own constructor must call this constructor before
+     * using $config for anything.
+     *
+     * @param array $info  Information about this authentication source.
+     * @param array &$config  Configuration for this authentication source.
+     */
+    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);
+
+        // Get the remember username config options
+        if (isset($config['remember.username.enabled'])) {
+            $this->rememberUsernameEnabled = (bool) $config['remember.username.enabled'];
+            unset($config['remember.username.enabled']);
+        }
+        if (isset($config['remember.username.checked'])) {
+            $this->rememberUsernameChecked = (bool) $config['remember.username.checked'];
+            unset($config['remember.username.checked']);
+        }
+        // Get the remember organization config options
+        if (isset($config['remember.organization.enabled'])) {
+            $this->rememberOrganizationEnabled = (bool) $config['remember.organization.enabled'];
+            unset($config['remember.organization.enabled']);
+        }
+        if (isset($config['remember.organization.checked'])) {
+            $this->rememberOrganizationChecked = (bool) $config['remember.organization.checked'];
+            unset($config['remember.organization.checked']);
+        }
+
+        $this->usernameOrgMethod = 'none';
+    }
+
+
+    /**
+     * Configure the way organizations as part of the username is handled.
+     *
+     * There are three possible values:
+     * - 'none': Force the user to select the correct organization from the dropdown box.
+     * - 'allow': Allow the user to enter the organization as part of the username.
+     * - 'force': Remove the dropdown box.
+     *
+     * If unconfigured, the default is 'none'.
+     *
+     * @param string $usernameOrgMethod  The method which should be used.
+     */
+    protected function setUsernameOrgMethod($usernameOrgMethod)
+    {
+        assert(in_array($usernameOrgMethod, array('none', 'allow', 'force'), true));
+
+        $this->usernameOrgMethod = $usernameOrgMethod;
+    }
+
+
+    /**
+     * Retrieve the way organizations as part of the username should be handled.
+     *
+     * There are three possible values:
+     * - 'none': Force the user to select the correct organization from the dropdown box.
+     * - 'allow': Allow the user to enter the organization as part of the username.
+     * - 'force': Remove the dropdown box.
+     *
+     * @return string  The method which should be used.
+     */
+    public function getUsernameOrgMethod()
+    {
+        return $this->usernameOrgMethod;
+    }
+
+    /**
+     * Getter for the authsource config option remember.username.enabled
+     * @return bool
+     */
+    public function getRememberUsernameEnabled()
+    {
+        return $this->rememberUsernameEnabled;
+    }
+
+    /**
+     * Getter for the authsource config option remember.username.checked
+     * @return bool
+     */
+    public function getRememberUsernameChecked()
+    {
+        return $this->rememberUsernameChecked;
+    }
+
+    /**
+     * Getter for the authsource config option remember.organization.enabled
+     * @return bool
+     */
+    public function getRememberOrganizationEnabled()
+    {
+        return $this->rememberOrganizationEnabled;
+    }
+
+    /**
+     * Getter for the authsource config option remember.organization.checked
+     * @return bool
+     */
+    public function getRememberOrganizationChecked()
+    {
+        return $this->rememberOrganizationChecked;
+    }
+
+    /**
+     * 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('core/loginuserpassorg.php');
+        $params = array('AuthState' => $id);
+        \SimpleSAML\Utils\HTTP::redirectTrustedURL($url, $params);
+    }
+
+
+    /**
+     * Attempt to log in using the given username, password and organization.
+     *
+     * 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.
+     *
+     * 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.
+     * @param string $organization  The id of the organization the user chose.
+     * @return array  Associative array with the user's attributes.
+     */
+    abstract protected function login($username, $password, $organization);
+
+
+    /**
+     * Retrieve list of organizations.
+     *
+     * The list of organizations is an associative array. The key of the array is the
+     * id of the organization, and the value is the description. The value can be another
+     * array, in which case that array is expected to contain language-code to
+     * description mappings.
+     *
+     * @return array  Associative array with the organizations.
+     */
+    abstract protected function getOrganizations();
+
+
+    /**
+     * Handle login request.
+     *
+     * This function is used by the login form (core/www/loginuserpassorg.php) when the user
+     * enters a username and password. On success, it will not return. On wrong
+     * username/password failure, and other errors, it will throw an exception.
+     *
+     * @param string $authStateId  The identifier of the authentication state.
+     * @param string $username  The username the user wrote.
+     * @param string $password  The password the user wrote.
+     * @param string $organization  The id of the organization the user chose.
+     */
+    public static function handleLogin($authStateId, $username, $password, $organization)
+    {
+        assert(is_string($authStateId));
+        assert(is_string($username));
+        assert(is_string($password));
+        assert(is_string($organization));
+
+        /* 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]);
+        }
+
+        $orgMethod = $source->getUsernameOrgMethod();
+        if ($orgMethod !== 'none') {
+            $tmp = explode('@', $username, 2);
+            if (count($tmp) === 2) {
+                $username = $tmp[0];
+                $organization = $tmp[1];
+            } else {
+                if ($orgMethod === 'force') {
+                    /* The organization should be a part of the username, but isn't. */
+                    throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
+                }
+            }
+        }
+
+        /* Attempt to log in. */
+        $attributes = $source->login($username, $password, $organization);
+
+        // Add the selected Org to the state
+        $state[self::ORGID] = $organization;
+        $state['PersistentAuthData'][] = self::ORGID;
+
+        $state['Attributes'] = $attributes;
+        \SimpleSAML\Auth\Source::completeAuth($state);
+    }
+
+
+    /**
+     * Get available organizations.
+     *
+     * This function is used by the login form to get the available organizations.
+     *
+     * @param string $authStateId  The identifier of the authentication state.
+     * @return array|NULL  Array of organizations. NULL if the user must enter the
+     *         organization as part of the username.
+     */
+    public static function listOrganizations($authStateId)
+    {
+        assert(is_string($authStateId));
+
+        /* 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]);
+        }
+
+        $orgMethod = $source->getUsernameOrgMethod();
+        if ($orgMethod === 'force') {
+            return null;
+        }
+
+        return $source->getOrganizations();
+    }
 }
diff --git a/modules/core/templates/loginuserpass.php b/modules/core/templates/loginuserpass.php
index 210db853a470b4c075eb7a8027af29fa8b7c1580..61b16608836684e80f3589483fbefe20d30ea8f5 100644
--- a/modules/core/templates/loginuserpass.php
+++ b/modules/core/templates/loginuserpass.php
@@ -145,10 +145,10 @@ if ($this->data['errorcode'] !== null) {
                     <td style="padding: .4em;">
                         <?php
                             if ($this->data['rememberOrganizationEnabled']) {
-                            	echo str_repeat("\t", 4);
-	                            echo '<input type="checkbox" id="remember_organization" tabindex="5" name="remember_organization" value="Yes" ';
+                                echo str_repeat("\t", 4);
+                                echo '<input type="checkbox" id="remember_organization" tabindex="5" name="remember_organization" value="Yes" ';
                                 echo ($this->data['rememberOrganizationChecked'] ? 'checked="Yes" /> ' : '/> ');
-                            	echo $this->t('{login:remember_organization}');
+                                echo $this->t('{login:remember_organization}');
                             }
                         ?>
                     </td>
diff --git a/modules/core/www/frontpage_config.php b/modules/core/www/frontpage_config.php
index 69e6a4cba47aecdd18805efc53b1934198f440cb..050695c2786af52e8807aa4e86e284060a8c0c1c 100644
--- a/modules/core/www/frontpage_config.php
+++ b/modules/core/www/frontpage_config.php
@@ -67,7 +67,7 @@ if ($config->getBoolean('admin.checkforupdates', true) && $current !== 'master')
         curl_setopt($ch, CURLOPT_USERAGENT, 'SimpleSAMLphp');
         curl_setopt($ch, CURLOPT_TIMEOUT, 2);
         curl_setopt($ch, CURLOPT_PROXY, $config->getString('proxy', null));
-        curl_setopt($ch, CURLOPT_PROXYUSERPWD, $config->getstring('proxy.auth', null));
+        curl_setopt($ch, CURLOPT_PROXYUSERPWD, $config->getValue('proxy.auth', null));
         $response = curl_exec($ch);
 
         if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) {
diff --git a/modules/core/www/loginuserpassorg.php b/modules/core/www/loginuserpassorg.php
index 371290fd06eba34dea9ed4d205cc01b7350bf582..acbad36735b11c8e327a19b32e362824f6bf262e 100644
--- a/modules/core/www/loginuserpassorg.php
+++ b/modules/core/www/loginuserpassorg.php
@@ -18,17 +18,17 @@ $state = \SimpleSAML\Auth\State::loadState($authStateId, \SimpleSAML\Module\core
 
 $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[\SimpleSAML\Module\core\Auth\UserPassOrgBase::AUTHID]);
+    throw new \Exception('Could not find authentication source with id '.$state[\SimpleSAML\Module\core\Auth\UserPassOrgBase::AUTHID]);
 }
 
 $organizations = \SimpleSAML\Module\core\Auth\UserPassOrgBase::listOrganizations($authStateId);
 
 if (array_key_exists('username', $_REQUEST)) {
     $username = $_REQUEST['username'];
-} elseif ($source->getRememberUsernameEnabled() && array_key_exists($source->getAuthId() . '-username', $_COOKIE)) {
-    $username = $_COOKIE[$source->getAuthId() . '-username'];
+} elseif ($source->getRememberUsernameEnabled() && array_key_exists($source->getAuthId().'-username', $_COOKIE)) {
+    $username = $_COOKIE[$source->getAuthId().'-username'];
 } elseif (isset($state['core:username'])) {
-    $username = (string)$state['core:username'];
+    $username = (string) $state['core:username'];
 } else {
     $username = '';
 }
@@ -41,10 +41,10 @@ if (array_key_exists('password', $_REQUEST)) {
 
 if (array_key_exists('organization', $_REQUEST)) {
     $organization = $_REQUEST['organization'];
-} elseif ($source->getRememberOrganizationEnabled() && array_key_exists($source->getAuthId() . '-organization', $_COOKIE)) {
-    $organization = $_COOKIE[$source->getAuthId() . '-organization'];
+} elseif ($source->getRememberOrganizationEnabled() && array_key_exists($source->getAuthId().'-organization', $_COOKIE)) {
+    $organization = $_COOKIE[$source->getAuthId().'-organization'];
 } elseif (isset($state['core:organization'])) {
-    $organization = (string)$state['core:organization'];
+    $organization = (string) $state['core:organization'];
 } else {
     $organization = '';
 }
@@ -67,7 +67,7 @@ if ($organizations === null || !empty($organization)) {
             $params = $sessionHandler->getCookieParams();
             $params['expire'] = time();
             $params['expire'] += (isset($_REQUEST['remember_username']) && $_REQUEST['remember_username'] == 'Yes' ? 31536000 : -300);
-            \SimpleSAML\Utils\HTTP::setCookie($source->getAuthId() . '-username', $username, $params, false);
+            \SimpleSAML\Utils\HTTP::setCookie($source->getAuthId().'-username', $username, $params, false);
         }
 
         if ($source->getRememberOrganizationEnabled()) {
@@ -75,7 +75,7 @@ if ($organizations === null || !empty($organization)) {
             $params = $sessionHandler->getCookieParams();
             $params['expire'] = time();
             $params['expire'] += (isset($_REQUEST['remember_organization']) && $_REQUEST['remember_organization'] == 'Yes' ? 31536000 : -300);
-            setcookie($source->getAuthId() . '-organization', $organization, $params['expire'], $params['path'], $params['domain'], $params['secure'], $params['httponly']);
+            setcookie($source->getAuthId().'-organization', $organization, $params['expire'], $params['path'], $params['domain'], $params['secure'], $params['httponly']);
         }
 
         try {
@@ -106,10 +106,14 @@ $t->data['rememberUsernameEnabled'] = $source->getRememberUsernameEnabled();
 $t->data['rememberUsernameChecked'] = $source->getRememberUsernameChecked();
 $t->data['rememberMeEnabled'] = false;
 $t->data['rememberMeChecked'] = false;
-if (isset($_COOKIE[$source->getAuthId() . '-username'])) $t->data['rememberUsernameChecked'] = true;
+if (isset($_COOKIE[$source->getAuthId().'-username'])) {
+    $t->data['rememberUsernameChecked'] = true;
+}
 $t->data['rememberOrganizationEnabled'] = $source->getRememberOrganizationEnabled();
 $t->data['rememberOrganizationChecked'] = $source->getRememberOrganizationChecked();
-if (isset($_COOKIE[$source->getAuthId() . '-organization'])) $t->data['rememberOrganizationChecked'] = true;
+if (isset($_COOKIE[$source->getAuthId().'-organization'])) {
+    $t->data['rememberOrganizationChecked'] = true;
+}
 $t->data['errorcode'] = $errorCode;
 $t->data['errorcodes'] = \SimpleSAML\Error\ErrorCodes::getAllErrorCodeMessages();
 $t->data['errorparams'] = $errorParams;
diff --git a/modules/saml/lib/Auth/Source/SP.php b/modules/saml/lib/Auth/Source/SP.php
index 8eb262208d915aecff119eadbbee42066fe6270c..e410a7eca80c3b185ba7c1125d87b92d5ddbe16b 100644
--- a/modules/saml/lib/Auth/Source/SP.php
+++ b/modules/saml/lib/Auth/Source/SP.php
@@ -287,10 +287,10 @@ class SP extends Source
                 \SAML2\Constants::BINDING_HOK_SSO)
             );
         } else {
-            $dst = $idpMetadata->getDefaultEndpoint('SingleSignOnService', array(
+            $dst = $idpMetadata->getEndpointPrioritizedByBinding('SingleSignOnService', [
                 \SAML2\Constants::BINDING_HTTP_REDIRECT,
-                \SAML2\Constants::BINDING_HTTP_POST)
-            );
+                \SAML2\Constants::BINDING_HTTP_POST,
+            ]);
         }
         $ar->setDestination($dst['Location']);
 
diff --git a/modules/saml/lib/Error.php b/modules/saml/lib/Error.php
index 605624190fdc6c708cc4027a6770996e5479a55a..ad0349f89e5a5de8f107249ff5b80971e3ad66c5 100644
--- a/modules/saml/lib/Error.php
+++ b/modules/saml/lib/Error.php
@@ -100,10 +100,10 @@ class Error extends \SimpleSAML\Error\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.
+     * @param \Exception $exception  The original exception.
      * @return \SimpleSAML\Module\saml\Error  The new exception.
      */
-    public static function fromException(\SimpleSAML\Error\Exception $exception)
+    public static function fromException(\Exception $exception)
     {
         if ($exception instanceof \SimpleSAML\Module\saml\Error) {
             // Return the original exception unchanged
diff --git a/modules/saml/lib/IdP/SAML2.php b/modules/saml/lib/IdP/SAML2.php
index 3e72e1402dca9d7e255ebe9e990fbd2c251ee64e..d391cb7380198fe57b4fa6c5614e52f8f0047409 100644
--- a/modules/saml/lib/IdP/SAML2.php
+++ b/modules/saml/lib/IdP/SAML2.php
@@ -55,7 +55,7 @@ class SAML2
         // create the session association (for logout)
         $association = array(
             'id'                => 'saml:'.$spEntityId,
-            'Handler'           => '\SimpleSAML\Modulesaml\IdP\SAML2',
+            'Handler'           => '\SimpleSAML\Module\saml\IdP\SAML2',
             'Expires'           => $assertion->getSessionNotOnOrAfter(),
             'saml:entityID'     => $spEntityId,
             'saml:NameID'       => $state['saml:idp:NameID'],
@@ -896,9 +896,9 @@ class SAML2
         $a->setNotOnOrAfter($now + $assertionLifetime);
 
         if (isset($state['saml:AuthnContextClassRef'])) {
-            $a->setAuthnContext($state['saml:AuthnContextClassRef']);
+            $a->setAuthnContextClassRef($state['saml:AuthnContextClassRef']);
         } else {
-            $a->setAuthnContext(\SAML2\Constants::AC_PASSWORD);
+            $a->setAuthnContextClassRef(\SAML2\Constants::AC_PASSWORD);
         }
 
         $sessionStart = $now;
diff --git a/modules/saml/lib/SP/LogoutStore.php b/modules/saml/lib/SP/LogoutStore.php
index 8d329a8cc6defd98a726dfcc9c6971ba42f654e4..3b98fdbeaf40f15a04e9ac93bdc1779e7143645d 100644
--- a/modules/saml/lib/SP/LogoutStore.php
+++ b/modules/saml/lib/SP/LogoutStore.php
@@ -22,7 +22,16 @@ class LogoutStore
             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';
+            switch ($store->driver) {
+                case 'pgsql':
+                    // This does not affect the NOT NULL constraint
+                    $query = 'ALTER TABLE ' . $store->prefix . '_saml_LogoutStore ALTER COLUMN _authSource TYPE VARCHAR(255)';
+                    break;
+                default:
+                    $query = 'ALTER TABLE ' . $store->prefix . '_saml_LogoutStore MODIFY _authSource VARCHAR(255) NOT NULL';
+                    break;
+            }
+
             try {
                 $store->pdo->exec($query);
             } catch (\Exception $e) {
diff --git a/templates/selectidp-dropdown.php b/templates/selectidp-dropdown.php
index 833520e6781b25e70dd61fe5d00c2e6364079a3c..2a2c5110337564d1020efb59322671217b9bc94e 100644
--- a/templates/selectidp-dropdown.php
+++ b/templates/selectidp-dropdown.php
@@ -35,7 +35,7 @@ foreach ($this->data['idplist'] as $idpentry) {
         <select id="dropdownlist" name="idpentityid">
             <?php
             usort($this->data['idplist'], function ($idpentry1, $idpentry2) {
-                return strcmp(
+                return strcasecmp(
                     $this->t('idpname_'.$idpentry1['entityid']),
                     $this->t('idpname_'.$idpentry2['entityid'])
                 );
diff --git a/templates/selectidp-links.php b/templates/selectidp-links.php
index b8f2d6e3d89d6c6dd40244993108b3e1d8bfcded..5a6b0c359ae89160b263bc8c04791cba9ee184fc 100644
--- a/templates/selectidp-links.php
+++ b/templates/selectidp-links.php
@@ -34,6 +34,12 @@ foreach ($this->data['idplist'] as $idpentry) {
             }
             ?></p>
 <?php
+        usort($this->data['idplist'], function ($idpentry1, $idpentry2) {
+            return strcasecmp(
+                $this->t('idpname_'.$idpentry1['entityid']),
+                $this->t('idpname_'.$idpentry2['entityid'])
+            );
+        });
         if (!empty($this->data['preferredidp']) &&
             array_key_exists($this->data['preferredidp'], $this->data['idplist'])
         ) {
diff --git a/tests/modules/core/lib/Auth/UserPassOrgBaseTest.php b/tests/modules/core/lib/Auth/UserPassOrgBaseTest.php
index 9b2fdea587f8460d4072e942f0bdbf6e7a9a8e94..3ee9098b878896066da8dad57e8ef508154d8e3d 100644
--- a/tests/modules/core/lib/Auth/UserPassOrgBaseTest.php
+++ b/tests/modules/core/lib/Auth/UserPassOrgBaseTest.php
@@ -1,10 +1,4 @@
 <?php
-/**
- * Created by PhpStorm.
- * User: agustin
- * Date: 16.10.2017
- * Time: 12:17
- */
 
 namespace SimpleSAML\Test\Module\core\Auth;
 
@@ -31,7 +25,9 @@ class UserPassOrgBaseTest extends \PHPUnit_Framework_TestCase
             )
         );
 
-        $mockUserPassOrgBase = $this->getMockBuilder('\sspmod_core_Auth_UserPassOrgBase')
+        // When PHP 5.4 support is dropped, replace with:
+        // $mockUserPassOrgBase = $this->getMockBuilder(\SimpleSAML\Module\core\Auth\UserPassOrgBase::class)
+        $mockUserPassOrgBase = $this->getMockBuilder(get_parent_class(new \SimpleSAML\Module\ldap\Auth\Source\LDAPMulti(array('AuthId' => 'my-org'), array())))
             ->setConstructorArgs(array(array('AuthId' => 'my-org'), &$config))
             ->setMethods(array())
             ->getMockForAbstractClass();
diff --git a/www/_include.php b/www/_include.php
index 78451ee31db218f69dae7f1d2a514d63eb5c0084..d3e6852ba38e78b29749334d6535196011857ef1 100644
--- a/www/_include.php
+++ b/www/_include.php
@@ -53,7 +53,7 @@ function SimpleSAML_error_handler($errno, $errstr, $errfile = null, $errline = 0
     }
 
     // show an error with a full backtrace
-    $context = (is_null($errfile)?'':" at $errfile:$errline") . (is_null($errcontext)?'':" $errcontext");
+    $context = (is_null($errfile)?'':" at $errfile:$errline");
     $e = new \SimpleSAML\Error\Exception('Error '.$errno.' - '.$errstr . $context);
     $e->logError();
 
diff --git a/www/errorreport.php b/www/errorreport.php
index f04eb9eacbd4307a581a693a9f1ad883eaaf1ba4..4ffe52452765c566be4f4422d3da2bec0e804046 100644
--- a/www/errorreport.php
+++ b/www/errorreport.php
@@ -82,7 +82,7 @@ $message = <<<MESSAGE
 MESSAGE;
 $message = sprintf(
     $message,
-    htmlspecialchars($text),
+    $text,
     $data['exceptionMsg'],
     $data['exceptionTrace'],
     $data['url'],