diff --git a/lib/SimpleSAML/Auth/AuthenticationFactory.php b/lib/SimpleSAML/Auth/AuthenticationFactory.php
index e59bac61bb05a5ee668b68ea955a5315429d089b..e5997b0e634aa6d95b43fa3b7754992fe4156a5f 100644
--- a/lib/SimpleSAML/Auth/AuthenticationFactory.php
+++ b/lib/SimpleSAML/Auth/AuthenticationFactory.php
@@ -13,10 +13,10 @@ use SimpleSAML\Session;
 class AuthenticationFactory
 {
     /** @var \SimpleSAML\Configuration */
-    protected $config;
+    protected Configuration $config;
 
     /** @var \SimpleSAML\Session */
-    protected $session;
+    protected Session $session;
 
 
     /**
diff --git a/lib/SimpleSAML/Auth/ProcessingChain.php b/lib/SimpleSAML/Auth/ProcessingChain.php
index 65a8fcd029cdd124d35b21c61afb62d7f953623d..a3612ff1981c85583738f14832f1e12f037a1d57 100644
--- a/lib/SimpleSAML/Auth/ProcessingChain.php
+++ b/lib/SimpleSAML/Auth/ProcessingChain.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace SimpleSAML\Auth;
 
+use Exception;
 use SimpleSAML\Assert\Assert;
 use SimpleSAML\Configuration;
 use SimpleSAML\Error;
@@ -45,7 +46,7 @@ class ProcessingChain
     /**
      * All authentication processing filters, in the order they should be applied.
      */
-    private $filters;
+    private array $filters = [];
 
 
     /**
@@ -58,8 +59,6 @@ class ProcessingChain
      */
     public function __construct(array $idpMetadata, array $spMetadata, string $mode = 'idp')
     {
-        $this->filters = [];
-
         $config = Configuration::getInstance();
         $configauthproc = $config->getArray('authproc.' . $mode, null);
 
@@ -125,7 +124,7 @@ class ProcessingChain
             }
 
             if (!is_array($filter)) {
-                throw new \Exception('Invalid authentication processing filter configuration: ' .
+                throw new Exception('Invalid authentication processing filter configuration: ' .
                     'One of the filters wasn\'t a string or an array.');
             }
 
@@ -147,7 +146,7 @@ class ProcessingChain
     private static function parseFilter(array $config, int $priority): ProcessingFilter
     {
         if (!array_key_exists('class', $config)) {
-            throw new \Exception('Authentication processing filter without name given.');
+            throw new Exception('Authentication processing filter without name given.');
         }
 
         $className = Module::resolveClass(
@@ -200,7 +199,7 @@ class ProcessingChain
         } catch (Error\Exception $e) {
             // No need to convert the exception
             throw $e;
-        } catch (\Exception $e) {
+        } catch (Exception $e) {
             /*
              * To be consistent with the exception we return after an redirect,
              * we convert this exception before returning it.
@@ -231,7 +230,7 @@ class ProcessingChain
                 $filter->process($state);
             } catch (Error\Exception $e) {
                 State::throwException($state, $e);
-            } catch (\Exception $e) {
+            } catch (Exception $e) {
                 $e = new Error\UnserializableException($e);
                 State::throwException($state, $e);
             }
diff --git a/lib/SimpleSAML/Auth/ProcessingFilter.php b/lib/SimpleSAML/Auth/ProcessingFilter.php
index 90442a5b2cfa91e6473b39a63b028c149622d962..139d66816c8a77cf03e07984ee8060af47eee7ba 100644
--- a/lib/SimpleSAML/Auth/ProcessingFilter.php
+++ b/lib/SimpleSAML/Auth/ProcessingFilter.php
@@ -32,9 +32,9 @@ abstract class ProcessingFilter
      * The priority can be any integer. The default for most filters is 50. Filters may however
      * specify their own default, if they typically should be amongst the first or the last filters.
      *
-     * The prioroty can also be overridden by the user by specifying the '%priority' option.
+     * The priority can also be overridden by the user by specifying the '%priority' option.
      */
-    public $priority = 50;
+    public int $priority = 50;
 
 
     /**
diff --git a/lib/SimpleSAML/Auth/Simple.php b/lib/SimpleSAML/Auth/Simple.php
index 1d435a7efb31d2465d2dd3c39e05b1afb212db6b..6e0ac4e07c94364824d4ff32412cbc2debcf3586 100644
--- a/lib/SimpleSAML/Auth/Simple.php
+++ b/lib/SimpleSAML/Auth/Simple.php
@@ -24,13 +24,13 @@ class Simple
      *
      * @var string
      */
-    protected $authSource;
+    protected string $authSource;
 
     /** @var \SimpleSAML\Configuration */
-    protected $app_config;
+    protected Configuration $app_config;
 
     /** @var \SimpleSAML\Session */
-    protected $session;
+    protected Session $session;
 
 
     /**
diff --git a/lib/SimpleSAML/Auth/Source.php b/lib/SimpleSAML/Auth/Source.php
index 3f52d31111c5e73f19ddfcb83d5d8a5472ded7a5..80617d427cf25b70815a5f80daee898817559219 100644
--- a/lib/SimpleSAML/Auth/Source.php
+++ b/lib/SimpleSAML/Auth/Source.php
@@ -28,7 +28,7 @@ abstract class Source
      *
      * @var string
      */
-    protected $authId;
+    protected string $authId = '';
 
 
     /**
diff --git a/lib/SimpleSAML/Auth/State.php b/lib/SimpleSAML/Auth/State.php
index 175fd9494e5f0cd4c7df787fed6c30470311f5c7..1e7153ea5c57a6b6c4e70243d661242a58463a08 100644
--- a/lib/SimpleSAML/Auth/State.php
+++ b/lib/SimpleSAML/Auth/State.php
@@ -101,7 +101,7 @@ class State
     /**
      * State timeout.
      */
-    private static $stateTimeout = null;
+    private static ?int $stateTimeout = null;
 
 
     /**
diff --git a/lib/SimpleSAML/Command/RouterDebugCommand.php b/lib/SimpleSAML/Command/RouterDebugCommand.php
index b5610c797dff3aa415330de1c352a1a92c5d5056..0df7febce3d4c5f6c3cc95042aaf40bbe573124f 100644
--- a/lib/SimpleSAML/Command/RouterDebugCommand.php
+++ b/lib/SimpleSAML/Command/RouterDebugCommand.php
@@ -20,9 +20,9 @@ class RouterDebugCommand extends Command
     protected static $defaultName = 'debug:router';
 
     /**
-     * @var RouterInterface
+     * @var \Symfony\Component\Routing\RouterInterface
      */
-    private $router;
+    private RouterInterface $router;
 
 
     /**
diff --git a/lib/SimpleSAML/Configuration.php b/lib/SimpleSAML/Configuration.php
index d562448cbf35da57f431b1b233b356a70c80c0b8..78e1cf80e067a0617b25b7ab058eb8eb6c35ee2e 100644
--- a/lib/SimpleSAML/Configuration.php
+++ b/lib/SimpleSAML/Configuration.php
@@ -31,9 +31,9 @@ class Configuration implements Utils\ClearableState
     /**
      * Associative array with mappings from instance-names to configuration objects.
      *
-     * @var array
+     * @var array<string, \SimpleSAML\Configuration>
      */
-    private static $instance = [];
+    private static array $instance = [];
 
     /**
      * Configuration directories.
@@ -41,9 +41,9 @@ class Configuration implements Utils\ClearableState
      * This associative array contains the mappings from configuration sets to
      * configuration directories.
      *
-     * @var array
+     * @var array<string, string>
      */
-    private static $configDirs = [];
+    private static array $configDirs = [];
 
     /**
      * Cache of loaded configuration files.
@@ -52,28 +52,28 @@ class Configuration implements Utils\ClearableState
      *
      * @var array
      */
-    private static $loadedConfigs = [];
+    private static array $loadedConfigs = [];
 
     /**
      * The configuration array.
      *
      * @var array
      */
-    private $configuration;
+    private array $configuration;
 
     /**
      * The location which will be given when an error occurs.
      *
      * @var string
      */
-    private $location;
+    private string $location;
 
     /**
      * The file this configuration was loaded from.
      *
      * @var string|null
      */
-    private $filename = null;
+    private ?string $filename = null;
 
     /**
      * Initializes a configuration from the given array.
diff --git a/lib/SimpleSAML/Database.php b/lib/SimpleSAML/Database.php
index 8a076654dae269a2256a0305c1c51bdec0d5bed5..ab5ddc2c71c1eac8a11140dfe315b442685331a8 100644
--- a/lib/SimpleSAML/Database.php
+++ b/lib/SimpleSAML/Database.php
@@ -27,28 +27,30 @@ class Database
 {
     /**
      * This variable holds the instance of the session - Singleton approach.
+     * @var \SimpleSAML\Database[]
      */
-    private static $instance = [];
+    private static array $instance = [];
 
     /**
      * PDO Object for the Primary database server
      */
-    private $dbPrimary;
+    private PDO $dbPrimary;
 
     /**
      * Array of PDO Objects for configured database secondaries
+     * @var \PDO[]
      */
-    private $dbSecondaries = [];
+    private array $dbSecondaries = [];
 
     /**
      * Prefix to apply to the tables
      */
-    private $tablePrefix;
+    private string $tablePrefix;
 
     /**
      * Array with information on the last error occurred.
      */
-    private $lastError;
+    private array $lastError = [];
 
 
     /**
diff --git a/lib/SimpleSAML/Error/AuthSource.php b/lib/SimpleSAML/Error/AuthSource.php
index 9ee3a50d76852c860bcc43383df46082b1e9246a..1de3be5935c0768bce2ac4070a97918b7ee7025b 100644
--- a/lib/SimpleSAML/Error/AuthSource.php
+++ b/lib/SimpleSAML/Error/AuthSource.php
@@ -20,13 +20,13 @@ class AuthSource extends Error
      * Authsource module name
      * @var string
      */
-    private $authsource;
+    private string $authsource;
 
     /**
      * Reason why this request was invalid.
      * @var string
      */
-    private $reason;
+    private string $reason;
 
 
     /**
diff --git a/lib/SimpleSAML/Error/BadRequest.php b/lib/SimpleSAML/Error/BadRequest.php
index ed491bd0eccfbdccc0128b5ed1746ce731302525..2b3c2c8e0dd29422afceb740d0fb39bb59efd1de 100644
--- a/lib/SimpleSAML/Error/BadRequest.php
+++ b/lib/SimpleSAML/Error/BadRequest.php
@@ -21,7 +21,7 @@ class BadRequest extends Error
      * Reason why this request was invalid.
      * @var string
      */
-    private $reason;
+    private string $reason;
 
 
     /**
diff --git a/lib/SimpleSAML/Error/ConfigurationError.php b/lib/SimpleSAML/Error/ConfigurationError.php
index 4fdcdded368a5177f56601c7fb52bc63633320f2..bc0d9c261c130973c7c2e68ecb28317294e5fe73 100644
--- a/lib/SimpleSAML/Error/ConfigurationError.php
+++ b/lib/SimpleSAML/Error/ConfigurationError.php
@@ -17,14 +17,14 @@ class ConfigurationError extends Error
      *
      * @var null|string
      */
-    protected $reason;
+    protected ?string $reason;
 
     /**
      * The configuration file that caused this exception.
      *
      * @var null|string
      */
-    protected $config_file;
+    protected ?string $config_file;
 
 
     /**
diff --git a/lib/SimpleSAML/Error/CriticalConfigurationError.php b/lib/SimpleSAML/Error/CriticalConfigurationError.php
index 14907a5aba43199ff2d425dd202a09d269b48bfe..b48581cb43db5777b37dc0b398d1de4c3eeffee6 100644
--- a/lib/SimpleSAML/Error/CriticalConfigurationError.php
+++ b/lib/SimpleSAML/Error/CriticalConfigurationError.php
@@ -34,7 +34,7 @@ class CriticalConfigurationError extends ConfigurationError
      *
      * @var array
      */
-    private static $minimum_config = [
+    private static array $minimum_config = [
         'logging.handler' => 'errorlog',
         'logging.level'  => Logger::DEBUG,
         'errorreporting' => false,
diff --git a/lib/SimpleSAML/Error/Error.php b/lib/SimpleSAML/Error/Error.php
index 2d7375f5b4d68a1beec97069314f0b906b2a95f5..e376027dfa33c828c261dfc30c9fabfb8545e812 100644
--- a/lib/SimpleSAML/Error/Error.php
+++ b/lib/SimpleSAML/Error/Error.php
@@ -25,49 +25,49 @@ class Error extends Exception
      *
      * @var string
      */
-    private $errorCode;
+    private string $errorCode;
 
     /**
      * The http code.
      *
      * @var integer
      */
-    protected $httpCode = 500;
+    protected int $httpCode = 500;
 
     /**
      * The error title tag in dictionary.
      *
      * @var string
      */
-    private $dictTitle;
+    private string $dictTitle;
 
     /**
      * The error description tag in dictionary.
      *
      * @var string
      */
-    private $dictDescr;
+    private string $dictDescr;
 
     /**
      * The name of module that threw the error.
      *
      * @var string|null
      */
-    private $module = null;
+    private ?string $module = null;
 
     /**
      * The parameters for the error.
      *
      * @var array
      */
-    private $parameters;
+    private array $parameters;
 
     /**
      * Name of custom include template for the error.
      *
      * @var string|null
      */
-    protected $includeTemplate = null;
+    protected ?string $includeTemplate = null;
 
 
     /**
diff --git a/lib/SimpleSAML/Error/Exception.php b/lib/SimpleSAML/Error/Exception.php
index 15d4fa644cf066fa8ef71a75194543bd6f9caed8..c0b339fd6ff049f1057bfa80387d869d06f575c5 100644
--- a/lib/SimpleSAML/Error/Exception.php
+++ b/lib/SimpleSAML/Error/Exception.php
@@ -27,14 +27,14 @@ class Exception extends \Exception
      *
      * @var array<int, string>
      */
-    private $backtrace = [];
+    private array $backtrace = [];
 
     /**
      * The cause of this exception.
      *
      * @var \SimpleSAML\Error\Exception|null
      */
-    private $cause = null;
+    private ?Exception $cause = null;
 
 
     /**
diff --git a/lib/SimpleSAML/Error/NotFound.php b/lib/SimpleSAML/Error/NotFound.php
index af96fc5f677a8f9bb5fd5adb4c2879815b17a46d..f7f180463a0dff1a0b57ae6514539030f0139e1a 100644
--- a/lib/SimpleSAML/Error/NotFound.php
+++ b/lib/SimpleSAML/Error/NotFound.php
@@ -21,7 +21,7 @@ class NotFound extends Error
     /**
      * Reason why the given page could not be found.
      */
-    private $reason;
+    private ?string $reason;
 
 
     /**
diff --git a/lib/SimpleSAML/Error/UnserializableException.php b/lib/SimpleSAML/Error/UnserializableException.php
index 14ea1d7b415f599e2bceb13a2b8f912c3f95c70e..d843f70428699a2c2cd4afb0bb7fef184ef010a6 100644
--- a/lib/SimpleSAML/Error/UnserializableException.php
+++ b/lib/SimpleSAML/Error/UnserializableException.php
@@ -27,7 +27,7 @@ class UnserializableException extends Exception
      *
      * @var string
      */
-    private $class;
+    private string $class;
 
 
     /**
diff --git a/lib/SimpleSAML/HTTP/RunnableResponse.php b/lib/SimpleSAML/HTTP/RunnableResponse.php
index 32938c1bba7f3002aeba1b1d85ec86946527b4cc..0e67003ea31f712767a14b5007b297386376d28d 100644
--- a/lib/SimpleSAML/HTTP/RunnableResponse.php
+++ b/lib/SimpleSAML/HTTP/RunnableResponse.php
@@ -17,7 +17,7 @@ use Symfony\Component\HttpFoundation\Response;
 class RunnableResponse extends Response
 {
     /** @var array */
-    protected $arguments;
+    protected array $arguments;
 
     /** @var callable */
     protected $callable;
diff --git a/lib/SimpleSAML/IdP.php b/lib/SimpleSAML/IdP.php
index 876e4d0eda8514d5b8d62f050a98c3d5334c860f..c5f983791fbdb73beb241063846a65f00c4d54b4 100644
--- a/lib/SimpleSAML/IdP.php
+++ b/lib/SimpleSAML/IdP.php
@@ -7,6 +7,7 @@ namespace SimpleSAML;
 use SAML2\Constants;
 use SimpleSAML\Assert\Assert;
 use SimpleSAML\Auth;
+use SimpleSAML\Configuration;
 use SimpleSAML\IdP\IFrameLogoutHandler;
 use SimpleSAML\IdP\LogoutHandlerInterface;
 use SimpleSAML\IdP\TraditionalLogoutHandler;
@@ -30,14 +31,14 @@ class IdP
      *
      * @var array
      */
-    private static $idpCache = [];
+    private static array $idpCache = [];
 
     /**
      * The identifier for this IdP.
      *
      * @var string
      */
-    private $id;
+    private string $id;
 
     /**
      * The "association group" for this IdP.
@@ -47,21 +48,21 @@ class IdP
      *
      * @var string
      */
-    private $associationGroup;
+    private string $associationGroup;
 
     /**
      * The configuration for this IdP.
      *
-     * @var Configuration
+     * @var \SimpleSAML\Configuration
      */
-    private $config;
+    private Configuration $config;
 
     /**
      * Our authsource.
      *
-     * @var Auth\Simple
+     * @var \SimpleSAML\Auth\Simple
      */
-    private $authSource;
+    private Auth\Simple $authSource;
 
 
     /**
diff --git a/lib/SimpleSAML/IdP/IFrameLogoutHandler.php b/lib/SimpleSAML/IdP/IFrameLogoutHandler.php
index b7303a256f3e6662b5ae5374afee8617e6343fae..9cf2f30ff8ee5cac6913978ba347a8b83eb20ebb 100644
--- a/lib/SimpleSAML/IdP/IFrameLogoutHandler.php
+++ b/lib/SimpleSAML/IdP/IFrameLogoutHandler.php
@@ -26,7 +26,8 @@ class IFrameLogoutHandler implements LogoutHandlerInterface
      *
      * @var \SimpleSAML\IdP
      */
-    private $idp;
+    private IDP $idp;
+
 
     /**
      * LogoutIFrame constructor.
@@ -38,6 +39,7 @@ class IFrameLogoutHandler implements LogoutHandlerInterface
         $this->idp = $idp;
     }
 
+
     /**
      * Start the logout operation.
      *
diff --git a/lib/SimpleSAML/IdP/TraditionalLogoutHandler.php b/lib/SimpleSAML/IdP/TraditionalLogoutHandler.php
index cf6c2a63cdf7f14097737989e14ff3766c3969be..a22834aff93e636f4a1a3456f8a09cc4541ecac0 100644
--- a/lib/SimpleSAML/IdP/TraditionalLogoutHandler.php
+++ b/lib/SimpleSAML/IdP/TraditionalLogoutHandler.php
@@ -24,7 +24,7 @@ class TraditionalLogoutHandler implements LogoutHandlerInterface
      *
      * @var \SimpleSAML\IdP
      */
-    private $idp;
+    private IDP $idp;
 
 
     /**
diff --git a/lib/SimpleSAML/Kernel.php b/lib/SimpleSAML/Kernel.php
index 9a51df2c46e6477aebd1bb151453fd92bc07cfef..be7321a35b1b83d05b129f0827ce7f5d3509e8e0 100644
--- a/lib/SimpleSAML/Kernel.php
+++ b/lib/SimpleSAML/Kernel.php
@@ -26,7 +26,7 @@ class Kernel extends BaseKernel
     public const CONFIG_EXTS = '.{php,xml,yaml,yml}';
 
     /** @var string */
-    private $module;
+    private string $module;
 
 
     /**
diff --git a/lib/SimpleSAML/Locale/Language.php b/lib/SimpleSAML/Locale/Language.php
index eeaaaa890aa0eec388f5ad118b459d6486681178..347b41232e8b55cf4d2473c61709e61e4748fab1 100644
--- a/lib/SimpleSAML/Locale/Language.php
+++ b/lib/SimpleSAML/Locale/Language.php
@@ -19,50 +19,51 @@ class Language
 {
     /**
      * This is the default language map. It is used to map languages codes from the user agent to other language codes.
+     * @var array<string, string>
      */
-    private static $defaultLanguageMap = ['nb' => 'no'];
+    private static array $defaultLanguageMap = ['nb' => 'no'];
 
     /**
      * The configuration to use.
      *
      * @var \SimpleSAML\Configuration
      */
-    private $configuration;
+    private Configuration $configuration;
 
     /**
      * An array holding a list of languages available.
      *
-     * @var array
+     * @var string[]
      */
-    private $availableLanguages;
+    private array $availableLanguages;
 
     /**
      * The language currently in use.
      *
      * @var null|string
      */
-    private $language = null;
+    private ?string $language = null;
 
     /**
      * The language to use by default.
      *
      * @var string
      */
-    private $defaultLanguage;
+    private string $defaultLanguage;
 
     /**
      * An array holding a list of languages that are written from right to left.
      *
-     * @var array
+     * @var string[]
      */
-    private $rtlLanguages;
+    private array $rtlLanguages;
 
     /**
      * HTTP GET language parameter name.
      *
      * @var string
      */
-    private $languageParameterName;
+    private string $languageParameterName;
 
     /**
      * A custom function to use in order to determine the language in use.
@@ -77,9 +78,9 @@ class Language
      * with some charming SimpleSAML-specific variants...
      * that must remain before 2.0 due to backwards compatibility
      *
-     * @var array
+     * @var array<string, string>
      */
-    public static $language_names = [
+    public static array $language_names = [
         'no'    => 'BokmĂĄl', // Norwegian BokmĂĄl
         'nn'    => 'Nynorsk', // Norwegian Nynorsk
         'se'    => 'Sámegiella', // Northern Sami
@@ -128,9 +129,9 @@ class Language
     /**
      * A mapping of SSP languages to locales
      *
-     * @var array
+     * @var array<string, string>
      */
-    private $languagePosixMapping = [
+    private array $languagePosixMapping = [
         'no' => 'nb_NO',
         'nn' => 'nn_NO',
     ];
diff --git a/lib/SimpleSAML/Locale/Localization.php b/lib/SimpleSAML/Locale/Localization.php
index b28c54da3919e767c208b8fb8692d39abcec0520..6aaae8aa8f58d5eff7f860b9ef06cad8cffdc5e2 100644
--- a/lib/SimpleSAML/Locale/Localization.php
+++ b/lib/SimpleSAML/Locale/Localization.php
@@ -22,7 +22,7 @@ class Localization
      *
      * @var \SimpleSAML\Configuration
      */
-    private $configuration;
+    private Configuration $configuration;
 
     /**
      * The default gettext domain.
@@ -50,35 +50,35 @@ class Localization
      *
      * @var string
      */
-    private $localeDir;
+    private string $localeDir;
 
     /**
      * Where specific domains are stored
      *
      * @var array
      */
-    private $localeDomainMap = [];
+    private array $localeDomainMap = [];
 
     /**
      * Pointer to currently active translator
      *
      * @var \Gettext\Translator
      */
-    private $translator;
+    private Translator $translator;
 
     /**
      * Pointer to current Language
      *
-     * @var Language
+     * @var \SimpleSAML\Locale\Language
      */
-    private $language;
+    private Language $language;
 
     /**
      * Language code representing the current Language
      *
      * @var string
      */
-    private $langcode;
+    private string $langcode;
 
 
     /**
@@ -86,7 +86,7 @@ class Localization
      *
      * @var string
      */
-    public $i18nBackend;
+    public string $i18nBackend;
 
 
     /**
diff --git a/lib/SimpleSAML/Locale/Translate.php b/lib/SimpleSAML/Locale/Translate.php
index 75ce2a1fcce98e19c421dac1ecfb383251371138..be9ac59ed704537a8c8f46956df4476644824879 100644
--- a/lib/SimpleSAML/Locale/Translate.php
+++ b/lib/SimpleSAML/Locale/Translate.php
@@ -23,35 +23,35 @@ class Translate
      *
      * @var \SimpleSAML\Configuration
      */
-    private $configuration;
+    private Configuration $configuration;
 
     /**
      * Associative array of languages.
      *
      * @var array
      */
-    private $langtext = [];
+    private array $langtext = [];
 
     /**
      * Associative array of dictionaries.
      *
      * @var array
      */
-    private $dictionaries = [];
+    private array $dictionaries = [];
 
     /**
      * The default dictionary.
      *
      * @var string|null
      */
-    private $defaultDictionary = null;
+    private ?string $defaultDictionary = null;
 
     /**
      * The language object we'll use internally.
      *
      * @var \SimpleSAML\Locale\Language
      */
-    private $language;
+    private Language $language;
 
 
     /**
@@ -324,6 +324,7 @@ class Translate
 
         $lang = null;
         include($phpFile);
+        /** @psalm-var array|null $lang */
         if (isset($lang)) {
             return $lang;
         }
diff --git a/lib/SimpleSAML/Logger.php b/lib/SimpleSAML/Logger.php
index ec47b8a4b447738854f2b4e165af99a90b81f967..49a390dcae82555538ce599e3db878457750a83f 100644
--- a/lib/SimpleSAML/Logger.php
+++ b/lib/SimpleSAML/Logger.php
@@ -22,34 +22,34 @@ class Logger
     /**
      * @var \SimpleSAML\Logger\LoggingHandlerInterface
      */
-    private static $loggingHandler;
+    private static LoggingHandlerInterface $loggingHandler;
 
     /**
      * @var bool
      */
-    private static $initializing = false;
+    private static bool $initializing = false;
 
     /**
      * @var integer|null
      */
-    private static $logLevel = null;
+    private static ?int $logLevel = null;
 
     /**
      * @var boolean
      */
-    private static $captureLog = false;
+    private static bool $captureLog = false;
 
     /**
-     * @var array
+     * @var string[]
      */
-    private static $capturedLog = [];
+    private static array $capturedLog = [];
 
     /**
      * Array with messages logged before the logging handler was initialized.
      *
      * @var array
      */
-    private static $earlyLog = [];
+    private static array $earlyLog = [];
 
     /**
      * List of log levels.
@@ -58,7 +58,7 @@ class Logger
      *
      * @var array
      */
-    private static $logLevelStack = [];
+    private static array $logLevelStack = [];
 
     /**
      * The current mask of log levels disabled.
@@ -67,7 +67,7 @@ class Logger
      *
      * @var int
      */
-    private static $logMask = 0;
+    private static int $logMask = 0;
 
     /**
      * This constant defines the string we set the track ID to while we are fetching the track ID from the session
@@ -83,7 +83,7 @@ class Logger
      *
      * @var string
      */
-    private static $trackid = self::NO_TRACKID;
+    private static string $trackid = self::NO_TRACKID;
 
     /**
      * This variable holds the format used to log any message. Its use varies depending on the log handler used (for
@@ -113,21 +113,21 @@ class Logger
      *
      * @var string The format of the log line.
      */
-    private static $format = '%date{%b %d %H:%M:%S} %process %level %stat[%trackid] %msg';
+    private static string $format = '%date{%b %d %H:%M:%S} %process %level %stat[%trackid] %msg';
 
     /**
      * This variable tells if we have a shutdown function registered or not.
      *
      * @var bool
      */
-    private static $shutdownRegistered = false;
+    private static bool $shutdownRegistered = false;
 
     /**
      * This variable tells if we are shutting down.
      *
      * @var bool
      */
-    private static $shuttingDown = false;
+    private static bool $shuttingDown = false;
 
     /** @var int */
     public const EMERG = 0;
diff --git a/lib/SimpleSAML/Logger/ErrorLogLoggingHandler.php b/lib/SimpleSAML/Logger/ErrorLogLoggingHandler.php
index 1900893aa9874a89b3ff7b697d5c8a0ed085a5e4..bfd0f2abb0b40186e289280c3b9f58814787e62b 100644
--- a/lib/SimpleSAML/Logger/ErrorLogLoggingHandler.php
+++ b/lib/SimpleSAML/Logger/ErrorLogLoggingHandler.php
@@ -17,9 +17,9 @@ class ErrorLogLoggingHandler implements LoggingHandlerInterface
     /**
      * This array contains the mappings from syslog log level to names.
      *
-     * @var array
+     * @var array<int, string>
      */
-    private static $levelNames = [
+    private static array $levelNames = [
         Logger::EMERG   => 'EMERG',
         Logger::ALERT   => 'ALERT',
         Logger::CRIT    => 'CRIT',
@@ -35,7 +35,7 @@ class ErrorLogLoggingHandler implements LoggingHandlerInterface
      *
      * @var string
      */
-    private $processname;
+    private string $processname;
 
 
     /**
diff --git a/lib/SimpleSAML/Logger/FileLoggingHandler.php b/lib/SimpleSAML/Logger/FileLoggingHandler.php
index f54e76ae10f89d881c422a06aeb4f8727b2f9a83..641a5f23535aa239cbcda1aeb813884f5b299e56 100644
--- a/lib/SimpleSAML/Logger/FileLoggingHandler.php
+++ b/lib/SimpleSAML/Logger/FileLoggingHandler.php
@@ -20,13 +20,13 @@ class FileLoggingHandler implements LoggingHandlerInterface
      *
      * @var null|string
      */
-    protected $logFile = null;
+    protected ?string $logFile = null;
 
     /**
      * This array contains the mappings from syslog log levels to names. Copied more or less directly from
      * SimpleSAML\Logger\ErrorLogLoggingHandler.
      *
-     * @var array
+     * @var array<int, string>
      */
     private static $levelNames = [
         Logger::EMERG   => 'EMERGENCY',
@@ -39,11 +39,11 @@ class FileLoggingHandler implements LoggingHandlerInterface
         Logger::DEBUG   => 'DEBUG',
     ];
 
-    /** @var string|null */
-    protected $processname = null;
+    /** @var string */
+    protected string $processname;
 
     /** @var string */
-    protected $format = "%b %d %H:%M:%S";
+    protected string $format = "%b %d %H:%M:%S";
 
 
     /**
diff --git a/lib/SimpleSAML/Logger/SyslogLoggingHandler.php b/lib/SimpleSAML/Logger/SyslogLoggingHandler.php
index bb38492013e6d458f0fb8cebefa56399c737aeb5..14309cac0d7996468deefa37bc131c0a3abf3181 100644
--- a/lib/SimpleSAML/Logger/SyslogLoggingHandler.php
+++ b/lib/SimpleSAML/Logger/SyslogLoggingHandler.php
@@ -15,10 +15,10 @@ use SimpleSAML\Utils;
 class SyslogLoggingHandler implements LoggingHandlerInterface
 {
     /** @var bool */
-    private $isWindows = false;
+    private bool $isWindows = false;
 
     /** @var string */
-    protected $format = "%b %d %H:%M:%S";
+    protected string $format = "%b %d %H:%M:%S";
 
 
     /**
diff --git a/lib/SimpleSAML/Memcache.php b/lib/SimpleSAML/Memcache.php
index 39e4b8a8883cfd1a6bef8a013de2dbe919dd0800..156e0bafc1a2636806d78f6e3557bfe760a9b43b 100644
--- a/lib/SimpleSAML/Memcache.php
+++ b/lib/SimpleSAML/Memcache.php
@@ -27,9 +27,9 @@ class Memcache
     /**
      * Cache of the memcache servers we are using.
      *
-     * @var \Memcached[]|null
+     * @var \Memcached[]
      */
-    private static $serverGroups = null;
+    private static array $serverGroups = [];
 
 
     /**
@@ -317,7 +317,7 @@ class Memcache
     private static function getMemcacheServers(): array
     {
         // check if we have loaded the servers already
-        if (self::$serverGroups != null) {
+        if (!empty(self::$serverGroups)) {
             return self::$serverGroups;
         }
 
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php
index 86d9446264c4b24227ba1d34b979bbb1b4173cb1..2af578cd8655dd07f7cf868ef3e270d8a6be5567 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php
@@ -27,18 +27,18 @@ class MetaDataStorageHandler implements ClearableState
      * instance of the metadata handler. This variable will be null if
      * we haven't instantiated a metadata handler yet.
      *
-     * @var MetaDataStorageHandler|null
+     * @var \SimpleSAML\Metadata\MetaDataStorageHandler|null
      */
-    private static $metadataHandler = null;
+    private static ?MetadataStorageHandler $metadataHandler = null;
 
 
     /**
      * This is a list of all the metadata sources we have in our metadata
      * chain. When we need metadata, we will look through this chain from start to end.
      *
-     * @var MetaDataStorageSource[]
+     * @var \SimpleSAML\Metadata\MetaDataStorageSource[]
      */
-    private $sources;
+    private array $sources = [];
 
 
     /**
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatFile.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatFile.php
index f40fa54002b529ea467ed318c83604e1066c6a50..3f6e9c5090ec78fffcc7ce930d765e0dcff0ebf2 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatFile.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatFile.php
@@ -23,7 +23,7 @@ class MetaDataStorageHandlerFlatFile extends MetaDataStorageSource
      *
      * @var string
      */
-    private $directory = '/';
+    private string $directory = '/';
 
 
     /**
@@ -31,7 +31,7 @@ class MetaDataStorageHandlerFlatFile extends MetaDataStorageSource
      *
      * @var array
      */
-    private $cachedMetadata = [];
+    private array $cachedMetadata = [];
 
 
     /**
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php
index 8136c7aeab088b034030500ee2b9fcecd523611e..f662f5138e5caa39054f7eae0e4f3ebee99f5057 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php
@@ -22,23 +22,25 @@ class MetaDataStorageHandlerPdo extends MetaDataStorageSource
 {
     /**
      * The PDO object
+     * @var \SimpleSAML\Database
      */
-    private $db;
+    private Database $db;
 
     /**
      * Prefix to apply to the metadata table
      */
-    private $tablePrefix;
+    private string $tablePrefix = '';
 
     /**
      * This is an associative array which stores the different metadata sets we have loaded.
      */
-    private $cachedMetadata = [];
+    private array $cachedMetadata = [];
 
     /**
      * All the metadata sets supported by this MetaDataStorageHandler
+     * @var string[]
      */
-    public $supportedSets = [
+    public array $supportedSets = [
         'adfs-idp-hosted',
         'adfs-sp-remote',
         'saml20-idp-hosted',
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php
index 6e1770f3e2b097121afd466d7ef8b93e48d36b11..358ba5839e32efd4e089247e05450c3772ef9b30 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php
@@ -30,7 +30,7 @@ class MetaDataStorageHandlerSerialize extends MetaDataStorageSource
      *
      * @var string
      */
-    private $directory = '/';
+    private string $directory = '/';
 
 
     /**
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerXML.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerXML.php
index 8ce1a288ba7a3cd1cf0dba7e24e6dae2a3e9899d..8f7dba1fa8bf6d9475842f6fbf328e7ea71e69fe 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerXML.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerXML.php
@@ -20,7 +20,7 @@ class MetaDataStorageHandlerXML extends MetaDataStorageSource
      *
      * @var array
      */
-    private $metadata;
+    private array $metadata;
 
 
     /**
diff --git a/lib/SimpleSAML/Metadata/SAMLBuilder.php b/lib/SimpleSAML/Metadata/SAMLBuilder.php
index 0eed9f37ea6ba2aced4ccf24d08a24535eb3fa0f..2f79664813dc0c4054706cb0228d492010e8887c 100644
--- a/lib/SimpleSAML/Metadata/SAMLBuilder.php
+++ b/lib/SimpleSAML/Metadata/SAMLBuilder.php
@@ -46,7 +46,7 @@ class SAMLBuilder
      *
      * @var \SAML2\XML\md\EntityDescriptor
      */
-    private $entityDescriptor;
+    private EntityDescriptor $entityDescriptor;
 
 
     /**
@@ -54,7 +54,7 @@ class SAMLBuilder
      *
      * @var int|null
      */
-    private $maxCache = null;
+    private ?int $maxCache = null;
 
 
     /**
@@ -62,7 +62,7 @@ class SAMLBuilder
      *
      * @var int|null
      */
-    private $maxDuration = null;
+    private ?int $maxDuration = null;
 
 
     /**
diff --git a/lib/SimpleSAML/Metadata/SAMLParser.php b/lib/SimpleSAML/Metadata/SAMLParser.php
index 637f551534696ceb974a85b8845a9cfc5522a176..e94509d12420e80848b8488ea5b748095dc00a29 100644
--- a/lib/SimpleSAML/Metadata/SAMLParser.php
+++ b/lib/SimpleSAML/Metadata/SAMLParser.php
@@ -58,7 +58,7 @@ class SAMLParser
      *
      * @var string[]
      */
-    private static $SAML20Protocols = [
+    private static array $SAML20Protocols = [
         Constants::NS_SAMLP,
     ];
 
@@ -67,7 +67,7 @@ class SAMLParser
      *
      * @var string
      */
-    private $entityId;
+    private string $entityId;
 
     /**
      * This is an array with the processed SPSSODescriptor elements we have found in this
@@ -77,9 +77,9 @@ class SAMLParser
      *   Each assertion consumer service is stored as an associative array with the
      *   elements that parseGenericEndpoint returns.
      *
-     * @var array[]
+     * @var array
      */
-    private $spDescriptors;
+    private array $spDescriptors;
 
     /**
      * This is an array with the processed IDPSSODescriptor elements we have found.
@@ -87,84 +87,84 @@ class SAMLParser
      * - 'SingleSignOnService': Array with the IdP's single sign on service endpoints. Each endpoint is stored
      *   as an associative array with the elements that parseGenericEndpoint returns.
      *
-     * @var array[]
+     * @var array
      */
-    private $idpDescriptors;
+    private array $idpDescriptors;
 
     /**
      * List of attribute authorities we have found.
      *
      * @var array
      */
-    private $attributeAuthorityDescriptors = [];
+    private array $attributeAuthorityDescriptors = [];
 
     /**
      * This is an associative array with the organization name for this entity. The key of
      * the associative array is the language code, while the value is a string with the
      * organization name.
      *
-     * @var string[]
+     * @var array<string, string>
      */
-    private $organizationName = [];
+    private array $organizationName = [];
 
     /**
      * This is an associative array with the organization display name for this entity. The key of
      * the associative array is the language code, while the value is a string with the
      * organization display name.
      *
-     * @var string[]
+     * @var array<string, string>
      */
-    private $organizationDisplayName = [];
+    private array $organizationDisplayName = [];
 
     /**
      * This is an associative array with the organization URI for this entity. The key of
      * the associative array is the language code, while the value is the URI.
      *
-     * @var string[]
+     * @var array<string, string>
      */
-    private $organizationURL = [];
+    private array $organizationURL = [];
 
     /**
      * This is an array of the Contact Persons of this entity.
      *
-     * @var array[]
+     * @var array
      */
-    private $contacts = [];
+    private array $contacts = [];
 
     /**
      * @var array
      */
-    private $scopes;
+    private array $scopes;
 
     /**
      * @var array
      */
-    private $entityAttributes;
+    private array $entityAttributes;
 
     /**
      * An associative array of attributes from the RegistrationInfo element.
      * @var array
      */
-    private $registrationInfo;
+    private array $registrationInfo;
 
     /**
      * @var array
      */
-    private $tags;
+    private array $tags;
 
     /**
      * This is an array of elements that may be used to validate this element.
      *
      * @var \SAML2\SignedElementHelper[]
      */
-    private $validators = [];
+    private array $validators = [];
 
     /**
      * The original EntityDescriptor element for this entity, as a base64 encoded string.
      *
      * @var string
      */
-    private $entityDescriptor;
+    private string $entityDescriptor;
 
 
     /**
diff --git a/lib/SimpleSAML/Metadata/Sources/MDQ.php b/lib/SimpleSAML/Metadata/Sources/MDQ.php
index a8ef2956f01d38784966d78738f8a3221329529f..c4ccb31f38bec4ff2fdc668e2f9f09c7624b1610 100644
--- a/lib/SimpleSAML/Metadata/Sources/MDQ.php
+++ b/lib/SimpleSAML/Metadata/Sources/MDQ.php
@@ -25,14 +25,14 @@ class MDQ extends \SimpleSAML\Metadata\MetaDataStorageSource
      *
      * @var string
      */
-    private $server;
+    private string $server;
 
     /**
      * The cache directory, or null if no cache directory is configured.
      *
      * @var string|null
      */
-    private $cacheDir;
+    private ?string $cacheDir;
 
 
     /**
@@ -40,7 +40,7 @@ class MDQ extends \SimpleSAML\Metadata\MetaDataStorageSource
      *
      * @var integer
      */
-    private $cacheLength;
+    private int $cacheLength;
 
 
     /**
diff --git a/lib/SimpleSAML/Module.php b/lib/SimpleSAML/Module.php
index f3f4ac03a291e80adc255d4e666d9434a83337e0..fa8e55072a50b71c504b1d988be70e68ab57c157 100644
--- a/lib/SimpleSAML/Module.php
+++ b/lib/SimpleSAML/Module.php
@@ -25,18 +25,18 @@ class Module
     /**
      * Index pages: file names to attempt when accessing directories.
      *
-     * @var array
+     * @var string[]
      */
-    public static $indexFiles = ['index.php', 'index.html', 'index.htm', 'index.txt'];
+    public static array $indexFiles = ['index.php', 'index.html', 'index.htm', 'index.txt'];
 
     /**
      * MIME Types
      *
      * The key is the file extension and the value the corresponding MIME type.
      *
-     * @var array
+     * @var array<string, string>
      */
-    public static $mimeTypes = [
+    public static array $mimeTypes = [
         'bmp'   => 'image/x-ms-bmp',
         'css'   => 'text/css',
         'gif'   => 'image/gif',
@@ -62,16 +62,16 @@ class Module
     /**
      * A list containing the modules currently installed.
      *
-     * @var array
+     * @var string[]
      */
-    public static $modules = [];
+    public static array $modules = [];
 
     /**
      * A list containing the modules that are enabled by default, unless specifically disabled
      *
-     * @var array
+     * @var array<string, bool>
      */
-    public static $core_modules = [
+    public static array $core_modules = [
         'core' => true,
         'saml' => true
     ];
@@ -81,7 +81,7 @@ class Module
      *
      * @var array
      */
-    public static $module_info = [];
+    public static array $module_info = [];
 
 
     /**
diff --git a/lib/SimpleSAML/Session.php b/lib/SimpleSAML/Session.php
index 7800bf5c4595143872f83d4d4975c513db79d427..438abff785d89539c23de8e2cc160b216f740c4b 100644
--- a/lib/SimpleSAML/Session.php
+++ b/lib/SimpleSAML/Session.php
@@ -7,7 +7,9 @@ namespace SimpleSAML;
 use SAML2\XML\saml\AttributeValue;
 use Serializable;
 use SimpleSAML\Assert\Assert;
+use SimpleSAML\Configuration;
 use SimpleSAML\Error;
+use SimpleSAML\Session;
 use SimpleSAML\Utils;
 
 /**
@@ -41,7 +43,7 @@ class Session implements Serializable, Utils\ClearableState
      *
      * @var array
      */
-    private static $sessions = [];
+    private static array $sessions = [];
 
     /**
      * This variable holds the instance of the session - Singleton approach.
@@ -50,28 +52,28 @@ class Session implements Serializable, Utils\ClearableState
      *
      * @var \SimpleSAML\Session|null
      */
-    private static $instance = null;
+    private static ?Session $instance = null;
 
     /**
      * The global configuration.
      *
-     * @var \SimpleSAML\Configuration
+     * @var \SimpleSAML\Configuration|null
      */
-    private static $config;
+    private static ?Configuration $config;
 
     /**
      * The session ID of this session.
      *
      * @var string|null
      */
-    private $sessionId;
+    private ?string $sessionId = null;
 
     /**
      * Transient session flag.
      *
      * @var boolean|false
      */
-    private $transient = false;
+    private bool $transient = false;
 
     /**
      * The track id is a new random unique identifier that is generated for each session.
@@ -80,12 +82,12 @@ class Session implements Serializable, Utils\ClearableState
      *
      * @var string
      */
-    private $trackid;
+    private string $trackid;
 
     /**
      * @var integer|null
      */
-    private $rememberMeExpire = null;
+    private ?int $rememberMeExpire = null;
 
     /**
      * Marks a session as modified, and therefore needs to be saved before destroying
@@ -93,14 +95,14 @@ class Session implements Serializable, Utils\ClearableState
      *
      * @var bool
      */
-    private $dirty = false;
+    private bool $dirty = false;
 
     /**
      * Tells the session object that the save callback has been registered and there's no need to register it again.
      *
      * @var bool
      */
-    private $callback_registered = false;
+    private bool $callback_registered = false;
 
     /**
      * This is an array of objects which will expire automatically after a set time. It is used
@@ -112,7 +114,7 @@ class Session implements Serializable, Utils\ClearableState
      *
      * @var array
      */
-    private $dataStore = [];
+    private array $dataStore = [];
 
     /**
      * The list of IdP-SP associations.
@@ -122,7 +124,7 @@ class Session implements Serializable, Utils\ClearableState
      *
      * @var array
      */
-    private $associations = [];
+    private array $associations = [];
 
     /**
      * The authentication token.
@@ -131,7 +133,7 @@ class Session implements Serializable, Utils\ClearableState
      *
      * @var string|null
      */
-    private $authToken;
+    private ?string $authToken = null;
 
     /**
      * Authentication data.
@@ -140,7 +142,7 @@ class Session implements Serializable, Utils\ClearableState
      *
      * @var array  Associative array of associative arrays.
      */
-    private $authData = [];
+    private array $authData = [];
 
 
     /**
@@ -256,7 +258,8 @@ class Session implements Serializable, Utils\ClearableState
     public static function getSessionFromRequest(): Session
     {
         // check if we already have initialized the session
-        if (isset(self::$instance)) {
+        /** @psalm-suppress RedundantCondition */
+        if (self::$instance !== null) {
             return self::$instance;
         }
 
@@ -292,6 +295,8 @@ class Session implements Serializable, Utils\ClearableState
          * error message). This means we don't need to create a new session again, we can use the one that's loaded now
          * instead.
          */
+
+        /** @psalm-suppress TypeDoesNotContainType */
         if (self::$instance !== null) {
             return self::$instance;
         }
@@ -413,7 +418,8 @@ class Session implements Serializable, Utils\ClearableState
      */
     public static function useTransientSession(): void
     {
-        if (isset(self::$instance)) {
+        /** @psalm-suppress RedundantCondition */
+        if (self::$instance !== null) {
             // we already have a session, don't bother with a transient session
             return;
         }
@@ -775,7 +781,7 @@ class Session implements Serializable, Utils\ClearableState
     public function updateSessionCookies(array $params = []): void
     {
         $sessionHandler = SessionHandler::getSessionHandler();
-        $params = array_merge($sessionHandler->getCookieParams(), is_array($params) ? $params : []);
+        $params = array_merge($sessionHandler->getCookieParams(), $params);
 
         if ($this->sessionId !== null) {
             $sessionHandler->setCookie($sessionHandler->getSessionCookieName(), $this->sessionId, $params);
@@ -1151,6 +1157,6 @@ class Session implements Serializable, Utils\ClearableState
     {
         self::$config = null;
         self::$instance = null;
-        self::$sessions = null;
+        self::$sessions = [];
     }
 }
diff --git a/lib/SimpleSAML/SessionHandler.php b/lib/SimpleSAML/SessionHandler.php
index 97f4212f5b1c2cd275397ae6a69064c2c5b781b8..1a234ed4ed4eab0b2473a6deacfddf3c8be0bc6a 100644
--- a/lib/SimpleSAML/SessionHandler.php
+++ b/lib/SimpleSAML/SessionHandler.php
@@ -22,9 +22,9 @@ abstract class SessionHandler
      * instance of the session handler. This variable will be NULL if
      * we haven't instantiated a session handler yet.
      *
-     * @var \SimpleSAML\SessionHandler
+     * @var \SimpleSAML\SessionHandler|null
      */
-    protected static $sessionHandler;
+    protected static ?SessionHandler $sessionHandler = null;
 
 
     /**
diff --git a/lib/SimpleSAML/SessionHandlerCookie.php b/lib/SimpleSAML/SessionHandlerCookie.php
index cb5fbfc9d022783a9eace631047d684ce4b9de39..a8d2c868d631ddbb53b7eab6bd2429aa5c3837ef 100644
--- a/lib/SimpleSAML/SessionHandlerCookie.php
+++ b/lib/SimpleSAML/SessionHandlerCookie.php
@@ -24,7 +24,7 @@ abstract class SessionHandlerCookie extends SessionHandler
      *
      * @var string|null
      */
-    private $session_id = null;
+    private ?string $session_id = null;
 
 
     /**
@@ -32,7 +32,7 @@ abstract class SessionHandlerCookie extends SessionHandler
      *
      * @var string
      */
-    protected $cookie_name;
+    protected string $cookie_name;
 
 
     /**
diff --git a/lib/SimpleSAML/SessionHandlerPHP.php b/lib/SimpleSAML/SessionHandlerPHP.php
index 587ea15f0339a20519ee48d885d6eae89e4d3ec0..e0f2646148b9852b7e22f5be1956001319637b88 100644
--- a/lib/SimpleSAML/SessionHandlerPHP.php
+++ b/lib/SimpleSAML/SessionHandlerPHP.php
@@ -23,7 +23,7 @@ class SessionHandlerPHP extends SessionHandler
      *
      * @var string
      */
-    protected $cookie_name;
+    protected string $cookie_name;
 
     /**
      * An associative array containing the details of a session existing previously to creating or loading one with this
@@ -35,7 +35,7 @@ class SessionHandlerPHP extends SessionHandler
      *
      * @var array
      */
-    private $previous_session = [];
+    private array $previous_session = [];
 
 
     /**
@@ -48,7 +48,7 @@ class SessionHandlerPHP extends SessionHandler
         parent::__construct();
 
         $config = Configuration::getInstance();
-        $this->cookie_name = $config->getString('session.phpsession.cookiename', null);
+        $this->cookie_name = $config->getString('session.phpsession.cookiename', ini_get('session.name') ?? 'PHPSESSID');
 
         if (session_status() === PHP_SESSION_ACTIVE) {
             if (session_name() === $this->cookie_name || $this->cookie_name === null) {
diff --git a/lib/SimpleSAML/SessionHandlerStore.php b/lib/SimpleSAML/SessionHandlerStore.php
index 66c2c911bb002b7cae4b15a47adbcca8b756273a..ec7cbfe1a20b6491bc85043709a5f980abcd16f0 100644
--- a/lib/SimpleSAML/SessionHandlerStore.php
+++ b/lib/SimpleSAML/SessionHandlerStore.php
@@ -19,7 +19,7 @@ class SessionHandlerStore extends SessionHandlerCookie
      *
      * @var \SimpleSAML\Store
      */
-    private $store;
+    private Store $store;
 
 
     /**
diff --git a/lib/SimpleSAML/Stats.php b/lib/SimpleSAML/Stats.php
index 4c47c0cc937eeb6121a5a02e81b2538e48ef7963..6176cbe87500960e2fdb76860d8a191c9bfbf193 100644
--- a/lib/SimpleSAML/Stats.php
+++ b/lib/SimpleSAML/Stats.php
@@ -21,15 +21,15 @@ class Stats
      *
      * @var boolean
      */
-    private static $initialized = false;
+    private static bool $initialized = false;
 
 
     /**
      * The statistics output callbacks.
      *
-     * @var array
+     * @var \SimpleSAML\Stats\Output[]
      */
-    private static $outputs = null;
+    private static array $outputs = [];
 
 
     /**
diff --git a/lib/SimpleSAML/Store.php b/lib/SimpleSAML/Store.php
index 86e86377733c7a921d6346e477d9442bcf807289..12e856f03dfd70f0781686fbc57d35177fef5b26 100644
--- a/lib/SimpleSAML/Store.php
+++ b/lib/SimpleSAML/Store.php
@@ -21,7 +21,7 @@ abstract class Store implements Utils\ClearableState
      *
      * @var \SimpleSAML\Store|false|null
      */
-    private static $instance;
+    private static $instance = null;
 
 
     /**
diff --git a/lib/SimpleSAML/Store/Memcache.php b/lib/SimpleSAML/Store/Memcache.php
index 8592675d6d48efeb6c723542d40005e77e6158d8..230a3ca752cf7d66e35ccb0ec53f203505638fe9 100644
--- a/lib/SimpleSAML/Store/Memcache.php
+++ b/lib/SimpleSAML/Store/Memcache.php
@@ -20,7 +20,7 @@ class Memcache extends Store
      *
      * @var string
      */
-    private $prefix;
+    private string $prefix;
 
 
     /**
diff --git a/lib/SimpleSAML/Store/Redis.php b/lib/SimpleSAML/Store/Redis.php
index dbdeb1d3adcdea6b53924ffa4bbdafc1c19dbd28..6a6aec8b404640066972717b7b02009b01c5ffdb 100644
--- a/lib/SimpleSAML/Store/Redis.php
+++ b/lib/SimpleSAML/Store/Redis.php
@@ -18,7 +18,7 @@ use SimpleSAML\Store;
 class Redis extends Store
 {
     /** @var \Predis\Client */
-    public $redis;
+    public Client $redis;
 
 
     /**
@@ -31,7 +31,7 @@ class Redis extends Store
             throw new Error\CriticalConfigurationError('predis/predis is not available.');
         }
 
-        Assert::nullOrIsInstanceOf($redis, \Predis\Client::class);
+        Assert::nullOrIsInstanceOf($redis, Client::class);
 
         if ($redis === null) {
             $config = Configuration::getInstance();
diff --git a/lib/SimpleSAML/Store/SQL.php b/lib/SimpleSAML/Store/SQL.php
index 10435dcc5a4bbd1e6919cc1dcaa43b6a174dab99..e5bcd6fb51a4c9096374043dc34bff24044486b2 100644
--- a/lib/SimpleSAML/Store/SQL.php
+++ b/lib/SimpleSAML/Store/SQL.php
@@ -23,28 +23,28 @@ class SQL extends Store
      *
      * @var \PDO
      */
-    public $pdo;
+    public PDO $pdo;
 
     /**
      * Our database driver.
      *
      * @var string
      */
-    public $driver;
+    public string $driver;
 
     /**
      * The prefix we should use for our tables.
      *
      * @var string
      */
-    public $prefix;
+    public string $prefix;
 
     /**
      * Associative array of table versions.
      *
      * @var array
      */
-    private $tableVersions;
+    private array $tableVersions;
 
 
     /**
@@ -313,9 +313,6 @@ class SQL extends Store
         }
 
         $value = $row['_value'];
-//        if (is_resource($value)) {
-//            $value = stream_get_contents($value);
-//        }
 
         Assert::string($value);
 
diff --git a/lib/SimpleSAML/Utils/Config/Metadata.php b/lib/SimpleSAML/Utils/Config/Metadata.php
index e4c66ee218a0590dc8d70dbe3957f4987e88dbb9..938eacf1e6ca7a8191156dab1c85c5825a3c88e1 100644
--- a/lib/SimpleSAML/Utils/Config/Metadata.php
+++ b/lib/SimpleSAML/Utils/Config/Metadata.php
@@ -20,7 +20,7 @@ class Metadata
      *
      * @var string
      */
-    public static $ENTITY_CATEGORY = 'http://macedir.org/entity-category';
+    public static string $ENTITY_CATEGORY = 'http://macedir.org/entity-category';
 
 
     /**
@@ -28,7 +28,7 @@ class Metadata
      *
      * @var string
      */
-    public static $HIDE_FROM_DISCOVERY = 'http://refeds.org/category/hide-from-discovery';
+    public static string $HIDE_FROM_DISCOVERY = 'http://refeds.org/category/hide-from-discovery';
 
 
     /**
@@ -38,10 +38,10 @@ class Metadata
      * it is required to allow additons to the main contact person element for trust
      * frameworks.
      *
-     * @var array The valid configuration options for a contact configuration array.
+     * @var string[] The valid configuration options for a contact configuration array.
      * @see "Metadata for the OASIS Security Assertion Markup Language (SAML) V2.0", section 2.3.2.2.
      */
-    public static $VALID_CONTACT_OPTIONS = [
+    public static array $VALID_CONTACT_OPTIONS = [
         'contactType',
         'emailAddress',
         'givenName',
@@ -53,10 +53,10 @@ class Metadata
 
 
     /**
-     * @var array The valid types of contact for a contact configuration array.
+     * @var string[] The valid types of contact for a contact configuration array.
      * @see "Metadata for the OASIS Security Assertion Markup Language (SAML) V2.0", section 2.3.2.2.
      */
-    public static $VALID_CONTACT_TYPES = [
+    public static array $VALID_CONTACT_TYPES = [
         'technical',
         'support',
         'administrative',
diff --git a/lib/SimpleSAML/Utils/EMail.php b/lib/SimpleSAML/Utils/EMail.php
index 6317cd6b2bae59d6384f68b2702896a3fb5e6438..38a71ad872977d981d0aa9593cfb704ec89248c7 100644
--- a/lib/SimpleSAML/Utils/EMail.php
+++ b/lib/SimpleSAML/Utils/EMail.php
@@ -20,13 +20,13 @@ use SimpleSAML\XHTML\Template;
 class EMail
 {
     /** @var array Dictionary with multivalues */
-    private $data = [];
+    private array $data = [];
 
     /** @var string Introduction text */
-    private $text = '';
+    private string $text = '';
 
-    /** @var PHPMailer The mailer instance */
-    private $mail;
+    /** @var \PHPMailer\PHPMailer\PHPMailer The mailer instance */
+    private PHPMailer $mail;
 
 
     /**
diff --git a/lib/SimpleSAML/Utils/Time.php b/lib/SimpleSAML/Utils/Time.php
index ee860b78cc0995b002e88fcb957ac762093a422c..9540e2646fbf31104cd8a9b6e6fb54289fa65a7a 100644
--- a/lib/SimpleSAML/Utils/Time.php
+++ b/lib/SimpleSAML/Utils/Time.php
@@ -21,7 +21,7 @@ class Time
      *
      * @var bool
      */
-    private static $tz_initialized = false;
+    private static bool $tz_initialized = false;
 
 
     /**
diff --git a/lib/SimpleSAML/XHTML/IdPDisco.php b/lib/SimpleSAML/XHTML/IdPDisco.php
index c0199a445dd6ddc06b963fff7df7abcf94fcb97f..ffc7da248dd13a5927b82ac79daaf57ed0dc765c 100644
--- a/lib/SimpleSAML/XHTML/IdPDisco.php
+++ b/lib/SimpleSAML/XHTML/IdPDisco.php
@@ -28,42 +28,42 @@ class IdPDisco
      *
      * @var \SimpleSAML\Configuration
      */
-    protected $config;
+    protected Configuration $config;
 
     /**
      * The identifier of this discovery service.
      *
      * @var string
      */
-    protected $instance;
+    protected string $instance;
 
     /**
      * An instance of the metadata handler, which will allow us to fetch metadata about IdPs.
      *
      * @var \SimpleSAML\Metadata\MetaDataStorageHandler
      */
-    protected $metadata;
+    protected MetadataStorageHandler $metadata;
 
     /**
      * The users session.
      *
      * @var \SimpleSAML\Session
      */
-    protected $session;
+    protected Session $session;
 
     /**
      * The metadata sets we find allowed entities in, in prioritized order.
      *
      * @var array
      */
-    protected $metadataSets;
+    protected array $metadataSets;
 
     /**
      * The entity id of the SP which accesses this IdP discovery service.
      *
      * @var string
      */
-    protected $spEntityId;
+    protected string $spEntityId;
 
     /**
      * HTTP parameter from the request, indicating whether the discovery service
@@ -71,14 +71,14 @@ class IdPDisco
      *
      * @var boolean
      */
-    protected $isPassive;
+    protected bool $isPassive;
 
     /**
      * The SP request to set the IdPentityID...
      *
      * @var string|null
      */
-    protected $setIdPentityID = null;
+    protected ?string $setIdPentityID = null;
 
     /**
      * The name of the query parameter which should contain the users choice of IdP.
@@ -86,7 +86,7 @@ class IdPDisco
      *
      * @var string
      */
-    protected $returnIdParam;
+    protected string $returnIdParam;
 
     /**
      * The list of scoped idp's. The intersection between the metadata idpList
@@ -95,14 +95,14 @@ class IdPDisco
      *
      * @var array
      */
-    protected $scopedIDPList = [];
+    protected array $scopedIDPList = [];
 
     /**
      * The URL the user should be redirected to after choosing an IdP.
      *
      * @var string
      */
-    protected $returnURL;
+    protected string $returnURL;
 
 
     /**
diff --git a/lib/SimpleSAML/XHTML/Template.php b/lib/SimpleSAML/XHTML/Template.php
index 3fde9897bf4ca0901ad2fc0784ea2af45223f877..2326b7d29bf1cac208d1f8d134de75cdfb56b197 100644
--- a/lib/SimpleSAML/XHTML/Template.php
+++ b/lib/SimpleSAML/XHTML/Template.php
@@ -36,56 +36,56 @@ class Template extends Response
      *
      * @var array
      */
-    public $data = [];
+    public array $data = [];
 
     /**
      * A translator instance configured to work with this template.
      *
      * @var \SimpleSAML\Locale\Translate
      */
-    private $translator;
+    private Translate $translator;
 
     /**
      * The localization backend
      *
      * @var \SimpleSAML\Locale\Localization
      */
-    private $localization;
+    private Localization $localization;
 
     /**
      * The configuration to use in this template.
      *
      * @var \SimpleSAML\Configuration
      */
-    private $configuration;
+    private Configuration $configuration;
 
     /**
      * The file to load in this template.
      *
      * @var string
      */
-    private $template = 'default.php';
+    private string $template = 'default.php';
 
     /**
      * The twig environment.
      *
      * @var \Twig\Environment
      */
-    private $twig;
+    private \Twig\Environment $twig;
 
     /**
      * The template name.
      *
      * @var string
      */
-    private $twig_template;
+    private string $twig_template;
 
     /**
      * Current module, if any.
      *
-     * @var string
+     * @var string|null
      */
-    private $module;
+    private ?string $module = null;
 
     /**
      * A template controller, if any.
@@ -96,7 +96,7 @@ class Template extends Response
      *
      * @var \SimpleSAML\XHTML\TemplateControllerInterface|null
      */
-    private $controller = null;
+    private ?TemplateControllerInterface $controller = null;
 
     /**
      * Whether we are using a non-default theme or not.
@@ -107,7 +107,7 @@ class Template extends Response
      *
      * @var array
      */
-    private $theme = ['module' => null, 'name' => 'default'];
+    private array $theme = ['module' => null, 'name' => 'default'];
 
 
     /**
diff --git a/lib/SimpleSAML/XHTML/TemplateControllerInterface.php b/lib/SimpleSAML/XHTML/TemplateControllerInterface.php
index 488676cd37052c4504621bb2a91f0070bf43dffa..dbda8a6923ae551007484c354836e227037d6da5 100644
--- a/lib/SimpleSAML/XHTML/TemplateControllerInterface.php
+++ b/lib/SimpleSAML/XHTML/TemplateControllerInterface.php
@@ -13,7 +13,6 @@ use Twig\Environment;
  */
 interface TemplateControllerInterface
 {
-
     /**
      * Implement to modify the twig environment after its initialization (e.g. add filters or extensions).
      *
diff --git a/lib/SimpleSAML/XML/Errors.php b/lib/SimpleSAML/XML/Errors.php
index 155cb66465284ae1ed0a6f41b1cee25b4288fa44..ee34f8a92bfad7b187e0320cd7a96835c3d2344c 100644
--- a/lib/SimpleSAML/XML/Errors.php
+++ b/lib/SimpleSAML/XML/Errors.php
@@ -21,12 +21,12 @@ class Errors
     /**
      * @var array This is an stack of error logs. The topmost element is the one we are currently working on.
      */
-    private static $errorStack = [];
+    private static array $errorStack = [];
 
     /**
      * @var bool This is the xml error state we had before we began logging.
      */
-    private static $xmlErrorState;
+    private static bool $xmlErrorState;
 
 
     /**
diff --git a/lib/SimpleSAML/XML/Parser.php b/lib/SimpleSAML/XML/Parser.php
index 07f506e172ae28b10f6f12169c29dbc2d3cbb9f1..ba2c4e13d27b50a1e5fca83a2b89221886e94ca5 100644
--- a/lib/SimpleSAML/XML/Parser.php
+++ b/lib/SimpleSAML/XML/Parser.php
@@ -15,7 +15,7 @@ use SimpleXMLElement;
 class Parser
 {
     /** @var \SimpleXMLElement */
-    public $simplexml;
+    public SimpleXMLElement $simplexml;
 
     /**
      * @param string $xml
diff --git a/lib/SimpleSAML/XML/Signer.php b/lib/SimpleSAML/XML/Signer.php
index 769b8dd76d2555f59d18cd36ad7dfc3553555720..898eb639a120ef205967df5c9b76e121fbf32264 100644
--- a/lib/SimpleSAML/XML/Signer.php
+++ b/lib/SimpleSAML/XML/Signer.php
@@ -25,23 +25,23 @@ class Signer
     /**
      * @var string The name of the ID attribute.
      */
-    private $idAttrName = '';
+    private string $idAttrName = '';
 
     /**
-     * @var XMLSecurityKey|false  The private key (as an XMLSecurityKey).
+     * @var \RobRichards\XMLSecLibs\XMLSecurityKey|false  The private key (as an XMLSecurityKey).
      */
     private $privateKey = false;
 
     /**
      * @var string The certificate (as text).
      */
-    private $certificate = '';
+    private string $certificate = '';
 
 
     /**
      * @var array Extra certificates which should be included in the response.
      */
-    private $extraCertificates = [];
+    private array $extraCertificates = [];
 
 
     /**
diff --git a/lib/SimpleSAML/XML/Validator.php b/lib/SimpleSAML/XML/Validator.php
index e09332bdb1648da89d10236766a342687b3072fd..7648910ede75b9f203c96036bfc7a3a59e8e69e8 100644
--- a/lib/SimpleSAML/XML/Validator.php
+++ b/lib/SimpleSAML/XML/Validator.php
@@ -23,12 +23,12 @@ class Validator
      * @var string|null This variable contains the X509 certificate the XML document
      *             was signed with, or NULL if it wasn't signed with an X509 certificate.
      */
-    private $x509Certificate = null;
+    private ?string $x509Certificate = null;
 
     /**
      * @var array|null This variable contains the nodes which are signed.
      */
-    private $validNodes = null;
+    private ?array $validNodes = null;
 
 
     /**
diff --git a/modules/admin/lib/Controller/Config.php b/modules/admin/lib/Controller/Config.php
index 463e266230e3d63ad052b9679942d3f99f53fbcf..e4823002060e6e5eb08a058654d0ddecf8edce07 100644
--- a/modules/admin/lib/Controller/Config.php
+++ b/modules/admin/lib/Controller/Config.php
@@ -27,7 +27,7 @@ class Config
     public const RELEASES_API = 'https://api.github.com/repos/simplesamlphp/simplesamlphp/releases/latest';
 
     /** @var \SimpleSAML\Configuration */
-    protected $config;
+    protected Configuration $config;
 
     /**
      * @var \SimpleSAML\Utils\Auth|string
@@ -35,11 +35,11 @@ class Config
      */
     protected $authUtils = Utils\Auth::class;
 
-    /** @var Menu */
-    protected $menu;
+    /** @var \SimpleSAML\Module\admin\Controller\Menu */
+    protected Menu $menu;
 
     /** @var \SimpleSAML\Session */
-    protected $session;
+    protected Session $session;
 
 
     /**
@@ -137,6 +137,7 @@ class Config
 
         Module::callHooks('configpage', $t);
         $this->menu->addOption('logout', Utils\Auth::getAdminLogoutURL(), Translate::noop('Log out'));
+        /** @psalm-var \SimpleSAML\XHTML\Template $t */
         return $this->menu->insert($t);
     }
 
diff --git a/modules/admin/lib/Controller/Federation.php b/modules/admin/lib/Controller/Federation.php
index d4ff475de74fa6944546c879a053de8c81f4ea0e..2b349d877c895026faf3b0b3ca870e661bb23880 100644
--- a/modules/admin/lib/Controller/Federation.php
+++ b/modules/admin/lib/Controller/Federation.php
@@ -34,7 +34,7 @@ use Symfony\Component\VarExporter\VarExporter;
 class Federation
 {
     /** @var \SimpleSAML\Configuration */
-    protected $config;
+    protected Configuration $config;
 
     /**
      * @var \SimpleSAML\Auth\Source|string
@@ -49,10 +49,10 @@ class Federation
     protected $authUtils = Utils\Auth::class;
 
     /** @var \SimpleSAML\Metadata\MetaDataStorageHandler */
-    protected $mdHandler;
+    protected MetadataStorageHandler $mdHandler;
 
-    /** @var Menu */
-    protected $menu;
+    /** @var \SimpleSAML\Module\admin\Controller\Menu */
+    protected Menu $menu;
 
 
     /**
@@ -195,6 +195,7 @@ class Federation
         Assert::isInstanceOf($t, Template::class);
 
         $this->menu->addOption('logout', $t->data['logouturl'], Translate::noop('Log out'));
+        /** @psalm-var \SimpleSAML\XHTML\Template $t */
         return $this->menu->insert($t);
     }
 
diff --git a/modules/admin/lib/Controller/Menu.php b/modules/admin/lib/Controller/Menu.php
index 1754042f8c19fdfcfe2458d8ffcfafc2123b7cbd..7e6345f11bd48205dbcde03e0597a99287b7650d 100644
--- a/modules/admin/lib/Controller/Menu.php
+++ b/modules/admin/lib/Controller/Menu.php
@@ -17,7 +17,7 @@ use SimpleSAML\XHTML\Template;
 final class Menu
 {
     /** @var array */
-    private $options;
+    private array $options;
 
 
     /**
@@ -88,7 +88,10 @@ final class Menu
     {
         $template->data['menu'] = $this->options;
         Module::callHooks('adminmenu', $template);
+
         Assert::isInstanceOf($template, Template::class);
+
+        /** @psalm-var \SimpleSAML\XHTML\Template $template */
         return $template;
     }
 }
diff --git a/modules/admin/lib/Controller/Test.php b/modules/admin/lib/Controller/Test.php
index 5d23f41eb197e488e6ac10d9f982df811e1b7f12..3be69e3d967213458d6e496681cfd47c3046e2d0 100644
--- a/modules/admin/lib/Controller/Test.php
+++ b/modules/admin/lib/Controller/Test.php
@@ -28,7 +28,7 @@ use Symfony\Component\HttpFoundation\Response;
 class Test
 {
     /** @var \SimpleSAML\Configuration */
-    protected $config;
+    protected Configuration $config;
 
     /**
      * @var \SimpleSAML\Utils\Auth|string
@@ -48,11 +48,11 @@ class Test
      */
     protected $authState = Auth\State::class;
 
-    /** @var Menu */
-    protected $menu;
+    /** @var \SimpleSAML\Module\admin\Controller\Menu */
+    protected Menu $menu;
 
     /** @var \SimpleSAML\Session */
-    protected $session;
+    protected Session $session;
 
 
     /**
@@ -118,8 +118,9 @@ class Test
                 'sources' => Auth\Source::getSources(),
             ];
         } else {
-            $simple = $this->authSimple;
-            $authsource = new $simple($as);
+            /** @psalm-suppress UndefinedClass */
+            $authsource = new $this->authSimple($as);
+
             if (!is_null($request->query->get('logout'))) {
                 return new RunnableResponse([$authsource, 'logout'], [$this->config->getBasePath() . 'logout.php']);
             } elseif (!is_null($request->query->get(Auth\State::EXCEPTION_PARAM))) {
@@ -161,6 +162,7 @@ class Test
         Assert::isInstanceOf($t, Template::class);
 
         $this->menu->addOption('logout', Utils\Auth::getAdminLogoutURL(), Translate::noop('Log out'));
+        /** @var \SimpleSAML\XHTML\Template $t */
         return $this->menu->insert($t);
     }
 
diff --git a/modules/core/lib/Auth/Process/AttributeAdd.php b/modules/core/lib/Auth/Process/AttributeAdd.php
index 28c82fc1aa53a917cced97fc4fd589b857d8a09b..d30084a8738a59201f39f8c7e14d9d92b0ccab9a 100644
--- a/modules/core/lib/Auth/Process/AttributeAdd.php
+++ b/modules/core/lib/Auth/Process/AttributeAdd.php
@@ -21,7 +21,7 @@ class AttributeAdd extends Auth\ProcessingFilter
      * Flag which indicates wheter this filter should append new values or replace old values.
      * @var bool
      */
-    private $replace = false;
+    private bool $replace = false;
 
     /**
      * Attributes which should be added/appended.
@@ -29,7 +29,7 @@ class AttributeAdd extends Auth\ProcessingFilter
      * Associative array of arrays.
      * @var array
      */
-    private $attributes = [];
+    private array $attributes = [];
 
 
     /**
diff --git a/modules/core/lib/Auth/Process/AttributeAlter.php b/modules/core/lib/Auth/Process/AttributeAlter.php
index badf28ad3d09e3ab50554dd3e430cfd2f17e0833..29a2c0823aa7aae0041d2c46217cf20168875147 100644
--- a/modules/core/lib/Auth/Process/AttributeAlter.php
+++ b/modules/core/lib/Auth/Process/AttributeAlter.php
@@ -21,19 +21,19 @@ class AttributeAlter extends Auth\ProcessingFilter
      * Should the pattern found be replaced?
      * @var bool
      */
-    private $replace = false;
+    private bool $replace = false;
 
     /**
      * Should the value found be removed?
      * @var bool
      */
-    private $remove = false;
+    private bool $remove = false;
 
     /**
      * Pattern to search for.
      * @var string
      */
-    private $pattern = '';
+    private string $pattern = '';
 
     /**
      * String to replace the pattern found with.
@@ -45,13 +45,13 @@ class AttributeAlter extends Auth\ProcessingFilter
      * Attribute to search in
      * @var string
      */
-    private $subject = '';
+    private string $subject = '';
 
     /**
      * Attribute to place the result in.
      * @var string
      */
-    private $target = '';
+    private string $target = '';
 
 
     /**
diff --git a/modules/core/lib/Auth/Process/AttributeCopy.php b/modules/core/lib/Auth/Process/AttributeCopy.php
index d0767528cd2857902af25c998d8284ad92681e07..199e4a8a24464f419878d27891bd638f4544a0eb 100644
--- a/modules/core/lib/Auth/Process/AttributeCopy.php
+++ b/modules/core/lib/Auth/Process/AttributeCopy.php
@@ -28,7 +28,7 @@ class AttributeCopy extends Auth\ProcessingFilter
      * Assosiative array with the mappings of attribute names.
      * @var array
      */
-    private $map = [];
+    private array $map = [];
 
 
     /**
diff --git a/modules/core/lib/Auth/Process/AttributeLimit.php b/modules/core/lib/Auth/Process/AttributeLimit.php
index 91d32fc3a40eda55db50252578ed211c1e1555ee..490940f3084293df10e530658373634bac353679 100644
--- a/modules/core/lib/Auth/Process/AttributeLimit.php
+++ b/modules/core/lib/Auth/Process/AttributeLimit.php
@@ -20,14 +20,14 @@ class AttributeLimit extends Auth\ProcessingFilter
      * List of attributes which this filter will allow through.
      * @var array
      */
-    private $allowedAttributes = [];
+    private array $allowedAttributes = [];
 
     /**
      * Whether the 'attributes' option in the metadata takes precedence.
      *
      * @var bool
      */
-    private $isDefault = false;
+    private bool $isDefault = false;
 
 
     /**
@@ -50,14 +50,12 @@ class AttributeLimit extends Auth\ProcessingFilter
                         var_export($value, true));
                 }
                 $this->allowedAttributes[] = $value;
-            } elseif (is_string($index)) {
+            } else { // Can only be string since PHP only allows string|int for array keys
                 if (!is_array($value)) {
                     throw new Error\Exception('AttributeLimit: Values for ' .
                         var_export($index, true) . ' must be specified in an array.');
                 }
                 $this->allowedAttributes[$index] = $value;
-            } else {
-                throw new Error\Exception('AttributeLimit: Invalid option: ' . var_export($index, true));
             }
         }
     }
diff --git a/modules/core/lib/Auth/Process/AttributeMap.php b/modules/core/lib/Auth/Process/AttributeMap.php
index d96068c9d25394729905e0b913a7440c74c56775..3fd36bdae63c4c997d8df4d17133569052e6bccc 100644
--- a/modules/core/lib/Auth/Process/AttributeMap.php
+++ b/modules/core/lib/Auth/Process/AttributeMap.php
@@ -21,13 +21,13 @@ class AttributeMap extends Auth\ProcessingFilter
      * Associative array with the mappings of attribute names.
      * @var array
      */
-    private $map = [];
+    private array $map = [];
 
     /**
      * Should attributes be duplicated or renamed.
      * @var bool
      */
-    private $duplicate = false;
+    private bool $duplicate = false;
 
 
     /**
@@ -55,10 +55,6 @@ class AttributeMap extends Auth\ProcessingFilter
                 continue;
             }
 
-            if (!is_string($origName)) {
-                throw new Exception('Invalid attribute name: ' . var_export($origName, true));
-            }
-
             if (!is_string($newName) && !is_array($newName)) {
                 throw new Exception('Invalid attribute name: ' . var_export($newName, true));
             }
diff --git a/modules/core/lib/Auth/Process/AttributeValueMap.php b/modules/core/lib/Auth/Process/AttributeValueMap.php
index 8f52114e4e396eb84c892ac7ebcbf553dd838a0f..26636d35bb4d020a40d1c76d9bc0a77e912370dd 100644
--- a/modules/core/lib/Auth/Process/AttributeValueMap.php
+++ b/modules/core/lib/Auth/Process/AttributeValueMap.php
@@ -20,31 +20,31 @@ class AttributeValueMap extends Auth\ProcessingFilter
      * The name of the attribute we should assign values to (ie: the target attribute).
      * @var string
      */
-    private $targetattribute = '';
+    private string $targetattribute = '';
 
     /**
      * The name of the attribute we should create values from.
      * @var string
      */
-    private $sourceattribute = '';
+    private string $sourceattribute = '';
 
     /**
      * The required $sourceattribute values and target affiliations.
      * @var array
      */
-    private $values = [];
+    private array $values = [];
 
     /**
      * Whether $sourceattribute should be kept or not.
      * @var bool
      */
-    private $keep = false;
+    private bool $keep = false;
 
     /**
      * Whether $target attribute values should be replaced by new values or not.
      * @var bool
      */
-    private $replace = false;
+    private bool $replace = false;
 
 
     /**
diff --git a/modules/core/lib/Auth/Process/Cardinality.php b/modules/core/lib/Auth/Process/Cardinality.php
index a05e67fd1c533fed4b8a0c416e7c7f9e6562ebae..5ad50c127f25336151b6e7f85ac5b6381422c84c 100644
--- a/modules/core/lib/Auth/Process/Cardinality.php
+++ b/modules/core/lib/Auth/Process/Cardinality.php
@@ -19,13 +19,13 @@ use SimpleSAML\Utils;
 class Cardinality extends Auth\ProcessingFilter
 {
     /** @var array Associative array with the mappings of attribute names. */
-    private $cardinality = [];
+    private array $cardinality = [];
 
     /** @var array Entities that should be ignored */
-    private $ignoreEntities = [];
+    private array $ignoreEntities = [];
 
     /** @var \SimpleSAML\Utils\HttpAdapter */
-    private $http;
+    private Utils\HttpAdapter $http;
 
 
     /**
diff --git a/modules/core/lib/Auth/Process/CardinalitySingle.php b/modules/core/lib/Auth/Process/CardinalitySingle.php
index 0593c2d344db5a5a7499920b1d9896c692510964..c849e7c8b596ea63d1052fa3e57de5237b335c41 100644
--- a/modules/core/lib/Auth/Process/CardinalitySingle.php
+++ b/modules/core/lib/Auth/Process/CardinalitySingle.php
@@ -21,22 +21,22 @@ use SimpleSAML\Utils;
 class CardinalitySingle extends Auth\ProcessingFilter
 {
     /** @var array Attributes that should be single-valued or we generate an error */
-    private $singleValued = [];
+    private array $singleValued = [];
 
     /** @var array Attributes for which the first value should be taken */
-    private $firstValue = [];
+    private array $firstValue = [];
 
     /** @var array Attributes that can be flattened to a single value */
-    private $flatten = [];
+    private array $flatten = [];
 
     /** @var string Separator for flattened value */
-    private $flattenWith = ';';
+    private string $flattenWith = ';';
 
     /** @var array Entities that should be ignored */
-    private $ignoreEntities = [];
+    private array $ignoreEntities = [];
 
     /** @var \SimpleSAML\Utils\HttpAdapter */
-    private $http;
+    private Utils\HttpAdapter $http;
 
 
     /**
diff --git a/modules/core/lib/Auth/Process/GenerateGroups.php b/modules/core/lib/Auth/Process/GenerateGroups.php
index 5793381f23b6116e1ce1356cf902bd57e6e776e3..2a8eadef7a1930a5e7e180ddfbd60e7954983aea 100644
--- a/modules/core/lib/Auth/Process/GenerateGroups.php
+++ b/modules/core/lib/Auth/Process/GenerateGroups.php
@@ -20,7 +20,7 @@ class GenerateGroups extends Auth\ProcessingFilter
      * The attributes we should generate groups from.
      * @var array
      */
-    private $generateGroupsFrom;
+    private array $generateGroupsFrom;
 
 
     /**
diff --git a/modules/core/lib/Auth/Process/LanguageAdaptor.php b/modules/core/lib/Auth/Process/LanguageAdaptor.php
index c6d14c9f0d174589d4a62e76b18b7618c4256cd2..c621172e6f61129548a03c457c34b3618b2c236d 100644
--- a/modules/core/lib/Auth/Process/LanguageAdaptor.php
+++ b/modules/core/lib/Auth/Process/LanguageAdaptor.php
@@ -17,7 +17,7 @@ use SimpleSAML\Logger;
 class LanguageAdaptor extends Auth\ProcessingFilter
 {
     /** @var string */
-    private $langattr = 'preferredLanguage';
+    private string $langattr = 'preferredLanguage';
 
 
     /**
diff --git a/modules/core/lib/Auth/Process/PHP.php b/modules/core/lib/Auth/Process/PHP.php
index 45b5b465060db8eee901ffca6b7c4df85b2aec44..15428a461a4cce69e45f34cc1704fe8c58d1df7c 100644
--- a/modules/core/lib/Auth/Process/PHP.php
+++ b/modules/core/lib/Auth/Process/PHP.php
@@ -21,7 +21,7 @@ class PHP extends Auth\ProcessingFilter
      *
      * @var string
      */
-    private $code;
+    private string $code;
 
 
     /**
diff --git a/modules/core/lib/Auth/Process/ScopeAttribute.php b/modules/core/lib/Auth/Process/ScopeAttribute.php
index 1b6ceca7cabd7c6943810d194a349fc01ae692ce..18955f9f64fbc171c3857504f4f3cf49dca18025 100644
--- a/modules/core/lib/Auth/Process/ScopeAttribute.php
+++ b/modules/core/lib/Auth/Process/ScopeAttribute.php
@@ -21,28 +21,28 @@ class ScopeAttribute extends Auth\ProcessingFilter
      *
      * @var string
      */
-    private $scopeAttribute;
+    private string $scopeAttribute;
 
     /**
      * The attribute we want to add scope to.
      *
      * @var string
      */
-    private $sourceAttribute;
+    private string $sourceAttribute;
 
     /**
      * The attribute we want to add the scoped attributes to.
      *
      * @var string
      */
-    private $targetAttribute;
+    private string $targetAttribute;
 
     /**
      * Only modify targetAttribute if it doesn't already exist.
      *
      * @var bool
      */
-    private $onlyIfEmpty = false;
+    private bool $onlyIfEmpty = false;
 
 
     /**
diff --git a/modules/core/lib/Auth/Process/ScopeFromAttribute.php b/modules/core/lib/Auth/Process/ScopeFromAttribute.php
index 121c6e3f3ee5af6f48209c2c03729f6d6407ed59..7734cacb42b2ba35107cb8aff953e2dbe86ec710 100644
--- a/modules/core/lib/Auth/Process/ScopeFromAttribute.php
+++ b/modules/core/lib/Auth/Process/ScopeFromAttribute.php
@@ -32,14 +32,14 @@ class ScopeFromAttribute extends Auth\ProcessingFilter
      *
      * @var string
      */
-    private $sourceAttribute;
+    private string $sourceAttribute;
 
     /**
      * The name of the attribute which includes the scope
      *
      * @var string
      */
-    private $targetAttribute;
+    private string $targetAttribute;
 
 
     /**
diff --git a/modules/core/lib/Auth/Process/StatisticsWithAttribute.php b/modules/core/lib/Auth/Process/StatisticsWithAttribute.php
index f7541d45a581c8cd4dcd8b51abcbf16013be2c90..bcbdd20d815e70c0063ada4bca5b6b4b213f9744 100644
--- a/modules/core/lib/Auth/Process/StatisticsWithAttribute.php
+++ b/modules/core/lib/Auth/Process/StatisticsWithAttribute.php
@@ -20,17 +20,17 @@ class StatisticsWithAttribute extends Auth\ProcessingFilter
      * The attribute to log
      * @var string|null
      */
-    private $attribute = null;
+    private ?string $attribute = null;
 
     /**
      * @var string
      */
-    private $typeTag = 'saml20-idp-SSO';
+    private string $typeTag = 'saml20-idp-SSO';
 
     /**
      * @var bool
      */
-    private $skipPassive = false;
+    private bool $skipPassive = false;
 
 
     /**
diff --git a/modules/core/lib/Auth/Process/TargetedID.php b/modules/core/lib/Auth/Process/TargetedID.php
index 2325fa2f62a4310dc8b4678d0ed20a0062271205..04b6aefc2c59d78e24f259fb12d415484da7cca2 100644
--- a/modules/core/lib/Auth/Process/TargetedID.php
+++ b/modules/core/lib/Auth/Process/TargetedID.php
@@ -37,14 +37,14 @@ class TargetedID extends Auth\ProcessingFilter
      *
      * @var string
      */
-    private $identifyingAttribute;
+    private string $identifyingAttribute;
 
     /**
      * Whether the attribute should be generated as a NameID value, or as a simple string.
      *
      * @var boolean
      */
-    private $generateNameId = false;
+    private bool $generateNameId = false;
 
     /**
      * @var \SimpleSAML\Utils\Config|string
diff --git a/modules/core/lib/Auth/UserPassBase.php b/modules/core/lib/Auth/UserPassBase.php
index 515445b90cbadee35b3a3732df19ac7667932365..d43fc3d1ae0cd0cb066c862a86dd5211f911eef1 100644
--- a/modules/core/lib/Auth/UserPassBase.php
+++ b/modules/core/lib/Auth/UserPassBase.php
@@ -41,7 +41,7 @@ abstract class UserPassBase extends Auth\Source
      *
      * @var string|null
      */
-    private $forcedUsername;
+    private ?string $forcedUsername = null;
 
     /**
      * Links to pages from login page.
@@ -49,7 +49,7 @@ abstract class UserPassBase extends Auth\Source
      *
      * @var array
      */
-    protected $loginLinks = [];
+    protected array $loginLinks = [];
 
     /**
      * Storage for authsource config option remember.username.enabled
@@ -58,7 +58,7 @@ abstract class UserPassBase extends Auth\Source
      *
      * @var bool
      */
-    protected $rememberUsernameEnabled = false;
+    protected bool $rememberUsernameEnabled = false;
 
     /**
      * Storage for authsource config option remember.username.checked
@@ -67,7 +67,7 @@ abstract class UserPassBase extends Auth\Source
      *
      * @var bool
      */
-    protected $rememberUsernameChecked = false;
+    protected bool $rememberUsernameChecked = false;
 
     /**
      * Storage for general config option session.rememberme.enable.
@@ -78,7 +78,7 @@ abstract class UserPassBase extends Auth\Source
      *
      * @var bool
      */
-    protected $rememberMeEnabled = false;
+    protected bool $rememberMeEnabled = false;
 
     /**
      * Storage for general config option session.rememberme.checked.
@@ -87,7 +87,7 @@ abstract class UserPassBase extends Auth\Source
      *
      * @var bool
      */
-    protected $rememberMeChecked = false;
+    protected bool $rememberMeChecked = false;
 
 
     /**
diff --git a/modules/core/lib/Auth/UserPassOrgBase.php b/modules/core/lib/Auth/UserPassOrgBase.php
index 03b9b214a07c880a009dc6590d0c0ce135b084aa..df6cca39327a1338a7bf9cb0e2dc5d0edbc614da 100644
--- a/modules/core/lib/Auth/UserPassOrgBase.php
+++ b/modules/core/lib/Auth/UserPassOrgBase.php
@@ -47,7 +47,7 @@ abstract class UserPassOrgBase extends Auth\Source
      *
      * @var string
      */
-    private $usernameOrgMethod;
+    private string $usernameOrgMethod;
 
     /**
      * Storage for authsource config option remember.username.enabled
@@ -56,7 +56,7 @@ abstract class UserPassOrgBase extends Auth\Source
      *
      * @var bool
      */
-    protected $rememberUsernameEnabled = false;
+    protected bool $rememberUsernameEnabled = false;
 
     /**
      * Storage for authsource config option remember.username.checked
@@ -65,7 +65,7 @@ abstract class UserPassOrgBase extends Auth\Source
      *
      * @var bool
      */
-    protected $rememberUsernameChecked = false;
+    protected bool $rememberUsernameChecked = false;
 
     /**
      * Storage for authsource config option remember.organization.enabled
@@ -74,7 +74,7 @@ abstract class UserPassOrgBase extends Auth\Source
      *
      * @var bool
      */
-    protected $rememberOrganizationEnabled = false;
+    protected bool $rememberOrganizationEnabled = false;
 
     /**
      * Storage for authsource config option remember.organization.checked
@@ -83,7 +83,7 @@ abstract class UserPassOrgBase extends Auth\Source
      *
      * @var bool
      */
-    protected $rememberOrganizationChecked = false;
+    protected bool $rememberOrganizationChecked = false;
 
 
     /**
diff --git a/modules/core/lib/Controller/Exception.php b/modules/core/lib/Controller/Exception.php
index b872b377b26628eb43b1c5317ad6bf5f5b194a5c..1e5a093b73350f89882c0f7f3c299c961b2f51ab 100644
--- a/modules/core/lib/Controller/Exception.php
+++ b/modules/core/lib/Controller/Exception.php
@@ -25,10 +25,10 @@ use Symfony\Component\HttpFoundation\Response;
 class Exception
 {
     /** @var \SimpleSAML\Configuration */
-    protected $config;
+    protected Configuration $config;
 
     /** @var \SimpleSAML\Session */
-    protected $session;
+    protected Session $session;
 
 
     /**
diff --git a/modules/core/lib/Controller/Login.php b/modules/core/lib/Controller/Login.php
index e54d60198cebecd0dd23505cb58779782fd8e7b7..a4941bc00fa12976abd3637e486405a52db31ef6 100644
--- a/modules/core/lib/Controller/Login.php
+++ b/modules/core/lib/Controller/Login.php
@@ -28,16 +28,16 @@ use Symfony\Component\HttpFoundation\Response;
 class Login
 {
     /** @var \SimpleSAML\Configuration */
-    protected $config;
+    protected Configuration $config;
 
     /** @var \SimpleSAML\Auth\AuthenticationFactory */
-    protected $factory;
+    protected AuthenticationFactory $factory;
 
     /** @var \SimpleSAML\Session */
-    protected $session;
+    protected Session $session;
 
     /** @var array */
-    protected $sources;
+    protected array $sources;
 
 
     /**
diff --git a/modules/core/lib/Controller/Redirection.php b/modules/core/lib/Controller/Redirection.php
index 373f77bff681b4bd23059069424222a3df806539..942dd675c1a3369cd6930de8e110ffbd22c72b36 100644
--- a/modules/core/lib/Controller/Redirection.php
+++ b/modules/core/lib/Controller/Redirection.php
@@ -26,10 +26,10 @@ use Symfony\Component\HttpFoundation\Response;
 class Redirection
 {
     /** @var \SimpleSAML\Configuration */
-    protected $config;
+    protected Configuration $config;
 
     /** @var \SimpleSAML\Session */
-    protected $session;
+    protected Session $session;
 
 
     /**
diff --git a/modules/core/lib/Stats/Output/File.php b/modules/core/lib/Stats/Output/File.php
index 17d890bc707be51e865efbe91b76d991e87284da..263c7001b357029bb9087f555e2649fec574bc8e 100644
--- a/modules/core/lib/Stats/Output/File.php
+++ b/modules/core/lib/Stats/Output/File.php
@@ -19,7 +19,7 @@ class File extends \SimpleSAML\Stats\Output
      * The log directory.
      * @var string
      */
-    private $logDir;
+    private string $logDir;
 
     /**
      * The file handle for the current file.
@@ -31,7 +31,7 @@ class File extends \SimpleSAML\Stats\Output
      * The current file date.
      * @var string|null
      */
-    private $fileDate = null;
+    private ?string $fileDate = null;
 
 
     /**
diff --git a/modules/core/lib/Storage/SQLPermanentStorage.php b/modules/core/lib/Storage/SQLPermanentStorage.php
index 183a38b658e1f1a4eb7d3d0d0440954f2c735945..7c21976aa743d17207a270715e4209d8b6fd4a67 100644
--- a/modules/core/lib/Storage/SQLPermanentStorage.php
+++ b/modules/core/lib/Storage/SQLPermanentStorage.php
@@ -19,7 +19,7 @@ use SimpleSAML\Configuration;
 class SQLPermanentStorage
 {
     /** @var \PDO */
-    private $db;
+    private PDO $db;
 
 
     /**
diff --git a/modules/cron/lib/Controller/Cron.php b/modules/cron/lib/Controller/Cron.php
index b7de7617958dc6ba49cfffeb7f3b610307e44f7b..0b6542d7f5862d4070682595e59f641f50f6d8f7 100644
--- a/modules/cron/lib/Controller/Cron.php
+++ b/modules/cron/lib/Controller/Cron.php
@@ -29,13 +29,13 @@ use Symfony\Component\HttpFoundation\Response;
 class Cron
 {
     /** @var \SimpleSAML\Configuration */
-    protected $config;
+    protected Configuration $config;
 
     /** @var \SimpleSAML\Configuration */
-    protected $cronconfig;
+    protected Configuration $cronconfig;
 
     /** @var \SimpleSAML\Session */
-    protected $session;
+    protected Session $session;
 
     /**
      * @var \SimpleSAML\Utils\Auth|string
diff --git a/modules/cron/lib/Cron.php b/modules/cron/lib/Cron.php
index 7c6b0c50f0be0c0dec9c674012f43619fc7810c6..b6f7b43f9aa272409353da156a1a9b7f11a7afad 100644
--- a/modules/cron/lib/Cron.php
+++ b/modules/cron/lib/Cron.php
@@ -19,7 +19,7 @@ class Cron
      * The configuration for the Cron module
      * @var \SimpleSAML\Configuration
      */
-    private $cronconfig;
+    private Configuration $cronconfig;
 
 
     /*
diff --git a/modules/exampleauth/lib/Auth/Source/StaticSource.php b/modules/exampleauth/lib/Auth/Source/StaticSource.php
index 270d6c0ed556923f34ef6158864eed099f19f67c..fc047932230c450258c5eec79e4413887f09af35 100644
--- a/modules/exampleauth/lib/Auth/Source/StaticSource.php
+++ b/modules/exampleauth/lib/Auth/Source/StaticSource.php
@@ -23,7 +23,7 @@ class StaticSource extends Auth\Source
      * The attributes we return.
      * @var array
      */
-    private $attributes;
+    private array $attributes;
 
 
     /**
diff --git a/modules/exampleauth/lib/Auth/Source/UserPass.php b/modules/exampleauth/lib/Auth/Source/UserPass.php
index a7a19adee7a9b86c8581d3c826aacd3341a8476d..e2d08094cdec50b788b5dbb21212147611b99873 100644
--- a/modules/exampleauth/lib/Auth/Source/UserPass.php
+++ b/modules/exampleauth/lib/Auth/Source/UserPass.php
@@ -27,7 +27,7 @@ class UserPass extends UserPassBase
      *
      * @var array
      */
-    private $users;
+    private array $users;
 
 
     /**
diff --git a/modules/multiauth/lib/Auth/Source/MultiAuth.php b/modules/multiauth/lib/Auth/Source/MultiAuth.php
index 3304ad27456f44b64a255af4b986b9767e1a97ea..2ad0482b1a20a6905a61fbfa81f32c248a8d05b0 100644
--- a/modules/multiauth/lib/Auth/Source/MultiAuth.php
+++ b/modules/multiauth/lib/Auth/Source/MultiAuth.php
@@ -48,12 +48,12 @@ class MultiAuth extends Auth\Source
      * Array of sources we let the user chooses among.
      * @var array
      */
-    private $sources;
+    private array $sources;
 
     /**
      * @var string|null preselect source in filter module configuration
      */
-    private $preselect;
+    private ?string $preselect;
 
 
     /**
diff --git a/modules/multiauth/lib/Controller/DiscoController.php b/modules/multiauth/lib/Controller/DiscoController.php
index e4d3eba97124092c83cfff739e28997d37330c18..efc685482f8ddb962bbb943d19eb15ac8e22716f 100644
--- a/modules/multiauth/lib/Controller/DiscoController.php
+++ b/modules/multiauth/lib/Controller/DiscoController.php
@@ -26,10 +26,10 @@ use Symfony\Component\HttpFoundation\Request;
 class DiscoController
 {
     /** @var \SimpleSAML\Configuration */
-    protected $config;
+    protected Configuration $config;
 
     /** @var \SimpleSAML\Session */
-    protected $session;
+    protected Session $session;
 
     /**
      * @var \SimpleSAML\Auth\Source|string
diff --git a/modules/saml/lib/Auth/Process/AttributeNameID.php b/modules/saml/lib/Auth/Process/AttributeNameID.php
index e840f2b6c21b0e4890646b6ace5710d229dc0392..0c3eae84667144c9885b671367c2788db85bdaac 100644
--- a/modules/saml/lib/Auth/Process/AttributeNameID.php
+++ b/modules/saml/lib/Auth/Process/AttributeNameID.php
@@ -22,7 +22,7 @@ class AttributeNameID extends BaseNameIDGenerator
      *
      * @var string
      */
-    private $attribute;
+    private string $attribute;
 
 
     /**
diff --git a/modules/saml/lib/Auth/Process/AuthnContextClassRef.php b/modules/saml/lib/Auth/Process/AuthnContextClassRef.php
index 93bf1c7197364510604f7d6909f0b30b0a7ebfc5..bb46319b10ebd0d88b8812327134504030a5d15f 100644
--- a/modules/saml/lib/Auth/Process/AuthnContextClassRef.php
+++ b/modules/saml/lib/Auth/Process/AuthnContextClassRef.php
@@ -20,7 +20,7 @@ class AuthnContextClassRef extends ProcessingFilter
      *
      * @var string|null
      */
-    private $authnContextClassRef = null;
+    private ?string $authnContextClassRef = null;
 
 
     /**
diff --git a/modules/saml/lib/Auth/Process/ExpectedAuthnContextClassRef.php b/modules/saml/lib/Auth/Process/ExpectedAuthnContextClassRef.php
index 31db71085b5d82a350fe62e8080aacbd318ad777..c4409880803d5fe2dd9f57555d023a3e0b4c4ec2 100644
--- a/modules/saml/lib/Auth/Process/ExpectedAuthnContextClassRef.php
+++ b/modules/saml/lib/Auth/Process/ExpectedAuthnContextClassRef.php
@@ -34,14 +34,14 @@ class ExpectedAuthnContextClassRef extends ProcessingFilter
      * Array of accepted AuthnContextClassRef
      * @var array
      */
-    private $accepted;
+    private array $accepted;
 
 
     /**
      * AuthnContextClassRef of the assertion
      * @var string|null
      */
-    private $AuthnContextClassRef = null;
+    private ?string $AuthnContextClassRef = null;
 
 
     /**
diff --git a/modules/saml/lib/Auth/Process/FilterScopes.php b/modules/saml/lib/Auth/Process/FilterScopes.php
index 3a80036386cad1aa662d3e2f8b0e5aaa4ede432f..9748a9c614208d0912d364d42ea10ad4061f487f 100644
--- a/modules/saml/lib/Auth/Process/FilterScopes.php
+++ b/modules/saml/lib/Auth/Process/FilterScopes.php
@@ -18,9 +18,9 @@ use SimpleSAML\Utils;
 class FilterScopes extends ProcessingFilter
 {
     /**
-     * @var array Stores any pre-configured scoped attributes which come from the filter configuration.
+     * @var string[]  Stores any pre-configured scoped attributes which come from the filter configuration.
      */
-    private $scopedAttributes = [
+    private array $scopedAttributes = [
         'eduPersonScopedAffiliation',
         'eduPersonPrincipalName'
     ];
diff --git a/modules/saml/lib/Auth/Process/NameIDAttribute.php b/modules/saml/lib/Auth/Process/NameIDAttribute.php
index 33e612eecfc0a1fc5d4702b1e888d8168f394f99..0037d045626d105ff4815dd9be17c0d754b22976 100644
--- a/modules/saml/lib/Auth/Process/NameIDAttribute.php
+++ b/modules/saml/lib/Auth/Process/NameIDAttribute.php
@@ -22,7 +22,7 @@ class NameIDAttribute extends ProcessingFilter
      *
      * @var string
      */
-    private $attribute;
+    private string $attribute;
 
 
     /**
@@ -30,7 +30,7 @@ class NameIDAttribute extends ProcessingFilter
      *
      * @var array
      */
-    private $format;
+    private array $format;
 
 
     /**
diff --git a/modules/saml/lib/Auth/Process/PersistentNameID.php b/modules/saml/lib/Auth/Process/PersistentNameID.php
index f54b2153216d3e7ddc4c845838280ac2d3f5405e..b7f825a69ded7d71e84afffb2f1be58d39ab8c66 100644
--- a/modules/saml/lib/Auth/Process/PersistentNameID.php
+++ b/modules/saml/lib/Auth/Process/PersistentNameID.php
@@ -24,7 +24,7 @@ class PersistentNameID extends BaseNameIDGenerator
      *
      * @var string
      */
-    private $attribute;
+    private string $attribute;
 
 
     /**
diff --git a/modules/saml/lib/Auth/Process/PersistentNameID2TargetedID.php b/modules/saml/lib/Auth/Process/PersistentNameID2TargetedID.php
index 99053c352d461421a228b52249750a332f7c167e..e713827e5bbc301eeab0c3987249035e24e45e2e 100644
--- a/modules/saml/lib/Auth/Process/PersistentNameID2TargetedID.php
+++ b/modules/saml/lib/Auth/Process/PersistentNameID2TargetedID.php
@@ -22,7 +22,7 @@ class PersistentNameID2TargetedID extends ProcessingFilter
      *
      * @var string
      */
-    private $attribute;
+    private string $attribute;
 
 
     /**
@@ -30,7 +30,7 @@ class PersistentNameID2TargetedID extends ProcessingFilter
      *
      * @var bool
      */
-    private $nameId;
+    private bool $nameId;
 
 
     /**
diff --git a/modules/saml/lib/Auth/Process/SQLPersistentNameID.php b/modules/saml/lib/Auth/Process/SQLPersistentNameID.php
index 2e2bd639dd23aab72764eee0ed8760a6de00d48d..60e8a0223335979768ba38a82fe34c908f7887d9 100644
--- a/modules/saml/lib/Auth/Process/SQLPersistentNameID.php
+++ b/modules/saml/lib/Auth/Process/SQLPersistentNameID.php
@@ -23,35 +23,35 @@ class SQLPersistentNameID extends BaseNameIDGenerator
      *
      * @var string
      */
-    private $attribute;
+    private string $attribute;
 
     /**
      * Whether we should create a persistent NameID if not explicitly requested (as saml:PersistentNameID does).
      *
      * @var boolean
      */
-    private $allowUnspecified = false;
+    private bool $allowUnspecified = false;
 
     /**
      * Whether we should create a persistent NameID if a different format is requested.
      *
      * @var boolean
      */
-    private $allowDifferent = false;
+    private bool $allowDifferent = false;
 
     /**
      * Whether we should ignore allowCreate in the NameID policy
      *
      * @var boolean
      */
-    private $alwaysCreate = false;
+    private bool $alwaysCreate = false;
 
     /**
      * Database store configuration.
      *
      * @var array
      */
-    private $storeConfig = [];
+    private array $storeConfig = [];
 
 
     /**
diff --git a/modules/saml/lib/Auth/Source/SP.php b/modules/saml/lib/Auth/Source/SP.php
index 4f633ccc4d58386dc634ff66a320a2298ca27e54..0340a1b4d042d1d9978548ace812968c7ea1f537 100644
--- a/modules/saml/lib/Auth/Source/SP.php
+++ b/modules/saml/lib/Auth/Source/SP.php
@@ -27,42 +27,42 @@ class SP extends \SimpleSAML\Auth\Source
      *
      * @var string
      */
-    private $entityId;
+    private string $entityId;
 
     /**
      * The metadata of this SP.
      *
      * @var \SimpleSAML\Configuration
      */
-    private $metadata;
+    private Configuration $metadata;
 
     /**
      * The IdP the user is allowed to log into.
      *
      * @var string|null  The IdP the user can log into, or null if the user can log into all IdPs.
      */
-    private $idp;
+    private ?string $idp;
 
     /**
      * URL to discovery service.
      *
      * @var string|null
      */
-    private $discoURL;
+    private ?string $discoURL;
 
     /**
      * Flag to indicate whether to disable sending the Scoping element.
      *
      * @var bool
      */
-    private $disable_scoping;
+    private bool $disable_scoping;
 
     /**
      * A list of supported protocols.
      *
      * @var string[]
      */
-    private $protocols = [];
+    private array $protocols = [];
 
 
     /**
diff --git a/modules/saml/lib/BaseNameIDGenerator.php b/modules/saml/lib/BaseNameIDGenerator.php
index c319ea450d607c5c30a55369c05da85029c99ff6..7c8d29d8336d93b1f0bdb23756f88b6158525c1f 100644
--- a/modules/saml/lib/BaseNameIDGenerator.php
+++ b/modules/saml/lib/BaseNameIDGenerator.php
@@ -46,7 +46,7 @@ abstract class BaseNameIDGenerator extends \SimpleSAML\Auth\ProcessingFilter
      *
      * @var string|null
      */
-    protected $format = null;
+    protected ?string $format = null;
 
 
     /**
diff --git a/modules/saml/lib/Error.php b/modules/saml/lib/Error.php
index c5101edb3f2ddd9aa2762b5c6fbfbf2c23e7b8b0..7a4655470615f4d24b028e88cce6310136377baa 100644
--- a/modules/saml/lib/Error.php
+++ b/modules/saml/lib/Error.php
@@ -21,21 +21,21 @@ class Error extends \SimpleSAML\Error\Exception
      *
      * @var string
      */
-    private $status;
+    private string $status;
 
     /**
      * The second-level status code, or NULL if no second-level status code is defined.
      *
      * @var string|null
      */
-    private $subStatus;
+    private ?string $subStatus;
 
     /**
      * The status message, or NULL if no status message is defined.
      *
      * @var string|null
      */
-    private $statusMessage;
+    private ?string $statusMessage;
 
 
     /**
diff --git a/psalm.xml b/psalm.xml
index 85eaf8882d1a266254852bcbf47dcf19602e7047..e760ea7ca3edf66d17d29d1c28d420887031793f 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -84,6 +84,13 @@
                 <directory name="tests" />
             </errorLevel>
         </InternalMethod>
+
+        <!-- Suppress Psalm-issue - We should be able to fix this with the static return-type in PHP 8.0 -->
+        <UnsafeInstantiation>
+            <errorLevel type="suppress">
+                <directory name="tests" />
+            </errorLevel>
+        </UnsafeInstantiation>
     </issueHandlers>
 
     <stubs>
diff --git a/tests/SigningTestCase.php b/tests/SigningTestCase.php
index b5ee39435f6b5515a8a295f12fe3b71f7be25b6e..2ab9443eb94df50b6ec07ba40943f18bae82fd9e 100644
--- a/tests/SigningTestCase.php
+++ b/tests/SigningTestCase.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace SimpleSAML\Test;
 
 use org\bovigo\vfs\vfsStream;
+use org\bovigo\vfs\vfsStreamDirectory;
 use PHPUnit\Framework\TestCase;
 use ReflectionClass;
 use SimpleSAML\Configuration;
@@ -19,7 +20,7 @@ class SigningTestCase extends TestCase
 {
     // openssl genrsa -out ca.key.pem 2048
     /** @var string $ca_private_key */
-    protected $ca_private_key = <<<'NOWDOC'
+    protected string $ca_private_key = <<<'NOWDOC'
 -----BEGIN RSA PRIVATE KEY-----
 MIIEpQIBAAKCAQEAtj5GuvnC5aCg8bhq2Yy4isp/uXtRRWKhbB5aYP7/1DwwwQ1Z
 LtBosBAA5SMD4s4L9w/bbJVVVAzhc9cpe2vDYLe1faUZlvOzJv/JuH/ux5NRkgmx
@@ -51,7 +52,7 @@ NOWDOC;
 
     // openssl req -key ca.key.pem -new -x509 -days 3650 -out ca.cert.pem
     /** @var string $ca_certificate */
-    private $ca_certificate = <<<'NOWDOC'
+    private string $ca_certificate = <<<'NOWDOC'
 -----BEGIN CERTIFICATE-----
 MIIDtjCCAp6gAwIBAgIJAII4rW68Q+IsMA0GCSqGSIb3DQEBCwUAMHAxCzAJBgNV
 BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
@@ -78,7 +79,7 @@ NOWDOC;
 
     // openssl genrsa -out good.key.pem 2048
     /** @var string $good_private_key */
-    protected $good_private_key = <<<'NOWDOC'
+    protected string $good_private_key = <<<'NOWDOC'
 -----BEGIN RSA PRIVATE KEY-----
 MIIEowIBAAKCAQEAqmNn4bt/jrMHgoWtwXLc2ok17BHh1O5ETbn9rK3KFjk3BXp5
 3aGveill+KbW7SgriGZSa1KBE2uaQy2mZpiBQqFrLcgKhtzaCNLyBvKOozQhn/XN
@@ -118,7 +119,7 @@ NOWDOC;
     //      -in good.csr.pem \
     //      -out good.cert.pem
     /** @var string $good_certificate */
-    protected $good_certificate = <<<'NOWDOC'
+    protected string $good_certificate = <<<'NOWDOC'
 -----BEGIN CERTIFICATE-----
 MIIDZTCCAk0CCQC+sxqJmyko6TANBgkqhkiG9w0BAQsFADBwMQswCQYDVQQGEwJB
 VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
@@ -143,28 +144,28 @@ hQc0xnrLQ255SjMn+nQtMkVSuKwAUqaAP1ByyiVbN1cBlHnMiJCjvBI58bSTdlVK
 NOWDOC;
 
     /** @var string */
-    protected $good_private_key_file;
+    protected string $good_private_key_file;
 
     /** @var string */
-    protected $good_certificate_file;
+    protected string $good_certificate_file;
 
     /** @var string */
-    protected $certdir;
+    protected string $certdir;
 
     /** @var \org\bovigo\vfs\vfsStreamDirectory */
-    protected $root;
+    protected VfsStreamDirectory $root;
 
     /** @var string */
-    protected $root_directory;
+    protected string $root_directory;
 
     /** @var string */
-    protected $ca_private_key_file;
+    protected string $ca_private_key_file;
 
     /** @var string */
-    protected $ca_certificate_file;
+    protected string $ca_certificate_file;
 
     /** @var \SimpleSAML\Configuration */
-    protected $config;
+    protected Configuration $config;
 
     protected const ROOTDIRNAME = 'testdir';
     protected const DEFAULTCERTDIR = 'certdir';
diff --git a/tests/Utils/ClearStateTestCase.php b/tests/Utils/ClearStateTestCase.php
index d82c423b805a74f498d637a3c2e35090018a9168..644e4353f8e287e94d221df0fd949fe6872474f6 100644
--- a/tests/Utils/ClearStateTestCase.php
+++ b/tests/Utils/ClearStateTestCase.php
@@ -13,16 +13,16 @@ class ClearStateTestCase extends TestCase
 {
     /**
      * Used for managing and clearing state
-     * @var StateClearer
+     * @var \SimpleSAML\Test\Utils\StateClearer|null
      */
-    protected static $stateClearer;
+    protected static ?StateClearer $stateClearer = null;
 
 
     /**
      */
     public static function setUpBeforeClass(): void
     {
-        if (!self::$stateClearer) {
+        if (self::$stateClearer === null) {
             self::$stateClearer = new StateClearer();
             self::$stateClearer->backupGlobals();
         }
diff --git a/tests/Utils/ExitTestException.php b/tests/Utils/ExitTestException.php
index dc64a0ae842e4814511222ae022ef117e4ae38e9..c981fb1cd455ce72e62b7fd98b9aad77f907b691 100644
--- a/tests/Utils/ExitTestException.php
+++ b/tests/Utils/ExitTestException.php
@@ -10,7 +10,7 @@ namespace SimpleSAML\Test\Utils;
 class ExitTestException extends \Exception
 {
     /** @var array */
-    private $testResult;
+    private array $testResult;
 
 
     /**
diff --git a/tests/Utils/StateClearer.php b/tests/Utils/StateClearer.php
index 05e69814d0365ebcdea0a751cc0e1886a28995ed..0a9147168c1fd88453fc4b58c930c2c8bb207c0f 100644
--- a/tests/Utils/StateClearer.php
+++ b/tests/Utils/StateClearer.php
@@ -13,13 +13,13 @@ class StateClearer
      * Global state to restore between test runs
      * @var array
      */
-    private $backups = [];
+    private array $backups = [];
 
     /**
      * Class that implement \SimpleSAML\Utils\ClearableState and should have clearInternalState called between tests
      * @var array
      */
-    private $clearableState = [
+    private array $clearableState = [
         'SimpleSAML\Configuration',
         'SimpleSAML\Metadata\MetaDataStorageHandler',
         'SimpleSAML\Store',
@@ -28,9 +28,9 @@ class StateClearer
 
     /**
      * Environmental variables to unset
-     * @var array
+     * @var string[]
      */
-    private $vars_to_unset = ['SIMPLESAMLPHP_CONFIG_DIR'];
+    private array $vars_to_unset = ['SIMPLESAMLPHP_CONFIG_DIR'];
 
 
     /**
diff --git a/tests/lib/SimpleSAML/SessionHandlerPHPTest.php b/tests/lib/SimpleSAML/SessionHandlerPHPTest.php
index 15a82c3817a52dc64b111e30b77c3365217b7f93..5e79591eac60d8f4ee62b915d080a77b2c128d5d 100644
--- a/tests/lib/SimpleSAML/SessionHandlerPHPTest.php
+++ b/tests/lib/SimpleSAML/SessionHandlerPHPTest.php
@@ -15,7 +15,7 @@ use SimpleSAML\Configuration;
 class SessionHandlerPHPTest extends ClearStateTestCase
 {
     /** @var array */
-    protected $sessionConfig = [
+    protected array $sessionConfig = [
         'session.cookie.name' => 'SimpleSAMLSessionID',
         'session.cookie.lifetime' => 100,
         'session.cookie.path' => '/ourPath',
@@ -25,7 +25,7 @@ class SessionHandlerPHPTest extends ClearStateTestCase
     ];
 
     /** @var array */
-    protected $original;
+    protected array $original;
 
 
     /**
diff --git a/tests/lib/SimpleSAML/SessionTest.php b/tests/lib/SimpleSAML/SessionTest.php
index 6c9326b80be5ede926cae0173fd375a37b5cc810..1a75ba4388c9343436bae3b032b03e5493400c1e 100644
--- a/tests/lib/SimpleSAML/SessionTest.php
+++ b/tests/lib/SimpleSAML/SessionTest.php
@@ -15,7 +15,7 @@ use SimpleSAML\Configuration;
 class SessionTest extends ClearStateTestCase
 {
     /** @var \SimpleSAML\Session */
-    protected $session;
+    protected Session $session;
 
     /**
      */
diff --git a/tests/lib/SimpleSAML/Store/RedisTest.php b/tests/lib/SimpleSAML/Store/RedisTest.php
index 069c2435a2760a49da43bb85da0065693e789cbf..9625027c6a11ed8e6bcdf9e37265768a2b38a25f 100644
--- a/tests/lib/SimpleSAML/Store/RedisTest.php
+++ b/tests/lib/SimpleSAML/Store/RedisTest.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace SimpleSAML\Test\Store;
 
 use PHPUnit\Framework\TestCase;
+use PHPUnit\Framework\MockObject\MockObject;
 use Predis\Client;
 use ReflectionClass;
 use SimpleSAML\Configuration;
@@ -22,13 +23,13 @@ use SimpleSAML\Store;
 class RedisTest extends TestCase
 {
     /** @var \PHPUnit\Framework\MockObject\MockObject */
-    protected $mocked_redis;
+    protected MockObject $mocked_redis;
 
     /** @var \SimpleSAML\Store\Redis */
-    protected $redis;
+    protected Store\Redis $redis;
 
     /** @var array */
-    protected $config;
+    protected array $config;
 
 
     /**
@@ -228,7 +229,11 @@ class RedisTest extends TestCase
         $reflectedClass = new ReflectionClass($className);
         $reflectedInstance = $reflectedClass->getProperty('instance');
         $reflectedInstance->setAccessible(true);
-        $reflectedInstance->setValue($service, null);
+        if ($service instanceof Configuration) {
+            $reflectedInstance->setValue($service, []);
+        } else {
+            $reflectedInstance->setValue($service, null);
+        }
         $reflectedInstance->setAccessible(false);
     }
 }
diff --git a/tests/lib/SimpleSAML/Store/SQLTest.php b/tests/lib/SimpleSAML/Store/SQLTest.php
index 28b23d6f4950d6bbc0ce5ea8bee4e62ef7a08111..14358f87f29af74bba2c91e6ff884fd90955c03c 100644
--- a/tests/lib/SimpleSAML/Store/SQLTest.php
+++ b/tests/lib/SimpleSAML/Store/SQLTest.php
@@ -188,7 +188,11 @@ class SQLTest extends TestCase
         $reflectedClass = new ReflectionClass($className);
         $reflectedInstance = $reflectedClass->getProperty('instance');
         $reflectedInstance->setAccessible(true);
-        $reflectedInstance->setValue($service, null);
+        if ($service instanceof Configuration) {
+            $reflectedInstance->setValue($service, []);
+        } else {
+            $reflectedInstance->setValue($service, null);
+        }
         $reflectedInstance->setAccessible(false);
     }
 }
diff --git a/tests/lib/SimpleSAML/StoreTest.php b/tests/lib/SimpleSAML/StoreTest.php
index ffeeb30e3b7cb436c2713d5b0722c97b4a996323..8f278eb6e008c519ea35ff33d5270410316c208d 100644
--- a/tests/lib/SimpleSAML/StoreTest.php
+++ b/tests/lib/SimpleSAML/StoreTest.php
@@ -137,7 +137,11 @@ class StoreTest extends TestCase
         $reflectedClass = new ReflectionClass($className);
         $reflectedInstance = $reflectedClass->getProperty('instance');
         $reflectedInstance->setAccessible(true);
-        $reflectedInstance->setValue($service, null);
+        if ($service instanceof Configuration) {
+            $reflectedInstance->setValue($service, []);
+        } else {
+            $reflectedInstance->setValue($service, null);
+        }
         $reflectedInstance->setAccessible(false);
     }
 }
diff --git a/tests/lib/SimpleSAML/Utils/CryptoTest.php b/tests/lib/SimpleSAML/Utils/CryptoTest.php
index 90b2f71cf0445b080434473f39e152c5b02bf7d1..fa06c98ecc5273667c39d4753645ea22302bde41 100644
--- a/tests/lib/SimpleSAML/Utils/CryptoTest.php
+++ b/tests/lib/SimpleSAML/Utils/CryptoTest.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace SimpleSAML\Test\Utils;
 
 use org\bovigo\vfs\vfsStream;
+use org\bovigo\vfs\vfsStreamDirectory;
 use PHPUnit\Framework\TestCase;
 use ReflectionMethod;
 use SimpleSAML\Configuration;
@@ -23,13 +24,13 @@ class CryptoTest extends TestCase
     private const DEFAULTCERTDIR = 'certdir';
 
     /** @var \org\bovigo\vfs\vfsStreamDirectory */
-    protected $root;
+    protected VfsStreamDirectory $root;
 
     /** @var string */
-    protected $root_directory;
+    protected string $root_directory;
 
     /** @var string */
-    protected $certdir;
+    protected string $certdir;
 
 
     /**
diff --git a/tests/lib/SimpleSAML/Utils/SystemTest.php b/tests/lib/SimpleSAML/Utils/SystemTest.php
index dd233f78921c6d9affb4af92944a0d9a11037770..493ceb94a3b813cb278044ca67d8656d0e3d282f 100644
--- a/tests/lib/SimpleSAML/Utils/SystemTest.php
+++ b/tests/lib/SimpleSAML/Utils/SystemTest.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Test\Utils;
 
 use InvalidArgumentException;
 use org\bovigo\vfs\vfsStream;
+use org\bovigo\vfs\vfsStreamDirectory;
 use PHPUnit\Framework\TestCase;
 use ReflectionClass;
 use SimpleSAML\Configuration;
@@ -24,9 +25,9 @@ class SystemTest extends TestCase
     private const DEFAULTTEMPDIR = 'tempdir';
 
     /** @var \org\bovigo\vfs\vfsStreamDirectory */
-    protected $root;
+    protected VfsStreamDirectory $root;
 
-    /** @var string */
+    /** @var string string */
     protected $root_directory;
 
 
@@ -284,7 +285,7 @@ class SystemTest extends TestCase
         $reflectedClass = new ReflectionClass($className);
         $reflectedInstance = $reflectedClass->getProperty('instance');
         $reflectedInstance->setAccessible(true);
-        $reflectedInstance->setValue($service, null);
+        $reflectedInstance->setValue($service, []);
         $reflectedInstance->setAccessible(false);
     }
 }
diff --git a/tests/lib/SimpleSAML/XML/ParserTest.php b/tests/lib/SimpleSAML/XML/ParserTest.php
index 1955d4f0f918afa8ffdcddc598273d47159aca77..077117ee40996e7b6f7661292a0d3d4f2cd879bb 100644
--- a/tests/lib/SimpleSAML/XML/ParserTest.php
+++ b/tests/lib/SimpleSAML/XML/ParserTest.php
@@ -27,8 +27,8 @@ class ParserTest extends TestCase
 </Root>
 XML;
 
-    /** @var Parser */
-    private $xml;
+    /** @var \SimpleSAML\XML\Parser */
+    private Parser $xml;
 
 
     /**
diff --git a/tests/lib/SimpleSAML/XML/SignerTest.php b/tests/lib/SimpleSAML/XML/SignerTest.php
index 0713f77e9bb202b6448b214ffcb1b318ae4ba9c2..c53a47795bc56fef69143e5b2b3d031edbe7695c 100644
--- a/tests/lib/SimpleSAML/XML/SignerTest.php
+++ b/tests/lib/SimpleSAML/XML/SignerTest.php
@@ -22,11 +22,11 @@ use SimpleSAML\XML\Signer;
 class SignerTest extends SigningTestCase
 {
     /** @var string */
-    private $other_certificate_file;
+    private string $other_certificate_file;
 
     // openssl req -new -x509 -key good.key.pem -out public2.pem -days 3650
     /** @var string */
-    private $other_certificate = <<<'NOWDOC'
+    private string $other_certificate = <<<'NOWDOC'
 -----BEGIN CERTIFICATE-----
 MIIDazCCAlOgAwIBAgIUGPKUWW1GN07xxAsGENQ+rZPyABAwDQYJKoZIhvcNAQEL
 BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
diff --git a/tests/modules/admin/lib/Controller/ConfigTest.php b/tests/modules/admin/lib/Controller/ConfigTest.php
index 097d9bc43383c09278626a158e1f8b3d16271f74..e7e513dca95b52b5ef757a6cf85d964d63064c38 100644
--- a/tests/modules/admin/lib/Controller/ConfigTest.php
+++ b/tests/modules/admin/lib/Controller/ConfigTest.php
@@ -22,13 +22,13 @@ use Symfony\Component\HttpFoundation\Response;
 class ConfigTest extends TestCase
 {
     /** @var \SimpleSAML\Configuration */
-    protected $config;
+    protected Configuration $config;
 
     /** @var \SimpleSAML\Utils\Auth */
-    protected $authUtils;
+    protected Utils\Auth $authUtils;
 
     /** @var \SimpleSAML\Session */
-    protected $session;
+    protected Session $session;
 
 
     /**
diff --git a/tests/modules/admin/lib/Controller/FederationTest.php b/tests/modules/admin/lib/Controller/FederationTest.php
index 54f161fd436d930765f6498901f7cba81caa1e4c..f15cb033c92c1d48b00b6eb9f9fb83b5789f7e4f 100644
--- a/tests/modules/admin/lib/Controller/FederationTest.php
+++ b/tests/modules/admin/lib/Controller/FederationTest.php
@@ -42,22 +42,22 @@ class FederationTest extends TestCase
     public const CERT_PUBLIC = '../' . self::SECURITY . '/certificates/rsa-pem/selfsigned.simplesamlphp.org.crt';
 
     /** @var \SimpleSAML\Configuration */
-    protected $config;
+    protected Configuration $config;
 
     /** @var \SimpleSAML\Utils\Auth */
-    protected $authUtils;
+    protected Utils\Auth $authUtils;
 
     /** @var string */
-    private $metadata_xml = self::LIBRARY . '/xml/metadata/valid-metadata-selfsigned.xml';
+    private string $metadata_xml = self::LIBRARY . '/xml/metadata/valid-metadata-selfsigned.xml';
 
     /** @var string */
-    private $broken_metadata_xml = self::LIBRARY . '/xml/metadata/corrupted-metadata-selfsigned.xml';
+    private string $broken_metadata_xml = self::LIBRARY . '/xml/metadata/corrupted-metadata-selfsigned.xml';
 
     /** @var string */
-    private $expired_metadata_xml = self::LIBRARY . '/xml/metadata/expired-metadata.xml';
+    private string $expired_metadata_xml = self::LIBRARY . '/xml/metadata/expired-metadata.xml';
 
     /** @var string */
-    private $ssp_metadata = self::FRAMEWORK . '/metadata/simplesamlphp/saml20-idp-remote_cert_selfsigned.php';
+    private string $ssp_metadata = self::FRAMEWORK . '/metadata/simplesamlphp/saml20-idp-remote_cert_selfsigned.php';
 
     /**
      * Set up for each test.
diff --git a/tests/modules/admin/lib/Controller/TestTest.php b/tests/modules/admin/lib/Controller/TestTest.php
index 72a887eaaf50004af4a6814585071c7383b5e6cb..78743f128572c4cd039645395dcc83aa6a14bb5a 100644
--- a/tests/modules/admin/lib/Controller/TestTest.php
+++ b/tests/modules/admin/lib/Controller/TestTest.php
@@ -10,7 +10,7 @@ use SimpleSAML\Auth;
 use SimpleSAML\Configuration;
 use SimpleSAML\Error;
 use SimpleSAML\HTTP\RunnableResponse;
-use SimpleSAML\Module\admin\Controller;
+use SimpleSAML\Module\admin\Controller\Test as TestController;
 use SimpleSAML\Session;
 use SimpleSAML\Utils;
 use SimpleSAML\XHTML\Template;
@@ -26,13 +26,13 @@ use Symfony\Component\HttpFoundation\Response;
 class TestTest extends TestCase
 {
     /** @var \SimpleSAML\Configuration */
-    protected $config;
+    protected Configuration $config;
 
     /** @var \SimpleSAML\Utils\Auth */
-    protected $authUtils;
+    protected Utils\Auth $authUtils;
 
     /** @var \SimpleSAML\Session */
-    protected $session;
+    protected Session $session;
 
 
     /**
@@ -83,7 +83,7 @@ class TestTest extends TestCase
             'GET'
         );
 
-        $c = new Controller\Test($this->config, $this->session);
+        $c = new TestController($this->config, $this->session);
         $c->setAuthUtils($this->authUtils);
         $response = $c->main($request);
 
@@ -103,7 +103,7 @@ class TestTest extends TestCase
             ['logout' => 'notnull']
         );
 
-        $c = new Controller\Test($this->config, $this->session);
+        $c = new TestController($this->config, $this->session);
         $c->setAuthUtils($this->authUtils);
         $c->setAuthSimple(new class ('admin') extends Auth\Simple {
             public function logout($params = null): void
@@ -130,7 +130,7 @@ class TestTest extends TestCase
             [Auth\State::EXCEPTION_PARAM => 'someException']
         );
 
-        $c = new Controller\Test($this->config, $this->session);
+        $c = new TestController($this->config, $this->session);
         $c->setAuthUtils($this->authUtils);
         $c->setAuthState(new class () extends Auth\State {
             public static function loadExceptionState(?string $id = null): ?array
@@ -156,7 +156,7 @@ class TestTest extends TestCase
             ['as' => 'admin']
         );
 
-        $c = new Controller\Test($this->config, $this->session);
+        $c = new TestController($this->config, $this->session);
         $c->setAuthUtils($this->authUtils);
         $c->setAuthSimple(new class ('admin') extends Auth\Simple {
             public function isAuthenticated(): bool
@@ -187,7 +187,7 @@ class TestTest extends TestCase
             'GET'
         );
 
-        $c = new Controller\Test($this->config, $this->session);
+        $c = new TestController($this->config, $this->session);
         $c->setAuthUtils($this->authUtils);
         $c->setAuthSimple(new class ('admin') extends Auth\Simple {
             public function isAuthenticated(): bool
diff --git a/tests/modules/core/lib/Auth/Process/AttributeLimitTest.php b/tests/modules/core/lib/Auth/Process/AttributeLimitTest.php
index 71c1ce10798cd8fe6a835489847f5f52fb95585b..7774ccf87c914f8c036a0628dd1562c3f03ec2f2 100644
--- a/tests/modules/core/lib/Auth/Process/AttributeLimitTest.php
+++ b/tests/modules/core/lib/Auth/Process/AttributeLimitTest.php
@@ -20,7 +20,7 @@ class AttributeLimitTest extends TestCase
      * setUpBeforeClass a request that will be used for the following tests.
      * note the above tests don't use self::$request for processFilter input.
      */
-    protected static $request;
+    protected static array $request;
 
 
     /**
diff --git a/tests/modules/core/lib/Auth/Process/CardinalitySingleTest.php b/tests/modules/core/lib/Auth/Process/CardinalitySingleTest.php
index 76a7857bb3d2497ceccddc7d475f51616f4ac2fd..3f18d49d44ff6793e009c7bb7e657fab93b9675c 100644
--- a/tests/modules/core/lib/Auth/Process/CardinalitySingleTest.php
+++ b/tests/modules/core/lib/Auth/Process/CardinalitySingleTest.php
@@ -16,7 +16,7 @@ use SimpleSAML\Module\core\Auth\Process\CardinalitySingle;
 class CardinalitySingleTest extends TestCase
 {
     /** @var \SimpleSAML\Utils\HttpAdapter|\PHPUnit\Framework\MockObject\MockObject */
-    private $http;
+    private object $http;
 
 
     /**
diff --git a/tests/modules/core/lib/Auth/Process/CardinalityTest.php b/tests/modules/core/lib/Auth/Process/CardinalityTest.php
index 3441848815940d313321ceb46867437d1d6702ad..9934351ae9d4621768088ba732afa6423c376eba 100644
--- a/tests/modules/core/lib/Auth/Process/CardinalityTest.php
+++ b/tests/modules/core/lib/Auth/Process/CardinalityTest.php
@@ -18,7 +18,7 @@ use SimpleSAML\Utils\HttpAdapter;
 class CardinalityTest extends TestCase
 {
     /** @var \SimpleSAML\Utils\HttpAdapter|\PHPUnit\Framework\MockObject\MockObject */
-    private $http;
+    private object $http;
 
 
     /**
diff --git a/tests/modules/core/lib/Auth/Process/TargetedIDTest.php b/tests/modules/core/lib/Auth/Process/TargetedIDTest.php
index 2920d9386d2a744dcafab31d25e786d8b7796760..0bccc514e0afbed8a2340224f2af1bf822f3470f 100644
--- a/tests/modules/core/lib/Auth/Process/TargetedIDTest.php
+++ b/tests/modules/core/lib/Auth/Process/TargetedIDTest.php
@@ -20,10 +20,10 @@ use SimpleSAML\Utils;
 class TargetedIDTest extends TestCase
 {
     /** @var \SimpleSAML\Configuration */
-    protected $config;
+    protected Configuration $config;
 
     /** @var \SimpleSAML\Utils\Config */
-    protected static $configUtils;
+    protected static Utils\Config $configUtils;
 
     /**
      * Set up for each test.
diff --git a/tests/modules/core/lib/Controller/LoginTest.php b/tests/modules/core/lib/Controller/LoginTest.php
index bb539a01ad0bbebab83e3a2a4a34f2218a796c66..341885210608455c1c8b52a174bc74351e2cff7d 100644
--- a/tests/modules/core/lib/Controller/LoginTest.php
+++ b/tests/modules/core/lib/Controller/LoginTest.php
@@ -30,13 +30,13 @@ use Symfony\Component\HttpFoundation\Request;
 class LoginTest extends ClearStateTestCase
 {
     /** @var array */
-    protected $authSources;
+    protected array $authSources;
 
     /** @var \SimpleSAML\Configuration */
-    protected $config;
+    protected Configuration $config;
 
     /** @var \SimpleSAML\Configuration[] */
-    protected $loadedConfigs;
+    protected array $loadedConfigs;
 
     /**
      * Set up for each test.
diff --git a/tests/modules/core/lib/Storage/SQLPermanentStorageTest.php b/tests/modules/core/lib/Storage/SQLPermanentStorageTest.php
index 204640081490b9fa7b9c634763c38a49119f9d2d..7e04f21ee2aa628d4fd49f829e4f8fcc47586749 100644
--- a/tests/modules/core/lib/Storage/SQLPermanentStorageTest.php
+++ b/tests/modules/core/lib/Storage/SQLPermanentStorageTest.php
@@ -16,7 +16,7 @@ use SimpleSAML\Module\core\Storage\SQLPermanentStorage;
 class SQLPermanentStorageTest extends TestCase
 {
     /** @var \SimpleSAML\Module\core\Storage\SQLPermanentStorage */
-    private static $sql;
+    private static SQLPermanentStorage $sql;
 
 
     /**
@@ -35,7 +35,6 @@ class SQLPermanentStorageTest extends TestCase
      */
     public static function tearDownAfterClass(): void
     {
-        self::$sql = null;
         unlink(sys_get_temp_dir() . '/sqllite/test.sqlite');
     }
 
diff --git a/tests/modules/cron/lib/Controller/CronTest.php b/tests/modules/cron/lib/Controller/CronTest.php
index d82da0d8af824838a1a40adcc28feb1fb3c99a23..da032e241f859bf93df551b754d637c7ebd97110 100644
--- a/tests/modules/cron/lib/Controller/CronTest.php
+++ b/tests/modules/cron/lib/Controller/CronTest.php
@@ -22,13 +22,13 @@ use Symfony\Component\HttpFoundation\Response;
 class CronTest extends TestCase
 {
     /** @var \SimpleSAML\Configuration */
-    protected $config;
+    protected Configuration $config;
 
     /** @var \SimpleSAML\Session */
-    protected $session;
+    protected Session $session;
 
     /** @var \SimpleSAML\Utils\Auth */
-    protected $authUtils;
+    protected Utils\Auth $authUtils;
 
 
     /**
diff --git a/tests/modules/multiauth/lib/Auth/Source/MultiAuthTest.php b/tests/modules/multiauth/lib/Auth/Source/MultiAuthTest.php
index 68e72a13ebbfa9ebb0dcd1c0b0f6d02181754ccc..5760e213d72780b215e04740c215c54fe385b665 100644
--- a/tests/modules/multiauth/lib/Auth/Source/MultiAuthTest.php
+++ b/tests/modules/multiauth/lib/Auth/Source/MultiAuthTest.php
@@ -15,11 +15,11 @@ use SimpleSAML\Module\multiauth\Auth\Source\MultiAuth;
  */
 class MultiAuthTest extends ClearStateTestCase
 {
-    /** @var Configuration */
-    private $config;
+    /** @var \SimpleSAML\Configuration */
+    private Configuration $config;
 
-    /** @var Configuration */
-    private $sourceConfig;
+    /** @var \SimpleSAML\Configuration */
+    private Configuration $sourceConfig;
 
 
     /**
diff --git a/tests/modules/multiauth/lib/Controller/DiscoControllerTest.php b/tests/modules/multiauth/lib/Controller/DiscoControllerTest.php
index ffecbde7c869891bf20160f65727999f4c8f106d..a5ae6ff6b3ebe7bcf5c34b20eb57a6c8780c4574 100644
--- a/tests/modules/multiauth/lib/Controller/DiscoControllerTest.php
+++ b/tests/modules/multiauth/lib/Controller/DiscoControllerTest.php
@@ -25,10 +25,10 @@ use Symfony\Component\HttpFoundation\Response;
 class DiscoControllerTest extends TestCase
 {
     /** @var \SimpleSAML\Configuration */
-    protected $config;
+    protected Configuration $config;
 
     /** @var \SimpleSAML\Session */
-    protected $session;
+    protected Session $session;
 
 
     /**
diff --git a/tests/modules/saml/lib/Auth/Source/Auth_Source_SP_Test.php b/tests/modules/saml/lib/Auth/Source/Auth_Source_SP_Test.php
index 28c3bfca9a0d3f2f35ce3cbf77068da2f07906da..9c697ea1b753b6688440f522f2b7e73dc9717051 100644
--- a/tests/modules/saml/lib/Auth/Source/Auth_Source_SP_Test.php
+++ b/tests/modules/saml/lib/Auth/Source/Auth_Source_SP_Test.php
@@ -25,13 +25,13 @@ use SimpleSAML\Test\Utils\SpTester;
 class SPTest extends ClearStateTestCase
 {
     /** @var \SimpleSAML\Configuration|null $idpMetadata */
-    private $idpMetadata = null;
+    private ?Configuration $idpMetadata = null;
 
     /** @var array $idpConfigArray */
-    private $idpConfigArray;
+    private array $idpConfigArray;
 
     /** @var \SimpleSAML\Configuration */
-    private $config;
+    private Configuration $config;
 
 
     /**
diff --git a/tests/modules/saml/lib/IdP/SAML2Test.php b/tests/modules/saml/lib/IdP/SAML2Test.php
index 503afddd1034c2c4e1dc5c7155446e45bf04f397..66f664332cc548207860688919e88fd8356edcf1 100644
--- a/tests/modules/saml/lib/IdP/SAML2Test.php
+++ b/tests/modules/saml/lib/IdP/SAML2Test.php
@@ -18,7 +18,7 @@ class SAML2Test extends ClearStateTestCase
      * Default values for the state array expected to be generated at the start of logins
      * @var array
      */
-    private $defaultExpectedAuthState = [
+    private array $defaultExpectedAuthState = [
         'Responder' => ['\SimpleSAML\Module\saml\IdP\SAML2', 'sendResponse'],
         '\SimpleSAML\Auth\State.exceptionFunc' => ['\SimpleSAML\Module\saml\IdP\SAML2', 'handleAuthError'],
         'saml:RelayState' => null,
diff --git a/tests/modules/saml/lib/IdP/SQLNameIDTest.php b/tests/modules/saml/lib/IdP/SQLNameIDTest.php
index f89e5bbc97161f41c264d20cc00a37c384a3c5d1..e33bd604e99d487a7202c8728a0aa8aa76b24ce7 100644
--- a/tests/modules/saml/lib/IdP/SQLNameIDTest.php
+++ b/tests/modules/saml/lib/IdP/SQLNameIDTest.php
@@ -106,7 +106,11 @@ class SQLNameIDTest extends TestCase
         $reflectedClass = new ReflectionClass($className);
         $reflectedInstance = $reflectedClass->getProperty('instance');
         $reflectedInstance->setAccessible(true);
-        $reflectedInstance->setValue($service, null);
+        if ($service instanceof Configuration) {
+            $reflectedInstance->setValue($service, []);
+        } else {
+            $reflectedInstance->setValue($service, null);
+        }
         $reflectedInstance->setAccessible(false);
     }
 }
diff --git a/tests/www/IndexTest.php b/tests/www/IndexTest.php
index 62183d57703a56bc40a986210c5c0590e3b41332..cd057203a0fa7d9146078ddd7eac2c0c20ec5641 100644
--- a/tests/www/IndexTest.php
+++ b/tests/www/IndexTest.php
@@ -19,22 +19,22 @@ class IndexTest extends TestCase
     /**
      * @var \SimpleSAML\TestUtils\BuiltInServer
      */
-    protected $server;
+    protected BuiltInServer $server;
 
     /**
      * @var string
      */
-    protected $server_addr;
+    protected string $server_addr;
 
     /**
      * @var int
      */
-    protected $server_pid;
+    protected int $server_pid;
 
     /**
      * @var string
      */
-    protected $shared_file;
+    protected string $shared_file;
 
 
     /**