<?xml version="1.0" encoding="UTF-8"?>

<!--
  ~ Copyright 2019 Red Hat, Inc.
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~   http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns="urn:jboss:domain:undertow:9.0"
           targetNamespace="urn:jboss:domain:undertow:9.0"
           xmlns:credential-reference="urn:wildfly:credential-reference:1.0"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified"
           version="1.0">

    <xs:import namespace="urn:wildfly:credential-reference:1.0" schemaLocation="wildfly-credential-reference_1_0.xsd"/>

    <!-- The undertow subsystem root element -->
    <xs:element name="subsystem" type="undertow-subsystemType"/>

    <xs:complexType name="undertow-subsystemType">
        <xs:annotation>
            <xs:documentation>
                <![CDATA[
                The configuration of the undertow subsystem.
            ]]>
            </xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:element name="byte-buffer-pool" type="byte-buffer-poolType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="buffer-cache" type="buffer-cacheType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="server" type="serverType" minOccurs="1" maxOccurs="unbounded"/>
            <xs:element name="servlet-container" type="servletContainerType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="handlers" type="handlerType" minOccurs="0" maxOccurs="1"/>
            <xs:element name="filters" type="filterType" minOccurs="0" maxOccurs="1"/>
            <xs:element name="application-security-domains" type="applicationSecurityDomainsType" minOccurs="0"/>
        </xs:sequence>
        <xs:attribute name="default-server" type="xs:string" default="default-server"/>
        <xs:attribute name="default-virtual-host" type="xs:string" default="default-host"/>
        <xs:attribute name="default-servlet-container" type="xs:string" default="default"/>
        <xs:attribute name="instance-id" type="xs:string" use="optional"/>
        <xs:attribute name="default-security-domain" type="xs:string" use="optional" default="other"/>
        <xs:attribute name="statistics-enabled" type="xs:boolean" default="false">
          <xs:annotation>
            <xs:documentation>Whether statistics are to be gathered for undertow subsystem.</xs:documentation>
          </xs:annotation>
        </xs:attribute>
    </xs:complexType>
    <xs:complexType name="serverType">
        <xs:sequence>
            <xs:element name="ajp-listener" type="ajp-listener-type" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="http-listener" type="http-listener-type" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="https-listener" type="https-listener-type" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="host" type="hostType" minOccurs="1" maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="default-host" use="optional" type="xs:string" default="default-host"/>
        <xs:attribute name="servlet-container" use="optional" type="xs:string" default="default"/>
    </xs:complexType>

    <xs:complexType name="socket-options-type">
        <xs:attribute name="receive-buffer" type="xs:int"/>
        <xs:attribute name="send-buffer" type="xs:int"/>
        <xs:attribute name="tcp-backlog" type="xs:int" default="10000"/>
        <xs:attribute name="tcp-keep-alive" type="xs:boolean"/>
        <xs:attribute name="read-timeout" type="xs:long"/>
        <xs:attribute name="write-timeout" type="xs:long"/>
        <xs:attribute name="max-connections" type="xs:int"/>
    </xs:complexType>

    <xs:complexType name="listener-type">
        <xs:complexContent>
            <xs:extension base="socket-options-type">
                <xs:attribute name="name" use="required" type="xs:string"/>
                <xs:attribute name="socket-binding" use="required" type="xs:string"/>
                <xs:attribute name="worker" type="xs:string" default="default"/>
                <xs:attribute name="buffer-pool" type="xs:string" default="default"/>
                <xs:attribute name="enabled" type="xs:boolean" default="true"/>
                <xs:attribute name="resolve-peer-address" type="xs:boolean" default="false"/>
                <xs:attribute name="max-post-size" type="xs:long" default="10485760"/>
                <xs:attribute name="buffer-pipelined-data" type="xs:boolean" default="false"/>
                <xs:attribute name="max-header-size" type="xs:long" default="1048576"/>
                <xs:attribute name="max-parameters" type="xs:long" default="1000"/>
                <xs:attribute name="max-headers" type="xs:long" default="200"/>
                <xs:attribute name="max-cookies" type="xs:long" default="200"/>
                <xs:attribute name="allow-encoded-slash" type="xs:boolean" default="false"/>
                <xs:attribute name="decode-url" type="xs:boolean" default="true"/>
                <xs:attribute name="url-charset" type="xs:string" default="UTF-8"/>
                <xs:attribute name="always-set-keep-alive" type="xs:boolean" default="true"/>
                <xs:attribute name="max-buffered-request-size" type="xs:long" default="16384"/>
                <xs:attribute name="record-request-start-time" type="xs:boolean" default="false"/>
                <xs:attribute name="allow-equals-in-cookie-value" type="xs:boolean" default="false"/>
                <xs:attribute name="no-request-timeout" type="xs:int" default="60000"/>
                <xs:attribute name="request-parse-timeout" type="xs:int"/>
                <xs:attribute name="disallowed-methods" type="stringList" default="TRACE"/>
                <xs:attribute name="secure" type="xs:boolean" default="false"/>
                <xs:attribute name="rfc6265-cookie-validation" type="xs:boolean" default="false"/>
                <xs:attribute name="allow-unescaped-characters-in-url" type="xs:boolean" default="false"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="http-listener-type">
        <xs:complexContent>
            <xs:extension base="listener-type">
               <xs:attribute name="certificate-forwarding" use="optional" type="xs:string" default="false">
                    <xs:annotation>
                        <xs:documentation>
                            <![CDATA[
                                If certificate forwarding should be enabled. If this is enabled then the listener will take the certificate from the SSL_CLIENT_CERT
                                attribute. This should only be enabled if behind a proxy, and the proxy is configured to always set these headers.
                               ]]>
                        </xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="redirect-socket" use="optional" type="xs:string">
                    <xs:annotation>
                        <xs:documentation>
                            <![CDATA[
                                If this listener is supporting non-SSL requests, and a request is received for which a matching <security-constraint> requires SSL transport,
                                undertow will automatically redirect the request to the socket binding port specified here.
                               ]]>
                        </xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="proxy-address-forwarding" use="optional" type="xs:string" default="false">
                    <xs:annotation>
                        <xs:documentation>
                            <![CDATA[
                              enables x-forwarded-host and similar headers and set a remote ip address and hostname
                               ]]>
                        </xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="enable-http2" use="optional" type="xs:string">
                    <xs:annotation>
                        <xs:documentation>
                            <![CDATA[
                              Enables HTTP2 upgrade and prior knowledge connections
                               ]]>
                        </xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="http2-enable-push" type="xs:boolean" use="optional" />
                <xs:attribute name="http2-header-table-size" type="xs:int" use="optional" />
                <xs:attribute name="http2-initial-window-size" type="xs:int" use="optional" />
                <xs:attribute name="http2-max-concurrent-streams" type="xs:int" use="optional" />
                <xs:attribute name="http2-max-frame-size" type="xs:int" use="optional" />
                <xs:attribute name="http2-max-header-list-size" type="xs:int" use="optional" />
                <xs:attribute name="require-host-http11" type="xs:boolean" use="optional" default="false"/>
                <xs:attribute name="proxy-protocol" type="xs:boolean" default="false"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="https-listener-type">
        <xs:complexContent>
            <xs:extension base="listener-type">
                <xs:attribute name="ssl-context" type="xs:string">
                    <xs:annotation>
                        <xs:documentation>
                            Reference to the SSLContext that should be used by this listener.

                            If neither ssl-context or security-realm are set the JVM wide default SSLContext will be used instead.

                            If this attribute is defined, the attributes 'verify-client', 'enabled-cipher-suites', 'enabled-protocols',
                            'ssl-session-cache-size', and 'ssl-session-timeout' must not be set.
                        </xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="certificate-forwarding" use="optional" type="xs:string" default="false">
                    <xs:annotation>
                        <xs:documentation>
                            <![CDATA[
                                                If certificate forwarding should be enabled. If this is enabled then the listener will take the certificate from the SSL_CLIENT_CERT
                                                attribute. This should only be enabled if behind a proxy, and the proxy is configured to always set these headers.
                                               ]]>
                        </xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="proxy-address-forwarding" use="optional" type="xs:string" default="false">
                    <xs:annotation>
                        <xs:documentation>
                            <![CDATA[
                                              enables x-forwarded-host and similar headers and set a remote ip address and hostname
                                               ]]>
                        </xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="security-realm" type="xs:string">
                    <xs:annotation>
                        <xs:documentation>
                            Reference to the legacy security realm to use to obtain an SSLContext.

                            If neither ssl-context or security-realm are set the JVM wide default SSLContext will be used instead.
                        </xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="verify-client" use="optional" type="xs:string"/>
                <xs:attribute name="enabled-cipher-suites" use="optional" type="xs:string"/>
                <xs:attribute name="enabled-protocols" use="optional" type="xs:string"/>
                <xs:attribute name="enable-http2" use="optional" type="xs:string"/>
                <xs:attribute name="enable-spdy" use="optional" type="xs:string"/>
                <xs:attribute name="ssl-session-cache-size" use="optional" type="xs:string"/>
                <xs:attribute name="ssl-session-timeout" use="optional" type="xs:string"/>
                <xs:attribute name="http2-enable-push" type="xs:boolean" use="optional" />
                <xs:attribute name="http2-header-table-size" type="xs:int" use="optional" />
                <xs:attribute name="http2-initial-window-size" type="xs:int" use="optional" />
                <xs:attribute name="http2-max-concurrent-streams" type="xs:int" use="optional" />
                <xs:attribute name="http2-max-frame-size" type="xs:int" use="optional" />
                <xs:attribute name="http2-max-header-list-size" type="xs:int" use="optional" />
                <xs:attribute name="require-host-http11" type="xs:boolean" use="optional" default="false"/>
                <xs:attribute name="proxy-protocol" type="xs:boolean" default="false"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="ajp-listener-type">
        <xs:complexContent>
            <xs:extension base="listener-type">
                <xs:attribute name="scheme" type="xs:string"/>
                <xs:attribute name="redirect-socket" use="optional" type="xs:string">
                    <xs:annotation>
                        <xs:documentation>
                            <![CDATA[
                                                If this listener is supporting non-SSL requests, and a request is received for which a matching <security-constraint> requires SSL transport,
                                                undertow will automatically redirect the request to the socket binding port specified here.
                                               ]]>
                        </xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="max-ajp-packet-size" type="xs:int"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="servletContainerType">
        <xs:sequence>
            <xs:element name="jsp-config" type="jsp-configurationType" maxOccurs="1" minOccurs="0"/>
            <xs:element name="session-cookie" type="session-cookieType" maxOccurs="1" minOccurs="0"/>
            <xs:element name="persistent-sessions" type="persistent-sessionsType" maxOccurs="1" minOccurs="0"/>
            <xs:element name="websockets" type="websocketsType" maxOccurs="1" minOccurs="0" />
            <xs:element name="mime-mappings" type="mime-mappingsType" maxOccurs="1" minOccurs="0" />
            <xs:element name="welcome-files" type="welcome-filesType" maxOccurs="1" minOccurs="0" />
            <xs:element name="crawler-session-management" type="crawler-session-managementType" maxOccurs="1" minOccurs="0" />
        </xs:sequence>
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="allow-non-standard-wrappers" use="optional" type="xs:boolean" default="false"/>
        <xs:attribute name="default-buffer-cache" use="optional" type="xs:string"/>
        <xs:attribute name="stack-trace-on-error" use="optional" default="local-only"/>
        <xs:attribute name="default-encoding" type="xs:string" use="optional"/>
        <xs:attribute name="use-listener-encoding" type="xs:boolean" use="optional" default="false"/>
        <xs:attribute name="ignore-flush" type="xs:boolean" use="optional" default="false"/>
        <xs:attribute name="eager-filter-initialization" type="xs:boolean" use="optional" default="false"/>
        <xs:attribute name="default-session-timeout" type="xs:integer" use="optional" default="30"/>
        <xs:attribute name="disable-caching-for-secured-pages" type="xs:boolean" use="optional" default="true"/>
        <xs:attribute name="directory-listing" type="xs:boolean" use="optional" />
        <xs:attribute name="proactive-authentication" type="xs:string" use="optional" default="false" />
        <xs:attribute name="session-id-length" type="xs:int" use="optional" default="30" />
        <xs:attribute name="max-sessions" type="xs:int" use="optional" />
        <xs:attribute name="disable-file-watch-service" type="xs:boolean" use="optional" />
        <xs:attribute name="disable-session-id-reuse" type="xs:boolean" use="optional" />
        <xs:attribute name="file-cache-max-file-size" type="xs:integer" use="optional" default="10485760"/>
        <xs:attribute name="file-cache-metadata-size" type="xs:integer" use="optional" default="100"/>
        <xs:attribute name="file-cache-time-to-live" type="xs:integer" use="optional"/>
        <xs:attribute name="default-cookie-version" type="xs:integer"  use="optional"/>
    </xs:complexType>

    <xs:complexType name="mime-mappingsType">
        <xs:sequence>
            <xs:element name="mime-mapping" type="mime-mappingType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="mime-mappingType">
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="value" use="required" type="xs:string"/>
    </xs:complexType>

    <xs:complexType name="welcome-filesType">
        <xs:sequence>
            <xs:element name="welcome-file" type="welcome-fileType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="welcome-fileType">
        <xs:attribute name="name" use="required" type="xs:string"/>
    </xs:complexType>

    <xs:complexType name="hostType">
        <xs:sequence>
            <xs:element name="location" type="locationType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="access-log" type="accessLogType" maxOccurs="1" minOccurs="0"/>
            <xs:element name="console-access-log" type="consoleAccessLogType" minOccurs="0"/>
            <xs:element name="filter-ref" type="filter-refType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="single-sign-on" minOccurs="0" maxOccurs="1" type="singleSignOnType"/>
            <xs:element name="http-invoker" minOccurs="0" maxOccurs="1" type="http-invokerType"/>
        </xs:sequence>
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="alias" use="optional" type="xs:string"/>
        <xs:attribute name="default-web-module" use="optional" type="xs:string" default="ROOT.war"/>
        <xs:attribute name="default-response-code" use="optional" type="xs:int" default="404">
            <xs:annotation>
                <xs:documentation>Default response code should be set in case server should respond with nonstandard code( other than 404 ) for unavailable resource.
                    For instance, server behind load balancer might want to respond with 5xx code to avoid being dropped by it.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="disable-console-redirect" use="optional" type="xs:boolean" default="false"/>
        <xs:attribute name="queue-requests-on-start" type="xs:boolean" default="true"/>
    </xs:complexType>

    <xs:complexType name="http-invokerType">
        <xs:attribute name="path" use="optional" type="xs:string" default="wildfly-services"/>
        <xs:attribute name="http-authentication-factory" type="xs:string" use="optional"/>
        <xs:attribute name="security-realm" type="xs:string" use="optional"/>
    </xs:complexType>

    <xs:complexType name="websocketsType">
        <xs:attribute name="worker" use="optional" type="xs:string" default="default"/>
        <xs:attribute name="buffer-pool" use="optional" type="xs:string" default="default"/>
        <xs:attribute name="dispatch-to-worker" use="optional" type="xs:boolean" default="true"/>
        <xs:attribute name="per-message-deflate" use="optional" type="xs:boolean" default="false"/>
        <xs:attribute name="deflater-level" use="optional" type="xs:int"/>
    </xs:complexType>

    <xs:complexType name="crawler-session-managementType">
        <xs:attribute name="user-agents" use="optional" type="xs:string"/>
        <xs:attribute name="session-timeout" use="optional" type="xs:integer"/>
    </xs:complexType>

    <xs:complexType name="jsp-configurationType">
        <xs:attribute name="disabled" default="false" type="xs:boolean"/>
        <xs:attribute name="development" default="false" type="xs:boolean"/>
        <xs:attribute name="keep-generated" default="true" type="xs:boolean"/>
        <xs:attribute name="trim-spaces" default="false" type="xs:boolean"/>
        <xs:attribute name="tag-pooling" default="true" type="xs:boolean"/>
        <xs:attribute name="mapped-file" default="true" type="xs:boolean"/>
        <xs:attribute name="check-interval" default="0" type="xs:int"/>
        <xs:attribute name="modification-test-interval" default="4" type="xs:int"/>
        <xs:attribute name="recompile-on-fail" default="false" type="xs:boolean"/>
        <xs:attribute name="smap" default="true" type="xs:boolean"/>
        <xs:attribute name="dump-smap" default="false" type="xs:boolean"/>
        <xs:attribute name="generate-strings-as-char-arrays" default="false" type="xs:boolean"/>
        <xs:attribute name="error-on-use-bean-invalid-class-attribute" default="false" type="xs:boolean"/>
        <xs:attribute name="scratch-dir" type="xs:string"/>
        <xs:attribute name="source-vm" default="1.8" type="xs:string"/>
        <xs:attribute name="target-vm" default="1.8" type="xs:string"/>
        <xs:attribute name="java-encoding" default="UTF8" type="xs:string"/>
        <xs:attribute name="x-powered-by" default="true" type="xs:boolean"/>
        <xs:attribute name="display-source-fragment" default="true" type="xs:boolean"/>
        <xs:attribute name="optimize-scriptlets" default="false" type="xs:string" />
    </xs:complexType>

    <xs:complexType name="session-cookieType">
        <xs:attribute name="name" type="xs:string"/>
        <xs:attribute name="domain" type="xs:string"/>
        <xs:attribute name="comment" type="xs:string"/>
        <xs:attribute name="http-only" type="xs:boolean"/>
        <xs:attribute name="secure" type="xs:boolean"/>
        <xs:attribute name="max-age" type="xs:int"/>
    </xs:complexType>

    <xs:complexType name="persistent-sessionsType">
        <xs:attribute name="path" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>
                    <![CDATA[
                  The path to store the session data. If not specified the data will just be stored in memory only.
                ]]>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="relative-to" type="xs:string" use="optional"/>
    </xs:complexType>

    <xs:complexType name="handlerType">
        <xs:sequence>
            <xs:element name="file" type="file-handlerType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="reverse-proxy" type="reverse-proxy-handlerType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>


    <xs:complexType name="filterType">
        <xs:sequence>
            <xs:element name="request-limit" type="request-limitType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="response-header" type="response-headerType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="gzip" type="gzipType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="error-page" type="errorPageType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="mod-cluster" type="modClusterType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="filter" type="customFilterType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="expression-filter" type="expressionFilterType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="rewrite" type="rewriteFilterType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="locationType">
        <xs:sequence>
            <xs:element name="filter-ref" type="filter-refType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="handler" use="required" type="xs:string"/>
    </xs:complexType>
    <xs:complexType name="accessLogType">
        <xs:attribute name="pattern" use="optional" type="xs:string" default="common"/>
        <xs:attribute name="worker" use="optional" type="xs:string" default="default"/>
        <xs:attribute name="directory" use="optional" type="xs:string" default="${jboss.server.log.dir}"/>
        <xs:attribute name="relative-to" use="optional" type="xs:string" />
        <xs:attribute name="prefix" use="optional" type="xs:string" default="access_log."/>
        <xs:attribute name="suffix" use="optional" type="xs:string" default="log"/>
        <xs:attribute name="rotate" use="optional" type="xs:string" default="true"/>
        <xs:attribute name="use-server-log" use="optional" type="xs:string" default="false"/>
        <xs:attribute name="extended" use="optional" type="xs:string" default="false" />
        <xs:attribute name="predicate" use="optional" type="xs:string" />
    </xs:complexType>
    <xs:complexType name="consoleAccessLogType">
        <xs:sequence minOccurs="0">
            <xs:element name="attributes" type="attributesType" minOccurs="0"/>
            <xs:element name="metadata" type="propertiesType" minOccurs="0"/>
        </xs:sequence>
        <xs:attribute name="include-host-name" type="xs:boolean" default="true"/>
        <xs:attribute name="worker" type="xs:string" default="default"/>
        <xs:attribute name="predicate" type="xs:string" />
    </xs:complexType>
    <xs:complexType name="propertiesType">
        <xs:annotation>
            <xs:documentation>
                A collection of free-form meta-data properties.
            </xs:documentation>
        </xs:annotation>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="property">
                <xs:complexType>
                    <xs:attribute name="name" type="xs:string" use="required"/>
                    <xs:attribute name="value" type="xs:string" use="required"/>
                </xs:complexType>
            </xs:element>
        </xs:choice>
    </xs:complexType>
    <xs:complexType name="attributesType">
        <xs:annotation>
            <xs:documentation>
                The available attributes to be included in the structured access log output.
            </xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:element name="authentication-type" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="bytes-sent" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="date-time" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                    <xs:attribute name="date-format" type="xs:string"/>
                    <xs:attribute name="time-zone" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="host-and-port" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="local-ip" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="local-port" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="local-server-name" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="path-parameter" minOccurs="0">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="name" maxOccurs="unbounded">
                            <xs:complexType>
                                <xs:attribute name="value" use="required"/>
                            </xs:complexType>
                        </xs:element>
                    </xs:sequence>
                    <xs:attribute name="key-prefix"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="predicate" minOccurs="0">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="name" maxOccurs="unbounded">
                            <xs:complexType>
                                <xs:attribute name="value" use="required"/>
                            </xs:complexType>
                        </xs:element>
                    </xs:sequence>
                    <xs:attribute name="key-prefix"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="query-parameter" minOccurs="0">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="name" maxOccurs="unbounded">
                            <xs:complexType>
                                <xs:attribute name="value" use="required"/>
                            </xs:complexType>
                        </xs:element>
                    </xs:sequence>
                    <xs:attribute name="key-prefix"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="query-string" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="include-question-mark" type="xs:boolean" default="false"/>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="relative-path" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="remote-host" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="remote-ip" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                    <xs:attribute name="obfuscated" type="xs:boolean" default="false"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="remote-user" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="request-header" minOccurs="0">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="name" maxOccurs="unbounded">
                            <xs:complexType>
                                <xs:attribute name="value" use="required"/>
                            </xs:complexType>
                        </xs:element>
                    </xs:sequence>
                    <xs:attribute name="key-prefix"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="request-line" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="request-method" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="request-path" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="request-protocol" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="request-scheme" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="request-url" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="resolved-path" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="response-code" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="response-header" minOccurs="0">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="name" maxOccurs="unbounded">
                            <xs:complexType>
                                <xs:attribute name="value" use="required"/>
                            </xs:complexType>
                        </xs:element>
                    </xs:sequence>
                    <xs:attribute name="key-prefix"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="response-reason-phrase" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="response-time" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                    <xs:attribute name="time-unit" default="MILLISECONDS">
                        <xs:simpleType>
                            <xs:restriction base="xs:token">
                                <xs:enumeration value="NANOSECONDS"/>
                                <xs:enumeration value="MICROSECONDS"/>
                                <xs:enumeration value="MILLISECONDS"/>
                                <xs:enumeration value="SECONDS"/>
                            </xs:restriction>
                        </xs:simpleType>
                    </xs:attribute>
                </xs:complexType>
            </xs:element>
            <xs:element name="secure-exchange" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="ssl-cipher" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="ssl-client-cert" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="ssl-session-id" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="stored-response" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="thread-name" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="transport-protocol" minOccurs="0">
                <xs:complexType>
                    <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="errorPageType">
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="code" use="required" type="xs:string"/>
        <xs:attribute name="path" use="required" type="xs:string"/>
    </xs:complexType>

    <xs:complexType name="paramType">
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="value" use="required" type="xs:string"/>
    </xs:complexType>



    <xs:complexType name="customFilterType">
        <xs:sequence>
            <xs:element name="param" type="paramType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="class-name" use="required" type="xs:string"/>
        <xs:attribute name="module" use="required" type="xs:string"/>
    </xs:complexType>
    <xs:complexType name="expressionFilterType">
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="expression" use="required" type="xs:string"/>
        <xs:attribute name="module" use="optional" type="xs:string"/>
    </xs:complexType>
    <xs:complexType name="rewriteFilterType">
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="target" use="required" type="xs:string"/>
        <xs:attribute name="redirect" use="optional" type="xs:string"/>
    </xs:complexType>
    <xs:complexType name="file-handlerType">
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="path" use="required" type="xs:string"/>
        <xs:attribute name="cache-buffer-size" use="optional" type="xs:int" default="1024"/>
        <xs:attribute name="cache-buffers" use="optional" type="xs:int" default="1024"/>
        <xs:attribute name="directory-listing" use="optional" type="xs:boolean" default="false"/>
        <xs:attribute name="follow-symlink" use="optional" type="xs:boolean" default="false"/>
        <xs:attribute name="safe-symlink-paths" use="optional" type="stringList"/>
        <xs:attribute name="case-sensitive" use="optional" type="xs:boolean" default="true"/>
    </xs:complexType>

    <xs:simpleType name="stringList">
        <xs:list itemType="xs:string"/>
    </xs:simpleType>

    <xs:complexType name="reverse-proxy-handlerType">
        <xs:sequence>
            <xs:element name="host" type="reverse-proxy-hostType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="connections-per-thread" use="optional" type="xs:integer"/>
        <xs:attribute name="session-cookie-names" use="optional" type="xs:string"/>
        <xs:attribute name="problem-server-retry" use="optional" type="xs:integer"/>
        <xs:attribute name="max-request-time" use="optional" type="xs:integer"/>
        <xs:attribute name="request-queue-size" use="optional" type="xs:integer"/>
        <xs:attribute name="cached-connections-per-thread" use="optional" type="xs:integer"/>
        <xs:attribute name="connection-idle-timeout" use="optional" type="xs:integer"/>
        <xs:attribute name="max-retries" type="xs:int" use="optional" />
    </xs:complexType>

    <xs:complexType name="reverse-proxy-hostType">
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="outbound-socket-binding" use="required" type="xs:string"/>
        <xs:attribute name="scheme" use="optional" type="xs:string" default="http"/>
        <xs:attribute name="path" use="optional" type="xs:string" default=""/>
        <xs:attribute name="instance-id" use="optional" type="xs:string"/>
        <xs:attribute name="ssl-context" type="xs:string" />
        <xs:attribute name="security-realm" type="xs:string" use="optional" />
        <xs:attribute name="enable-http2" type="xs:boolean" use="optional" default="false" />
    </xs:complexType>

    <xs:complexType name="filter-refType">
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="predicate" use="optional" type="xs:string">
            <xs:annotation>
                <xs:documentation>
                    <![CDATA[
                          Predicates provide a simple way of making a true/false decision  based on an exchange. Many handlers have a requirement that they be applied conditionally, and predicates provide a general way to specify a condition. Predicates can be created programatically (they are just java classes that implement the Predicate interface), however there is also a simple language for specifying a predicate. Some examples below:
                          regex['/resources/*.\.css'] - regular expression match of the relative URL
                          regex[pattern='text/.*', value='%{i,Content-Type}, full-match=true] - Matches requests with a text/.* content type
                          equals[{'%{i,Content-Type}', 'text/xml'}] - Matches if the content type header is text/xml
                          contains[search='MSIE', value='%{i,User-Agent}'] and path-suffix['.js'] - User agent contains MSIE and request URL ends with .js
                          regex['/resources/(*.)\.css'] and equals[{'$1', 'myCssFile'}] - regex match, with a reference to match group 1 later in the expression
                        ]]>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="priority" use="optional" type="xs:string" />
    </xs:complexType>

    <xs:complexType name="singleSignOnType">
        <xs:attribute name="domain" type="xs:string">
            <xs:annotation>
                <xs:documentation>
                    <![CDATA[
                              Cookie domain to use.
                              ]]>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="path" type="xs:string">
            <xs:annotation>
                <xs:documentation>
                    <![CDATA[
                              Cookie path to use.
                              ]]>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="http-only" type="xs:boolean" default="false">
            <xs:annotation>
                <xs:documentation>
                    <![CDATA[
                              Cookie httpOnly attribute
                              ]]>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="secure" type="xs:boolean" default="false">
            <xs:annotation>
                <xs:documentation>
                    <![CDATA[
                              Cookie secure attribute
                              ]]>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="cookie-name" type="xs:string" default="JSESSIONIDSSO">
            <xs:annotation>
                <xs:documentation>
                    <![CDATA[
                              Cooke name
                              ]]>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>


    <xs:complexType name="buffer-cacheType">
        <xs:annotation>
            <xs:documentation>
                <![CDATA[
                  A buffer cache. I cache consists of 1 or more regions, that are split up into smaller buffers.
                  The total cache size is the buffer size * the buffers per region * the number of regions.
                ]]>
            </xs:documentation>
        </xs:annotation>
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="buffer-size" use="optional" type="xs:string"/>
        <xs:attribute name="buffers-per-region" use="optional" type="xs:string"/>
        <xs:attribute name="max-regions" use="optional" type="xs:string"/>
    </xs:complexType>

    <xs:complexType name="byte-buffer-poolType">
        <xs:annotation>
            <xs:documentation>
                <![CDATA[
                The buffer pool used for IO operations
                ]]>
            </xs:documentation>
        </xs:annotation>
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="buffer-size" use="optional" type="xs:int"/>
        <xs:attribute name="direct" use="optional" type="xs:boolean"/>
        <xs:attribute name="thread-local-cache-size" use="optional" type="xs:int"/>
        <xs:attribute name="max-pool-size" use="optional" type="xs:int"/>
        <xs:attribute name="leak-detection-percent" use="optional" type="xs:int"/>
    </xs:complexType>
    <xs:complexType name="request-limitType">
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="max-concurrent-requests" use="required" type="xs:integer"/>
        <xs:attribute name="queue-size" use="optional" type="xs:integer" default="0"/>
    </xs:complexType>
    <xs:complexType name="response-headerType">
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="header-name" use="required" type="xs:string"/>
        <xs:attribute name="header-value" use="required" type="xs:string"/>
    </xs:complexType>

    <xs:complexType name="gzipType">
        <xs:attribute name="name" use="required" type="xs:string"/>
    </xs:complexType>

    <xs:complexType name="modClusterType">
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="management-socket-binding" type="xs:string" use="required"/>
        <xs:attribute name="advertise-socket-binding" type="xs:string" use="optional"/>
        <xs:attribute name="security-key" type="xs:string" use="optional"/>
        <xs:attribute name="advertise-protocol" type="xs:string" use="optional"/>
        <xs:attribute name="advertise-path" type="xs:string" use="optional"/>
        <xs:attribute name="advertise-frequency" type="xs:int" use="optional"/>
        <xs:attribute name="failover-strategy" type="failoverStrategy" default="LOAD_BALANCED" use="optional">
            <xs:annotation>
                <xs:documentation>
                    Determines how a failover node is chosen, in the event that the node to which a session has affinity is not available.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="health-check-interval" type="xs:int" use="optional"/>
        <xs:attribute name="broken-node-timeout" type="xs:int" use="optional"/>
        <xs:attribute name="worker" type="xs:string" use="optional" />
        <xs:attribute name="max-request-time" type="xs:int" use="optional"/>
        <xs:attribute name="management-access-predicate" type="xs:string" use="optional"/>
        <xs:attribute name="connections-per-thread" type="xs:int" use="optional" />
        <xs:attribute name="cached-connections-per-thread" type="xs:int" use="optional" />
        <xs:attribute name="connection-idle-timeout" type="xs:int" use="optional" />
        <xs:attribute name="request-queue-size" type="xs:int" use="optional" />
        <xs:attribute name="ssl-context" type="xs:string" />
        <xs:attribute name="security-realm" type="xs:string" use="optional" />
        <xs:attribute name="use-alias" type="xs:string" use="optional" default="false" />
        <xs:attribute name="enable-http2" type="xs:string" use="optional" default="false" />
        <xs:attribute name="max-ajp-packet-size" type="xs:int" use="optional" />
        <xs:attribute name="http2-enable-push" type="xs:boolean" use="optional" />
        <xs:attribute name="http2-header-table-size" type="xs:int" use="optional" />
        <xs:attribute name="http2-initial-window-size" type="xs:int" use="optional" />
        <xs:attribute name="http2-max-concurrent-streams" type="xs:int" use="optional" />
        <xs:attribute name="http2-max-frame-size" type="xs:int" use="optional" />
        <xs:attribute name="http2-max-header-list-size" type="xs:int" use="optional" />
        <xs:attribute name="max-retries" type="xs:int" use="optional" />
    </xs:complexType>

    <xs:simpleType name="failoverStrategy">
        <xs:restriction base="xs:token">
            <xs:enumeration value="LOAD_BALANCED">
                <xs:annotation>
                    <xs:documentation>
                        Failover target chosen via load balancing mechanism.
                    </xs:documentation>
                </xs:annotation>
            </xs:enumeration>
            <xs:enumeration value="DETERMINISTIC">
                <xs:annotation>
                    <xs:documentation>
                        Failover target chosen deterministically from the associated session identifier.
                    </xs:documentation>
                </xs:annotation>
            </xs:enumeration>
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="applicationSecurityDomainsType">
        <xs:annotation>
            <xs:documentation>
                Listing of security domains from applications that should be mapped to an Elytron
                backed authentication policy.
            </xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:element name="application-security-domain" type="applicationSecurityDomainType" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="applicationSecurityDomainType">
        <xs:sequence>
            <xs:element name="single-sign-on" type="applicationSecurityDomainSingleSignOnType" minOccurs="0"/>
        </xs:sequence>
        <xs:attribute name="name" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>
                    The name of the security domain as specified in deployments.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="http-authentication-factory" type="xs:string">
            <xs:annotation>
                <xs:documentation>
                    Reference to the HttpAuthenticationFactory that should be used.

                    Exactly one of http-authentication-factory or security-domain must be defined.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="override-deployment-config" type="xs:boolean" default="false">
            <xs:annotation>
                <xs:documentation>
                    The references HttpServerAuthenticationMechanismFactory contains it's own policy configuration
                    to control the authentication mechanisms it supports, if this attribute is set to 'true'
                    that policy will override the methods specified within the deployment.

                    This attribute can only be specified if a http-authentication-factory is also specified.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="security-domain" type="xs:string">
            <xs:annotation>
                <xs:documentation>
                    Reference to the security-domain that should be associated with the deployment, where a
                    security-domain is referenced instead of a http-authentication-factory the authentication mechanisms
                    BASIC, DIGEST, FORM and CLIENT_CERT will be availble for the deployment to use - additionally the deployment
                    can make use of the programatic login API.

                    Exactly one of http-authentication-factory or security-domain must be defined.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="enable-jacc" type="xs:boolean" use="optional" default="false">
            <xs:annotation>
                <xs:documentation>
                    Enable authorization using JACC.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="enable-jaspi" type="xs:boolean" default="true">
            <xs:annotation>
                <xs:documentation>
                    Should deployments matching against this 'application-security-domain' have
                    JASPI enabled, by setting to false JASPI will be completely disabled for the deployment.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="integrated-jaspi" type="xs:boolean" default="true">
            <xs:annotation>
                <xs:documentation>
                    When integrated-jaspi is enabled during JASPI authentication the resulting
                    identity will be loaded from the SecurityDomain referenced by the deployment, if
                    this is switched off AdHoc identities will be created instead.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="applicationSecurityDomainSingleSignOnType">
        <xs:complexContent>
            <xs:extension base="singleSignOnType">
                <xs:sequence>
                    <xs:element name="credential-reference" type="credential-reference:credentialReferenceType" minOccurs="0"/>
                </xs:sequence>
                <xs:attribute name="key-store" type="xs:string" use="required">
                    <xs:annotation>
                        <xs:documentation>References key store containing the key used to sign and verify logout requests.</xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="key-alias" type="xs:string" use="required">
                    <xs:annotation>
                        <xs:documentation>The alias of the key used to sign and verify logout requests.</xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="client-ssl-context" type="xs:string">
                    <xs:annotation>
                        <xs:documentation>The ssl context used to secure back-channel logout connections.</xs:documentation>
                    </xs:annotation>
                </xs:attribute>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

</xs:schema>
