diff --git a/composer.json b/composer.json
index 1bb7fc0a864d8d706a3246df8f7e7786657080cd..9512ba875e581cfa6603a26e47daf695c8151787 100644
--- a/composer.json
+++ b/composer.json
@@ -86,7 +86,7 @@
         "symfony/routing": "^3.4 || ^4.0",
         "symfony/yaml": "^3.4 || ^4.0",
         "twig/twig": "~1.0 || ~2.0",
-        "webmozart/assert": "~1.4",
+        "webmozart/assert": "~1.5",
         "whitehat101/apr1-md5": "~1.0"
     },
     "require-dev": {
diff --git a/lib/SimpleSAML/Auth/ProcessingChain.php b/lib/SimpleSAML/Auth/ProcessingChain.php
index 3ba249ecf344123c3f921b98d42c83646c23ef19..468940c71c41aa5be1d5a92eac6c468b90020139 100644
--- a/lib/SimpleSAML/Auth/ProcessingChain.php
+++ b/lib/SimpleSAML/Auth/ProcessingChain.php
@@ -9,6 +9,7 @@ use SimpleSAML\Error;
 use SimpleSAML\Logger;
 use SimpleSAML\Module;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Class for implementing authentication processing chains for IdPs.
@@ -58,8 +59,8 @@ class ProcessingChain
      */
     public function __construct($idpMetadata, $spMetadata, $mode = 'idp')
     {
-        assert(is_array($idpMetadata));
-        assert(is_array($spMetadata));
+        Assert::isArray($idpMetadata);
+        Assert::isArray($spMetadata);
 
         $this->filters = [];
 
@@ -192,9 +193,9 @@ class ProcessingChain
      */
     public function processState(&$state)
     {
-        assert(is_array($state));
-        assert(array_key_exists('ReturnURL', $state) || array_key_exists('ReturnCall', $state));
-        assert(!array_key_exists('ReturnURL', $state) || !array_key_exists('ReturnCall', $state));
+        Assert::isArray($state);
+        Assert::true(array_key_exists('ReturnURL', $state) || array_key_exists('ReturnCall', $state));
+        Assert::true(!array_key_exists('ReturnURL', $state) || !array_key_exists('ReturnCall', $state));
 
         $state[self::FILTERS_INDEX] = $this->filters;
 
@@ -238,7 +239,7 @@ class ProcessingChain
      */
     public static function resumeProcessing($state)
     {
-        assert(is_array($state));
+        Assert::isArray($state);
 
         while (count($state[self::FILTERS_INDEX]) > 0) {
             $filter = array_shift($state[self::FILTERS_INDEX]);
@@ -254,8 +255,8 @@ class ProcessingChain
 
         // Completed
 
-        assert(array_key_exists('ReturnURL', $state) || array_key_exists('ReturnCall', $state));
-        assert(!array_key_exists('ReturnURL', $state) || !array_key_exists('ReturnCall', $state));
+        Assert::true(array_key_exists('ReturnURL', $state) || array_key_exists('ReturnCall', $state));
+        Assert::true(!array_key_exists('ReturnURL', $state) || !array_key_exists('ReturnCall', $state));
 
 
         if (array_key_exists('ReturnURL', $state)) {
@@ -272,10 +273,10 @@ class ProcessingChain
             State::deleteState($state);
 
             $func = $state['ReturnCall'];
-            assert(is_callable($func));
+            Assert::isCallable($func);
 
             call_user_func($func, $state);
-            assert(false);
+            Assert::true(false);
         }
     }
 
@@ -293,9 +294,9 @@ class ProcessingChain
      */
     public function processStatePassive(&$state)
     {
-        assert(is_array($state));
+        Assert::isArray($state);
         // Should not be set when calling this method
-        assert(!array_key_exists('ReturnURL', $state));
+        Assert::keyNotExists($state, 'ReturnURL');
 
         // Notify filters about passive request
         $state['isPassive'] = true;
@@ -330,7 +331,7 @@ class ProcessingChain
      */
     public static function fetchProcessedState($id)
     {
-        assert(is_string($id));
+        Assert::string($id);
 
         return State::loadState($id, self::COMPLETED_STAGE);
     }
@@ -343,7 +344,7 @@ class ProcessingChain
      */
     private static function addUserID(array &$state)
     {
-        assert(array_key_exists('Attributes', $state));
+        Assert::keyExists($state, 'Attributes');
 
         if (isset($state['Destination']['userid.attribute'])) {
             $attributeName = $state['Destination']['userid.attribute'];
diff --git a/lib/SimpleSAML/Auth/ProcessingFilter.php b/lib/SimpleSAML/Auth/ProcessingFilter.php
index 964e63e1a7884b8800b47427e12428ec9f661780..8622b987bccb17d720551d0e5c9edbd9c3dcf62f 100644
--- a/lib/SimpleSAML/Auth/ProcessingFilter.php
+++ b/lib/SimpleSAML/Auth/ProcessingFilter.php
@@ -4,6 +4,8 @@ declare(strict_types=1);
 
 namespace SimpleSAML\Auth;
 
+use Webmozart\Assert\Assert;
+
 /**
  * Base class for authentication processing filters.
  *
@@ -47,7 +49,7 @@ abstract class ProcessingFilter
      */
     public function __construct(&$config, $reserved)
     {
-        assert(is_array($config));
+        Assert::isArray($config);
 
         if (array_key_exists('%priority', $config)) {
             $this->priority = $config['%priority'];
diff --git a/lib/SimpleSAML/Auth/Simple.php b/lib/SimpleSAML/Auth/Simple.php
index ac9e5afe8a1ba01b9273e16b3725460230bdd1ba..652fcdc7f4a3af06e7b29092dc8ee38e04e7920a 100644
--- a/lib/SimpleSAML/Auth/Simple.php
+++ b/lib/SimpleSAML/Auth/Simple.php
@@ -9,6 +9,7 @@ use SimpleSAML\Error;
 use SimpleSAML\Module;
 use SimpleSAML\Session;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Helper class for simple authentication applications.
@@ -41,7 +42,7 @@ class Simple
      */
     public function __construct($authSource, Configuration $config = null, Session $session = null)
     {
-        assert(is_string($authSource));
+        Assert::string($authSource);
 
         if ($config === null) {
             $config = Configuration::getInstance();
@@ -167,7 +168,7 @@ class Simple
 
         $as = $this->getAuthSource();
         $as->initLogin($returnTo, $errorURL, $params);
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -189,7 +190,7 @@ class Simple
      */
     public function logout($params = null)
     {
-        assert(is_array($params) || is_string($params) || $params === null);
+        Assert::true(is_array($params) || is_string($params) || $params === null);
 
         if ($params === null) {
             $params = Utils\HTTP::getSelfURL();
@@ -201,11 +202,11 @@ class Simple
             ];
         }
 
-        assert(is_array($params));
-        assert(isset($params['ReturnTo']) || isset($params['ReturnCallback']));
+        Assert::isArray($params);
+        Assert::true(isset($params['ReturnTo']) || isset($params['ReturnCallback']));
 
         if (isset($params['ReturnStateParam']) || isset($params['ReturnStateStage'])) {
-            assert(isset($params['ReturnStateParam'], $params['ReturnStateStage']));
+            Assert::true(isset($params['ReturnStateParam'], $params['ReturnStateStage']));
         }
 
         if ($this->session->isValid($this->authSource)) {
@@ -238,16 +239,16 @@ class Simple
      */
     public static function logoutCompleted($state)
     {
-        assert(is_array($state));
-        assert(isset($state['ReturnTo']) || isset($state['ReturnCallback']));
+        Assert::isArray($state);
+        Assert::true(isset($state['ReturnTo']) || isset($state['ReturnCallback']));
 
         if (isset($state['ReturnCallback'])) {
             call_user_func($state['ReturnCallback'], $state);
-            assert(false);
+            Assert::true(false);
         } else {
             $params = [];
             if (isset($state['ReturnStateParam']) || isset($state['ReturnStateStage'])) {
-                assert(isset($state['ReturnStateParam'], $state['ReturnStateStage']));
+                Assert::true(isset($state['ReturnStateParam'], $state['ReturnStateStage']));
                 $stateID = State::saveState($state, $state['ReturnStateStage']);
                 $params[$state['ReturnStateParam']] = $stateID;
             }
@@ -285,7 +286,7 @@ class Simple
      */
     public function getAuthData($name)
     {
-        assert(is_string($name));
+        Assert::string($name);
 
         if (!$this->isAuthenticated()) {
             return null;
@@ -320,7 +321,7 @@ class Simple
      */
     public function getLoginURL($returnTo = null)
     {
-        assert($returnTo === null || is_string($returnTo));
+        Assert::nullOrString($returnTo);
 
         if ($returnTo === null) {
             $returnTo = Utils\HTTP::getSelfURL();
@@ -345,7 +346,7 @@ class Simple
      */
     public function getLogoutURL($returnTo = null)
     {
-        assert($returnTo === null || is_string($returnTo));
+        Assert::nullOrString($returnTo);
 
         if ($returnTo === null) {
             $returnTo = Utils\HTTP::getSelfURL();
diff --git a/lib/SimpleSAML/Auth/Source.php b/lib/SimpleSAML/Auth/Source.php
index b818ccc9d2c8b06c54202fd20937853c17dcee65..9f1acd989a27bfb86b559debe15070a4849b2f47 100644
--- a/lib/SimpleSAML/Auth/Source.php
+++ b/lib/SimpleSAML/Auth/Source.php
@@ -10,6 +10,7 @@ use SimpleSAML\Logger;
 use SimpleSAML\Module;
 use SimpleSAML\Session;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * This class defines a base class for authentication source.
@@ -42,10 +43,10 @@ abstract class Source
      */
     public function __construct($info, &$config)
     {
-        assert(is_array($info));
-        assert(is_array($config));
+        Assert::isArray($info);
+        Assert::isArray($config);
+        Assert::keyExists($info, 'AuthId');
 
-        assert(array_key_exists('AuthId', $info));
         $this->authId = $info['AuthId'];
     }
 
@@ -60,7 +61,7 @@ abstract class Source
      */
     public static function getSourcesOfType($type)
     {
-        assert(is_string($type));
+        Assert::string($type);
 
         $config = Configuration::getConfig('authsources.php');
 
@@ -123,7 +124,7 @@ abstract class Source
      */
     public function reauthenticate(array &$state)
     {
-        assert(isset($state['ReturnCallback']));
+        Assert::notNull($state['ReturnCallback']);
 
         // the default implementation just copies over the previous authentication data
         $session = Session::getSessionFromRequest();
@@ -150,16 +151,16 @@ abstract class Source
      */
     public static function completeAuth(&$state)
     {
-        assert(is_array($state));
-        assert(array_key_exists('LoginCompletedHandler', $state));
+        Assert::isArray($state);
+        Assert::keyExists($state, 'LoginCompletedHandler');
 
         State::deleteState($state);
 
         $func = $state['LoginCompletedHandler'];
-        assert(is_callable($func));
+        Assert::isCallable($func);
 
         call_user_func($func, $state);
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -179,8 +180,8 @@ abstract class Source
      */
     public function initLogin($return, $errorURL = null, array $params = [])
     {
-        assert(is_string($return) || is_array($return));
-        assert(is_string($errorURL) || $errorURL === null);
+        Assert::True(is_string($return) || is_array($return));
+        Assert::nullOrString($errorURL);
 
         $state = array_merge($params, [
             '\SimpleSAML\Auth\DefaultAuth.id' => $this->authId, // TODO: remove in 2.0
@@ -228,11 +229,11 @@ abstract class Source
      */
     public static function loginCompleted($state)
     {
-        assert(is_array($state));
-        assert(array_key_exists('\SimpleSAML\Auth\Source.Return', $state));
-        assert(array_key_exists('\SimpleSAML\Auth\Source.id', $state));
-        assert(array_key_exists('Attributes', $state));
-        assert(!array_key_exists('LogoutState', $state) || is_array($state['LogoutState']));
+        Assert::isArray($state);
+        Assert::keyExists($state, '\SimpleSAML\Auth\Source.Return');
+        Assert::keyExists($state, '\SimpleSAML\Auth\Source.id');
+        Assert::keyExists($state, 'Attributes');
+        Assert::true(!array_key_exists('LogoutState', $state) || is_array($state['LogoutState']));
 
         $return = $state['\SimpleSAML\Auth\Source.Return'];
 
@@ -247,7 +248,7 @@ abstract class Source
         } else {
             call_user_func($return, $state);
         }
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -267,7 +268,7 @@ abstract class Source
      */
     public function logout(&$state)
     {
-        assert(is_array($state));
+        Assert::isArray($state);
         // default logout handler which doesn't do anything
     }
 
@@ -284,16 +285,16 @@ abstract class Source
      */
     public static function completeLogout(&$state)
     {
-        assert(is_array($state));
-        assert(array_key_exists('LogoutCompletedHandler', $state));
+        Assert::isArray($state);
+        Assert::keyExists($state, 'LogoutCompletedHandler');
 
         State::deleteState($state);
 
         $func = $state['LogoutCompletedHandler'];
-        assert(is_callable($func));
+        Assert::isCallable($func);
 
         call_user_func($func, $state);
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -361,8 +362,8 @@ abstract class Source
      */
     public static function getById($authId, $type = null)
     {
-        assert(is_string($authId));
-        assert($type === null || is_string($type));
+        Assert::string($authId);
+        Assert::nullOrString($type);
 
         // for now - load and parse config file
         $config = Configuration::getConfig('authsources.php');
@@ -401,8 +402,8 @@ abstract class Source
      */
     public static function logoutCallback($state)
     {
-        assert(is_array($state));
-        assert(array_key_exists('\SimpleSAML\Auth\Source.logoutSource', $state));
+        Assert::isArray($state);
+        Assert::keyExists($state, '\SimpleSAML\Auth\Source.logoutSource');
 
         $source = $state['\SimpleSAML\Auth\Source.logoutSource'];
 
@@ -434,8 +435,8 @@ abstract class Source
      */
     protected function addLogoutCallback($assoc, $state)
     {
-        assert(is_string($assoc));
-        assert(is_array($state));
+        Assert::string($assoc);
+        Assert::isArray($state);
 
         if (!array_key_exists('LogoutCallback', $state)) {
             // the authentication requester doesn't have a logout callback
@@ -479,7 +480,7 @@ abstract class Source
      */
     protected function callLogoutCallback($assoc)
     {
-        assert(is_string($assoc));
+        Assert::string($assoc);
 
         $id = strlen($this->authId) . ':' . $this->authId . $assoc;
 
@@ -493,9 +494,9 @@ abstract class Source
             return;
         }
 
-        assert(is_array($data));
-        assert(array_key_exists('callback', $data));
-        assert(array_key_exists('state', $data));
+        Assert::isArray($data);
+        Assert::keyExists($data, 'callback');
+        Assert::keyExists($data, 'state');
 
         $callback = $data['callback'];
         $callbackState = $data['state'];
diff --git a/lib/SimpleSAML/Auth/State.php b/lib/SimpleSAML/Auth/State.php
index 2a298356d0569a8595187a7308b122ef5451dea6..4821b8d0ffbd4f47a529bcb6d17f4e73687f2851 100644
--- a/lib/SimpleSAML/Auth/State.php
+++ b/lib/SimpleSAML/Auth/State.php
@@ -9,6 +9,7 @@ use SimpleSAML\Error;
 use SimpleSAML\Logger;
 use SimpleSAML\Session;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * This is a helper class for saving and loading state information.
@@ -155,8 +156,8 @@ class State
      */
     public static function getStateId(&$state, $rawId = false)
     {
-        assert(is_array($state));
-        assert(is_bool($rawId));
+        Assert::isArray($state);
+        Assert::boolean($rawId);
 
         if (!array_key_exists(self::ID, $state)) {
             $state[self::ID] = Utils\Random::generateID();
@@ -204,9 +205,9 @@ class State
      */
     public static function saveState(&$state, $stage, $rawId = false)
     {
-        assert(is_array($state));
-        assert(is_string($stage));
-        assert(is_bool($rawId));
+        Assert::isArray($state);
+        Assert::string($stage);
+        Assert::boolean($rawId);
 
         $return = self::getStateId($state, $rawId);
         $id = $state[self::ID];
@@ -269,9 +270,9 @@ class State
      */
     public static function loadState($id, $stage, $allowMissing = false)
     {
-        assert(is_string($id));
-        assert(is_string($stage));
-        assert(is_bool($allowMissing));
+        Assert::string($id);
+        Assert::string($stage);
+        Assert::boolean($allowMissing);
         Logger::debug('Loading state: ' . var_export($id, true));
 
         $sid = self::parseStateID($id);
@@ -293,9 +294,9 @@ class State
         }
 
         $state = unserialize($state);
-        assert(is_array($state));
-        assert(array_key_exists(self::ID, $state));
-        assert(array_key_exists(self::STAGE, $state));
+        Assert::isArray($state);
+        Assert::keyExists($state, self::ID);
+        Assert::keyExists($state, self::STAGE);
 
         // Verify stage
         if ($state[self::STAGE] !== $stage) {
@@ -330,7 +331,7 @@ class State
      */
     public static function deleteState(&$state)
     {
-        assert(is_array($state));
+        Assert::isArray($state);
 
         if (!array_key_exists(self::ID, $state)) {
             // This state hasn't been saved
@@ -355,7 +356,7 @@ class State
      */
     public static function throwException($state, Error\Exception $exception)
     {
-        assert(is_array($state));
+        Assert::isArray($state);
 
         if (array_key_exists(self::EXCEPTION_HANDLER_URL, $state)) {
             // Save the exception
@@ -370,10 +371,10 @@ class State
         } elseif (array_key_exists(self::EXCEPTION_HANDLER_FUNC, $state)) {
             // Call the exception handler
             $func = $state[self::EXCEPTION_HANDLER_FUNC];
-            assert(is_callable($func));
+            Assert::isCallable($func);
 
             call_user_func($func, $exception, $state);
-            assert(false);
+            Assert::true(false);
         } else {
             /*
              * No exception handler is defined for the current state.
@@ -393,7 +394,7 @@ class State
      */
     public static function loadExceptionState($id = null)
     {
-        assert(is_string($id) || $id === null);
+        Assert::nullOrString($id);
 
         if ($id === null) {
             if (!array_key_exists(self::EXCEPTION_PARAM, $_REQUEST)) {
@@ -405,7 +406,7 @@ class State
 
         /** @var array $state */
         $state = self::loadState($id, self::EXCEPTION_STAGE);
-        assert(array_key_exists(self::EXCEPTION_DATA, $state));
+        Assert::keyExists($state, self::EXCEPTION_DATA);
 
         return $state;
     }
diff --git a/lib/SimpleSAML/Bindings/Shib13/Artifact.php b/lib/SimpleSAML/Bindings/Shib13/Artifact.php
index cc37699003620c0c4f675d4e92ac07bc2128f493..f1b6741c6904bdedc453964579d9ca280df42828 100644
--- a/lib/SimpleSAML/Bindings/Shib13/Artifact.php
+++ b/lib/SimpleSAML/Bindings/Shib13/Artifact.php
@@ -15,6 +15,7 @@ use SAML2\DOMDocumentFactory;
 use SimpleSAML\Configuration;
 use SimpleSAML\Error;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 class Artifact
 {
@@ -28,7 +29,7 @@ class Artifact
      */
     private static function getArtifacts(): array
     {
-        assert(array_key_exists('QUERY_STRING', $_SERVER));
+        Assert::keyExists($_SERVER, 'QUERY_STRING');
 
         // We need to process the query string manually, to capture all SAMLart parameters
 
diff --git a/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php b/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php
index 594c079d3d1117e6b8e4206d4a46d03e94eebf06..82e491ad4dba74236797b2951a561c2a58f26515 100644
--- a/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php
+++ b/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php
@@ -18,6 +18,7 @@ use SimpleSAML\Metadata\MetaDataStorageHandler;
 use SimpleSAML\Utils;
 use SimpleSAML\XML\Shib13\AuthnResponse;
 use SimpleSAML\XML\Signer;
+use Webmozart\Assert\Assert;
 
 class HTTPPost
 {
@@ -105,7 +106,7 @@ class HTTPPost
             // sign the response - this must be done after encrypting the assertion
             // we insert the signature before the saml2p:Status element
             $statusElements = Utils\XML::getDOMChildren($responseroot, 'Status', '@saml1p');
-            assert(count($statusElements) === 1);
+            Assert::same(count($statusElements), 1);
             $signer->sign($responseroot, $responseroot, $statusElements[0]);
         } else {
             // Sign the assertion
@@ -132,7 +133,7 @@ class HTTPPost
      */
     public function decodeResponse($post)
     {
-        assert(is_array($post));
+        Assert::isArray($post);
 
         if (!array_key_exists('SAMLResponse', $post)) {
             throw new \Exception('Missing required SAMLResponse parameter.');
diff --git a/lib/SimpleSAML/Configuration.php b/lib/SimpleSAML/Configuration.php
index aa05a86607711b007b3ede4b9a56a87c3c702191..7a58db7c38be548de8dde35a30903e499a008a9e 100644
--- a/lib/SimpleSAML/Configuration.php
+++ b/lib/SimpleSAML/Configuration.php
@@ -7,6 +7,7 @@ namespace SimpleSAML;
 use SAML2\Constants;
 use SimpleSAML\Error;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Configuration of SimpleSAMLphp
@@ -93,8 +94,8 @@ class Configuration implements Utils\ClearableState
      */
     public function __construct($config, $location)
     {
-        assert(is_array($config));
-        assert(is_string($location));
+        Assert::isArray($config);
+        Assert::string($location);
 
         $this->configuration = $config;
         $this->location = $location;
@@ -193,8 +194,8 @@ class Configuration implements Utils\ClearableState
      */
     public static function setConfigDir($path, $configSet = 'simplesaml')
     {
-        assert(is_string($path));
-        assert(is_string($configSet));
+        Assert::string($path);
+        Assert::string($configSet);
 
         self::$configDirs[$configSet] = $path;
     }
@@ -216,8 +217,8 @@ class Configuration implements Utils\ClearableState
         $filename = 'config.php',
         $configSet = 'simplesaml'
     ) {
-        assert(is_string($filename));
-        assert(is_string($configSet));
+        Assert::string($filename);
+        Assert::string($configSet);
 
         if (!array_key_exists($configSet, self::$configDirs)) {
             if ($configSet !== 'simplesaml') {
@@ -245,8 +246,8 @@ class Configuration implements Utils\ClearableState
      */
     public static function getConfig($filename = 'config.php', $configSet = 'simplesaml')
     {
-        assert(is_string($filename));
-        assert(is_string($configSet));
+        Assert::string($filename);
+        Assert::string($configSet);
 
         if (!array_key_exists($configSet, self::$configDirs)) {
             if ($configSet !== 'simplesaml') {
@@ -275,8 +276,8 @@ class Configuration implements Utils\ClearableState
      */
     public static function getOptionalConfig($filename = 'config.php', $configSet = 'simplesaml')
     {
-        assert(is_string($filename));
-        assert(is_string($configSet));
+        Assert::string($filename);
+        Assert::string($configSet);
 
         if (!array_key_exists($configSet, self::$configDirs)) {
             if ($configSet !== 'simplesaml') {
@@ -305,8 +306,8 @@ class Configuration implements Utils\ClearableState
      */
     public static function loadFromArray($config, $location = '[ARRAY]', $instance = null)
     {
-        assert(is_array($config));
-        assert(is_string($location));
+        Assert::isArray($config);
+        Assert::string($location);
 
         $c = new Configuration($config, $location);
         if ($instance !== null) {
@@ -333,7 +334,7 @@ class Configuration implements Utils\ClearableState
      */
     public static function getInstance($instancename = 'simplesaml')
     {
-        assert(is_string($instancename));
+        Assert::string($instancename);
 
         // check if the instance exists already
         if (array_key_exists($instancename, self::$instance)) {
@@ -369,9 +370,9 @@ class Configuration implements Utils\ClearableState
      */
     public static function init($path, $instancename = 'simplesaml', $configfilename = 'config.php')
     {
-        assert(is_string($path));
-        assert(is_string($instancename));
-        assert(is_string($configfilename));
+        Assert::string($path);
+        Assert::string($instancename);
+        Assert::string($configfilename);
 
         if ($instancename === 'simplesaml') {
             // for backwards compatibility
@@ -402,15 +403,16 @@ class Configuration implements Utils\ClearableState
      */
     public function copyFromBase($instancename, $filename)
     {
-        assert(is_string($instancename));
-        assert(is_string($filename));
-        assert($this->filename !== null);
+        Assert::string($instancename);
+        Assert::string($filename);
+        Assert::notNull($this->filename);
 
         // check if we already have loaded the given config - return the existing instance if we have
         if (array_key_exists($instancename, self::$instance)) {
             return self::$instance[$instancename];
         }
 
+        /** @var string $this->filename */
         $dir = dirname($this->filename);
 
         self::$instance[$instancename] = self::loadFromFile($dir . '/' . $filename, true);
@@ -578,7 +580,7 @@ class Configuration implements Utils\ClearableState
             return null;
         }
 
-        assert(is_string($path));
+        Assert::string($path);
 
         return Utils\System::resolvePath($path, $this->getBaseDir());
     }
@@ -640,13 +642,13 @@ class Configuration implements Utils\ClearableState
 
         // the directory wasn't set in the configuration file, path is <base directory>/lib/SimpleSAML/Configuration.php
         $dir = __FILE__;
-        assert(basename($dir) === 'Configuration.php');
+        Assert::same(basename($dir), 'Configuration.php');
 
         $dir = dirname($dir);
-        assert(basename($dir) === 'SimpleSAML');
+        Assert::same(basename($dir), 'SimpleSAML');
 
         $dir = dirname($dir);
-        assert(basename($dir) === 'lib');
+        Assert::same(basename($dir), 'lib');
 
         $dir = dirname($dir);
 
@@ -675,7 +677,7 @@ class Configuration implements Utils\ClearableState
      */
     public function getBoolean($name, $default = self::REQUIRED_OPTION)
     {
-        assert(is_string($name));
+        Assert::string($name);
 
         $ret = $this->getValue($name, $default);
 
@@ -713,7 +715,7 @@ class Configuration implements Utils\ClearableState
      */
     public function getString($name, $default = self::REQUIRED_OPTION)
     {
-        assert(is_string($name));
+        Assert::string($name);
 
         $ret = $this->getValue($name, $default);
 
@@ -751,7 +753,7 @@ class Configuration implements Utils\ClearableState
      */
     public function getInteger($name, $default = self::REQUIRED_OPTION)
     {
-        assert(is_string($name));
+        Assert::string($name);
 
         $ret = $this->getValue($name, $default);
 
@@ -793,9 +795,9 @@ class Configuration implements Utils\ClearableState
      */
     public function getIntegerRange($name, $minimum, $maximum, $default = self::REQUIRED_OPTION)
     {
-        assert(is_string($name));
-        assert(is_int($minimum));
-        assert(is_int($maximum));
+        Assert::string($name);
+        Assert::integer($minimum);
+        Assert::integer($maximum);
 
         $ret = $this->getInteger($name, $default);
 
@@ -839,8 +841,8 @@ class Configuration implements Utils\ClearableState
      */
     public function getValueValidate($name, $allowedValues, $default = self::REQUIRED_OPTION)
     {
-        assert(is_string($name));
-        assert(is_array($allowedValues));
+        Assert::string($name);
+        Assert::isArray($allowedValues);
 
         $ret = $this->getValue($name, $default);
         if ($ret === $default) {
@@ -884,7 +886,7 @@ class Configuration implements Utils\ClearableState
      */
     public function getArray($name, $default = self::REQUIRED_OPTION)
     {
-        assert(is_string($name));
+        Assert::string($name);
 
         $ret = $this->getValue($name, $default);
 
@@ -916,7 +918,7 @@ class Configuration implements Utils\ClearableState
      */
     public function getArrayize($name, $default = self::REQUIRED_OPTION)
     {
-        assert(is_string($name));
+        Assert::string($name);
 
         $ret = $this->getValue($name, $default);
 
@@ -949,7 +951,7 @@ class Configuration implements Utils\ClearableState
      */
     public function getArrayizeString($name, $default = self::REQUIRED_OPTION)
     {
-        assert(is_string($name));
+        Assert::string($name);
 
         $ret = $this->getArrayize($name, $default);
 
@@ -992,7 +994,7 @@ class Configuration implements Utils\ClearableState
      */
     public function getConfigItem($name, $default = [])
     {
-        assert(is_string($name));
+        Assert::string($name);
 
         $ret = $this->getValue($name, $default);
 
@@ -1033,7 +1035,7 @@ class Configuration implements Utils\ClearableState
      */
     public function getConfigList($name)
     {
-        assert(is_string($name));
+        Assert::string($name);
 
         $ret = $this->getValue($name, []);
 
@@ -1097,7 +1099,7 @@ class Configuration implements Utils\ClearableState
      */
     private function getDefaultBinding($endpointType)
     {
-        assert(is_string($endpointType));
+        Assert::string($endpointType);
 
         $set = $this->getString('metadata-set');
         switch ($set . ':' . $endpointType) {
@@ -1130,7 +1132,7 @@ class Configuration implements Utils\ClearableState
      */
     public function getEndpoints($endpointType)
     {
-        assert(is_string($endpointType));
+        Assert::string($endpointType);
 
         $loc = $this->location . '[' . var_export($endpointType, true) . ']:';
 
@@ -1211,7 +1213,7 @@ class Configuration implements Utils\ClearableState
      */
     public function getEndpointPrioritizedByBinding($endpointType, array $bindings, $default = self::REQUIRED_OPTION)
     {
-        assert(is_string($endpointType));
+        Assert::string($endpointType);
 
         $endpoints = $this->getEndpoints($endpointType);
 
@@ -1246,7 +1248,7 @@ class Configuration implements Utils\ClearableState
      */
     public function getDefaultEndpoint($endpointType, array $bindings = null, $default = self::REQUIRED_OPTION)
     {
-        assert(is_string($endpointType));
+        Assert::string($endpointType);
 
         $endpoints = $this->getEndpoints($endpointType);
 
@@ -1279,7 +1281,7 @@ class Configuration implements Utils\ClearableState
      */
     public function getLocalizedString($name, $default = self::REQUIRED_OPTION)
     {
-        assert(is_string($name));
+        Assert::string($name);
 
         $ret = $this->getValue($name, $default);
         if ($ret === $default) {
@@ -1327,8 +1329,8 @@ class Configuration implements Utils\ClearableState
      */
     public function getPublicKeys($use = null, $required = false, $prefix = '')
     {
-        assert(is_bool($required));
-        assert(is_string($prefix));
+        Assert::boolean($required);
+        Assert::string($prefix);
 
         if ($this->hasValue($prefix . 'keys')) {
             $ret = [];
diff --git a/lib/SimpleSAML/Error/Assertion.php b/lib/SimpleSAML/Error/Assertion.php
index 30e6d786647896d3a71117747f5769a45a6c1721..28f88b5f021ae7180330e5e87c0c28af6181b7f8 100644
--- a/lib/SimpleSAML/Error/Assertion.php
+++ b/lib/SimpleSAML/Error/Assertion.php
@@ -4,6 +4,8 @@ declare(strict_types=1);
 
 namespace SimpleSAML\Error;
 
+use Webmozart\Assert\Assert;
+
 /**
  * Class for creating exceptions from assertion failures.
  *
@@ -30,7 +32,7 @@ class Assertion extends Exception
      */
     public function __construct($assertion = null)
     {
-        assert($assertion === null || is_string($assertion));
+        Assert::nullOrString($assertion);
 
         $msg = 'Assertion failed: ' . var_export($assertion, true);
         parent::__construct($msg);
diff --git a/lib/SimpleSAML/Error/AuthSource.php b/lib/SimpleSAML/Error/AuthSource.php
index f6caaf1ade47c71b9806526a06af0afb85835e37..fcc3f3c027e4eb9a840559c466ebdb77db48aea5 100644
--- a/lib/SimpleSAML/Error/AuthSource.php
+++ b/lib/SimpleSAML/Error/AuthSource.php
@@ -4,6 +4,8 @@ declare(strict_types=1);
 
 namespace SimpleSAML\Error;
 
+use Webmozart\Assert\Assert;
+
 /**
  * Baseclass for auth source exceptions.
  *
@@ -36,8 +38,8 @@ class AuthSource extends Error
      */
     public function __construct($authsource, $reason, $cause = null)
     {
-        assert(is_string($authsource));
-        assert(is_string($reason));
+        Assert::string($authsource);
+        Assert::string($reason);
 
         $this->authsource = $authsource;
         $this->reason = $reason;
diff --git a/lib/SimpleSAML/Error/BadRequest.php b/lib/SimpleSAML/Error/BadRequest.php
index d45c2ba442ec79ea30aa1058fe6bf0422db582fe..77463b452bc945259669e802c19df9d713507f03 100644
--- a/lib/SimpleSAML/Error/BadRequest.php
+++ b/lib/SimpleSAML/Error/BadRequest.php
@@ -4,6 +4,8 @@ declare(strict_types=1);
 
 namespace SimpleSAML\Error;
 
+use Webmozart\Assert\Assert;
+
 /**
  * Exception which will show a 400 Bad Request error page.
  *
@@ -30,7 +32,7 @@ class BadRequest extends Error
      */
     public function __construct($reason)
     {
-        assert(is_string($reason));
+        Assert::string($reason);
 
         $this->reason = $reason;
         parent::__construct(['BADREQUEST', '%REASON%' => $this->reason]);
diff --git a/lib/SimpleSAML/Error/Error.php b/lib/SimpleSAML/Error/Error.php
index 563d373816971a40331a32c543477c1208eeb975..ffa004f4ebe82233a1502abba40a82075f0f08fc 100644
--- a/lib/SimpleSAML/Error/Error.php
+++ b/lib/SimpleSAML/Error/Error.php
@@ -9,6 +9,7 @@ use SimpleSAML\Logger;
 use SimpleSAML\Session;
 use SimpleSAML\Utils;
 use SimpleSAML\XHTML\Template;
+use Webmozart\Assert\Assert;
 
 /**
  * Class that wraps SimpleSAMLphp errors in exceptions.
@@ -80,7 +81,7 @@ class Error extends Exception
      */
     public function __construct($errorCode, \Exception $cause = null, $httpCode = null)
     {
-        assert(is_string($errorCode) || is_array($errorCode));
+        Assert::true(is_string($errorCode) || is_array($errorCode));
 
         if (is_array($errorCode)) {
             $this->parameters = $errorCode;
@@ -263,9 +264,9 @@ class Error extends Exception
 
         $show_function = $config->getArray('errors.show_function', null);
         if (isset($show_function)) {
-            assert(is_callable($show_function));
+            Assert::isCallable($show_function);
             call_user_func($show_function, $config, $data);
-            assert(false);
+            Assert::true(false);
         } else {
             $t = new Template($config, 'error.php', 'errors');
             $t->data = array_merge($t->data, $data);
diff --git a/lib/SimpleSAML/Error/Exception.php b/lib/SimpleSAML/Error/Exception.php
index b0b7b8809bd0c94ae1c213dd2abb42edf5a601b4..885ef1e8db8d8afd9fb113f61a49cd66f636372e 100644
--- a/lib/SimpleSAML/Error/Exception.php
+++ b/lib/SimpleSAML/Error/Exception.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Error;
 
 use SimpleSAML\Configuration;
 use SimpleSAML\Logger;
+use Webmozart\Assert\Assert;
 
 /**
  * Base class for SimpleSAMLphp Exceptions
@@ -49,8 +50,8 @@ class Exception extends \Exception
      */
     public function __construct($message, $code = 0, \Exception $cause = null)
     {
-        assert(is_string($message));
-        assert(is_int($code));
+        Assert::string($message);
+        Assert::integer($code);
 
         parent::__construct($message, $code);
 
diff --git a/lib/SimpleSAML/Error/MetadataNotFound.php b/lib/SimpleSAML/Error/MetadataNotFound.php
index 9eabf67af9837c6bfce51218653948b18d7e7dbd..8ef13f5cde57785f1e5f3b6b350cbad2f876fd87 100644
--- a/lib/SimpleSAML/Error/MetadataNotFound.php
+++ b/lib/SimpleSAML/Error/MetadataNotFound.php
@@ -4,6 +4,8 @@ declare(strict_types=1);
 
 namespace SimpleSAML\Error;
 
+use Webmozart\Assert\Assert;
+
 /**
  * Error for missing metadata.
  *
@@ -19,7 +21,7 @@ class MetadataNotFound extends Error
      */
     public function __construct($entityId)
     {
-        assert(is_string($entityId));
+        Assert::string($entityId);
 
         $this->includeTemplate = 'core:no_metadata.tpl.php';
         parent::__construct([
diff --git a/lib/SimpleSAML/Error/NotFound.php b/lib/SimpleSAML/Error/NotFound.php
index 0a5f72e0fa91ef18201f40de4330c0e14b500c4e..498427eabd503a50feb86c849c372eb1a7eb31c5 100644
--- a/lib/SimpleSAML/Error/NotFound.php
+++ b/lib/SimpleSAML/Error/NotFound.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace SimpleSAML\Error;
 
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Exception which will show a 404 Not Found error page.
@@ -31,7 +32,7 @@ class NotFound extends Error
      */
     public function __construct($reason = null)
     {
-        assert($reason === null || is_string($reason));
+        Assert::nullOrString($reason);
 
         $url = Utils\HTTP::getSelfURL();
 
diff --git a/lib/SimpleSAML/IdP.php b/lib/SimpleSAML/IdP.php
index bacc8c8040279e7e784c3542f7169994ab2b8381..5590304f0010fbd92cbdcc4b4d8c1cf7a3663672 100644
--- a/lib/SimpleSAML/IdP.php
+++ b/lib/SimpleSAML/IdP.php
@@ -4,12 +4,13 @@ declare(strict_types=1);
 
 namespace SimpleSAML;
 
-use SAML2\Constants as SAML2;
+use SAML2\Constants;
 use SimpleSAML\Auth;
 use SimpleSAML\Error;
 use SimpleSAML\Metadata\MetaDataStorageHandler;
 use SimpleSAML\Module\saml\Error\NoPassive;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * IdP class.
@@ -130,7 +131,7 @@ class IdP
      */
     public static function getById($id)
     {
-        assert(is_string($id));
+        Assert::string($id);
 
         if (isset(self::$idpCache[$id])) {
             return self::$idpCache[$id];
@@ -151,7 +152,7 @@ class IdP
      */
     public static function getByState(array &$state)
     {
-        assert(isset($state['core:IdP']));
+        Assert::notNull($state['core:IdP']);
 
         return self::getById($state['core:IdP']);
     }
@@ -177,7 +178,7 @@ class IdP
      */
     public function getSPName($assocId)
     {
-        assert(is_string($assocId));
+        Assert::string($assocId);
 
         $prefix = substr($assocId, 0, 4);
         $spEntityId = substr($assocId, strlen($prefix) + 1);
@@ -219,8 +220,8 @@ class IdP
      */
     public function addAssociation(array $association)
     {
-        assert(isset($association['id']));
-        assert(isset($association['Handler']));
+        Assert::notNull($association['id']);
+        Assert::notNull($association['Handler']);
 
         $association['core:IdP'] = $this->id;
 
@@ -249,7 +250,7 @@ class IdP
      */
     public function terminateAssociation($assocId)
     {
-        assert(is_string($assocId));
+        Assert::string($assocId);
 
         $session = Session::getSessionFromRequest();
         $session->terminateAssociation($this->associationGroup, $assocId);
@@ -275,7 +276,7 @@ class IdP
      */
     public static function postAuthProc(array $state)
     {
-        assert(is_callable($state['Responder']));
+        Assert::isCallable($state['Responder']);
 
         if (isset($state['core:SP'])) {
             $session = Session::getSessionFromRequest();
@@ -288,7 +289,7 @@ class IdP
         }
 
         call_user_func($state['Responder'], $state);
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -351,7 +352,7 @@ class IdP
     private function authenticate(array &$state)
     {
         if (isset($state['isPassive']) && (bool) $state['isPassive']) {
-            throw new NoPassive(SAML2::STATUS_RESPONDER, 'Passive authentication not supported.');
+            throw new NoPassive(Constants::STATUS_RESPONDER, 'Passive authentication not supported.');
         }
 
         $this->authSource->login($state);
@@ -386,7 +387,7 @@ class IdP
      */
     public function handleAuthenticationRequest(array &$state)
     {
-        assert(isset($state['Responder']));
+        Assert::notNull($state['Responder']);
 
         $state['core:IdP'] = $this->id;
 
@@ -413,7 +414,7 @@ class IdP
         try {
             if ($needAuth) {
                 $this->authenticate($state);
-                assert(false);
+                Assert::true(false);
             } else {
                 $this->reauthenticate($state);
             }
@@ -463,11 +464,11 @@ class IdP
      */
     public function finishLogout(array &$state)
     {
-        assert(isset($state['Responder']));
+        Assert::notNull($state['Responder']);
 
         $idp = IdP::getByState($state);
         call_user_func($state['Responder'], $idp, $state);
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -483,8 +484,8 @@ class IdP
      */
     public function handleLogoutRequest(array &$state, $assocId)
     {
-        assert(isset($state['Responder']));
-        assert(is_string($assocId) || $assocId === null);
+        Assert::notNull($state['Responder']);
+        Assert::nullOrString($assocId);
 
         $state['core:IdP'] = $this->id;
         $state['core:TerminatedAssocId'] = $assocId;
@@ -505,7 +506,7 @@ class IdP
             $handler = $this->getLogoutHandler();
             $handler->startLogout($state, $assocId);
         }
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -521,11 +522,11 @@ class IdP
      */
     public function handleLogoutResponse($assocId, $relayState, Error\Exception $error = null)
     {
-        assert(is_string($assocId));
-        assert(is_string($relayState) || $relayState === null);
+        Assert::string($assocId);
+        Assert::nullOrString($relayState);
 
         $index = strpos($assocId, ':');
-        assert(is_int($index));
+        Assert::integer($index);
 
         $session = Session::getSessionFromRequest();
         $session->deleteData('core:idp-ssotime', $this->id . ';' . substr($assocId, $index + 1));
@@ -533,7 +534,7 @@ class IdP
         $handler = $this->getLogoutHandler();
         $handler->onResponse($assocId, $relayState, $error);
 
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -547,7 +548,7 @@ class IdP
      */
     public function doLogoutRedirect($url)
     {
-        assert(is_string($url));
+        Assert::string($url);
 
         $state = [
             'Responder'       => ['\SimpleSAML\IdP', 'finishLogoutRedirect'],
@@ -555,7 +556,7 @@ class IdP
         ];
 
         $this->handleLogoutRequest($state, null);
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -570,9 +571,9 @@ class IdP
      */
     public static function finishLogoutRedirect(IdP $idp, array $state)
     {
-        assert(isset($state['core:Logout:URL']));
+        Assert::notNull($state['core:Logout:URL']);
 
         Utils\HTTP::redirectTrustedURL($state['core:Logout:URL']);
-        assert(false);
+        Assert::true(false);
     }
 }
diff --git a/lib/SimpleSAML/IdP/IFrameLogoutHandler.php b/lib/SimpleSAML/IdP/IFrameLogoutHandler.php
index c315cc82f27625fc9007d7b9b8226d98f95bf705..b95fc62feee9ea9d8554333486bb8c57269d34c0 100644
--- a/lib/SimpleSAML/IdP/IFrameLogoutHandler.php
+++ b/lib/SimpleSAML/IdP/IFrameLogoutHandler.php
@@ -11,6 +11,7 @@ use SimpleSAML\IdP;
 use SimpleSAML\Module;
 use SimpleSAML\Utils;
 use SimpleSAML\XHTML\Template;
+use Webmozart\Assert\Assert;
 
 /**
  * Class that handles iframe logout.
@@ -46,7 +47,7 @@ class IFrameLogoutHandler implements LogoutHandlerInterface
      */
     public function startLogout(array &$state, $assocId)
     {
-        assert(is_string($assocId) || $assocId === null);
+        Assert::nullOrString($assocId);
 
         $associations = $this->idp->getAssociations();
 
@@ -96,7 +97,7 @@ class IFrameLogoutHandler implements LogoutHandlerInterface
      */
     public function onResponse($assocId, $relayState, Error\Exception $error = null)
     {
-        assert(is_string($assocId));
+        Assert::string($assocId);
 
         $this->idp->terminateAssociation($assocId);
 
diff --git a/lib/SimpleSAML/IdP/TraditionalLogoutHandler.php b/lib/SimpleSAML/IdP/TraditionalLogoutHandler.php
index 7ea2bfe74c88651681b6f25611a9aeedc5b4287f..88543949002a0d2c9e1de3371617d910cda3d35f 100644
--- a/lib/SimpleSAML/IdP/TraditionalLogoutHandler.php
+++ b/lib/SimpleSAML/IdP/TraditionalLogoutHandler.php
@@ -9,6 +9,7 @@ use SimpleSAML\Error;
 use SimpleSAML\IdP;
 use SimpleSAML\Logger;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Class that handles traditional logout.
@@ -68,7 +69,7 @@ class TraditionalLogoutHandler implements LogoutHandlerInterface
 
             // Try the next SP
             $this->logoutNextSP($state);
-            assert(false);
+            Assert::true(false);
         }
     }
 
@@ -104,8 +105,8 @@ class TraditionalLogoutHandler implements LogoutHandlerInterface
      */
     public function onResponse($assocId, $relayState, Error\Exception $error = null)
     {
-        assert(is_string($assocId));
-        assert(is_string($relayState) || $relayState === null);
+        Assert::string($assocId);
+        Assert::nullOrString($relayState);
 
         if ($relayState === null) {
             throw new Error\Exception('RelayState lost during logout.');
diff --git a/lib/SimpleSAML/Locale/Language.php b/lib/SimpleSAML/Locale/Language.php
index 4f6581313c7787965f278652de53336d7b88db87..13cba995b0f60bd8d9bb65ea2d24d38b7c413ee4 100644
--- a/lib/SimpleSAML/Locale/Language.php
+++ b/lib/SimpleSAML/Locale/Language.php
@@ -15,6 +15,7 @@ namespace SimpleSAML\Locale;
 use SimpleSAML\Configuration;
 use SimpleSAML\Logger;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 class Language
 {
@@ -410,7 +411,7 @@ class Language
      */
     public static function setLanguageCookie($language)
     {
-        assert(is_string($language));
+        Assert::string($language);
 
         $language = strtolower($language);
         $config = Configuration::getInstance();
diff --git a/lib/SimpleSAML/Locale/Translate.php b/lib/SimpleSAML/Locale/Translate.php
index 768e5302983f13d405a8d0efdf02c916b85948f3..4d441c21b0e53e4aa3398be9483a8df6a7d7c0dd 100644
--- a/lib/SimpleSAML/Locale/Translate.php
+++ b/lib/SimpleSAML/Locale/Translate.php
@@ -16,6 +16,7 @@ use Gettext\BaseTranslator;
 use SimpleSAML\Configuration;
 use SimpleSAML\Logger;
 use SimpleSAML\Module;
+use Webmozart\Assert\Assert;
 
 class Translate
 {
@@ -128,7 +129,7 @@ class Translate
      */
     public function getTag($tag)
     {
-        assert(is_string($tag));
+        Assert::string($tag);
 
         // first check translations loaded by the includeInlineTranslation and includeLanguageFile methods
         if (array_key_exists($tag, $this->langtext)) {
@@ -166,7 +167,7 @@ class Translate
      */
     public function getPreferredTranslation($translations)
     {
-        assert(is_array($translations));
+        Assert::isArray($translations);
 
         // look up translation of tag in the selected language
         $selected_language = $this->language->getLanguage();
@@ -387,7 +388,7 @@ class Translate
     private function readDictionaryJSON(string $filename): array
     {
         $definitionFile = $filename . '.definition.json';
-        assert(file_exists($definitionFile));
+        Assert::true(file_exists($definitionFile));
 
         $fileContent = file_get_contents($definitionFile);
         $lang = json_decode($fileContent, true);
@@ -419,7 +420,7 @@ class Translate
     private function readDictionaryPHP(string $filename): array
     {
         $phpFile = $filename . '.php';
-        assert(file_exists($phpFile));
+        Assert::true(file_exists($phpFile));
 
         $lang = null;
         include($phpFile);
diff --git a/lib/SimpleSAML/Logger.php b/lib/SimpleSAML/Logger.php
index c7a86e0f3fb3d630a3d12beb246900f761dac4f6..5556e22a1b72bb7f95d4f652914fca59128c4d56 100644
--- a/lib/SimpleSAML/Logger.php
+++ b/lib/SimpleSAML/Logger.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace SimpleSAML;
 
 use SimpleSAML\Logger\ErrorLogLoggingHandler;
+use Webmozart\Assert\Assert;
 
 /**
  * The main logger class for SimpleSAMLphp.
@@ -357,7 +358,7 @@ class Logger
      */
     public static function maskErrors($mask)
     {
-        assert(is_int($mask));
+        Assert::integer($mask);
 
         $currentEnabled = error_reporting();
         self::$logLevelStack[] = [$currentEnabled, self::$logMask];
@@ -423,7 +424,7 @@ class Logger
 
         // get the configuration
         $config = Configuration::getInstance();
-        assert($config instanceof Configuration);
+        Assert::isInstanceOf($config, Configuration::class);
 
         // setting minimum log_level
         self::$logLevel = $config->getInteger('logging.level', self::INFO);
diff --git a/lib/SimpleSAML/Memcache.php b/lib/SimpleSAML/Memcache.php
index 98684debd6d973268df9cb2c2d03987ca573ba99..84b5b83f48be6a7b9a52349a54c1ccc7e784b428 100644
--- a/lib/SimpleSAML/Memcache.php
+++ b/lib/SimpleSAML/Memcache.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace SimpleSAML;
 
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * This file implements functions to read and write to a group of memcache
@@ -186,7 +187,7 @@ class Memcache
      */
     public static function delete($key)
     {
-        assert(is_string($key));
+        Assert::string($key);
         Logger::debug("deleting key $key from memcache");
 
         // store this object to all groups of memcache servers
@@ -429,7 +430,7 @@ class Memcache
     {
         // get the configuration instance
         $config = Configuration::getInstance();
-        assert($config instanceof Configuration);
+        Assert::isInstanceOf($config, Configuration::class);
 
         // get the expire-value from the configuration
         $expire = $config->getInteger('memcache_store.expires', 0);
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php
index 98548235911f63fb266a46dfb9ff32ed8e8f0bcb..c284deec700137d53f31faf19d3a95d21fed8d48 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php
@@ -12,6 +12,7 @@ use SimpleSAML\Logger;
 use SimpleSAML\Utils;
 use SimpleSAML\Error\MetadataNotFound;
 use SimpleSAML\Utils\ClearableState;
+use Webmozart\Assert\Assert;
 
 /**
  * This file defines a class for metadata handling.
@@ -107,7 +108,7 @@ class MetaDataStorageHandler implements \SimpleSAML\Utils\ClearableState
 
         // get the configuration
         $config = Configuration::getInstance();
-        assert($config instanceof Configuration);
+        Assert::isInstanceOf($config, Configuration::class);
 
         $baseurl = Utils\HTTP::getSelfURLHost() . $config->getBasePath();
 
@@ -150,7 +151,7 @@ class MetaDataStorageHandler implements \SimpleSAML\Utils\ClearableState
      */
     public function getList($set = 'saml20-idp-remote', $showExpired = false)
     {
-        assert(is_string($set));
+        Assert::string($set);
 
         $result = [];
 
@@ -205,7 +206,7 @@ class MetaDataStorageHandler implements \SimpleSAML\Utils\ClearableState
      */
     public function getMetaDataCurrentEntityID($set, $type = 'entityid')
     {
-        assert(is_string($set));
+        Assert::string($set);
 
         // first we look for the hostname/path combination
         $currenthostwithpath = Utils\HTTP::getSelfHostWithPath(); // sp.example.org/university
@@ -312,13 +313,13 @@ class MetaDataStorageHandler implements \SimpleSAML\Utils\ClearableState
      */
     public function getMetaData($index, $set)
     {
-        assert(is_string($set));
+        Assert::string($set);
 
         if ($index === null) {
             $index = $this->getMetaDataCurrentEntityID($set, 'metaindex');
         }
 
-        assert(is_string($index));
+        Assert::string($index);
 
         foreach ($this->sources as $source) {
             $metadata = $source->getMetaData($index, $set);
@@ -335,7 +336,7 @@ class MetaDataStorageHandler implements \SimpleSAML\Utils\ClearableState
 
                 $metadata['metadata-index'] = $index;
                 $metadata['metadata-set'] = $set;
-                assert(array_key_exists('entityid', $metadata));
+                Assert::keyExists($metadata, 'entityid');
                 return $metadata;
             }
         }
@@ -357,8 +358,8 @@ class MetaDataStorageHandler implements \SimpleSAML\Utils\ClearableState
      */
     public function getMetaDataConfig($entityId, $set)
     {
-        assert(is_string($entityId));
-        assert(is_string($set));
+        Assert::string($entityId);
+        Assert::string($set);
 
         $metadata = $this->getMetaData($entityId, $set);
         return Configuration::loadFromArray($metadata, $set . '/' . var_export($entityId, true));
@@ -376,8 +377,8 @@ class MetaDataStorageHandler implements \SimpleSAML\Utils\ClearableState
      */
     public function getMetaDataConfigForSha1($sha1, $set)
     {
-        assert(is_string($sha1));
-        assert(is_string($set));
+        Assert::string($sha1);
+        Assert::string($set);
 
         $result = [];
 
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatFile.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatFile.php
index 45d8e61fae35659d3cd3d9255ce9e028857bb1b2..fb123fcb43046eb4c32af62a3cb0c2b34c2c6e78 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatFile.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatFile.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace SimpleSAML\Metadata;
 
 use SimpleSAML\Configuration;
+use Webmozart\Assert\Assert;
 
 /**
  * This file defines a flat file metadata source.
@@ -45,7 +46,7 @@ class MetaDataStorageHandlerFlatFile extends MetaDataStorageSource
      */
     protected function __construct($config)
     {
-        assert(is_array($config));
+        Assert::isArray($config);
 
         // get the configuration
         $globalConfig = Configuration::getInstance();
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php
index 841f7282dedac466fc6cfe99c33c703123c7b2db..d6c08b0e9cdda475d5d87531603b794f65c8d572 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Metadata;
 
 use SimpleSAML\Database;
 use SimpleSAML\Error;
+use Webmozart\Assert\Assert;
 
 /**
  * Class for handling metadata files stored in a database.
@@ -63,7 +64,7 @@ class MetaDataStorageHandlerPdo extends MetaDataStorageSource
      */
     public function __construct($config)
     {
-        assert(is_array($config));
+        Assert::isArray($config);
 
         $this->db = Database::getInstance();
     }
@@ -122,7 +123,7 @@ class MetaDataStorageHandlerPdo extends MetaDataStorageSource
      */
     public function getMetadataSet($set)
     {
-        assert(is_string($set));
+        Assert::string($set);
 
         if (array_key_exists($set, $this->cachedMetadata)) {
             return $this->cachedMetadata[$set];
@@ -153,8 +154,8 @@ class MetaDataStorageHandlerPdo extends MetaDataStorageSource
      */
     public function getMetaData($entityId, $set)
     {
-        assert(is_string($entityId));
-        assert(is_string($set));
+        Assert::string($entityId);
+        Assert::string($set);
 
         // validate the metadata set is valid
         if (!in_array($set, $this->supportedSets, true)) {
@@ -227,9 +228,9 @@ class MetaDataStorageHandlerPdo extends MetaDataStorageSource
      */
     public function addEntry($index, $set, $entityData)
     {
-        assert(is_string($index));
-        assert(is_string($set));
-        assert(is_array($entityData));
+        Assert::string($index);
+        Assert::string($set);
+        assert::isArray($entityData);
 
         if (!in_array($set, $this->supportedSets, true)) {
             return false;
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php
index c2dd6b0f1d8caf276a100ed7ae64ae747ca9d7ce..b797b1da76a7a2507f952ff34fb0e391888991a8 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php
@@ -7,6 +7,7 @@ namespace SimpleSAML\Metadata;
 use SimpleSAML\Configuration;
 use SimpleSAML\Logger;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Class for handling metadata files in serialized format.
@@ -41,7 +42,7 @@ class MetaDataStorageHandlerSerialize extends MetaDataStorageSource
      */
     public function __construct($config)
     {
-        assert(is_array($config));
+        Assert::isArray($config);
 
         $globalConfig = Configuration::getInstance();
 
@@ -121,7 +122,7 @@ class MetaDataStorageHandlerSerialize extends MetaDataStorageSource
      */
     public function getMetadataSet($set)
     {
-        assert(is_string($set));
+        Assert::string($set);
 
         $ret = [];
 
@@ -176,8 +177,8 @@ class MetaDataStorageHandlerSerialize extends MetaDataStorageSource
      */
     public function getMetaData($entityId, $set)
     {
-        assert(is_string($entityId));
-        assert(is_string($set));
+        Assert::string($entityId);
+        Assert::string($set);
 
         $filePath = $this->getMetadataPath($entityId, $set);
 
@@ -220,9 +221,9 @@ class MetaDataStorageHandlerSerialize extends MetaDataStorageSource
      */
     public function saveMetadata($entityId, $set, $metadata)
     {
-        assert(is_string($entityId));
-        assert(is_string($set));
-        assert(is_array($metadata));
+        Assert::string($entityId);
+        Assert::string($set);
+        Assert::isArray($metadata);
 
         $filePath = $this->getMetadataPath($entityId, $set);
         $newPath = $filePath . '.new';
@@ -272,8 +273,8 @@ class MetaDataStorageHandlerSerialize extends MetaDataStorageSource
      */
     public function deleteMetadata($entityId, $set)
     {
-        assert(is_string($entityId));
-        assert(is_string($set));
+        Assert::string($entityId);
+        Assert::string($set);
 
         $filePath = $this->getMetadataPath($entityId, $set);
 
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageSource.php b/lib/SimpleSAML/Metadata/MetaDataStorageSource.php
index 7a0b4be4bff3134e9fc6da7a637c0367461c9ca2..481572288dca6fe0b82e4912c749296be6db93b2 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageSource.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageSource.php
@@ -7,6 +7,7 @@ namespace SimpleSAML\Metadata;
 use SimpleSAML\Error;
 use SimpleSAML\Module;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * This abstract class defines an interface for metadata storage sources.
@@ -36,7 +37,7 @@ abstract class MetaDataStorageSource
      */
     public static function parseSources($sourcesConfig)
     {
-        assert(is_array($sourcesConfig));
+        Assert::isArray($sourcesConfig);
 
         $sources = [];
 
@@ -65,7 +66,7 @@ abstract class MetaDataStorageSource
      */
     public static function getSource($sourceConfig)
     {
-        assert(is_array($sourceConfig));
+        Assert::isArray($sourceConfig);
 
         if (array_key_exists('type', $sourceConfig)) {
             $type = $sourceConfig['type'];
@@ -238,8 +239,8 @@ abstract class MetaDataStorageSource
     public function getMetaData($index, $set)
     {
 
-        assert(is_string($index));
-        assert(isset($set));
+        Assert::string($index);
+        Assert::notNull($set);
 
         $metadataSet = $this->getMetadataSet($set);
 
@@ -299,7 +300,7 @@ abstract class MetaDataStorageSource
      */
     protected function lookupIndexFromEntityId($entityId, array $metadataSet)
     {
-        assert(is_string($entityId));
+        Assert::string($entityId);
 
         // check for hostname
         $currentHost = Utils\HTTP::getSelfHost(); // sp.example.org
@@ -359,8 +360,8 @@ abstract class MetaDataStorageSource
      */
     protected function updateEntityID($metadataSet, $entityId, array $metadataEntry)
     {
-        assert(is_string($metadataSet));
-        assert(is_string($entityId));
+        Assert::string($metadataSet);
+        Assert::string($entityId);
 
         $modifiedMetadataEntry = $metadataEntry;
 
diff --git a/lib/SimpleSAML/Metadata/SAMLBuilder.php b/lib/SimpleSAML/Metadata/SAMLBuilder.php
index e90df10dab41aa8987a23e63785066fc00b34bce..b066db7427e06b15e67cfb2a981316366c7f872f 100644
--- a/lib/SimpleSAML/Metadata/SAMLBuilder.php
+++ b/lib/SimpleSAML/Metadata/SAMLBuilder.php
@@ -28,6 +28,7 @@ use SimpleSAML\Configuration;
 use SimpleSAML\Logger;
 use SimpleSAML\Module\adfs\SAML2\XML\fed\SecurityTokenServiceType;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Class for generating SAML 2.0 metadata from SimpleSAMLphp metadata arrays.
@@ -74,7 +75,7 @@ class SAMLBuilder
      */
     public function __construct($entityId, $maxCache = null, $maxDuration = null)
     {
-        assert(is_string($entityId));
+        Assert::string($entityId);
 
         $this->maxCache = $maxCache;
         $this->maxDuration = $maxDuration;
@@ -130,7 +131,7 @@ class SAMLBuilder
      */
     public function getEntityDescriptorText($formatted = true)
     {
-        assert(is_bool($formatted));
+        Assert::boolean($formatted);
 
         $xml = $this->getEntityDescriptor();
         if ($formatted) {
@@ -149,9 +150,9 @@ class SAMLBuilder
      */
     public function addSecurityTokenServiceType($metadata)
     {
-        assert(is_array($metadata));
-        assert(isset($metadata['entityid']));
-        assert(isset($metadata['metadata-set']));
+        Assert::isArray($metadata);
+        Assert::notNull($metadata['entityid']);
+        Assert::notNull($metadata['metadata-set']);
 
         $metadata = Configuration::loadFromArray($metadata, $metadata['entityid']);
         $defaultEndpoint = $metadata->getDefaultEndpoint('SingleSignOnService');
@@ -478,8 +479,8 @@ class SAMLBuilder
      */
     public function addMetadata($set, $metadata)
     {
-        assert(is_string($set));
-        assert(is_array($metadata));
+        Assert::string($set);
+        Assert::isArray($metadata);
 
         $this->setExpiration($metadata);
 
@@ -514,10 +515,10 @@ class SAMLBuilder
      */
     public function addMetadataSP20($metadata, $protocols = [Constants::NS_SAMLP])
     {
-        assert(is_array($metadata));
-        assert(is_array($protocols));
-        assert(isset($metadata['entityid']));
-        assert(isset($metadata['metadata-set']));
+        Assert::isArray($metadata);
+        Assert::isArray($protocols);
+        Assert::notNull($metadata['entityid']);
+        Assert::notNull($metadata['metadata-set']);
 
         $metadata = Configuration::loadFromArray($metadata, $metadata['entityid']);
 
@@ -571,9 +572,9 @@ class SAMLBuilder
      */
     public function addMetadataIdP20($metadata)
     {
-        assert(is_array($metadata));
-        assert(isset($metadata['entityid']));
-        assert(isset($metadata['metadata-set']));
+        Assert::isArray($metadata);
+        Assert::notNull($metadata['entityid']);
+        Assert::notNull($metadata['metadata-set']);
 
         $metadata = Configuration::loadFromArray($metadata, $metadata['entityid']);
 
@@ -621,9 +622,9 @@ class SAMLBuilder
      */
     public function addMetadataSP11($metadata)
     {
-        assert(is_array($metadata));
-        assert(isset($metadata['entityid']));
-        assert(isset($metadata['metadata-set']));
+        Assert::isArray($metadata);
+        Assert::notNull($metadata['entityid']);
+        Assert::notNull($metadata['metadata-set']);
 
         $metadata = Configuration::loadFromArray($metadata, $metadata['entityid']);
 
@@ -662,9 +663,9 @@ class SAMLBuilder
      */
     public function addMetadataIdP11($metadata)
     {
-        assert(is_array($metadata));
-        assert(isset($metadata['entityid']));
-        assert(isset($metadata['metadata-set']));
+        Assert::isArray($metadata);
+        Assert::notNull($metadata['entityid']);
+        Assert::notNull($metadata['metadata-set']);
 
         $metadata = Configuration::loadFromArray($metadata, $metadata['entityid']);
 
@@ -695,8 +696,8 @@ class SAMLBuilder
      */
     public function addAttributeAuthority(array $metadata)
     {
-        assert(isset($metadata['entityid']));
-        assert(isset($metadata['metadata-set']));
+        Assert::notNull($metadata['entityid']);
+        Assert::notNull($metadata['metadata-set']);
 
         $metadata = Configuration::loadFromArray($metadata, $metadata['entityid']);
 
@@ -734,9 +735,9 @@ class SAMLBuilder
      */
     public function addContact($type, $details)
     {
-        assert(is_string($type));
-        assert(is_array($details));
-        assert(in_array($type, ['technical', 'support', 'administrative', 'billing', 'other'], true));
+        Assert::string($type);
+        Assert::isArray($details);
+        Assert::oneOf($type, ['technical', 'support', 'administrative', 'billing', 'other']);
 
         // TODO: remove this check as soon as getContact() is called always before calling this function
         $details = Utils\Config\Metadata::getContact($details);
@@ -792,7 +793,7 @@ class SAMLBuilder
      */
     private function addX509KeyDescriptor(RoleDescriptor $rd, string $use, string $x509data)
     {
-        assert(in_array($use, ['encryption', 'signing'], true));
+        Assert::oneOf($use, ['encryption', 'signing']);
 
         $keyDescriptor = \SAML2\Utils::createKeyDescriptor($x509data);
         $keyDescriptor->setUse($use);
diff --git a/lib/SimpleSAML/Metadata/SAMLParser.php b/lib/SimpleSAML/Metadata/SAMLParser.php
index 73d64c9419d89e5eab830f2f58b9dd660eca6545..45880788020fcbe58ba310b0c698f51f79c08c94 100644
--- a/lib/SimpleSAML/Metadata/SAMLParser.php
+++ b/lib/SimpleSAML/Metadata/SAMLParser.php
@@ -37,6 +37,7 @@ use SAML2\XML\saml\Attribute;
 use SAML2\XML\shibmd\Scope;
 use SimpleSAML\Logger;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * This is class for parsing of SAML 1.x and SAML 2.0 metadata.
@@ -287,7 +288,7 @@ class SAMLParser
      */
     public static function parseDocument($document)
     {
-        assert($document instanceof DOMDocument);
+        Assert::isInstanceOf($document, DOMDocument::class);
 
         $entityElement = self::findEntityDescriptor($document);
 
@@ -305,7 +306,7 @@ class SAMLParser
      */
     public static function parseElement($entityElement)
     {
-        assert($entityElement instanceof EntityDescriptor);
+        Assert::isInstanceOf($entityElement, EntityDescriptor::class);
         return new SAMLParser($entityElement, null, []);
     }
 
@@ -412,7 +413,7 @@ class SAMLParser
             return $ret;
         }
 
-        assert($element instanceof EntitiesDescriptor);
+        Assert::isInstanceOf($element, EntitiesDescriptor::class);
 
         $extensions = self::processExtensions($element, $parentExtensions);
         $expTime = self::getExpireTime($element, $maxExpireTime);
@@ -503,8 +504,8 @@ class SAMLParser
      */
     private function addExtensions(array &$metadata, array $roleDescriptor)
     {
-        assert(array_key_exists('scope', $roleDescriptor));
-        assert(array_key_exists('tags', $roleDescriptor));
+        Assert::keyExists($roleDescriptor, 'scope');
+        Assert::keyExists($roleDescriptor, 'tags');
 
         $scopes = array_merge($this->scopes, array_diff($roleDescriptor['scope'], $this->scopes));
         if (!empty($scopes)) {
@@ -1004,7 +1005,7 @@ class SAMLParser
         AttributeAuthorityDescriptor $element,
         $expireTime
     ) {
-        assert($expireTime === null || is_int($expireTime));
+        Assert::nullOrInteger($expireTime);
 
         $aad = self::parseRoleDescriptorType($element, $expireTime);
         $aad['entityid'] = $this->getEntityId();
@@ -1450,7 +1451,7 @@ class SAMLParser
     public function validateSignature($certificates)
     {
         foreach ($certificates as $cert) {
-            assert(is_string($cert));
+            Assert::string($cert);
             $certFile = Utils\Config::getCertPath($cert);
             if (!file_exists($certFile)) {
                 throw new \Exception(
@@ -1525,7 +1526,7 @@ class SAMLParser
      */
     public function validateFingerprint($fingerprint, $algorithm)
     {
-        assert(is_string($fingerprint));
+        Assert::string($fingerprint);
 
         $fingerprint = strtolower(str_replace(":", "", $fingerprint));
 
diff --git a/lib/SimpleSAML/Metadata/Sources/MDQ.php b/lib/SimpleSAML/Metadata/Sources/MDQ.php
index 4b3a3adb7ef2ddc46da6167609e1c58570a409f5..889b429e086f68d9f86883048494cb085f0b4b07 100644
--- a/lib/SimpleSAML/Metadata/Sources/MDQ.php
+++ b/lib/SimpleSAML/Metadata/Sources/MDQ.php
@@ -10,6 +10,7 @@ use SimpleSAML\Error;
 use SimpleSAML\Logger;
 use SimpleSAML\Metadata\SAMLParser;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * This class implements SAML Metadata Query Protocol
@@ -76,7 +77,7 @@ class MDQ extends \SimpleSAML\Metadata\MetaDataStorageSource
      */
     protected function __construct($config)
     {
-        assert(is_array($config));
+        Assert::isArray($config);
 
         if (!array_key_exists('server', $config)) {
             throw new \Exception(__CLASS__ . ": the 'server' configuration option is not set.");
@@ -134,8 +135,8 @@ class MDQ extends \SimpleSAML\Metadata\MetaDataStorageSource
      */
     private function getCacheFilename($set, $entityId)
     {
-        assert(is_string($set));
-        assert(is_string($entityId));
+        Assert::string($set);
+        Assert::string($entityId);
 
         if ($this->cacheDir === null) {
             throw new Error\ConfigurationError("Missing cache directory configuration.");
@@ -280,8 +281,8 @@ class MDQ extends \SimpleSAML\Metadata\MetaDataStorageSource
      */
     public function getMetaData($index, $set)
     {
-        assert(is_string($index));
-        assert(is_string($set));
+        Assert::string($index);
+        Assert::string($set);
 
         Logger::info(__CLASS__ . ': loading metadata entity [' . $index . '] from [' . $set . ']');
 
diff --git a/lib/SimpleSAML/Module.php b/lib/SimpleSAML/Module.php
index 88692e246174b77fa687edadff4da7b881d04111..674312c3054003a404f6ed3586df5bbfe3d9eb2c 100644
--- a/lib/SimpleSAML/Module.php
+++ b/lib/SimpleSAML/Module.php
@@ -13,6 +13,7 @@ use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpFoundation\ResponseHeaderBag;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Webmozart\Assert\Assert;
 
 /**
  * Helper class for accessing information about modules.
@@ -136,7 +137,7 @@ class Module
         }
 
         $url = $request->server->get('PATH_INFO');
-        assert(substr($url, 0, 1) === '/');
+        Assert::same(substr($url, 0, 1), '/');
 
         /* clear the PATH_INFO option, so that a script can detect whether it is called with anything following the
          *'.php'-ending.
@@ -423,9 +424,9 @@ class Module
      */
     public static function resolveClass($id, $type, $subclass = null)
     {
-        assert(is_string($id));
-        assert(is_string($type));
-        assert(is_string($subclass) || $subclass === null);
+        Assert::string($id);
+        Assert::string($type);
+        Assert::nullOrString($subclass);
 
         $tmp = explode(':', $id, 2);
         if (count($tmp) === 1) {
@@ -475,8 +476,8 @@ class Module
      */
     public static function getModuleURL($resource, array $parameters = [])
     {
-        assert(is_string($resource));
-        assert($resource[0] !== '/');
+        Assert::string($resource);
+        Assert::notSame($resource[0], '/');
 
         $url = Utils\HTTP::getBaseURL() . 'module.php/' . $resource;
         if (!empty($parameters)) {
@@ -537,7 +538,7 @@ class Module
      */
     public static function callHooks($hook, &$data = null)
     {
-        assert(is_string($hook));
+        Assert::string($hook);
 
         $modules = self::getModules();
         $config = Configuration::getOptionalConfig()->getArray('module.enable', []);
diff --git a/lib/SimpleSAML/Session.php b/lib/SimpleSAML/Session.php
index 5d6b6f683bc906a2a32af0d8ddc2cf0994a1b042..fdb69c9614f4a7bbd9355667e02ee0158601c2c4 100644
--- a/lib/SimpleSAML/Session.php
+++ b/lib/SimpleSAML/Session.php
@@ -7,6 +7,7 @@ namespace SimpleSAML;
 use SAML2\XML\saml\AttributeValue;
 use SimpleSAML\Error;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * The Session class holds information about a user session, and everything attached to it.
@@ -324,7 +325,7 @@ class Session implements \Serializable, Utils\ClearableState
      */
     public static function getSession($sessionId = null)
     {
-        assert(is_string($sessionId) || $sessionId === null);
+        Assert::nullOrString($sessionId);
 
         $sh = SessionHandler::getSessionHandler();
 
@@ -347,7 +348,7 @@ class Session implements \Serializable, Utils\ClearableState
             return null;
         }
 
-        assert($session instanceof self);
+        Assert::isInstanceOf($session, self::class);
 
         if ($checkToken) {
             $globalConfig = Configuration::getInstance();
@@ -426,7 +427,7 @@ class Session implements \Serializable, Utils\ClearableState
      */
     public static function createSession($sessionId)
     {
-        assert(is_string($sessionId));
+        Assert::string($sessionId);
         self::$sessions[$sessionId] = null;
     }
 
@@ -567,7 +568,7 @@ class Session implements \Serializable, Utils\ClearableState
      */
     public function setRememberMeExpire($expire = null)
     {
-        assert(is_int($expire) || $expire === null);
+        Assert::nullOrInteger($expire);
 
         if ($expire === null) {
             $expire = time() + self::$config->getInteger('session.rememberme.lifetime', 14 * 86400);
@@ -591,8 +592,8 @@ class Session implements \Serializable, Utils\ClearableState
      */
     public function doLogin($authority, array $data = null)
     {
-        assert(is_string($authority));
-        assert(is_array($data) || $data === null);
+        Assert::string($authority);
+        Assert::nullOrArray($data);
 
         Logger::debug('Session: doLogin("' . $authority . '")');
 
@@ -716,7 +717,7 @@ class Session implements \Serializable, Utils\ClearableState
      */
     private function callLogoutHandlers(string $authority)
     {
-        assert(isset($this->authData[$authority]));
+        Assert::notNull($this->authData[$authority]);
 
         if (empty($this->authData[$authority]['LogoutHandlers'])) {
             return;
@@ -751,7 +752,7 @@ class Session implements \Serializable, Utils\ClearableState
      */
     public function isValid($authority)
     {
-        assert(is_string($authority));
+        Assert::string($authority);
 
         if (!isset($this->authData[$authority])) {
             Logger::debug(
@@ -779,7 +780,7 @@ class Session implements \Serializable, Utils\ClearableState
      */
     public function updateSessionCookies($params = null)
     {
-        assert(is_null($params) || is_array($params));
+        Assert::nullOrArray($params);
 
         $sessionHandler = SessionHandler::getSessionHandler();
 
@@ -807,8 +808,8 @@ class Session implements \Serializable, Utils\ClearableState
      */
     public function setAuthorityExpire($authority, $expire = null)
     {
-        assert(isset($this->authData[$authority]));
-        assert(is_int($expire) || $expire === null);
+        Assert::notNull($this->authData[$authority]);
+        Assert::nullOrInteger($expire);
 
         $this->markDirty();
 
@@ -831,7 +832,7 @@ class Session implements \Serializable, Utils\ClearableState
      */
     public function registerLogoutHandler($authority, $classname, $functionname)
     {
-        assert(isset($this->authData[$authority]));
+        Assert::notNull($this->authData[$authority]);
 
         $logout_handler = [$classname, $functionname];
 
@@ -857,8 +858,8 @@ class Session implements \Serializable, Utils\ClearableState
      */
     public function deleteData($type, $id)
     {
-        assert(is_string($type));
-        assert(is_string($id));
+        Assert::string($type);
+        Assert::string($id);
 
         if (!array_key_exists($type, $this->dataStore)) {
             return;
@@ -887,9 +888,9 @@ class Session implements \Serializable, Utils\ClearableState
      */
     public function setData($type, $id, $data, $timeout = null)
     {
-        assert(is_string($type));
-        assert(is_string($id));
-        assert(is_int($timeout) || $timeout === null || $timeout === self::DATA_TIMEOUT_SESSION_END);
+        Assert::string($type);
+        Assert::string($id);
+        Assert::true(is_int($timeout) || $timeout === null || $timeout === self::DATA_TIMEOUT_SESSION_END);
 
         if ($timeout === null) {
             // use the default timeout
@@ -962,8 +963,8 @@ class Session implements \Serializable, Utils\ClearableState
      */
     public function getData($type, $id)
     {
-        assert(is_string($type));
-        assert($id === null || is_string($id));
+        Assert::string($type);
+        Assert::nullOrString($id);
 
         if ($id === null) {
             return null;
@@ -995,7 +996,7 @@ class Session implements \Serializable, Utils\ClearableState
      */
     public function getDataOfType($type)
     {
-        assert(is_string($type));
+        Assert::string($type);
 
         if (!array_key_exists($type, $this->dataStore)) {
             return [];
@@ -1018,7 +1019,7 @@ class Session implements \Serializable, Utils\ClearableState
      */
     public function getAuthState($authority)
     {
-        assert(is_string($authority));
+        Assert::string($authority);
 
         if (!isset($this->authData[$authority])) {
             return null;
@@ -1051,9 +1052,9 @@ class Session implements \Serializable, Utils\ClearableState
      */
     public function addAssociation($idp, array $association)
     {
-        assert(is_string($idp));
-        assert(isset($association['id']));
-        assert(isset($association['Handler']));
+        Assert::string($idp);
+        Assert::notNull($association['id']);
+        Assert::notNull($association['Handler']);
 
         if (!isset($this->associations)) {
             $this->associations = [];
@@ -1079,7 +1080,7 @@ class Session implements \Serializable, Utils\ClearableState
      */
     public function getAssociations($idp)
     {
-        assert(is_string($idp));
+        Assert::string($idp);
 
         if (!isset($this->associations)) {
             $this->associations = [];
@@ -1114,8 +1115,8 @@ class Session implements \Serializable, Utils\ClearableState
      */
     public function terminateAssociation($idp, $associationId)
     {
-        assert(is_string($idp));
-        assert(is_string($associationId));
+        Assert::string($idp);
+        Assert::string($associationId);
 
         if (!isset($this->associations)) {
             return;
@@ -1140,8 +1141,8 @@ class Session implements \Serializable, Utils\ClearableState
      */
     public function getAuthData($authority, $name)
     {
-        assert(is_string($authority));
-        assert(is_string($name));
+        Assert::string($authority);
+        Assert::string($name);
 
         if (!isset($this->authData[$authority][$name])) {
             return null;
diff --git a/lib/SimpleSAML/SessionHandlerCookie.php b/lib/SimpleSAML/SessionHandlerCookie.php
index 3cef005df778c43a81c4f34c81e18ce20cc27bd9..02c3de3f53c2efc79919acc2edde4712a57c7ee4 100644
--- a/lib/SimpleSAML/SessionHandlerCookie.php
+++ b/lib/SimpleSAML/SessionHandlerCookie.php
@@ -16,6 +16,7 @@ declare(strict_types=1);
 namespace SimpleSAML;
 
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 abstract class SessionHandlerCookie extends SessionHandler
 {
@@ -157,8 +158,8 @@ abstract class SessionHandlerCookie extends SessionHandler
      */
     public function setCookie($sessionName, $sessionID, array $cookieParams = null)
     {
-        assert(is_string($sessionName));
-        assert(is_string($sessionID) || $sessionID === null);
+        Assert::string($sessionName);
+        Assert::nullOrString($sessionID);
 
         if ($cookieParams !== null) {
             $params = array_merge($this->getCookieParams(), $cookieParams);
diff --git a/lib/SimpleSAML/SessionHandlerPHP.php b/lib/SimpleSAML/SessionHandlerPHP.php
index c1832f20a6e1a76583468d410c0958fbc06c086e..1952946d3e913e55bf8e76464cee3e4141e94b11 100644
--- a/lib/SimpleSAML/SessionHandlerPHP.php
+++ b/lib/SimpleSAML/SessionHandlerPHP.php
@@ -15,6 +15,7 @@ namespace SimpleSAML;
 
 use SimpleSAML\Error;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 class SessionHandlerPHP extends SessionHandler
 {
@@ -251,7 +252,7 @@ class SessionHandlerPHP extends SessionHandler
      */
     public function loadSession($sessionId = null)
     {
-        assert(is_string($sessionId) || $sessionId === null);
+        Assert::nullOrString($sessionId);
 
         if ($sessionId !== null) {
             if (session_id() === '' && !(version_compare(PHP_VERSION, '7.2', 'ge') && headers_sent())) {
@@ -275,7 +276,7 @@ class SessionHandlerPHP extends SessionHandler
         }
 
         $session = $_SESSION['SimpleSAMLphp_SESSION'];
-        assert(is_string($session));
+        Assert::string($session);
 
         $session = unserialize($session);
 
diff --git a/lib/SimpleSAML/SessionHandlerStore.php b/lib/SimpleSAML/SessionHandlerStore.php
index 1169fab11035e1bfdffac47d1a09c312e2ce1ff7..4f459fa847fcbca10df7f0bcb526d2e8b6a0ba5f 100644
--- a/lib/SimpleSAML/SessionHandlerStore.php
+++ b/lib/SimpleSAML/SessionHandlerStore.php
@@ -10,6 +10,8 @@ declare(strict_types=1);
 
 namespace SimpleSAML;
 
+use Webmozart\Assert\Assert;
+
 class SessionHandlerStore extends SessionHandlerCookie
 {
     /**
@@ -42,7 +44,7 @@ class SessionHandlerStore extends SessionHandlerCookie
      */
     public function loadSession($sessionId = null)
     {
-        assert(is_string($sessionId) || $sessionId === null);
+        Assert::nullOrString($sessionId);
 
         if ($sessionId === null) {
             $sessionId = $this->getCookieSessionId();
@@ -54,7 +56,7 @@ class SessionHandlerStore extends SessionHandlerCookie
 
         $session = $this->store->get('session', $sessionId);
         if ($session !== null) {
-            assert($session instanceof Session);
+            Assert::isInstanceOf($session, Session::class);
             return $session;
         }
 
diff --git a/lib/SimpleSAML/Stats.php b/lib/SimpleSAML/Stats.php
index caa0afe699f1ae91eb3c38fa74771ddfadf6d94e..281e35bb6d9ba8db5eed3e0c8ba548da4e87767f 100644
--- a/lib/SimpleSAML/Stats.php
+++ b/lib/SimpleSAML/Stats.php
@@ -4,6 +4,8 @@ declare(strict_types=1);
 
 namespace SimpleSAML;
 
+use Webmozart\Assert\Assert;
+
 /**
  * Statistics handler class.
  *
@@ -74,10 +76,10 @@ class Stats
      */
     public static function log($event, array $data = [])
     {
-        assert(is_string($event));
-        assert(!isset($data['op']));
-        assert(!isset($data['time']));
-        assert(!isset($data['_id']));
+        Assert::string($event);
+        Assert::keyNotExists($data, 'op');
+        Assert::keyNotExists($data, 'time');
+        Assert::keyNotExists($data, '_id');
 
         if (!self::$initialized) {
             self::initOutputs();
diff --git a/lib/SimpleSAML/Store/Memcache.php b/lib/SimpleSAML/Store/Memcache.php
index e674ae0fdb746b1b415b0e2ae01d53fce8d29e4e..d704cf55938c17666e5eef56cdc3db9f13f05f73 100644
--- a/lib/SimpleSAML/Store/Memcache.php
+++ b/lib/SimpleSAML/Store/Memcache.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Store;
 
 use SimpleSAML\Configuration;
 use SimpleSAML\Store;
+use Webmozart\Assert\Assert;
 
 /**
  * A memcache based data store.
@@ -41,8 +42,8 @@ class Memcache extends Store
      */
     public function get($type, $key)
     {
-        assert(is_string($type));
-        assert(is_string($key));
+        Assert::string($type);
+        Assert::string($key);
 
         return \SimpleSAML\Memcache::get($this->prefix . '.' . $type . '.' . $key);
     }
@@ -59,9 +60,9 @@ class Memcache extends Store
      */
     public function set($type, $key, $value, $expire = null)
     {
-        assert(is_string($type));
-        assert(is_string($key));
-        assert($expire === null || (is_int($expire) && $expire > 2592000));
+        Assert::string($type);
+        Assert::string($key);
+        Assert::nullOrGreaterThan($expire, 2592000);
 
         if ($expire === null) {
             $expire = 0;
@@ -80,8 +81,8 @@ class Memcache extends Store
      */
     public function delete($type, $key)
     {
-        assert(is_string($type));
-        assert(is_string($key));
+        Assert::string($type);
+        Assert::string($key);
 
         \SimpleSAML\Memcache::delete($this->prefix . '.' . $type . '.' . $key);
     }
diff --git a/lib/SimpleSAML/Store/Redis.php b/lib/SimpleSAML/Store/Redis.php
index acf766e35db88cdbcafd170e70ce9c99d8c23fba..f502977bc5dcc4bc58e0b0926773ca39b5c67e68 100644
--- a/lib/SimpleSAML/Store/Redis.php
+++ b/lib/SimpleSAML/Store/Redis.php
@@ -8,6 +8,7 @@ use Predis\Client;
 use SimpleSAML\Configuration;
 use SimpleSAML\Error;
 use SimpleSAML\Store;
+use Webmozart\Assert\Assert;
 
 /**
  * A data store using Redis to keep the data.
@@ -23,14 +24,14 @@ class Redis extends Store
      * Initialize the Redis data store.
      * @param \Predis\Client|null $redis
      */
-    public function __construct($redis = null)
+    public function __construct(Client $redis = null)
     {
-        assert($redis === null || is_subclass_of($redis, Client::class));
-
         if (!class_exists(Client::class)) {
             throw new Error\CriticalConfigurationError('predis/predis is not available.');
         }
 
+        Assert::nullOrIsInstanceOf($redis, \Predis\Client::class);
+
         if ($redis === null) {
             $config = Configuration::getInstance();
 
@@ -78,8 +79,8 @@ class Redis extends Store
      */
     public function get($type, $key)
     {
-        assert(is_string($type));
-        assert(is_string($key));
+        Assert::string($type);
+        Assert::string($key);
 
         $result = $this->redis->get("{$type}.{$key}");
 
@@ -102,9 +103,9 @@ class Redis extends Store
      */
     public function set($type, $key, $value, $expire = null)
     {
-        assert(is_string($type));
-        assert(is_string($key));
-        assert($expire === null || (is_int($expire) && $expire > 2592000));
+        Assert::string($type);
+        Assert::string($key);
+        Assert::nullOrGreaterThan($expire, 2592000);
 
         $serialized = serialize($value);
 
@@ -126,8 +127,8 @@ class Redis extends Store
      */
     public function delete($type, $key)
     {
-        assert(is_string($type));
-        assert(is_string($key));
+        Assert::string($type);
+        Assert::string($key);
 
         $this->redis->del("{$type}.{$key}");
     }
diff --git a/lib/SimpleSAML/Store/SQL.php b/lib/SimpleSAML/Store/SQL.php
index 08e7d1837b6977dc9b310664eb56fab43da88202..501cc68aa26fe498a401e65b3f8c1702779ad28e 100644
--- a/lib/SimpleSAML/Store/SQL.php
+++ b/lib/SimpleSAML/Store/SQL.php
@@ -9,6 +9,7 @@ use PDOException;
 use SimpleSAML\Configuration;
 use SimpleSAML\Logger;
 use SimpleSAML\Store;
+use Webmozart\Assert\Assert;
 
 /**
  * A data store using a RDBMS to keep the data.
@@ -189,7 +190,7 @@ class SQL extends Store
      */
     public function getTableVersion($name)
     {
-        assert(is_string($name));
+        Assert::string($name);
 
         if (!isset($this->tableVersions[$name])) {
             return 0;
@@ -208,8 +209,8 @@ class SQL extends Store
      */
     public function setTableVersion($name, $version)
     {
-        assert(is_string($name));
-        assert(is_int($version));
+        Assert::string($name);
+        Assert::integer($version);
 
         $this->insertOrUpdate(
             $this->prefix . '_tableVersion',
@@ -232,7 +233,7 @@ class SQL extends Store
      */
     public function insertOrUpdate($table, array $keys, array $data)
     {
-        assert(is_string($table));
+        Assert::string($table);
 
         $colNames = '(' . implode(', ', array_keys($data)) . ')';
         $values = 'VALUES(:' . implode(', :', array_keys($data)) . ')';
@@ -310,8 +311,8 @@ class SQL extends Store
      */
     public function get($type, $key)
     {
-        assert(is_string($type));
-        assert(is_string($key));
+        Assert::string($type);
+        Assert::string($key);
 
         if (strlen($key) > 50) {
             $key = sha1($key);
@@ -354,9 +355,9 @@ class SQL extends Store
      */
     public function set($type, $key, $value, $expire = null)
     {
-        assert(is_string($type));
-        assert(is_string($key));
-        assert($expire === null || (is_int($expire) && $expire > 2592000));
+        Assert::string($type);
+        Assert::string($key);
+        Assert::nullOrGreaterThan($expire, 2592000);
 
         if (rand(0, 1000) < 10) {
             $this->cleanKVStore();
@@ -393,8 +394,8 @@ class SQL extends Store
      */
     public function delete($type, $key)
     {
-        assert(is_string($type));
-        assert(is_string($key));
+        Assert::string($type);
+        Assert::string($key);
 
         if (strlen($key) > 50) {
             $key = sha1($key);
diff --git a/lib/SimpleSAML/Utils/Crypto.php b/lib/SimpleSAML/Utils/Crypto.php
index 59c6cd2fa0507ed22ee0b1f00320a85c2714faa5..c12519adb178984f355ee19eeec5138c4fc7e1e0 100644
--- a/lib/SimpleSAML/Utils/Crypto.php
+++ b/lib/SimpleSAML/Utils/Crypto.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Utils;
 
 use SimpleSAML\Configuration;
 use SimpleSAML\Error;
+use Webmozart\Assert\Assert;
 
 /**
  * A class for cryptography-related functions.
@@ -289,7 +290,7 @@ class Crypto
 
             // normalize fingerprint(s) - lowercase and no colons
             foreach ($fps as &$fp) {
-                assert(is_string($fp));
+                Assert::string($fp);
                 $fp = strtolower(str_replace(':', '', $fp));
             }
 
diff --git a/lib/SimpleSAML/Utils/EMail.php b/lib/SimpleSAML/Utils/EMail.php
index 08c70df75adcc5ed5dddbbcb82fe5f13c9cf9414..dd861bc3803f2691afce2c46c539790147b26849 100644
--- a/lib/SimpleSAML/Utils/EMail.php
+++ b/lib/SimpleSAML/Utils/EMail.php
@@ -8,6 +8,7 @@ use PHPMailer\PHPMailer\PHPMailer;
 use SimpleSAML\Configuration;
 use SimpleSAML\Logger;
 use SimpleSAML\XHTML\Template;
+use Webmozart\Assert\Assert;
 
 /**
  * E-mailer class that can generate a formatted e-mail from array
@@ -159,7 +160,7 @@ class EMail
      */
     public function setTransportMethod($transportMethod, array $transportOptions = [])
     {
-        assert(is_string($transportMethod));
+        Assert::string($transportMethod);
 
         switch (strtolower($transportMethod)) {
             // smtp transport method
@@ -231,7 +232,7 @@ class EMail
      */
     public static function initFromConfig(EMail $EMail)
     {
-        assert($EMail instanceof EMail);
+        Assert::isInstanceOf($EMail, EMail::class);
 
         $config = Configuration::getInstance();
         $EMail->setTransportMethod(
diff --git a/lib/SimpleSAML/Utils/XML.php b/lib/SimpleSAML/Utils/XML.php
index 8c178fee12edb3c0c53697b6cd85e4ecc5cec13b..6f97ccb4e8e766b579a4a6bcc73d508e1408ce59 100644
--- a/lib/SimpleSAML/Utils/XML.php
+++ b/lib/SimpleSAML/Utils/XML.php
@@ -20,6 +20,7 @@ use SimpleSAML\Configuration;
 use SimpleSAML\Error;
 use SimpleSAML\Logger;
 use SimpleSAML\XML\Errors;
+use Webmozart\Assert\Assert;
 
 class XML
 {
@@ -144,7 +145,7 @@ class XML
                 Logger::debug('Encrypted message:');
                 break;
             default:
-                assert(false);
+                Assert::true(false);
         }
 
         $str = self::formatXMLString($message);
diff --git a/lib/SimpleSAML/XHTML/IdPDisco.php b/lib/SimpleSAML/XHTML/IdPDisco.php
index d5b64751346121ffb202aa2af8fc21e37c3bb5b4..8e941879832f9151505eb40c39446144e30baf50 100644
--- a/lib/SimpleSAML/XHTML/IdPDisco.php
+++ b/lib/SimpleSAML/XHTML/IdPDisco.php
@@ -9,6 +9,7 @@ use SimpleSAML\Logger;
 use SimpleSAML\Metadata\MetaDataStorageHandler;
 use SimpleSAML\Session;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * This class implements a generic IdP discovery service, for use in various IdP
@@ -119,7 +120,7 @@ class IdPDisco
      */
     public function __construct(array $metadataSets, $instance)
     {
-        assert(is_string($instance));
+        Assert::string($instance);
 
         // initialize standard classes
         $this->config = Configuration::getInstance();
@@ -395,7 +396,7 @@ class IdPDisco
      */
     protected function setPreviousIdP($idp)
     {
-        assert(is_string($idp));
+        Assert::string($idp);
 
         $this->log('Choice made [' . $idp . '] Setting cookie.');
         $this->setCookie('lastidp', $idp);
diff --git a/lib/SimpleSAML/XHTML/Template.php b/lib/SimpleSAML/XHTML/Template.php
index e584d825de589b62b9f13c79d09cc021b8397fa2..4ceed77ea29ccb2139e7e6c15fe0e5df3e688ad8 100644
--- a/lib/SimpleSAML/XHTML/Template.php
+++ b/lib/SimpleSAML/XHTML/Template.php
@@ -24,6 +24,7 @@ use Symfony\Component\HttpFoundation\Response;
 use Twig\Loader\FilesystemLoader;
 use Twig\TwigFilter;
 use Twig\TwigFunction;
+use Webmozart\Assert\Assert;
 
 class Template extends Response
 {
@@ -588,6 +589,7 @@ class Template extends Response
     {
         $extensions = ['.tpl.php', '.php'];
 
+        $extensions = ['.tpl.php', '.php'];
         list($templateModule, $templateName) = $this->findModuleAndTemplateName($template);
         $templateModule = ($templateModule !== null) ? $templateModule : 'default';
 
diff --git a/lib/SimpleSAML/XML/Errors.php b/lib/SimpleSAML/XML/Errors.php
index 7db0b0699bf1dea6df29a3bb129d343d2c320c49..2f7114f53ef299fd40e1091098162ae7a12ed483 100644
--- a/lib/SimpleSAML/XML/Errors.php
+++ b/lib/SimpleSAML/XML/Errors.php
@@ -15,6 +15,7 @@ declare(strict_types=1);
 namespace SimpleSAML\XML;
 
 use LibXMLError;
+use Webmozart\Assert\Assert;
 
 class Errors
 {
@@ -114,7 +115,7 @@ class Errors
      */
     public static function formatError($error)
     {
-        assert($error instanceof LibXMLError);
+        Assert::isInstanceOf($error, LibXMLError::class);
         return 'level=' . $error->level
             . ',code=' . $error->code
             . ',line=' . $error->line
@@ -135,7 +136,7 @@ class Errors
      */
     public static function formatErrors($errors)
     {
-        assert(is_array($errors));
+        Assert::isArray($errors);
 
         $ret = '';
         foreach ($errors as $error) {
diff --git a/lib/SimpleSAML/XML/Shib13/AuthnResponse.php b/lib/SimpleSAML/XML/Shib13/AuthnResponse.php
index e61e369fe895876a40cb5769ae241a8905c198b0..0d666a97fc237d2422d03ec6f75cab5fc8dbdcda 100644
--- a/lib/SimpleSAML/XML/Shib13/AuthnResponse.php
+++ b/lib/SimpleSAML/XML/Shib13/AuthnResponse.php
@@ -22,6 +22,7 @@ use SimpleSAML\Error;
 use SimpleSAML\Metadata\MetaDataStorageHandler;
 use SimpleSAML\Utils;
 use SimpleSAML\XML\Validator;
+use Webmozart\Assert\Assert;
 
 class AuthnResponse
 {
@@ -64,7 +65,7 @@ class AuthnResponse
      */
     public function setMessageValidated($messageValidated)
     {
-        assert(is_bool($messageValidated));
+        Assert::boolean($messageValidated);
 
         $this->messageValidated = $messageValidated;
     }
@@ -77,7 +78,7 @@ class AuthnResponse
      */
     public function setXML($xml)
     {
-        assert(is_string($xml));
+        Assert::string($xml);
 
         try {
             $this->dom = DOMDocumentFactory::fromString(str_replace("\r", "", $xml));
@@ -112,7 +113,7 @@ class AuthnResponse
      */
     public function validate()
     {
-        assert($this->dom instanceof DOMDocument);
+        Assert::isInstanceOf($this->dom, DOMDocument::class);
 
         if ($this->messageValidated) {
             // This message was validated externally
@@ -120,6 +121,7 @@ class AuthnResponse
         }
 
         // Validate the signature
+        /** @var \DOMDocument $this->dom */
         $this->validator = new Validator($this->dom, ['ResponseID', 'AssertionID']);
 
         // Get the issuer of the response
@@ -179,7 +181,7 @@ class AuthnResponse
             $node = dom_import_simplexml($node);
         }
 
-        assert($node instanceof DOMNode);
+        Assert::isInstanceOf($node, DOMNode::class);
 
         return $this->validator->isNodeValidated($node);
     }
@@ -195,14 +197,15 @@ class AuthnResponse
      */
     private function doXPathQuery(string $query, DOMNode $node = null): DOMNodeList
     {
-        assert($this->dom instanceof DOMDocument);
-
+        Assert::isInstanceOf($this->dom, DOMDocument::class);
         if ($node === null) {
+            /** @var \DOMDocument $this->dom */
             $node = $this->dom->documentElement;
         }
 
-        assert($node instanceof DOMNode);
+        Assert::isInstanceOf($node, DOMNode::class);
 
+        /** @var \DOMDocument $this->dom */
         $xPath = new DOMXpath($this->dom);
         $xPath->registerNamespace('shibp', self::SHIB_PROTOCOL_NS);
         $xPath->registerNamespace('shib', self::SHIB_ASSERT_NS);
@@ -218,7 +221,7 @@ class AuthnResponse
      */
     public function getSessionIndex()
     {
-        assert($this->dom instanceof DOMDocument);
+        Assert::isInstanceOf($this->dom, DOMDocument::class);
 
         $query = '/shibp:Response/shib:Assertion/shib:AuthnStatement';
         $nodelist = $this->doXPathQuery($query);
@@ -357,8 +360,8 @@ class AuthnResponse
      */
     public function generate(Configuration $idp, Configuration $sp, $shire, $attributes)
     {
-        assert(is_string($shire));
-        assert($attributes === null || is_array($attributes));
+        Assert::string($shire);
+        Assert::nullOrArray($attributes);
 
         if ($sp->hasValue('scopedattributes')) {
             $scopedAttributes = $sp->getArray('scopedattributes');
diff --git a/lib/SimpleSAML/XML/Signer.php b/lib/SimpleSAML/XML/Signer.php
index e71c9079eec21cb0d34f1d0d1eaf596b859d8013..7c84570fbb99f0f285a48be9a8b43f8594ab853f 100644
--- a/lib/SimpleSAML/XML/Signer.php
+++ b/lib/SimpleSAML/XML/Signer.php
@@ -19,6 +19,7 @@ use DOMText;
 use RobRichards\XMLSecLibs\XMLSecurityDSig;
 use RobRichards\XMLSecLibs\XMLSecurityKey;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 class Signer
 {
@@ -62,7 +63,7 @@ class Signer
      */
     public function __construct($options = [])
     {
-        assert(is_array($options));
+        Assert::isArray($options);
 
         if (array_key_exists('privatekey', $options)) {
             $pass = null;
@@ -102,8 +103,8 @@ class Signer
      */
     public function loadPrivateKeyArray($privatekey)
     {
-        assert(is_array($privatekey));
-        assert(array_key_exists('PEM', $privatekey));
+        Assert::isArray($privatekey);
+        Assert::keyExists($privatekey, 'PEM');
 
         $this->privateKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, ['type' => 'private']);
         if (array_key_exists('password', $privatekey)) {
@@ -129,9 +130,9 @@ class Signer
      */
     public function loadPrivateKey($file, $pass = null, $full_path = false)
     {
-        assert(is_string($file));
-        assert(is_string($pass) || $pass === null);
-        assert(is_bool($full_path));
+        Assert::string($file);
+        Assert::nullOrString($pass);
+        Assert::boolean($full_path);
 
         if (!$full_path) {
             $keyFile = Utils\Config::getCertPath($file);
@@ -167,7 +168,7 @@ class Signer
      */
     public function loadPublicKeyArray($publickey)
     {
-        assert(is_array($publickey));
+        Assert::isArray($publickey);
 
         if (!array_key_exists('PEM', $publickey)) {
             // We have a public key with only a fingerprint
@@ -194,8 +195,8 @@ class Signer
      */
     public function loadCertificate($file, $full_path = false)
     {
-        assert(is_string($file));
-        assert(is_bool($full_path));
+        Assert::string($file);
+        Assert::boolean($full_path);
 
         if (!$full_path) {
             $certFile = Utils\Config::getCertPath($file);
@@ -223,7 +224,7 @@ class Signer
      */
     public function setIDAttribute($idAttrName)
     {
-        assert(is_string($idAttrName));
+        Assert::string($idAttrName);
 
         $this->idAttrName = $idAttrName;
     }
@@ -243,8 +244,8 @@ class Signer
      */
     public function addCertificate($file, $full_path = false)
     {
-        assert(is_string($file));
-        assert(is_bool($full_path));
+        Assert::string($file);
+        Assert::boolean($full_path);
 
         if (!$full_path) {
             $certFile = Utils\Config::getCertPath($file);
@@ -280,10 +281,9 @@ class Signer
      */
     public function sign($node, $insertInto, $insertBefore = null)
     {
-        assert($node instanceof DOMElement);
-        assert($insertInto instanceof DOMElement);
-        assert($insertBefore === null || $insertBefore instanceof DOMElement ||
-            $insertBefore instanceof DOMComment || $insertBefore instanceof DOMText);
+        Assert::isInstanceOf($node, DOMElement::class);
+        Assert::isInstanceOf($insertInto, DOMElement::class);
+        Assert::nullOrInstanceOfAny($insertBefore, [DOMElement::class, DOMComment::class, DOMText::class]);
 
         $privateKey = $this->privateKey;
         if ($privateKey === false) {
diff --git a/lib/SimpleSAML/XML/Validator.php b/lib/SimpleSAML/XML/Validator.php
index 665f20ec206ec1d412edd5943b323db4e39ed8d2..33c17bf234b6b58d69312a0c7223db317b6bca1f 100644
--- a/lib/SimpleSAML/XML/Validator.php
+++ b/lib/SimpleSAML/XML/Validator.php
@@ -11,9 +11,11 @@ declare(strict_types=1);
 
 namespace SimpleSAML\XML;
 
+use DOMNode;
 use RobRichards\XMLSecLibs\XMLSecEnc;
 use RobRichards\XMLSecLibs\XMLSecurityDSig;
 use SimpleSAML\Logger;
+use Webmozart\Assert\Assert;
 
 class Validator
 {
@@ -44,12 +46,12 @@ class Validator
      *          this attribute is NULL (the default), then we will use whatever is the default
      *          ID. Can be eigther a string with one value, or an array with multiple ID
      *          attrbute names.
-     * @param array|bool $publickey The public key / certificate which should be used to validate the XML node.
+     * @param array|false $publickey The public key / certificate which should be used to validate the XML node.
      * @throws \Exception
      */
     public function __construct($xmlNode, $idAttribute = null, $publickey = false)
     {
-        assert($xmlNode instanceof \DOMDocument);
+        Assert::isInstanceOf($xmlNode, DOMNode::class);
 
         if ($publickey === null) {
             $publickey = false;
@@ -58,7 +60,7 @@ class Validator
                 'PEM' => $publickey,
             ];
         } else {
-            assert($publickey === false || is_array($publickey));
+            Assert::true($publickey === false || is_array($publickey));
         }
 
         // Create an XML security object
@@ -112,7 +114,7 @@ class Validator
                  * Check that the response contains a certificate with a matching
                  * fingerprint.
                  */
-                assert(is_array($publickey['certFingerprint']));
+                Assert::isArray($publickey['certFingerprint']);
 
                 $certificate = $objKey->getX509Certificate();
                 if ($certificate === null) {
@@ -213,7 +215,7 @@ class Validator
         }
 
         foreach ($fingerprints as $fp) {
-            assert(is_string($fp));
+            Assert::string($fp);
 
             if ($fp === $certFingerprint) {
                 // The fingerprints matched
@@ -241,7 +243,7 @@ class Validator
      */
     public function validateFingerprint($fingerprints)
     {
-        assert(is_string($fingerprints) || is_array($fingerprints));
+        Assert::true(is_string($fingerprints) || is_array($fingerprints));
 
         if ($this->x509Certificate === null) {
             throw new \Exception('Key used to sign the message was not an X509 certificate.');
@@ -253,7 +255,7 @@ class Validator
 
         // Normalize the fingerprints
         foreach ($fingerprints as &$fp) {
-            assert(is_string($fp));
+            Assert::string($fp);
 
             // Make sure that the fingerprint is in the correct format
             $fp = strtolower(str_replace(":", "", $fp));
@@ -272,7 +274,7 @@ class Validator
      */
     public function isNodeValidated($node)
     {
-        assert($node instanceof \DOMNode);
+        Assert::isInstanceOf($node, DOMNode::class);
 
         if ($this->validNodes !== null) {
             while ($node !== null) {
@@ -302,7 +304,7 @@ class Validator
      */
     public function validateCA($caFile)
     {
-        assert(is_string($caFile));
+        Assert::string($caFile);
 
         if ($this->x509Certificate === null) {
             throw new \Exception('Key used to sign the message was not an X509 certificate.');
@@ -414,8 +416,8 @@ class Validator
      */
     public static function validateCertificate($certificate, $caFile)
     {
-        assert(is_string($certificate));
-        assert(is_string($caFile));
+        Assert::string($certificate);
+        Assert::string($caFile);
 
         if (!file_exists($caFile)) {
             throw new \Exception('Could not load CA file: ' . $caFile);
diff --git a/modules/core/hooks/hook_frontpage.php b/modules/core/hooks/hook_frontpage.php
index d56a7f0ed433496971e21ec1148c893e475b8f8f..f6ff146a3978a41970a25dbefc0979a22e4a7612 100644
--- a/modules/core/hooks/hook_frontpage.php
+++ b/modules/core/hooks/hook_frontpage.php
@@ -2,6 +2,8 @@
 
 declare(strict_types=1);
 
+use Webmozart\Assert\Assert;
+
 /**
  * Hook to add the modinfo module to the frontpage.
  *
@@ -10,8 +12,8 @@ declare(strict_types=1);
  */
 function core_hook_frontpage(&$links)
 {
-    assert(is_array($links));
-    assert(array_key_exists('links', $links));
+    Assert::isArray($links);
+    Assert::keyExists($links, 'links');
 
     $links['links']['frontpage_welcome'] = [
         'href' => SimpleSAML\Module::getModuleURL('core/frontpage_welcome.php'),
diff --git a/modules/core/hooks/hook_sanitycheck.php b/modules/core/hooks/hook_sanitycheck.php
index 9bf9132d59f0e476a222e9470e9f2c494d72da7d..c786872bb70049a549d8e81c4ea825ddb4a22a6d 100644
--- a/modules/core/hooks/hook_sanitycheck.php
+++ b/modules/core/hooks/hook_sanitycheck.php
@@ -2,6 +2,8 @@
 
 declare(strict_types=1);
 
+use Webmozart\Assert\Assert;
+
 /**
  * Hook to do sanitycheck
  *
@@ -10,9 +12,9 @@ declare(strict_types=1);
  */
 function core_hook_sanitycheck(&$hookinfo)
 {
-    assert(is_array($hookinfo));
-    assert(array_key_exists('errors', $hookinfo));
-    assert(array_key_exists('info', $hookinfo));
+    Assert::isArray($hookinfo);
+    Assert::keyExists($hookinfo, 'errors');
+    Assert::keyExists($hookinfo, 'info');
 
     $config = \SimpleSAML\Configuration::getInstance();
 
diff --git a/modules/core/lib/ACL.php b/modules/core/lib/ACL.php
index a952cbe531c80c98584782fcfa885a81201e7542..6ab1baa790f1ea76cf345e95b5794ac05221e0cb 100644
--- a/modules/core/lib/ACL.php
+++ b/modules/core/lib/ACL.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Module\core;
 
 use SimpleSAML\Configuration;
 use SimpleSAML\Error;
+use Webmozart\Assert\Assert;
 
 /**
  * Generic library for access control lists.
@@ -29,7 +30,7 @@ class ACL
      */
     public function __construct($acl)
     {
-        assert(is_string($acl) || is_array($acl));
+        Assert::true(is_string($acl) || is_array($acl));
 
         if (is_string($acl)) {
             $acl = self::getById($acl);
diff --git a/modules/core/lib/Auth/Process/AttributeAdd.php b/modules/core/lib/Auth/Process/AttributeAdd.php
index 116fd8ce4145193d8a1a4fe45e512cb9f9be2621..59d1dce47053ef1ae5fce9474aa15b56e8179911 100644
--- a/modules/core/lib/Auth/Process/AttributeAdd.php
+++ b/modules/core/lib/Auth/Process/AttributeAdd.php
@@ -4,6 +4,8 @@ declare(strict_types=1);
 
 namespace SimpleSAML\Module\core\Auth\Process;
 
+use Webmozart\Assert\Assert;
+
 /**
  * Filter to add attributes.
  *
@@ -39,7 +41,7 @@ class AttributeAdd extends \SimpleSAML\Auth\ProcessingFilter
     {
         parent::__construct($config, $reserved);
 
-        assert(is_array($config));
+        Assert::isArray($config);
 
         foreach ($config as $name => $values) {
             if (is_int($name)) {
@@ -77,8 +79,8 @@ class AttributeAdd extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$request)
     {
-        assert(is_array($request));
-        assert(array_key_exists('Attributes', $request));
+        Assert::isArray($request);
+        Assert::keyExists($request, 'Attributes');
 
         $attributes = &$request['Attributes'];
 
diff --git a/modules/core/lib/Auth/Process/AttributeAlter.php b/modules/core/lib/Auth/Process/AttributeAlter.php
index 2ca333dc896b517d4a0f2f9fc0ffa3f96d6ad5cd..4fec537e847a5fbac759a3aadba857e6de780343 100644
--- a/modules/core/lib/Auth/Process/AttributeAlter.php
+++ b/modules/core/lib/Auth/Process/AttributeAlter.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace SimpleSAML\Module\core\Auth\Process;
 
 use SimpleSAML\Error;
+use Webmozart\Assert\Assert;
 
 /**
  * Filter to modify attributes using regular expressions
@@ -64,7 +65,7 @@ class AttributeAlter extends \SimpleSAML\Auth\ProcessingFilter
     {
         parent::__construct($config, $reserved);
 
-        assert(is_array($config));
+        Assert::isArray($config);
 
         // parse filter configuration
         foreach ($config as $name => $value) {
@@ -106,8 +107,8 @@ class AttributeAlter extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$request)
     {
-        assert(is_array($request));
-        assert(array_key_exists('Attributes', $request));
+        Assert::isArray($request);
+        Assert::keyExists($request, 'Attributes');
 
         // get attributes from request
         $attributes = &$request['Attributes'];
diff --git a/modules/core/lib/Auth/Process/AttributeCopy.php b/modules/core/lib/Auth/Process/AttributeCopy.php
index 29fdd4fe3908287782cf15114bb9fe60ebc7517e..fe1ae5017595ef40ed9e93ed208010d59ba20180 100644
--- a/modules/core/lib/Auth/Process/AttributeCopy.php
+++ b/modules/core/lib/Auth/Process/AttributeCopy.php
@@ -4,6 +4,8 @@ declare(strict_types=1);
 
 namespace SimpleSAML\Module\core\Auth\Process;
 
+use Webmozart\Assert\Assert;
+
 /**
  * Attribute filter for renaming attributes.
  *
@@ -38,7 +40,7 @@ class AttributeCopy extends \SimpleSAML\Auth\ProcessingFilter
     {
         parent::__construct($config, $reserved);
 
-        assert(is_array($config));
+        Assert::isArray($config);
 
         foreach ($config as $source => $destination) {
             if (!is_string($source)) {
@@ -62,8 +64,8 @@ class AttributeCopy extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$request)
     {
-        assert(is_array($request));
-        assert(array_key_exists('Attributes', $request));
+        Assert::isArray($request);
+        Assert::keyExists($request, 'Attributes');
 
         $attributes = &$request['Attributes'];
 
diff --git a/modules/core/lib/Auth/Process/AttributeLimit.php b/modules/core/lib/Auth/Process/AttributeLimit.php
index ee4b32240154d20ed20be3de39bb6da9a3a897f1..ffa79c0b501d849aaa2d40d38e513b1cd6e88f5d 100644
--- a/modules/core/lib/Auth/Process/AttributeLimit.php
+++ b/modules/core/lib/Auth/Process/AttributeLimit.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Module\core\Auth\Process;
 
 use SimpleSAML\Error;
 use SimpleSAML\Logger;
+use Webmozart\Assert\Assert;
 
 /**
  * A filter for limiting which attributes are passed on.
@@ -40,7 +41,7 @@ class AttributeLimit extends \SimpleSAML\Auth\ProcessingFilter
     {
         parent::__construct($config, $reserved);
 
-        assert(is_array($config));
+        Assert::isArray($config);
 
         foreach ($config as $index => $value) {
             if ($index === 'default') {
@@ -95,8 +96,8 @@ class AttributeLimit extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$request)
     {
-        assert(is_array($request));
-        assert(array_key_exists('Attributes', $request));
+        Assert::isArray($request);
+        assert::keyExists($request, 'Attributes');
 
         if ($this->isDefault) {
             $allowedAttributes = self::getSPIdPAllowed($request);
diff --git a/modules/core/lib/Auth/Process/AttributeMap.php b/modules/core/lib/Auth/Process/AttributeMap.php
index bc21b574610f2e3db8756958d902f9bf52104041..2ff61fc2e867310fb8a021451e99d856de765576 100644
--- a/modules/core/lib/Auth/Process/AttributeMap.php
+++ b/modules/core/lib/Auth/Process/AttributeMap.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Module\core\Auth\Process;
 
 use SimpleSAML\Configuration;
 use SimpleSAML\Module;
+use Webmozart\Assert\Assert;
 
 /**
  * Attribute filter for renaming attributes.
@@ -40,7 +41,7 @@ class AttributeMap extends \SimpleSAML\Auth\ProcessingFilter
     {
         parent::__construct($config, $reserved);
 
-        assert(is_array($config));
+        Assert::isArray($config);
         $mapFiles = [];
 
         foreach ($config as $origName => $newName) {
@@ -123,8 +124,8 @@ class AttributeMap extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$request)
     {
-        assert(is_array($request));
-        assert(array_key_exists('Attributes', $request));
+        Assert::isArray($request);
+        Assert::keyExists($request, 'Attributes');
 
         $mapped_attributes = [];
 
diff --git a/modules/core/lib/Auth/Process/AttributeValueMap.php b/modules/core/lib/Auth/Process/AttributeValueMap.php
index 86a2471113464f77b73ec35c646f537d41dc4c99..9f640777153e046f6ca71086bd1aa41956b8e1d5 100644
--- a/modules/core/lib/Auth/Process/AttributeValueMap.php
+++ b/modules/core/lib/Auth/Process/AttributeValueMap.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Module\core\Auth\Process;
 
 use SimpleSAML\Error;
 use SimpleSAML\Logger;
+use Webmozart\Assert\Assert;
 
 /**
  * Filter to create target attribute based on value(s) in source attribute
@@ -57,7 +58,7 @@ class AttributeValueMap extends \SimpleSAML\Auth\ProcessingFilter
     {
         parent::__construct($config, $reserved);
 
-        assert(is_array($config));
+        Assert::isArray($config);
 
         // parse configuration
         foreach ($config as $name => $value) {
@@ -115,8 +116,8 @@ class AttributeValueMap extends \SimpleSAML\Auth\ProcessingFilter
     {
         Logger::debug('Processing the AttributeValueMap filter.');
 
-        assert(is_array($request));
-        assert(array_key_exists('Attributes', $request));
+        Assert::isArray($request);
+        Assert::keyExists($request, 'Attributes');
         $attributes = &$request['Attributes'];
 
         if (!array_key_exists($this->sourceattribute, $attributes)) {
diff --git a/modules/core/lib/Auth/Process/Cardinality.php b/modules/core/lib/Auth/Process/Cardinality.php
index 0ddb1ff8916144a297550e9bcdaec1c29ef75fd1..96f68fbd090d073230639729ccc98aa5bd501dc5 100644
--- a/modules/core/lib/Auth/Process/Cardinality.php
+++ b/modules/core/lib/Auth/Process/Cardinality.php
@@ -9,6 +9,7 @@ use SimpleSAML\Error;
 use SimpleSAML\Logger;
 use SimpleSAML\Module;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Filter to ensure correct cardinality of attributes
@@ -39,7 +40,7 @@ class Cardinality extends \SimpleSAML\Auth\ProcessingFilter
     public function __construct(&$config, $reserved, Utils\HttpAdapter $http = null)
     {
         parent::__construct($config, $reserved);
-        assert(is_array($config));
+        Assert::isArray($config);
 
         $this->http = $http ? : new Utils\HttpAdapter();
 
@@ -112,8 +113,8 @@ class Cardinality extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$request)
     {
-        assert(is_array($request));
-        assert(array_key_exists("Attributes", $request));
+        Assert::isArray($request);
+        Assert::keyExists($request, 'Attributes');
 
         $entityid = false;
         if (array_key_exists('Source', $request) && array_key_exists('entityid', $request['Source'])) {
diff --git a/modules/core/lib/Auth/Process/CardinalitySingle.php b/modules/core/lib/Auth/Process/CardinalitySingle.php
index 36d0b8bb3631d51a1db1508e5dfefba5be896ec5..cf59af15f59fdf23e70ea6c8e9dea7e324582c71 100644
--- a/modules/core/lib/Auth/Process/CardinalitySingle.php
+++ b/modules/core/lib/Auth/Process/CardinalitySingle.php
@@ -8,6 +8,7 @@ use SimpleSAML\Auth;
 use SimpleSAML\Logger;
 use SimpleSAML\Module;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Filter to ensure correct cardinality of single-valued attributes
@@ -49,7 +50,7 @@ class CardinalitySingle extends \SimpleSAML\Auth\ProcessingFilter
     public function __construct(&$config, $reserved, Utils\HttpAdapter $http = null)
     {
         parent::__construct($config, $reserved);
-        assert(is_array($config));
+        Assert::isArray($config);
 
         $this->http = $http ? : new Utils\HttpAdapter();
 
@@ -87,8 +88,8 @@ class CardinalitySingle extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$request)
     {
-        assert(is_array($request));
-        assert(array_key_exists("Attributes", $request));
+        Assert::isArray($request);
+        Assert::keyExists($request, 'Attributes');
 
         if (
             array_key_exists('Source', $request)
diff --git a/modules/core/lib/Auth/Process/ExtendIdPSession.php b/modules/core/lib/Auth/Process/ExtendIdPSession.php
index ab4e2126b997260016e7200f5cbbb045d9828be2..0366ff2f36f4bea607e40702822eb643db1743ae 100644
--- a/modules/core/lib/Auth/Process/ExtendIdPSession.php
+++ b/modules/core/lib/Auth/Process/ExtendIdPSession.php
@@ -7,6 +7,7 @@ namespace SimpleSAML\Module\core\Auth\Process;
 use SimpleSAML\Configuration;
 use SimpleSAML\Session;
 use SimpleSAML\SessionHandler;
+use Webmozart\Assert\Assert;
 
 /**
  * Extend IdP session and cookies.
@@ -19,7 +20,7 @@ class ExtendIdPSession extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$state)
     {
-        assert(is_array($state));
+        Assert::isArray($state);
 
         if (empty($state['Expire']) || empty($state['Authority'])) {
             return;
diff --git a/modules/core/lib/Auth/Process/GenerateGroups.php b/modules/core/lib/Auth/Process/GenerateGroups.php
index e04b800dfc197e63f47135c06f5a091560c0dae7..9a6ef0d3de93487be498fc1d259ef7e9dadafd70 100644
--- a/modules/core/lib/Auth/Process/GenerateGroups.php
+++ b/modules/core/lib/Auth/Process/GenerateGroups.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace SimpleSAML\Module\core\Auth\Process;
 
 use SimpleSAML\Logger;
+use Webmozart\Assert\Assert;
 
 /**
  * Filter to generate a groups attribute based on many of the attributes of the user.
@@ -31,7 +32,7 @@ class GenerateGroups extends \SimpleSAML\Auth\ProcessingFilter
     {
         parent::__construct($config, $reserved);
 
-        assert(is_array($config));
+        Assert::isArray($config);
 
         if (count($config) === 0) {
             // Use default groups
@@ -61,8 +62,8 @@ class GenerateGroups extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$request)
     {
-        assert(is_array($request));
-        assert(array_key_exists('Attributes', $request));
+        Assert::isArray($request);
+        Assert::keyExists($request, 'Attributes');
 
         $groups = [];
         $attributes = &$request['Attributes'];
diff --git a/modules/core/lib/Auth/Process/LanguageAdaptor.php b/modules/core/lib/Auth/Process/LanguageAdaptor.php
index 45889c068d29a709e368fd5920f5989bf92c6d87..1984c4e32b683c538179bdbb52d319246e535bf7 100644
--- a/modules/core/lib/Auth/Process/LanguageAdaptor.php
+++ b/modules/core/lib/Auth/Process/LanguageAdaptor.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Module\core\Auth\Process;
 
 use SimpleSAML\Locale\Language;
 use SimpleSAML\Logger;
+use Webmozart\Assert\Assert;
 
 /**
  * Filter to set and get language settings from attributes.
@@ -28,7 +29,7 @@ class LanguageAdaptor extends \SimpleSAML\Auth\ProcessingFilter
     public function __construct(&$config, $reserved)
     {
         parent::__construct($config, $reserved);
-        assert(is_array($config));
+        Assert::isArray($config);
 
         if (array_key_exists('attributename', $config)) {
             $this->langattr = $config['attributename'];
@@ -46,8 +47,8 @@ class LanguageAdaptor extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$request)
     {
-        assert(is_array($request));
-        assert(array_key_exists('Attributes', $request));
+        Assert::isArray($request);
+        Assert::keyExists($request, 'Attributes');
 
         $attributes = &$request['Attributes'];
 
diff --git a/modules/core/lib/Auth/Process/PHP.php b/modules/core/lib/Auth/Process/PHP.php
index 9b79f0988a467c201116e8b192c04b9c8ed3c7ca..5bcf8c0e06d1ab4b7682edd24446a1c5f939125c 100644
--- a/modules/core/lib/Auth/Process/PHP.php
+++ b/modules/core/lib/Auth/Process/PHP.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace SimpleSAML\Module\core\Auth\Process;
 
 use SimpleSAML\Error;
+use Webmozart\Assert\Assert;
 
 /**
  * Attribute filter for running arbitrary PHP code.
@@ -34,7 +35,7 @@ class PHP extends \SimpleSAML\Auth\ProcessingFilter
     {
         parent::__construct($config, $reserved);
 
-        assert(is_array($config));
+        Assert::isArray($config);
 
         if (!isset($config['code'])) {
             throw new Error\Exception("core:PHP: missing mandatory configuration option 'code'.");
@@ -53,8 +54,8 @@ class PHP extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$request)
     {
-        assert(is_array($request));
-        assert(array_key_exists('Attributes', $request));
+        Assert::isArray($request);
+        Assert::keyExists($request, 'Attributes');
 
         /**
          * @param array &$attributes
diff --git a/modules/core/lib/Auth/Process/ScopeAttribute.php b/modules/core/lib/Auth/Process/ScopeAttribute.php
index 7effc2adbbbfb2d361c9614cb01b7c1b54c9d895..b1228a1f68fd997f634ec5d9ec17bde26202258d 100644
--- a/modules/core/lib/Auth/Process/ScopeAttribute.php
+++ b/modules/core/lib/Auth/Process/ScopeAttribute.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace SimpleSAML\Module\core\Auth\Process;
 
 use SimpleSAML\Configuration;
+use Webmozart\Assert\Assert;
 
 /**
  * Add a scoped variant of an attribute.
@@ -52,7 +53,7 @@ class ScopeAttribute extends \SimpleSAML\Auth\ProcessingFilter
     public function __construct(&$config, $reserved)
     {
         parent::__construct($config, $reserved);
-        assert(is_array($config));
+        Assert::isArray($config);
 
         $cfg = Configuration::loadFromArray($config, 'ScopeAttribute');
 
@@ -71,8 +72,8 @@ class ScopeAttribute extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$request)
     {
-        assert(is_array($request));
-        assert(array_key_exists('Attributes', $request));
+        Assert::isArray($request);
+        Assert::keyExists($request, 'Attributes');
 
         $attributes = &$request['Attributes'];
 
diff --git a/modules/core/lib/Auth/Process/ScopeFromAttribute.php b/modules/core/lib/Auth/Process/ScopeFromAttribute.php
index e94acfe33c1e062d06776e0483555fe36e12e6ed..a8a44012b34b34e44c2f546937aaa9132378196c 100644
--- a/modules/core/lib/Auth/Process/ScopeFromAttribute.php
+++ b/modules/core/lib/Auth/Process/ScopeFromAttribute.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Module\core\Auth\Process;
 
 use SimpleSAML\Configuration;
 use SimpleSAML\Logger;
+use Webmozart\Assert\Assert;
 
 /**
  * Retrieve a scope from a source attribute and add it as a virtual target
@@ -49,7 +50,7 @@ class ScopeFromAttribute extends \SimpleSAML\Auth\ProcessingFilter
     public function __construct(&$config, $reserved)
     {
         parent::__construct($config, $reserved);
-        assert(is_array($config));
+        Assert::isArray($config);
 
         $cfg = Configuration::loadFromArray($config, 'ScopeFromAttribute');
         $this->targetAttribute = $cfg->getString('targetAttribute');
@@ -65,8 +66,8 @@ class ScopeFromAttribute extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$request)
     {
-        assert(is_array($request));
-        assert(array_key_exists('Attributes', $request));
+        Assert::isArray($request);
+        Assert::keyExists($request, 'Attributes');
 
         $attributes = &$request['Attributes'];
 
diff --git a/modules/core/lib/Auth/Process/StatisticsWithAttribute.php b/modules/core/lib/Auth/Process/StatisticsWithAttribute.php
index 05f5d92ed88aafc5e95010c1a4f273fbd966bcfe..07ecc94d0924278940e52f921eb2087c96c9ab9b 100644
--- a/modules/core/lib/Auth/Process/StatisticsWithAttribute.php
+++ b/modules/core/lib/Auth/Process/StatisticsWithAttribute.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace SimpleSAML\Module\core\Auth\Process;
 
 use SimpleSAML\Logger;
+use Webmozart\Assert\Assert;
 
 /**
  * Log a line in the STAT log with one attribute.
@@ -41,7 +42,7 @@ class StatisticsWithAttribute extends \SimpleSAML\Auth\ProcessingFilter
     {
         parent::__construct($config, $reserved);
 
-        assert(is_array($config));
+        Assert::isArray($config);
 
         if (array_key_exists('attributename', $config)) {
             $this->attribute = $config['attributename'];
@@ -71,8 +72,8 @@ class StatisticsWithAttribute extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$state)
     {
-        assert(is_array($state));
-        assert(array_key_exists('Attributes', $state));
+        Assert::isArray($state);
+        Assert::keyExists($state, 'Attributes');
 
         $logAttribute = 'NA';
         $isPassive = '';
diff --git a/modules/core/lib/Auth/Process/TargetedID.php b/modules/core/lib/Auth/Process/TargetedID.php
index 66095c0c7daa0bbbac1d40a605dbb784e860199b..1e8273bd974e1a9f89475b65a99acdbb5b577bb4 100644
--- a/modules/core/lib/Auth/Process/TargetedID.php
+++ b/modules/core/lib/Auth/Process/TargetedID.php
@@ -7,6 +7,7 @@ namespace SimpleSAML\Module\core\Auth\Process;
 use SAML2\Constants;
 use SAML2\XML\saml\NameID;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Filter to generate the eduPersonTargetedID attribute.
@@ -64,7 +65,7 @@ class TargetedID extends \SimpleSAML\Auth\ProcessingFilter
     {
         parent::__construct($config, $reserved);
 
-        assert(is_array($config));
+        Assert::isArray($config);
 
         if (array_key_exists('attributename', $config)) {
             $this->attribute = $config['attributename'];
@@ -90,8 +91,8 @@ class TargetedID extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$state)
     {
-        assert(is_array($state));
-        assert(array_key_exists('Attributes', $state));
+        Assert::isArray($state);
+        Assert::keyExists($state, 'Attributes');
 
         if ($this->attribute === null) {
             if (!array_key_exists('UserID', $state)) {
diff --git a/modules/core/lib/Auth/Process/WarnShortSSOInterval.php b/modules/core/lib/Auth/Process/WarnShortSSOInterval.php
index 7f2005b96ab3315d6b40ee48f9d4fe09bddcc051..e75b56cd7cac3eac4ca352a1010861dc3873de42 100644
--- a/modules/core/lib/Auth/Process/WarnShortSSOInterval.php
+++ b/modules/core/lib/Auth/Process/WarnShortSSOInterval.php
@@ -8,6 +8,7 @@ use SimpleSAML\Auth;
 use SimpleSAML\Logger;
 use SimpleSAML\Module;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Give a warning to the user if we receive multiple requests in a short time.
@@ -27,7 +28,7 @@ class WarnShortSSOInterval extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$state)
     {
-        assert(is_array($state));
+        Assert::isArray($state);
 
         if (!array_key_exists('PreviousSSOTimestamp', $state)) {
             /*
diff --git a/modules/core/lib/Auth/Source/AdminPassword.php b/modules/core/lib/Auth/Source/AdminPassword.php
index 7875e1a1abe72f12d569ad759901f8ca886708db..5fc1b7b5e7ec5498ab6423244c12632a63288f07 100644
--- a/modules/core/lib/Auth/Source/AdminPassword.php
+++ b/modules/core/lib/Auth/Source/AdminPassword.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Module\core\Auth\Source;
 
 use SimpleSAML\Configuration;
 use SimpleSAML\Error;
+use Webmozart\Assert\Assert;
 
 /**
  * Authentication source which verifies the password against
@@ -24,8 +25,8 @@ class AdminPassword extends \SimpleSAML\Module\core\Auth\UserPassBase
      */
     public function __construct($info, $config)
     {
-        assert(is_array($info));
-        assert(is_array($config));
+        Assert::isArray($info);
+        Assert::isArray($config);
 
         // Call the parent constructor first, as required by the interface
         parent::__construct($info, $config);
@@ -49,8 +50,8 @@ class AdminPassword extends \SimpleSAML\Module\core\Auth\UserPassBase
      */
     protected function login($username, $password)
     {
-        assert(is_string($username));
-        assert(is_string($password));
+        Assert::string($username);
+        Assert::string($password);
 
         $config = Configuration::getInstance();
         $adminPassword = $config->getString('auth.adminpassword', '123');
diff --git a/modules/core/lib/Auth/UserPassBase.php b/modules/core/lib/Auth/UserPassBase.php
index e29512533fb07b1f3cff7f7c447f986b65ea90d5..919cda96af81d59c34738e4809ba94fe260df35e 100644
--- a/modules/core/lib/Auth/UserPassBase.php
+++ b/modules/core/lib/Auth/UserPassBase.php
@@ -11,6 +11,7 @@ use SimpleSAML\Error;
 use SimpleSAML\Logger;
 use SimpleSAML\Module;
 use SimpleSAML\Utils\HTTP;
+use Webmozart\Assert\Assert;
 
 /**
  * Helper class for username/password authentication.
@@ -101,8 +102,8 @@ abstract class UserPassBase extends \SimpleSAML\Auth\Source
      */
     public function __construct($info, &$config)
     {
-        assert(is_array($info));
-        assert(is_array($config));
+        Assert::isArray($info);
+        Assert::isArray($config);
 
         if (isset($config['core:loginpage_links'])) {
             $this->loginLinks = $config['core:loginpage_links'];
@@ -136,7 +137,7 @@ abstract class UserPassBase extends \SimpleSAML\Auth\Source
      */
     public function setForcedUsername($forcedUsername)
     {
-        assert(is_string($forcedUsername) || $forcedUsername === null);
+        Assert::nullOrString($forcedUsername);
         $this->forcedUsername = $forcedUsername;
     }
 
@@ -201,7 +202,7 @@ abstract class UserPassBase extends \SimpleSAML\Auth\Source
      */
     public function authenticate(&$state)
     {
-        assert(is_array($state));
+        Assert::isArray($state);
 
         /*
          * Save the identifier of this authentication source, so that we can
@@ -239,7 +240,7 @@ abstract class UserPassBase extends \SimpleSAML\Auth\Source
             }
 
             $attributes = $this->login($username, $password);
-            assert(is_array($attributes));
+            Assert::isArray($attributes);
             $state['Attributes'] = $attributes;
 
             return;
@@ -257,7 +258,7 @@ abstract class UserPassBase extends \SimpleSAML\Auth\Source
         HTTP::redirectTrustedURL($url, $params);
 
         // The previous function never returns, so this code is never executed.
-        assert(false);
+        assert::true(false);
     }
 
 
@@ -291,16 +292,16 @@ abstract class UserPassBase extends \SimpleSAML\Auth\Source
      */
     public static function handleLogin($authStateId, $username, $password)
     {
-        assert(is_string($authStateId));
-        assert(is_string($username));
-        assert(is_string($password));
+        Assert::string($authStateId);
+        Assert::string($username);
+        Assert::string($password);
 
         // Here we retrieve the state array we saved in the authenticate-function.
         /** @var array $state */
         $state = Auth\State::loadState($authStateId, self::STAGEID);
 
         // Retrieve the authentication source we are executing.
-        assert(array_key_exists(self::AUTHID, $state));
+        Assert::keyExists($state, self::AUTHID);
 
         /** @var \SimpleSAML\Module\core\Auth\UserPassBase|null $source */
         $source = Auth\Source::getById($state[self::AUTHID]);
@@ -324,7 +325,7 @@ abstract class UserPassBase extends \SimpleSAML\Auth\Source
         Logger::stats('User \'' . $username . '\' successfully authenticated from ' . $_SERVER['REMOTE_ADDR']);
 
         // Save the attributes we received from the login-function in the $state-array
-        assert(is_array($attributes));
+        Assert::isArray($attributes);
         $state['Attributes'] = $attributes;
 
         // Return control to SimpleSAMLphp after successful authentication.
diff --git a/modules/core/lib/Auth/UserPassOrgBase.php b/modules/core/lib/Auth/UserPassOrgBase.php
index 426eeb102c034071dc99002943208f59551da562..608ca86726a1c601d8ff94d9121e2b65e78bd09c 100644
--- a/modules/core/lib/Auth/UserPassOrgBase.php
+++ b/modules/core/lib/Auth/UserPassOrgBase.php
@@ -9,6 +9,7 @@ use SimpleSAML\Error;
 use SimpleSAML\Logger;
 use SimpleSAML\Module;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Helper class for username/password/organization authentication.
@@ -100,8 +101,8 @@ abstract class UserPassOrgBase extends \SimpleSAML\Auth\Source
      */
     public function __construct($info, &$config)
     {
-        assert(is_array($info));
-        assert(is_array($config));
+        Assert::isArray($info);
+        Assert::isArray($config);
 
         // Call the parent constructor first, as required by the interface
         parent::__construct($info, $config);
@@ -144,7 +145,7 @@ abstract class UserPassOrgBase extends \SimpleSAML\Auth\Source
      */
     protected function setUsernameOrgMethod($usernameOrgMethod)
     {
-        assert(in_array($usernameOrgMethod, ['none', 'allow', 'force'], true));
+        Assert::oneOf($usernameOrgMethod, ['none', 'allow', 'force']);
 
         $this->usernameOrgMethod = $usernameOrgMethod;
     }
@@ -217,7 +218,7 @@ abstract class UserPassOrgBase extends \SimpleSAML\Auth\Source
      */
     public function authenticate(&$state)
     {
-        assert(is_array($state));
+        Assert::isArray($state);
 
         // We are going to need the authId in order to retrieve this authentication source later
         $state[self::AUTHID] = $this->authId;
@@ -275,17 +276,17 @@ abstract class UserPassOrgBase extends \SimpleSAML\Auth\Source
      */
     public static function handleLogin($authStateId, $username, $password, $organization)
     {
-        assert(is_string($authStateId));
-        assert(is_string($username));
-        assert(is_string($password));
-        assert(is_string($organization));
+        Assert::string($authStateId);
+        Assert::string($username);
+        Assert::string($password);
+        assert::string($organization);
 
         /* Retrieve the authentication state. */
         /** @var array $state */
         $state = Auth\State::loadState($authStateId, self::STAGEID);
 
         /* Find authentication source. */
-        assert(array_key_exists(self::AUTHID, $state));
+        Assert::keyExists($state, self::AUTHID);
 
         /** @var \SimpleSAML\Module\core\Auth\UserPassOrgBase|null $source */
         $source = Auth\Source::getById($state[self::AUTHID]);
@@ -340,14 +341,14 @@ abstract class UserPassOrgBase extends \SimpleSAML\Auth\Source
      */
     public static function listOrganizations($authStateId)
     {
-        assert(is_string($authStateId));
+        Assert::string($authStateId);
 
         /* Retrieve the authentication state. */
         /** @var array $state */
         $state = Auth\State::loadState($authStateId, self::STAGEID);
 
         /* Find authentication source. */
-        assert(array_key_exists(self::AUTHID, $state));
+        Assert::keyExists($state, self::AUTHID);
 
         /** @var \SimpleSAML\Module\core\Auth\UserPassOrgBase|null $source */
         $source = Auth\Source::getById($state[self::AUTHID]);
diff --git a/modules/core/lib/Stats/Output/File.php b/modules/core/lib/Stats/Output/File.php
index b39b072d4833fac58ecd306fd07fd5ce6d58e83d..4ff860d053923fa2ba748e5746b556d372c22249 100644
--- a/modules/core/lib/Stats/Output/File.php
+++ b/modules/core/lib/Stats/Output/File.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Module\core\Stats\Output;
 
 use SimpleSAML\Configuration;
 use SimpleSAML\Error;
+use Webmozart\Assert\Assert;
 
 /**
  * Statistics logger that writes to a set of log files
@@ -86,7 +87,7 @@ class File extends \SimpleSAML\Stats\Output
      */
     public function emit(array $data)
     {
-        assert(isset($data['time']));
+        Assert::notNull($data['time']);
 
         $time = $data['time'];
         $milliseconds = (int) (($time - (int) $time) * 1000);
diff --git a/modules/core/templates/logout-iframe-wrapper.tpl.php b/modules/core/templates/logout-iframe-wrapper.tpl.php
index 3392e4cb4f0dd202417ba8def2047a38bba938a2..a26e55a62b72e87ae1213b0ada1018aa3edc544e 100644
--- a/modules/core/templates/logout-iframe-wrapper.tpl.php
+++ b/modules/core/templates/logout-iframe-wrapper.tpl.php
@@ -1,5 +1,7 @@
 <?php
 
+use Webmozart\Assert\Assert;
+
 $id = $this->data['auth_state'];
 $SPs = $this->data['SPs'];
 
@@ -19,7 +21,7 @@ foreach ($SPs as $assocId => $sp) {
     if ($sp['core:Logout-IFrame:State'] !== 'inprogress') {
         continue;
     }
-    assert(isset($sp['core:Logout-IFrame:URL']));
+    Assert::notNull($sp['core:Logout-IFrame:URL']);
 
     $url = $sp["core:Logout-IFrame:URL"];
 
diff --git a/modules/core/templates/logout-iframe.tpl.php b/modules/core/templates/logout-iframe.tpl.php
index 54ca2c1829d135cef464a64a055d7aa965443f67..fca62bba7b2762e7fa8bf5532bae9bca3b52b5e1 100644
--- a/modules/core/templates/logout-iframe.tpl.php
+++ b/modules/core/templates/logout-iframe.tpl.php
@@ -1,5 +1,7 @@
 <?php
 
+use Webmozart\Assert\Assert;
+
 $id = $this->data['auth_state'];
 $type = $this->data['type'];
 $from = $this->data['from'];
@@ -26,7 +28,7 @@ $spTimeout = [];
 $nFailed = 0;
 $nProgress = 0;
 foreach ($SPs as $assocId => $sp) {
-    assert(isset($sp['core:Logout-IFrame:State']));
+    Assert::notNull($sp['core:Logout-IFrame:State']);
     $state = $sp['core:Logout-IFrame:State'];
     $spStatus[sha1($assocId)] = $state;
     if (isset($sp['core:Logout-IFrame:Timeout'])) {
@@ -101,7 +103,7 @@ foreach ($SPs as $assocId => $sp) {
         $spName = $assocId;
     }
 
-    assert(isset($sp['core:Logout-IFrame:State']));
+    Assert::notNull($sp['core:Logout-IFrame:State']);
     $spState = $sp['core:Logout-IFrame:State'];
 
     $spId = sha1($assocId);
@@ -181,7 +183,7 @@ if ($type === 'init') {
             if ($sp['core:Logout-IFrame:State'] !== 'inprogress') {
                 continue;
             }
-            assert(isset($sp['core:Logout-IFrame:URL']));
+            Assert::notNull($sp['core:Logout-IFrame:URL']);
             echo '<iframe style="width:0; height:0; border:0;" src="'.
                 htmlspecialchars($sp['core:Logout-IFrame:URL']).'"></iframe>';
         }
diff --git a/modules/core/templates/no_cookie.tpl.php b/modules/core/templates/no_cookie.tpl.php
index 65bdd8ceff54ea9c829b896e87f62be67748b75a..8c6c34e25288a99051c1675a055886d68881928b 100644
--- a/modules/core/templates/no_cookie.tpl.php
+++ b/modules/core/templates/no_cookie.tpl.php
@@ -1,6 +1,8 @@
 <?php
 
-assert(array_key_exists('retryURL', $this->data));
+use Webmozart\Assert\Assert;
+
+Assert::keyExists($this->data, 'retryURL');
 $retryURL = $this->data['retryURL'];
 
 $header = htmlspecialchars($this->t('{core:no_cookie:header}'));
diff --git a/modules/core/www/authenticate.php b/modules/core/www/authenticate.php
index 4658cb151c4291d0b1c7c7851488dc5a9373d62e..62ab03fc8c58977833c526d83da542f18aae66b9 100644
--- a/modules/core/www/authenticate.php
+++ b/modules/core/www/authenticate.php
@@ -1,5 +1,7 @@
 <?php
 
+use Webmozart\Assert\Assert;
+
 $config = \SimpleSAML\Configuration::getInstance();
 
 if (!array_key_exists('as', $_REQUEST)) {
@@ -23,9 +25,9 @@ if (array_key_exists(\SimpleSAML\Auth\State::EXCEPTION_PARAM, $_REQUEST)) {
     /** @var array $state */
     $state = \SimpleSAML\Auth\State::loadExceptionState();
 
-    assert(array_key_exists(\SimpleSAML\Auth\State::EXCEPTION_DATA, $state));
-    $e = $state[\SimpleSAML\Auth\State::EXCEPTION_DATA];
+    Assert::keyExists($state, \SimpleSAML\Auth\State::EXCEPTION_DATA);
 
+    $e = $state[\SimpleSAML\Auth\State::EXCEPTION_DATA];
     throw $e;
 }
 
diff --git a/modules/core/www/postredirect.php b/modules/core/www/postredirect.php
index ac2439b93f69246cc394491f4f061bf1c4de58bb..b5d08eeb0ffbfe7dd8237a17f3de14e9ebbaa19f 100644
--- a/modules/core/www/postredirect.php
+++ b/modules/core/www/postredirect.php
@@ -1,5 +1,7 @@
 <?php
 
+use Webmozart\Assert\Assert;
+
 /**
  * This page provides a way to create a redirect to a POST request.
  *
@@ -40,9 +42,9 @@ if ($postData === null) {
 
 $session->deleteData('core_postdatalink', $postId);
 
-assert(is_array($postData));
-assert(array_key_exists('url', $postData));
-assert(array_key_exists('post', $postData));
+Assert::isArray($postData);
+Assert::keyExists($postData, 'url');
+Assert::keyExists($postData, 'post');
 
 if (!\SimpleSAML\Utils\HTTP::isValidURL($postData['url'])) {
     throw new \SimpleSAML\Error\Exception('Invalid destination URL.');
diff --git a/modules/cron/hooks/hook_cron.php b/modules/cron/hooks/hook_cron.php
index a135360764f5f724e545e2c9df274c3c3e9d9fb6..18b18847b750b9b263f6bdaf1e57882cf1f59245 100644
--- a/modules/cron/hooks/hook_cron.php
+++ b/modules/cron/hooks/hook_cron.php
@@ -1,5 +1,7 @@
 <?php
 
+use Webmozart\Assert\Assert;
+
 /**
  * Hook to run a cron job.
  *
@@ -8,9 +10,9 @@
  */
 function cron_hook_cron(&$croninfo)
 {
-    assert(is_array($croninfo));
-    assert(array_key_exists('summary', $croninfo));
-    assert(array_key_exists('tag', $croninfo));
+    Assert::isArray($croninfo);
+    Assert::keyExists($croninfo, 'summary');
+    Assert::keyExists($croninfo, 'tag');
 
     $cronconfig = \SimpleSAML\Configuration::getConfig('module_cron.php');
 
diff --git a/modules/cron/hooks/hook_frontpage.php b/modules/cron/hooks/hook_frontpage.php
index 2de5d22e2ff803d1b0c1752a6319773b6d7cdce3..3ca4903136dbf2064e59cf529cbc95260c970750 100644
--- a/modules/cron/hooks/hook_frontpage.php
+++ b/modules/cron/hooks/hook_frontpage.php
@@ -1,5 +1,7 @@
 <?php
 
+use Webmozart\Assert\Assert;
+
 /**
  * Hook to add the modinfo module to the frontpage.
  *
@@ -8,8 +10,8 @@
  */
 function cron_hook_frontpage(&$links)
 {
-    assert(is_array($links));
-    assert(array_key_exists('links', $links));
+    Assert::isArray($links);
+    Assert::keyExists($links, 'links');
 
     $links['config'][] = [
         'href' => SimpleSAML\Module::getModuleURL('cron/croninfo.php'),
diff --git a/modules/exampleauth/lib/Auth/Process/RedirectTest.php b/modules/exampleauth/lib/Auth/Process/RedirectTest.php
index 50b5ca18142b04e6ad8a1aeef6b3fabd4dba4f71..88e6da07fac2005786dbb8a360faba0d2f1fbe5e 100644
--- a/modules/exampleauth/lib/Auth/Process/RedirectTest.php
+++ b/modules/exampleauth/lib/Auth/Process/RedirectTest.php
@@ -7,6 +7,7 @@ namespace SimpleSAML\Module\exampleauth\Auth\Process;
 use SimpleSAML\Auth;
 use SimpleSAML\Module;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * A simple processing filter for testing that redirection works as it should.
@@ -22,8 +23,8 @@ class RedirectTest extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$state)
     {
-        assert(is_array($state));
-        assert(array_key_exists('Attributes', $state));
+        Assert::isArray($state);
+        Assert::keyExists($state, 'Attributes');
 
         // To check whether the state is saved correctly
         $state['Attributes']['RedirectTest1'] = ['OK'];
diff --git a/modules/exampleauth/lib/Auth/Source/External.php b/modules/exampleauth/lib/Auth/Source/External.php
index f6560882719a724f6539bd51c3fd962e57824f6b..b6e8101d80385f00fe0813472284410b92562fe8 100644
--- a/modules/exampleauth/lib/Auth/Source/External.php
+++ b/modules/exampleauth/lib/Auth/Source/External.php
@@ -8,6 +8,7 @@ use SimpleSAML\Auth;
 use SimpleSAML\Error;
 use SimpleSAML\Module;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Example external authentication source.
@@ -45,8 +46,8 @@ class External extends \SimpleSAML\Auth\Source
      */
     public function __construct($info, $config)
     {
-        assert(is_array($info));
-        assert(is_array($config));
+        Assert::isArray($info);
+        Assert::isArray($config);
 
         // Call the parent constructor first, as required by the interface
         parent::__construct($info, $config);
@@ -108,7 +109,7 @@ class External extends \SimpleSAML\Auth\Source
      */
     public function authenticate(&$state)
     {
-        assert(is_array($state));
+        Assert::isArray($state);
 
         $attributes = $this->getUser();
         if ($attributes !== null) {
@@ -179,7 +180,7 @@ class External extends \SimpleSAML\Auth\Source
         /*
          * The redirect function never returns, so we never get this far.
          */
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -259,7 +260,7 @@ class External extends \SimpleSAML\Auth\Source
         /*
          * The completeAuth-function never returns, so we never get this far.
          */
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -272,7 +273,7 @@ class External extends \SimpleSAML\Auth\Source
      */
     public function logout(&$state)
     {
-        assert(is_array($state));
+        Assert::isArray($state);
 
         if (!session_id()) {
             // session_start not called before. Do it here
diff --git a/modules/exampleauth/lib/Auth/Source/StaticSource.php b/modules/exampleauth/lib/Auth/Source/StaticSource.php
index 5901d9b67bf0d9217077a57dd4454fb2512e9ceb..35deb54794a4df15f72417ce5fa675629be29b85 100644
--- a/modules/exampleauth/lib/Auth/Source/StaticSource.php
+++ b/modules/exampleauth/lib/Auth/Source/StaticSource.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace SimpleSAML\Module\exampleauth\Auth\Source;
 
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Example authentication source.
@@ -32,8 +33,8 @@ class StaticSource extends \SimpleSAML\Auth\Source
      */
     public function __construct($info, $config)
     {
-        assert(is_array($info));
-        assert(is_array($config));
+        Assert::isArray($info);
+        Assert::isArray($config);
 
         // Call the parent constructor first, as required by the interface
         parent::__construct($info, $config);
@@ -56,7 +57,7 @@ class StaticSource extends \SimpleSAML\Auth\Source
      */
     public function authenticate(&$state)
     {
-        assert(is_array($state));
+        Assert::isArray($state);
         $state['Attributes'] = $this->attributes;
     }
 }
diff --git a/modules/exampleauth/lib/Auth/Source/UserPass.php b/modules/exampleauth/lib/Auth/Source/UserPass.php
index 4a615881447cc6c5ce935212925b882241a00ec9..6d6849f2377e862b27f5c629f4e800ae2c08bf9c 100644
--- a/modules/exampleauth/lib/Auth/Source/UserPass.php
+++ b/modules/exampleauth/lib/Auth/Source/UserPass.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Module\exampleauth\Auth\Source;
 
 use SimpleSAML\Error;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Example authentication source - username & password.
@@ -36,8 +37,8 @@ class UserPass extends \SimpleSAML\Module\core\Auth\UserPassBase
      */
     public function __construct($info, $config)
     {
-        assert(is_array($info));
-        assert(is_array($config));
+        Assert::isArray($info);
+        Assert::isArray($config);
 
         // Call the parent constructor first, as required by the interface
         parent::__construct($info, $config);
@@ -87,8 +88,8 @@ class UserPass extends \SimpleSAML\Module\core\Auth\UserPassBase
      */
     protected function login($username, $password)
     {
-        assert(is_string($username));
-        assert(is_string($password));
+        Assert::string($username);
+        Assert::string($password);
 
         $userpass = $username . ':' . $password;
         if (!array_key_exists($userpass, $this->users)) {
diff --git a/modules/multiauth/lib/Auth/Source/MultiAuth.php b/modules/multiauth/lib/Auth/Source/MultiAuth.php
index 6bc2cc0abc0c6eb15ee76bc5e7551bd6e956926c..9592429730559dc981b6b8da9709269fa10a86e9 100644
--- a/modules/multiauth/lib/Auth/Source/MultiAuth.php
+++ b/modules/multiauth/lib/Auth/Source/MultiAuth.php
@@ -10,6 +10,7 @@ use SimpleSAML\Error;
 use SimpleSAML\Module;
 use SimpleSAML\Session;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Authentication source which let the user chooses among a list of
@@ -60,8 +61,8 @@ class MultiAuth extends \SimpleSAML\Auth\Source
      */
     public function __construct($info, $config)
     {
-        assert(is_array($info));
-        assert(is_array($config));
+        Assert::isArray($info);
+        Assert::isArray($config);
 
         // Call the parent constructor first, as required by the interface
         parent::__construct($info, $config);
@@ -140,7 +141,7 @@ class MultiAuth extends \SimpleSAML\Auth\Source
      */
     public function authenticate(&$state)
     {
-        assert(is_array($state));
+        Assert::isArray($state);
 
         $state[self::AUTHID] = $this->authId;
         $state[self::SOURCESID] = $this->sources;
@@ -166,7 +167,7 @@ class MultiAuth extends \SimpleSAML\Auth\Source
         Utils\HTTP::redirectTrustedURL($url, $params);
 
         // The previous function never returns, so this code is never executed
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -185,8 +186,8 @@ class MultiAuth extends \SimpleSAML\Auth\Source
      */
     public static function delegateAuthentication($authId, $state)
     {
-        assert(is_string($authId));
-        assert(is_array($state));
+        assert::string($authId);
+        Assert::isArray($state);
 
         $as = Auth\Source::getById($authId);
         $valid_sources = array_map(
@@ -235,7 +236,7 @@ class MultiAuth extends \SimpleSAML\Auth\Source
      */
     public function logout(&$state)
     {
-        assert(is_array($state));
+        Assert::isArray($state);
 
         // Get the source that was used to authenticate
         $session = Session::getSessionFromRequest();
@@ -261,7 +262,7 @@ class MultiAuth extends \SimpleSAML\Auth\Source
      */
     public function setPreviousSource($source)
     {
-        assert(is_string($source));
+        Assert::string($source);
 
         $cookieName = 'multiauth_source_' . $this->authId;
 
diff --git a/modules/portal/hooks/hook_htmlinject.php b/modules/portal/hooks/hook_htmlinject.php
index 7939763eee71a042a4c7cf68e5b3dc6ad1249393..d446a6ed63b8c1a60a0011ab67f6eed95b631afb 100644
--- a/modules/portal/hooks/hook_htmlinject.php
+++ b/modules/portal/hooks/hook_htmlinject.php
@@ -1,5 +1,7 @@
 <?php
 
+use Webmozart\Assert\Assert;
+
 /**
  * Hook to inject HTML content into all pages...
  *
@@ -8,15 +10,15 @@
  */
 function portal_hook_htmlinject(&$hookinfo)
 {
-    assert(is_array($hookinfo));
-    assert(array_key_exists('pre', $hookinfo));
-    assert(array_key_exists('post', $hookinfo));
-    assert(array_key_exists('page', $hookinfo));
+    Assert::isArray($hookinfo);
+    Assert::keyExists($hookinfo, 'pre');
+    Assert::keyExists($hookinfo, 'post');
+    Assert::keyExists($hookinfo, 'page');
 
     $links = ['links' => []];
     \SimpleSAML\Module::callHooks('frontpage', $links);
 
-    assert(is_array($links));
+    Assert::isArray($links);
 
     $portalConfig = \SimpleSAML\Configuration::getOptionalConfig('module_portal.php');
 
diff --git a/modules/saml/hooks/hook_metadata_hosted.php b/modules/saml/hooks/hook_metadata_hosted.php
index 569a6803197881b9239b48738956ac9a6b58b0a2..75ee581b251354789831b7f8b8c24b68770f1c55 100644
--- a/modules/saml/hooks/hook_metadata_hosted.php
+++ b/modules/saml/hooks/hook_metadata_hosted.php
@@ -1,5 +1,7 @@
 <?php
 
+use Webmozart\Assert\Assert;
+
 /**
  * Hook to add the metadata for hosted entities to the frontpage.
  *
@@ -8,7 +10,7 @@
  */
 function saml_hook_metadata_hosted(&$metadataHosted)
 {
-    assert(is_array($metadataHosted));
+    Assert::isArray($metadataHosted);
 
     $sources = \SimpleSAML\Auth\Source::getSourcesOfType('saml:SP');
 
diff --git a/modules/saml/lib/Auth/Process/AttributeNameID.php b/modules/saml/lib/Auth/Process/AttributeNameID.php
index 51e7d8739817639983396ca776c3d667aa11188e..7e5647cf8b230fe7dd05b2feb84236b4884a2201 100644
--- a/modules/saml/lib/Auth/Process/AttributeNameID.php
+++ b/modules/saml/lib/Auth/Process/AttributeNameID.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Module\saml\Auth\Process;
 
 use SimpleSAML\Error;
 use SimpleSAML\Logger;
+use Webmozart\Assert\Assert;
 
 /**
  * Authentication processing filter to create a NameID from an attribute.
@@ -34,7 +35,7 @@ class AttributeNameID extends \SimpleSAML\Module\saml\BaseNameIDGenerator
     public function __construct($config, $reserved)
     {
         parent::__construct($config, $reserved);
-        assert(is_array($config));
+        Assert::isArray($config);
 
         if (!isset($config['Format'])) {
             throw new Error\Exception("AttributeNameID: Missing required option 'Format'.");
diff --git a/modules/saml/lib/Auth/Process/AuthnContextClassRef.php b/modules/saml/lib/Auth/Process/AuthnContextClassRef.php
index 407e08de35fa1f60d18436a809cecf2e2dd71024..e717accfdd91e6eb43f9854bc3e4d9b16e16122d 100644
--- a/modules/saml/lib/Auth/Process/AuthnContextClassRef.php
+++ b/modules/saml/lib/Auth/Process/AuthnContextClassRef.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace SimpleSAML\Module\saml\Auth\Process;
 
 use SimpleSAML\Error;
+use Webmozart\Assert\Assert;
 
 /**
  * Filter for setting the AuthnContextClassRef in the response.
@@ -32,7 +33,7 @@ class AuthnContextClassRef extends \SimpleSAML\Auth\ProcessingFilter
     public function __construct($config, $reserved)
     {
         parent::__construct($config, $reserved);
-        assert(is_array($config));
+        Assert::isArray($config);
 
         if (!isset($config['AuthnContextClassRef'])) {
             throw new Error\Exception('Missing AuthnContextClassRef option in processing filter.');
@@ -50,7 +51,7 @@ class AuthnContextClassRef extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$state)
     {
-        assert(is_array($state));
+        Assert::isArray($state);
 
         $state['saml:AuthnContextClassRef'] = $this->authnContextClassRef;
     }
diff --git a/modules/saml/lib/Auth/Process/ExpectedAuthnContextClassRef.php b/modules/saml/lib/Auth/Process/ExpectedAuthnContextClassRef.php
index 7b0fd991cc296df664feb7bb171ca9f93d8a44f1..0edc8e00e4cc17d6018f961f440eff16d25edd71 100644
--- a/modules/saml/lib/Auth/Process/ExpectedAuthnContextClassRef.php
+++ b/modules/saml/lib/Auth/Process/ExpectedAuthnContextClassRef.php
@@ -9,6 +9,7 @@ use SimpleSAML\Error;
 use SimpleSAML\Logger;
 use SimpleSAML\Module;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Attribute filter to validate AuthnContextClassRef values.
@@ -54,7 +55,7 @@ class ExpectedAuthnContextClassRef extends \SimpleSAML\Auth\ProcessingFilter
     {
         parent::__construct($config, $reserved);
 
-        assert(is_array($config));
+        Assert::isArray($config);
         if (empty($config['accepted'])) {
             Logger::error(
                 'ExpectedAuthnContextClassRef: Configuration error. There is no accepted AuthnContextClassRef.'
@@ -74,8 +75,8 @@ class ExpectedAuthnContextClassRef extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$request)
     {
-        assert(is_array($request));
-        assert(array_key_exists('saml:sp:State', $request));
+        Assert::isArray($request);
+        Assert::keyExists($request, 'Attributes');
 
         $this->AuthnContextClassRef = $request['saml:sp:State']['saml:sp:AuthnContext'];
 
diff --git a/modules/saml/lib/Auth/Process/FilterScopes.php b/modules/saml/lib/Auth/Process/FilterScopes.php
index 8965e843732e51b0da9038ca5f0bf1bced2240cd..8b33e723a18bd1a9e1b64b3bc85b230146b542d5 100644
--- a/modules/saml/lib/Auth/Process/FilterScopes.php
+++ b/modules/saml/lib/Auth/Process/FilterScopes.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Module\saml\Auth\Process;
 
 use SimpleSAML\Logger;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Filter to remove attribute values which are not properly scoped.
@@ -35,7 +36,7 @@ class FilterScopes extends \SimpleSAML\Auth\ProcessingFilter
     public function __construct(&$config, $reserved)
     {
         parent::__construct($config, $reserved);
-        assert(is_array($config));
+        Assert::isArray($config);
 
         if (array_key_exists('attributes', $config) && !empty($config['attributes'])) {
             $this->scopedAttributes = $config['attributes'];
diff --git a/modules/saml/lib/Auth/Process/NameIDAttribute.php b/modules/saml/lib/Auth/Process/NameIDAttribute.php
index f112f37b384c9c87eb6e94a88869637e27ba46e6..e7e5655e5cdc300965fafb5fa744be58c43dff20 100644
--- a/modules/saml/lib/Auth/Process/NameIDAttribute.php
+++ b/modules/saml/lib/Auth/Process/NameIDAttribute.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Module\saml\Auth\Process;
 
 use SAML2\Constants;
 use SimpleSAML\Error;
+use Webmozart\Assert\Assert;
 
 /**
  * Authentication processing filter to create an attribute from a NameID.
@@ -40,7 +41,7 @@ class NameIDAttribute extends \SimpleSAML\Auth\ProcessingFilter
     public function __construct($config, $reserved)
     {
         parent::__construct($config, $reserved);
-        assert(is_array($config));
+        Assert::isArray($config);
 
         if (isset($config['attribute'])) {
             $this->attribute = (string) $config['attribute'];
@@ -110,16 +111,16 @@ class NameIDAttribute extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$state)
     {
-        assert(is_array($state));
-        assert(isset($state['Source']['entityid']));
-        assert(isset($state['Destination']['entityid']));
+        Assert::isArray($state);
+        Assert::keyExists($state['Source'], 'entityid');
+        Assert::keyExists($state['Destination'], 'entityid');
 
         if (!isset($state['saml:sp:NameID'])) {
             return;
         }
 
         $rep = $state['saml:sp:NameID'];
-        assert(!is_null($rep->getValue()));
+        Assert::notNull($rep->getValue());
         $rep->{'%'} = '%';
         if ($rep->getFormat() !== null) {
             $rep->setFormat(Constants::NAMEID_UNSPECIFIED);
diff --git a/modules/saml/lib/Auth/Process/PersistentNameID.php b/modules/saml/lib/Auth/Process/PersistentNameID.php
index f5c568e9aee55c2d484b62a93a5670c478d4aedd..07965c8e0101d0b9cd97d21f21fd79595febc7c6 100644
--- a/modules/saml/lib/Auth/Process/PersistentNameID.php
+++ b/modules/saml/lib/Auth/Process/PersistentNameID.php
@@ -8,6 +8,7 @@ use SAML2\Constants;
 use SimpleSAML\Error;
 use SimpleSAML\Logger;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Authentication processing filter to generate a persistent NameID.
@@ -36,7 +37,7 @@ class PersistentNameID extends \SimpleSAML\Module\saml\BaseNameIDGenerator
     public function __construct($config, $reserved)
     {
         parent::__construct($config, $reserved);
-        assert(is_array($config));
+        Assert::isArray($config);
 
         $this->format = Constants::NAMEID_PERSISTENT;
 
diff --git a/modules/saml/lib/Auth/Process/PersistentNameID2TargetedID.php b/modules/saml/lib/Auth/Process/PersistentNameID2TargetedID.php
index 24399d6596c87a81332a822224ea37c5b1a6e092..3c98c4405e3575e8e5b8b75e586b5b0a4463ab11 100644
--- a/modules/saml/lib/Auth/Process/PersistentNameID2TargetedID.php
+++ b/modules/saml/lib/Auth/Process/PersistentNameID2TargetedID.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Module\saml\Auth\Process;
 
 use SAML2\Constants;
 use SimpleSAML\Logger;
+use Webmozart\Assert\Assert;
 
 /**
  * Authentication processing filter to create the eduPersonTargetedID attribute from the persistent NameID.
@@ -40,7 +41,7 @@ class PersistentNameID2TargetedID extends \SimpleSAML\Auth\ProcessingFilter
     public function __construct($config, $reserved)
     {
         parent::__construct($config, $reserved);
-        assert(is_array($config));
+        Assert::isArray($config);
 
         if (isset($config['attribute'])) {
             $this->attribute = (string) $config['attribute'];
@@ -64,7 +65,7 @@ class PersistentNameID2TargetedID extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$state)
     {
-        assert(is_array($state));
+        Assert::isArray($state);
         if (!isset($state['saml:NameID'][Constants::NAMEID_PERSISTENT])) {
             Logger::warning(
                 'Unable to generate eduPersonTargetedID because no persistent NameID was available.'
diff --git a/modules/saml/lib/Auth/Process/SQLPersistentNameID.php b/modules/saml/lib/Auth/Process/SQLPersistentNameID.php
index c8550368f21fa0a4bc0676b5dec2c0f377413850..76a676bf15b53ceb0736ef73ef97013be440608d 100644
--- a/modules/saml/lib/Auth/Process/SQLPersistentNameID.php
+++ b/modules/saml/lib/Auth/Process/SQLPersistentNameID.php
@@ -7,6 +7,7 @@ namespace SimpleSAML\Module\saml\Auth\Process;
 use SAML2\Constants;
 use SimpleSAML\Error;
 use SimpleSAML\Logger;
+use Webmozart\Assert\Assert;
 
 /**
  * Authentication processing filter to generate a persistent NameID.
@@ -63,7 +64,7 @@ class SQLPersistentNameID extends \SimpleSAML\Module\saml\BaseNameIDGenerator
     public function __construct($config, $reserved)
     {
         parent::__construct($config, $reserved);
-        assert(is_array($config));
+        Assert::isArray($config);
 
         $this->format = Constants::NAMEID_PERSISTENT;
 
diff --git a/modules/saml/lib/Auth/Process/TransientNameID.php b/modules/saml/lib/Auth/Process/TransientNameID.php
index 7ab4fec76ae37069590f9e76955cf61c339808bf..4f82a7fbb38b40a55dc9d62f0736477b1bacdd6a 100644
--- a/modules/saml/lib/Auth/Process/TransientNameID.php
+++ b/modules/saml/lib/Auth/Process/TransientNameID.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Module\saml\Auth\Process;
 
 use SAML2\Constants;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Authentication processing filter to generate a transient NameID.
@@ -24,7 +25,7 @@ class TransientNameID extends \SimpleSAML\Module\saml\BaseNameIDGenerator
     public function __construct($config, $reserved)
     {
         parent::__construct($config, $reserved);
-        assert(is_array($config));
+        Assert::isArray($config);
 
         $this->format = Constants::NAMEID_TRANSIENT;
     }
diff --git a/modules/saml/lib/Auth/Source/SP.php b/modules/saml/lib/Auth/Source/SP.php
index 99ce51a6712d04ac921b707e1dc81820e34bfc44..e9ebaa259d02b1d081d89ee474fcd88d692549c9 100644
--- a/modules/saml/lib/Auth/Source/SP.php
+++ b/modules/saml/lib/Auth/Source/SP.php
@@ -19,6 +19,7 @@ use SimpleSAML\Session;
 use SimpleSAML\Store;
 use SimpleSAML\Utils;
 use SimpleSAML\XML\Shib13;
+use Webmozart\Assert\Assert;
 
 class SP extends \SimpleSAML\Auth\Source
 {
@@ -73,8 +74,8 @@ class SP extends \SimpleSAML\Auth\Source
      */
     public function __construct($info, $config)
     {
-        assert(is_array($info));
-        assert(is_array($config));
+        Assert::isArray($info);
+        Assert::isArray($config);
 
         // Call the parent constructor first, as required by the interface
         parent::__construct($info, $config);
@@ -288,7 +289,7 @@ class SP extends \SimpleSAML\Auth\Source
      */
     public function getIdPMetadata($entityId)
     {
-        assert(is_string($entityId));
+        Assert::string($entityId);
 
         if ($this->idp !== null && $this->idp !== $entityId) {
             throw new Error\Exception('Cannot retrieve metadata for IdP ' .
@@ -687,7 +688,7 @@ class SP extends \SimpleSAML\Auth\Source
 
         $this->sendSAML2AuthnRequest($state, $b, $ar);
 
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -704,7 +705,7 @@ class SP extends \SimpleSAML\Auth\Source
     public function sendSAML2AuthnRequest(array &$state, Binding $binding, AuthnRequest $ar)
     {
         $binding->send($ar);
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -717,7 +718,7 @@ class SP extends \SimpleSAML\Auth\Source
      */
     public function startSSO($idp, array $state)
     {
-        assert(is_string($idp));
+        Assert::string($idp);
 
         $idpMetadata = $this->getIdPMetadata($idp);
 
@@ -725,13 +726,13 @@ class SP extends \SimpleSAML\Auth\Source
         switch ($type) {
             case 'shib13-idp-remote':
                 $this->startSSO1($idpMetadata, $state);
-                assert(false); // Should not return
+                Assert::true(false); // Should not return
             case 'saml20-idp-remote':
                 $this->startSSO2($idpMetadata, $state);
-                assert(false); // Should not return
+                Assert::true(false); // Should not return
             default:
                 // Should only be one of the known types
-                assert(false);
+                Assert::true(false);
         }
     }
 
@@ -782,7 +783,7 @@ class SP extends \SimpleSAML\Auth\Source
      */
     public function authenticate(&$state)
     {
-        assert(is_array($state));
+        Assert::isArray($state);
 
         // We are going to need the authId in order to retrieve this authentication source later
         $state['saml:sp:AuthId'] = $this->authId;
@@ -822,11 +823,11 @@ class SP extends \SimpleSAML\Auth\Source
 
         if ($idp === null) {
             $this->startDisco($state);
-            assert(false);
+            Assert::true(false);
         }
 
         $this->startSSO($idp, $state);
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -929,10 +930,10 @@ class SP extends \SimpleSAML\Auth\Source
      */
     public static function askForIdPChange(array &$state)
     {
-        assert(array_key_exists('saml:sp:IdPMetadata', $state));
-        assert(array_key_exists('saml:sp:AuthId', $state));
-        assert(array_key_exists('core:IdP', $state));
-        assert(array_key_exists('SPMetadata', $state));
+        Assert::keyExists($state, 'saml:sp:IdPMetadata');
+        Assert::keyExists($state, 'saml:sp:AuthId');
+        Assert::keyExists($state, 'core:IdP');
+        Assert::keyExists($state, 'SPMetadata');
 
         if (isset($state['isPassive']) && (bool) $state['isPassive']) {
             // passive request, we cannot authenticate the user
@@ -946,7 +947,7 @@ class SP extends \SimpleSAML\Auth\Source
         $id = Auth\State::saveState($state, 'saml:proxy:invalid_idp', true);
         $url = Module::getModuleURL('saml/proxy/invalid_session.php');
         Utils\HTTP::redirectTrustedURL($url, ['AuthState' => $id]);
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -969,7 +970,7 @@ class SP extends \SimpleSAML\Auth\Source
 
         $idp = IdP::getByState($state);
         $idp->handleLogoutRequest($state, null);
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -981,7 +982,7 @@ class SP extends \SimpleSAML\Auth\Source
      */
     public static function reauthPostLogin(array $state)
     {
-        assert(isset($state['ReturnCallback']));
+        Assert::keyExists($state, 'ReturnCallback');
 
         // Update session state
         $session = Session::getSessionFromRequest();
@@ -990,7 +991,7 @@ class SP extends \SimpleSAML\Auth\Source
 
         // resume the login process
         call_user_func($state['ReturnCallback'], $state);
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -1005,7 +1006,7 @@ class SP extends \SimpleSAML\Auth\Source
      */
     public static function reauthPostLogout(IdP $idp, array $state)
     {
-        assert(isset($state['saml:sp:AuthId']));
+        Assert::keyExists($state, 'saml:sp:AuthId');
 
         Logger::debug('Proxy: logout completed.');
 
@@ -1018,7 +1019,7 @@ class SP extends \SimpleSAML\Auth\Source
 
         Logger::debug('Proxy: logging in again.');
         $sp->authenticate($state);
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -1030,10 +1031,10 @@ class SP extends \SimpleSAML\Auth\Source
      */
     public function startSLO2(&$state)
     {
-        assert(is_array($state));
-        assert(array_key_exists('saml:logout:IdP', $state));
-        assert(array_key_exists('saml:logout:NameID', $state));
-        assert(array_key_exists('saml:logout:SessionIndex', $state));
+        Assert::isArray($state);
+        Assert::keyExists($state, 'saml:logout:IdP');
+        Assert::keyExists($state, 'saml:logout:NameID');
+        Assert::keyExists($state, 'saml:logout:SessionIndex');
 
         $id = Auth\State::saveState($state, 'saml:slosent');
 
@@ -1074,7 +1075,7 @@ class SP extends \SimpleSAML\Auth\Source
         $b = Binding::getBinding($endpoint['Binding']);
         $b->send($lr);
 
-        assert(false);
+        Assert::true(false);
     }
 
 
@@ -1086,8 +1087,8 @@ class SP extends \SimpleSAML\Auth\Source
      */
     public function logout(&$state)
     {
-        assert(is_array($state));
-        assert(array_key_exists('saml:logout:Type', $state));
+        Assert::isArray($state);
+        Assert::keyExists($state, 'saml:logout:Type');
 
         $logoutType = $state['saml:logout:Type'];
         switch ($logoutType) {
@@ -1099,7 +1100,7 @@ class SP extends \SimpleSAML\Auth\Source
                 return;
             default:
                 // Should never happen
-                assert(false);
+                Assert::true(false);
         }
     }
 
@@ -1114,9 +1115,9 @@ class SP extends \SimpleSAML\Auth\Source
      */
     public function handleResponse(array $state, $idp, array $attributes)
     {
-        assert(is_string($idp));
-        assert(array_key_exists('LogoutState', $state));
-        assert(array_key_exists('saml:logout:Type', $state['LogoutState']));
+        Assert::string($idp);
+        Assert::keyExists($state, 'LogoutState');
+        Assert::keyExists($state, 'saml:logout:Type');
 
         $idpMetadata = $this->getIdPMetadata($idp);
 
@@ -1159,7 +1160,7 @@ class SP extends \SimpleSAML\Auth\Source
      */
     public function handleLogout($idpEntityId)
     {
-        assert(is_string($idpEntityId));
+        Assert::string($idpEntityId);
 
         /* Call the logout callback we registered in onProcessingCompleted(). */
         $this->callLogoutCallback($idpEntityId);
@@ -1183,8 +1184,8 @@ class SP extends \SimpleSAML\Auth\Source
      */
     public static function handleUnsolicitedAuth($authId, array $state, $redirectTo)
     {
-        assert(is_string($authId));
-        assert(is_string($redirectTo));
+        Assert::string($authId);
+        Assert::string($redirectTo);
 
         $session = Session::getSessionFromRequest();
         $session->doLogin($authId, Auth\State::getPersistentAuthData($state));
@@ -1201,9 +1202,9 @@ class SP extends \SimpleSAML\Auth\Source
      */
     public static function onProcessingCompleted(array $authProcState)
     {
-        assert(array_key_exists('saml:sp:IdP', $authProcState));
-        assert(array_key_exists('saml:sp:State', $authProcState));
-        assert(array_key_exists('Attributes', $authProcState));
+        Assert::keyExists($authProcState, 'saml:sp:IdP');
+        Assert::keyExists($authProcState, 'saml:sp:State');
+        Assert::keyExists($authProcState, 'Attributes');
 
         $idp = $authProcState['saml:sp:IdP'];
         $state = $authProcState['saml:sp:State'];
diff --git a/modules/saml/lib/BaseNameIDGenerator.php b/modules/saml/lib/BaseNameIDGenerator.php
index 04f4e4e22e5f54d50b981c0981e0cb90158d7438..bffb4435eb5d50cf6105b49c6f8ec83a06a6f8b0 100644
--- a/modules/saml/lib/BaseNameIDGenerator.php
+++ b/modules/saml/lib/BaseNameIDGenerator.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Module\saml;
 
 use SAML2\XML\saml\NameID;
 use SimpleSAML\Logger;
+use Webmozart\Assert\Assert;
 
 /**
  * Base filter for generating NameID values.
@@ -57,7 +58,7 @@ abstract class BaseNameIDGenerator extends \SimpleSAML\Auth\ProcessingFilter
     public function __construct($config, $reserved)
     {
         parent::__construct($config, $reserved);
-        assert(is_array($config));
+        Assert::isArray($config);
 
         if (isset($config['NameQualifier'])) {
             $this->nameQualifier = $config['NameQualifier'];
@@ -89,8 +90,8 @@ abstract class BaseNameIDGenerator extends \SimpleSAML\Auth\ProcessingFilter
      */
     public function process(&$state)
     {
-        assert(is_array($state));
-        assert(is_string($this->format));
+        Assert::isArray($state);
+        Assert::string($this->format);
 
         $value = $this->getValue($state);
         if ($value === null) {
@@ -121,6 +122,7 @@ abstract class BaseNameIDGenerator extends \SimpleSAML\Auth\ProcessingFilter
             $nameId->setSPNameQualifier($this->spNameQualifier);
         }
 
+        /** @psalm-suppress PossiblyNullArrayOffset */
         $state['saml:NameID'][$this->format] = $nameId;
     }
 }
diff --git a/modules/saml/lib/Error.php b/modules/saml/lib/Error.php
index c91c8e97d2e9d7cb3abe52807a94007f8f5c4c27..26c51bcb921eb66b2b7c0a414a0b030f0befe961 100644
--- a/modules/saml/lib/Error.php
+++ b/modules/saml/lib/Error.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace SimpleSAML\Module\saml;
 
 use SAML2\Constants;
+use Webmozart\Assert\Assert;
 
 /**
  * Class for representing a SAML 2 error.
@@ -48,9 +49,9 @@ class Error extends \SimpleSAML\Error\Exception
      */
     public function __construct($status, $subStatus = null, $statusMessage = null, \Exception $cause = null)
     {
-        assert(is_string($status));
-        assert($subStatus === null || is_string($subStatus));
-        assert($statusMessage === null || is_string($statusMessage));
+        Assert::string($status);
+        Assert::nullOrString($subStatus);
+        Assert::nullOrString($statusMessage);
 
         $st = self::shortStatus($status);
         if ($subStatus !== null) {
diff --git a/modules/saml/lib/IdP/SAML1.php b/modules/saml/lib/IdP/SAML1.php
index 861f9612ba964de1fe62de598d00bd78db6ab7ba..5b2eeb226757ee6f9846b45394651603b84640b8 100644
--- a/modules/saml/lib/IdP/SAML1.php
+++ b/modules/saml/lib/IdP/SAML1.php
@@ -14,6 +14,7 @@ use SimpleSAML\Metadata\MetaDataStorageHandler;
 use SimpleSAML\Stats;
 use SimpleSAML\Utils;
 use SimpleSAML\XML\Shib13\AuthnResponse;
+use Webmozart\Assert\Assert;
 
 /**
  * IdP implementation for SAML 1.1 protocol.
@@ -137,10 +138,13 @@ class SAML1
      */
     public static function sendResponse(array $state)
     {
-        assert(isset($state['Attributes']));
-        assert(isset($state['SPMetadata']));
-        assert(isset($state['saml:shire']));
-        assert(array_key_exists('saml:target', $state)); // Can be NULL
+        Assert::keyExists($state, 'Attributes');
+        Assert::keyExists($state, 'SPMetadata');
+        Assert::keyExists($state, 'saml:shire');
+        Assert::notNull($state['Attributes']);
+        Assert::notNull($state['SPMetadata']);
+        Assert::notNull($state['saml:shire']);
+        Assert::keyExists($state, 'saml:target'); // Can be NULL
 
         $spMetadata = $state["SPMetadata"];
         $spEntityId = $spMetadata['entityid'];
diff --git a/modules/saml/lib/IdP/SAML2.php b/modules/saml/lib/IdP/SAML2.php
index 0e654d133e288f15a8cda9fe4bcd48567b1b898f..664bcf6f5ca337fb640e4f2d72fd91d5b94682e3 100644
--- a/modules/saml/lib/IdP/SAML2.php
+++ b/modules/saml/lib/IdP/SAML2.php
@@ -34,6 +34,7 @@ use SimpleSAML\Metadata\MetaDataStorageHandler;
 use SimpleSAML\Module;
 use SimpleSAML\Stats;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * IdP implementation for SAML 2.0 protocol.
@@ -50,11 +51,11 @@ class SAML2
      */
     public static function sendResponse(array $state)
     {
-        assert(isset($state['Attributes']));
-        assert(isset($state['SPMetadata']));
-        assert(isset($state['saml:ConsumerURL']));
-        assert(array_key_exists('saml:RequestId', $state)); // Can be NULL
-        assert(array_key_exists('saml:RelayState', $state)); // Can be NULL.
+        Assert::keyExists($state, 'saml:RequestId'); // Can be NULL
+        Assert::keyExists($state, 'saml:RelayState'); // Can be NULL.
+        Assert::notNull($state['Attributes']);
+        Assert::notNull($state['SPMetadata']);
+        Assert::notNull($state['saml:ConsumerURL']);
 
         $spMetadata = $state["SPMetadata"];
         $spEntityId = $spMetadata['entityid'];
@@ -128,10 +129,10 @@ class SAML2
      */
     public static function handleAuthError(\SimpleSAML\Error\Exception $exception, array $state)
     {
-        assert(isset($state['SPMetadata']));
-        assert(isset($state['saml:ConsumerURL']));
-        assert(array_key_exists('saml:RequestId', $state)); // Can be NULL.
-        assert(array_key_exists('saml:RelayState', $state)); // Can be NULL.
+        Assert::keyExists($state, 'saml:RequestId'); // Can be NULL.
+        Assert::keyExists($state, 'saml:RelayState'); // Can be NULL.
+        Assert::notNull($state['SPMetadata']);
+        Assert::notNull($state['saml:ConsumerURL']);
 
         $spMetadata = $state["SPMetadata"];
         $spEntityId = $spMetadata['entityid'];
@@ -495,7 +496,7 @@ class SAML2
      */
     public static function sendLogoutRequest(IdP $idp, array $association, $relayState)
     {
-        assert(is_string($relayState) || $relayState === null);
+        Assert::nullOrString($relayState);
 
         Logger::info('Sending SAML 2.0 LogoutRequest to: ' . var_export($association['saml:entityID'], true));
 
@@ -533,9 +534,9 @@ class SAML2
      */
     public static function sendLogoutResponse(IdP $idp, array $state)
     {
-        assert(isset($state['saml:SPEntityId']));
-        assert(isset($state['saml:RequestId']));
-        assert(array_key_exists('saml:RelayState', $state)); // Can be NULL.
+        Assert::keyExists($state, 'saml:RelayState'); // Can be NULL.
+        Assert::notNull($state['saml:SPEntityId']);
+        Assert::notNull($state['saml:RequestId']);
 
         $spEntityId = $state['saml:SPEntityId'];
 
@@ -678,7 +679,7 @@ class SAML2
      */
     public static function getLogoutURL(IdP $idp, array $association, $relayState)
     {
-        assert(is_string($relayState) || $relayState === null);
+        Assert::nullOrString($relayState);
 
         Logger::info('Sending SAML 2.0 LogoutRequest to: ' . var_export($association['saml:entityID'], true));
 
@@ -1048,7 +1049,7 @@ class SAML2
                             $doc = DOMDocumentFactory::fromString('<root>' . $value . '</root>');
                             $value = $doc->firstChild->childNodes;
                         }
-                        assert($value instanceof DOMNodeList || $value instanceof NameID);
+                        Assert::isInstanceOfAny($value, [\DOMNodeList::class, \SAML2\XML\saml\NameID::class]);
                         break;
                     default:
                         throw new Error\Exception('Invalid encoding for attribute ' .
@@ -1115,8 +1116,8 @@ class SAML2
         Configuration $spMetadata,
         array &$state
     ): Assertion {
-        assert(isset($state['Attributes']));
-        assert(isset($state['saml:ConsumerURL']));
+        Assert::notNull($state['Attributes']);
+        Assert::notNull($state['saml:ConsumerURL']);
 
         $now = time();
 
diff --git a/modules/saml/lib/IdP/SQLNameID.php b/modules/saml/lib/IdP/SQLNameID.php
index 592ec92c05bad3e5cda8886e28a33d24ec5a61af..37a3a2899ae56ed753212a3f4d4a6a1ae61e1afb 100644
--- a/modules/saml/lib/IdP/SQLNameID.php
+++ b/modules/saml/lib/IdP/SQLNameID.php
@@ -10,6 +10,7 @@ use SimpleSAML\Error;
 use SimpleSAML\Store;
 use SimpleSAML\Database;
 use SimpleSAML\Configuration;
+use Webmozart\Assert\Assert;
 
 /**
  * Helper class for working with persistent NameIDs stored in SQL datastore.
@@ -179,10 +180,10 @@ class SQLNameID
      */
     public static function add($idpEntityId, $spEntityId, $user, $value, array $config = [])
     {
-        assert(is_string($idpEntityId));
-        assert(is_string($spEntityId));
-        assert(is_string($user));
-        assert(is_string($value));
+        Assert::string($idpEntityId);
+        Assert::string($spEntityId);
+        Assert::string($user);
+        Assert::string($value);
 
         $params = [
             '_idp' => $idpEntityId,
@@ -208,9 +209,9 @@ class SQLNameID
      */
     public static function get($idpEntityId, $spEntityId, $user, array $config = [])
     {
-        assert(is_string($idpEntityId));
-        assert(is_string($spEntityId));
-        assert(is_string($user));
+        Assert::string($idpEntityId);
+        Assert::string($spEntityId);
+        Assert::string($user);
 
         $params = [
             '_idp' => $idpEntityId,
@@ -243,9 +244,9 @@ class SQLNameID
      */
     public static function delete($idpEntityId, $spEntityId, $user, array $config = [])
     {
-        assert(is_string($idpEntityId));
-        assert(is_string($spEntityId));
-        assert(is_string($user));
+        Assert::string($idpEntityId);
+        Assert::string($spEntityId);
+        assert::string($user);
 
         $params = [
             '_idp' => $idpEntityId,
@@ -269,8 +270,8 @@ class SQLNameID
      */
     public static function getIdentities($idpEntityId, $spEntityId, array $config = [])
     {
-        assert(is_string($idpEntityId));
-        assert(is_string($spEntityId));
+        Assert::string($idpEntityId);
+        assert::string($spEntityId);
 
         $params = [
             '_idp' => $idpEntityId,
diff --git a/modules/saml/lib/Message.php b/modules/saml/lib/Message.php
index 57814ba7ddd16ea318d16cbaf43437fa8e8e0b9a..fe047d955ef7585298a1dbd8634d0113c7a2842b 100644
--- a/modules/saml/lib/Message.php
+++ b/modules/saml/lib/Message.php
@@ -22,6 +22,7 @@ use SimpleSAML\Configuration;
 use SimpleSAML\Error as SSP_Error;
 use SimpleSAML\Logger;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * Common code for building SAML 2 messages based on the available metadata.
@@ -319,7 +320,7 @@ class Message
         // load the new private key if it exists
         $keyArray = Utils\Crypto::loadPrivateKey($dstMetadata, false, 'new_');
         if ($keyArray !== null) {
-            assert(isset($keyArray['PEM']));
+            assert::keyExists($keyArray, 'PEM');
 
             $key = new XMLSecurityKey(XMLSecurityKey::RSA_1_5, ['type' => 'private']);
             if (array_key_exists('password', $keyArray)) {
@@ -329,9 +330,13 @@ class Message
             $keys[] = $key;
         }
 
-        // find the existing private key
+        /**
+         * find the existing private key
+         *
+         * @var array $keyArray  Because the second param is true
+         */
         $keyArray = Utils\Crypto::loadPrivateKey($dstMetadata, true);
-        assert(isset($keyArray['PEM']));
+        Assert::keyExists($keyArray, 'PEM');
 
         $key = new XMLSecurityKey(XMLSecurityKey::RSA_1_5, ['type' => 'private']);
         if (array_key_exists('password', $keyArray)) {
@@ -384,7 +389,7 @@ class Message
         Configuration $dstMetadata,
         $assertion
     ): Assertion {
-        assert($assertion instanceof Assertion || $assertion instanceof EncryptedAssertion);
+        Assert::isInstanceOfAny($assertion, [\SAML2\Assertion::class, \SAML2\EncryptedAssertion::class]);
 
         if ($assertion instanceof Assertion) {
             $encryptAssertion = $srcMetadata->getBoolean('assertion.encryption', null);
@@ -669,7 +674,7 @@ class Message
         $assertion,
         bool $responseSigned
     ): Assertion {
-        assert($assertion instanceof Assertion || $assertion instanceof EncryptedAssertion);
+        Assert::isInstanceOfAny($assertion, [\SAML2\Assertion::class, \SAML2\EncryptedAssertion::class]);
 
         $assertion = self::decryptAssertion($idpMetadata, $spMetadata, $assertion);
         self::decryptAttributes($idpMetadata, $spMetadata, $assertion);
diff --git a/modules/saml/lib/SP/LogoutStore.php b/modules/saml/lib/SP/LogoutStore.php
index fd64666945edc2e312caa5ae9a75a4a02a4c646a..9123eadd0368d97b90992b3e1988afa3054b0c6d 100644
--- a/modules/saml/lib/SP/LogoutStore.php
+++ b/modules/saml/lib/SP/LogoutStore.php
@@ -10,6 +10,7 @@ use SimpleSAML\Logger;
 use SimpleSAML\Session;
 use SimpleSAML\Store;
 use SimpleSAML\Utils;
+use Webmozart\Assert\Assert;
 
 /**
  * A directory over logout information.
@@ -306,7 +307,7 @@ class LogoutStore
             if ($sessionId === null) {
                 continue;
             }
-            assert(is_string($sessionId));
+            Assert::string($sessionId);
             $res[$sessionIndex] = $sessionId;
         }
 
@@ -331,9 +332,9 @@ class LogoutStore
      */
     public static function addSession($authId, $nameId, $sessionIndex, $expire)
     {
-        assert(is_string($authId));
-        assert(is_string($sessionIndex) || $sessionIndex === null);
-        assert(is_int($expire));
+        Assert::string($authId);
+        Assert::nullorString($sessionIndex);
+        Assert::integer($expire);
 
         $session = Session::getSessionFromRequest();
         if ($session->isTransient()) {
@@ -386,7 +387,7 @@ class LogoutStore
      */
     public static function logoutSessions($authId, $nameId, array $sessionIndexes)
     {
-        assert(is_string($authId));
+        Assert::string($authId);
 
         $store = Store::getInstance();
         if ($store === false) {
@@ -400,7 +401,7 @@ class LogoutStore
 
         // Normalize SessionIndexes
         foreach ($sessionIndexes as &$sessionIndex) {
-            assert(is_string($sessionIndex));
+            Assert::string($sessionIndex);
             if (strlen($sessionIndex) > 50) {
                 $sessionIndex = sha1($sessionIndex);
             }
diff --git a/modules/saml/www/sp/discoresp.php b/modules/saml/www/sp/discoresp.php
index ec944c3ed8ed6e15bf997f2cf8b2e671980f4fe5..8ee798645fc591a1f35fba38175eac2a92cdd322 100644
--- a/modules/saml/www/sp/discoresp.php
+++ b/modules/saml/www/sp/discoresp.php
@@ -4,6 +4,8 @@
  * Handler for response from IdP discovery service.
  */
 
+use Webmozart\Assert\Assert;
+
 if (!array_key_exists('AuthID', $_REQUEST)) {
     throw new \SimpleSAML\Error\BadRequest('Missing AuthID to discovery service response handler');
 }
@@ -16,7 +18,7 @@ if (!array_key_exists('idpentityid', $_REQUEST)) {
 $state = \SimpleSAML\Auth\State::loadState($_REQUEST['AuthID'], 'saml:sp:sso');
 
 // Find authentication source
-assert(array_key_exists('saml:sp:AuthId', $state));
+Assert::keyExists($state, 'saml:sp:AuthId');
 $sourceId = $state['saml:sp:AuthId'];
 
 $source = \SimpleSAML\Auth\Source::getById($sourceId);
diff --git a/modules/saml/www/sp/saml1-acs.php b/modules/saml/www/sp/saml1-acs.php
index 6b981774ce113d96c7e72748fab7c3c4874f5a83..34ca9ece6428edc6edcd48e11ff7b6d469d2099e 100644
--- a/modules/saml/www/sp/saml1-acs.php
+++ b/modules/saml/www/sp/saml1-acs.php
@@ -1,6 +1,7 @@
 <?php
 
 use SimpleSAML\Bindings\Shib13\Artifact;
+use Webmozart\Assert\Assert;
 
 if (!array_key_exists('SAMLResponse', $_REQUEST) && !array_key_exists('SAMLart', $_REQUEST)) {
     throw new \SimpleSAML\Error\BadRequest('Missing SAMLResponse or SAMLart parameter.');
@@ -40,14 +41,14 @@ if (preg_match('@^https?://@i', $target)) {
     $state = \SimpleSAML\Auth\State::loadState($_REQUEST['TARGET'], 'saml:sp:sso');
 
     // Check that the authentication source is correct
-    assert(array_key_exists('saml:sp:AuthId', $state));
+    Assert::keyExists($state, 'saml:sp:AuthId');
     if ($state['saml:sp:AuthId'] !== $sourceId) {
         throw new \SimpleSAML\Error\Exception(
             'The authentication source id in the URL does not match the authentication source which sent the request.'
         );
     }
 
-    assert(isset($state['saml:idp']));
+    Assert::notNull($state['saml:idp']);
 }
 
 $spMetadata = $source->getMetadata();
@@ -92,4 +93,4 @@ $state['LogoutState'] = $logoutState;
 $state['saml:sp:NameID'] = $response->getNameID();
 
 $source->handleResponse($state, $responseIssuer, $attributes);
-assert(false);
+Assert::true(false);
diff --git a/modules/saml/www/sp/saml2-acs.php b/modules/saml/www/sp/saml2-acs.php
index 3d1db4088bc4cdbcb5f592f6e4996c8851d0de9c..11a17bf4d64028e58348754317eba629ef242b53 100644
--- a/modules/saml/www/sp/saml2-acs.php
+++ b/modules/saml/www/sp/saml2-acs.php
@@ -4,6 +4,8 @@
  * Assertion consumer service handler for SAML 2.0 SP authentication client.
  */
 
+use Webmozart\Assert\Assert;
+
 if (!array_key_exists('PATH_INFO', $_SERVER)) {
     throw new \SimpleSAML\Error\BadRequest('Missing authentication source ID in assertion consumer service URL');
 }
@@ -95,7 +97,7 @@ if (!empty($stateId)) {
 
 if ($state) {
     // check that the authentication source is correct
-    assert(array_key_exists('saml:sp:AuthId', $state));
+    Assert::keyExists($state, 'saml:sp:AuthId');
     if ($state['saml:sp:AuthId'] !== $sourceId) {
         throw new \SimpleSAML\Error\Exception(
             'The authentication source id in the URL does not match the authentication source which sent the request.'
@@ -103,7 +105,7 @@ if ($state) {
     }
 
     // check that the issuer is the one we are expecting
-    assert(array_key_exists('ExpectedIssuer', $state));
+    Assert::keyExists($state, 'ExpectedIssuer');
     if ($state['ExpectedIssuer'] !== $issuer) {
         $idpMetadata = $source->getIdPMetadata($issuer);
         $idplist = $idpMetadata->getArrayize('IDPList', []);
@@ -262,4 +264,4 @@ if (isset($state['\SimpleSAML\Auth\Source.ReturnURL'])) {
 $state['PersistentAuthData'][] = 'saml:sp:prevAuth';
 
 $source->handleResponse($state, $issuer, $attributes);
-assert(false);
+Assert::true(false);
diff --git a/www/saml2/idp/SSOService.php b/www/saml2/idp/SSOService.php
index 5a400b854499c39bc04cf7fc62d99ede897551ed..61b472ece679d30b62af7dfd008ba67b756e7959 100644
--- a/www/saml2/idp/SSOService.php
+++ b/www/saml2/idp/SSOService.php
@@ -11,6 +11,8 @@
 
 require_once('../../_include.php');
 
+use Webmozart\Assert\Assert;
+
 \SimpleSAML\Logger::info('SAML2.0 - IdP.SSOService: Accessing SAML 2.0 IdP endpoint SSOService');
 
 $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
@@ -26,4 +28,4 @@ try {
         throw $e; // do not ignore other exceptions!
     }
 }
-assert(false);
+Assert::true(false);
diff --git a/www/saml2/idp/SingleLogoutService.php b/www/saml2/idp/SingleLogoutService.php
index 2d3c0e4b4a1c1f2331aab0c9da1b9e80d31b0eb1..ab4a49b0f1062346cf10f3b119d24511371238ed 100644
--- a/www/saml2/idp/SingleLogoutService.php
+++ b/www/saml2/idp/SingleLogoutService.php
@@ -10,6 +10,8 @@
 
 require_once('../../_include.php');
 
+use Webmozart\Assert\Assert;
+
 \SimpleSAML\Logger::info('SAML2.0 - IdP.SingleLogoutService: Accessing SAML 2.0 IdP endpoint SingleLogoutService');
 
 $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
@@ -34,4 +36,4 @@ if (isset($_REQUEST['ReturnTo'])) {
         }
     }
 }
-assert(false);
+Assert::true(false);
diff --git a/www/saml2/idp/initSLO.php b/www/saml2/idp/initSLO.php
index 82c38c8d4d0dddcb4d895916a9b09551faa76466..24e6748f870df7e971643feb540de754d3950cfe 100644
--- a/www/saml2/idp/initSLO.php
+++ b/www/saml2/idp/initSLO.php
@@ -2,6 +2,8 @@
 
 require_once('../../_include.php');
 
+use Webmozart\Assert\Assert;
+
 $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
 $idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
 $idp = \SimpleSAML\IdP::getById('saml2:' . $idpEntityId);
@@ -13,4 +15,4 @@ if (!isset($_GET['RelayState'])) {
 }
 
 $idp->doLogoutRedirect(\SimpleSAML\Utils\HTTP::checkURLAllowed((string) $_GET['RelayState']));
-assert(false);
+Assert::true(false);
diff --git a/www/saml2/idp/metadata.php b/www/saml2/idp/metadata.php
index 698cb9f4a308397905fe66165d02f9aeb9f3ea6c..4ba2fa1d82b92e9ab30b0e5556955c4bd668b142 100644
--- a/www/saml2/idp/metadata.php
+++ b/www/saml2/idp/metadata.php
@@ -8,6 +8,7 @@ use SimpleSAML\Utils\Auth as Auth;
 use SimpleSAML\Utils\Crypto as Crypto;
 use SimpleSAML\Utils\HTTP as HTTP;
 use SimpleSAML\Utils\Config\Metadata as Metadata;
+use Webmozart\Assert\Assert;
 
 // load SimpleSAMLphp configuration and metadata
 $config = \SimpleSAML\Configuration::getInstance();
@@ -55,7 +56,7 @@ try {
 
     if ($idpmeta->hasValue('https.certificate')) {
         $httpsCert = Crypto::loadPublicKey($idpmeta, true, 'https.');
-        assert(isset($httpsCert['certData']));
+        Assert::notNull($httpsCert['certData']);
         $availableCerts['https.crt'] = $httpsCert;
         $keys[] = [
             'type'            => 'X509Certificate',
diff --git a/www/shib13/idp/SSOService.php b/www/shib13/idp/SSOService.php
index 14a014fcdb8e8e56b948534494fdea47c34ade5e..d99365867b8322486f15e7ac192c50ee8f548473 100644
--- a/www/shib13/idp/SSOService.php
+++ b/www/shib13/idp/SSOService.php
@@ -11,6 +11,8 @@
 
 require_once '../../_include.php';
 
+use Webmozart\Assert\Assert;
+
 \SimpleSAML\Logger::info('Shib1.3 - IdP.SSOService: Accessing Shibboleth 1.3 IdP endpoint SSOService');
 
 $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
@@ -18,4 +20,4 @@ $idpEntityId = $metadata->getMetaDataCurrentEntityID('shib13-idp-hosted');
 $idp = \SimpleSAML\IdP::getById('saml1:'.$idpEntityId);
 \SimpleSAML\Module\saml\IdP\SAML1::receiveAuthnRequest($idp);
 
-assert(false);
+Assert::true(false);