public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        // Fail when session is disabled.
        if (session_status() === PHP_SESSION_DISABLED) {

            throw new SessionDisabledException;

        }

        // Fail when session is already started.
        if (session_status() === PHP_SESSION_ACTIVE) {

            throw new SessionAlreadyStartedException;

        }

        // Set the user defined session parameters.
        if (! is_null($this->save_handler)) session_set_save_handler($this->save_handler);
        if (! is_null($this->name)) session_name($this->name);
        if (! is_null($this->save_path)) session_save_path($this->save_path);
        if (! is_null($this->cache_limiter)) session_cache_limiter($this->cache_limiter);
        if (! is_null($this->cache_expire)) session_cache_expire($this->cache_expire);
        if ($this->cookie_params != []) $this->setCookieParams($this->cookie_params);

        // Set the session id.
        $name = session_name();

        $id = $request->getCookieParams()[$name] ?? '';

        session_id($id);

        // Start the session with options disabling cookies.
        if (session_start(self::SESSION_START_OPTIONS)) {

            // Add the session to the request.
            $request = $request->withAttribute(Session::class, new Session($_SESSION));

            // Get a response from the request handler.
            $response = $handler->handle($request);

            // Save the session data and close the session.
            session_write_close();

            // Return a response with session headers attached.
            return $this->attachSessionHeaders($response);

        }

        throw new SessionStartException;
    }