private async Task <AuthorizeRequestValidationResult> ValidateOptionalParametersAsync(ValidatedAuthorizeRequest request)
    {
        //////////////////////////////////////////////////////////
        // check nonce
        //////////////////////////////////////////////////////////
        var nonce = request.Raw.Get(OidcConstants.AuthorizeRequest.Nonce);

        if (nonce.IsPresent())
        {
            if (nonce.Length > _options.InputLengthRestrictions.Nonce)
            {
                LogError("Nonce too long", request);
                return(Invalid(request, description: "Invalid nonce"));
            }

            request.Nonce = nonce;
        }
        else
        {
            if (request.ResponseType.FromSpaceSeparatedString().Contains(TokenTypes.IdentityToken))
            {
                LogError("Nonce required for flow with id_token response type", request);
                return(Invalid(request, description: "Invalid nonce"));
            }
        }


        //////////////////////////////////////////////////////////
        // check prompt
        //////////////////////////////////////////////////////////
        var prompt = request.Raw.Get(OidcConstants.AuthorizeRequest.Prompt);

        if (prompt.IsPresent())
        {
            var prompts = prompt.Split(' ', StringSplitOptions.RemoveEmptyEntries);
            if (prompts.All(p => Constants.SupportedPromptModes.Contains(p)))
            {
                if (prompts.Contains(OidcConstants.PromptModes.None) && prompts.Length > 1)
                {
                    LogError("prompt contains 'none' and other values. 'none' should be used by itself.", request);
                    return(Invalid(request, description: "Invalid prompt"));
                }

                request.OriginalPromptModes = prompts;
            }
            else
            {
                _logger.LogDebug("Unsupported prompt mode - ignored: " + prompt);
            }
        }

        var suppressed_prompt = request.Raw.Get(Constants.SuppressedPrompt);

        if (suppressed_prompt.IsPresent())
        {
            var prompts = suppressed_prompt.Split(' ', StringSplitOptions.RemoveEmptyEntries);
            if (prompts.All(p => Constants.SupportedPromptModes.Contains(p)))
            {
                if (prompts.Contains(OidcConstants.PromptModes.None) && prompts.Length > 1)
                {
                    LogError("suppressed_prompt contains 'none' and other values. 'none' should be used by itself.", request);
                    return(Invalid(request, description: "Invalid prompt"));
                }

                request.SuppressedPromptModes = prompts;
            }
            else
            {
                _logger.LogDebug("Unsupported suppressed_prompt mode - ignored: " + prompt);
            }
        }

        request.PromptModes = request.OriginalPromptModes.Except(request.SuppressedPromptModes).ToArray();

        //////////////////////////////////////////////////////////
        // check ui locales
        //////////////////////////////////////////////////////////
        var uilocales = request.Raw.Get(OidcConstants.AuthorizeRequest.UiLocales);

        if (uilocales.IsPresent())
        {
            if (uilocales.Length > _options.InputLengthRestrictions.UiLocale)
            {
                LogError("UI locale too long", request);
                return(Invalid(request, description: "Invalid ui_locales"));
            }

            request.UiLocales = uilocales;
        }

        //////////////////////////////////////////////////////////
        // check display
        //////////////////////////////////////////////////////////
        var display = request.Raw.Get(OidcConstants.AuthorizeRequest.Display);

        if (display.IsPresent())
        {
            if (Constants.SupportedDisplayModes.Contains(display))
            {
                request.DisplayMode = display;
            }

            _logger.LogDebug("Unsupported display mode - ignored: " + display);
        }

        //////////////////////////////////////////////////////////
        // check max_age
        //////////////////////////////////////////////////////////
        var maxAge = request.Raw.Get(OidcConstants.AuthorizeRequest.MaxAge);

        if (maxAge.IsPresent())
        {
            if (int.TryParse(maxAge, out var seconds))
            {
                if (seconds >= 0)
                {
                    request.MaxAge = seconds;
                }
                else
                {
                    LogError("Invalid max_age.", request);
                    return(Invalid(request, description: "Invalid max_age"));
                }
            }
            else
            {
                LogError("Invalid max_age.", request);
                return(Invalid(request, description: "Invalid max_age"));
            }
        }

        //////////////////////////////////////////////////////////
        // check login_hint
        //////////////////////////////////////////////////////////
        var loginHint = request.Raw.Get(OidcConstants.AuthorizeRequest.LoginHint);

        if (loginHint.IsPresent())
        {
            if (loginHint.Length > _options.InputLengthRestrictions.LoginHint)
            {
                LogError("Login hint too long", request);
                return(Invalid(request, description: "Invalid login_hint"));
            }

            request.LoginHint = loginHint;
        }

        //////////////////////////////////////////////////////////
        // check acr_values
        //////////////////////////////////////////////////////////
        var acrValues = request.Raw.Get(OidcConstants.AuthorizeRequest.AcrValues);

        if (acrValues.IsPresent())
        {
            if (acrValues.Length > _options.InputLengthRestrictions.AcrValues)
            {
                LogError("Acr values too long", request);
                return(Invalid(request, description: "Invalid acr_values"));
            }

            request.AuthenticationContextReferenceClasses = acrValues.FromSpaceSeparatedString().Distinct().ToList();
        }

        //////////////////////////////////////////////////////////
        // check custom acr_values: idp
        //////////////////////////////////////////////////////////
        var idp = request.GetIdP();

        if (idp.IsPresent())
        {
            // if idp is present but client does not allow it, strip it from the request message
            if (request.Client.IdentityProviderRestrictions != null && request.Client.IdentityProviderRestrictions.Any())
            {
                if (!request.Client.IdentityProviderRestrictions.Contains(idp))
                {
                    _logger.LogWarning("idp requested ({idp}) is not in client restriction list.", idp);
                    request.RemoveIdP();
                }
            }
        }

        //////////////////////////////////////////////////////////
        // check session cookie
        //////////////////////////////////////////////////////////
        if (_options.Endpoints.EnableCheckSessionEndpoint)
        {
            if (request.Subject.IsAuthenticated())
            {
                var sessionId = await _userSession.GetSessionIdAsync();

                if (sessionId.IsPresent())
                {
                    request.SessionId = sessionId;
                }
                else
                {
                    LogError("Check session endpoint enabled, but SessionId is missing", request);
                }
            }
            else
            {
                request.SessionId = ""; // empty string for anonymous users
            }
        }

        return(Valid(request));
    }