<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="urn:jboss:domain:modeshape:3.0"
           xmlns="urn:jboss:domain:modeshape:3.0"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified"
           version="3.0">

    <!-- The subsystem root element -->
    <xs:element name="subsystem" type="subsystem">
        <xs:annotation>
            <xs:documentation>Enumerates the available repositories.</xs:documentation>
        </xs:annotation>
    </xs:element>

    <xs:complexType name="subsystem">
        <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="webapp" type="webapp">
                <xs:annotation>
                    <xs:documentation>Defines an embedded web application.</xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="repository" type="repository">
                <xs:annotation>
                    <xs:documentation>Defines an embedded repository.</xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="webapp">
        <xs:attribute name="name" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>The name of the web application that is located in the ModeShape's main module, under the
                    deployments directory
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>

        <xs:attribute name="exploded" type="xs:boolean" use="optional" default="true">
            <xs:annotation>
                <xs:documentation>Indicates if the web application is exploded or not</xs:documentation>
            </xs:annotation>
        </xs:attribute>

        <xs:attribute name="auto-deploy" type="xs:boolean" use="optional" default="true">
            <xs:annotation>
                <xs:documentation>Indicates if the web application should be auto deployed when the ModeShape subsystem starts
                    up
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="repository">
        <xs:sequence minOccurs="0" maxOccurs="unbounded">
            <xs:choice>
                <xs:choice minOccurs="0" maxOccurs="1">
                    <xs:element name="db-persistence" type="db-persistence" minOccurs="0" maxOccurs="1">
                        <xs:annotation>
                            <xs:documentation>
                                The repository DB persistence configuration.
                            </xs:documentation>
                        </xs:annotation>
                    </xs:element>
                    <xs:element name="file-persistence" type="file-persistence" minOccurs="0" maxOccurs="1">
                        <xs:annotation>
                            <xs:documentation>
                                The repository FS persistence configuration.
                            </xs:documentation>
                        </xs:annotation>
                    </xs:element>
                </xs:choice>
                <xs:element name="custom-persistence" type="custom-persistence" minOccurs="0" maxOccurs="1">
                    <xs:annotation>
                        <xs:documentation>
                            A repository custom persistence configuration. If absent, will default to an in-memory H2 database.
                        </xs:documentation>
                    </xs:annotation>
                </xs:element>  
            </xs:choice>
            <xs:element name="workspaces" type="workspaces" minOccurs="0" maxOccurs="1">
                <xs:annotation>
                    <xs:documentation>The definition of the pre-existing workspaces that will exist when the repository starts
                        up.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>

            <xs:element name="node-types" type="node-types" minOccurs="0" maxOccurs="1">
                <xs:annotation>
                    <xs:documentation>The definition of node type (CND) files that should be import on repository start-up
                    </xs:documentation>
                </xs:annotation>
            </xs:element>

            <xs:element name="authenticators" type="authenticators" minOccurs="0" maxOccurs="1">
                <xs:annotation>
                    <xs:documentation>The definition of the custom authenticators.</xs:documentation>
                </xs:annotation>
            </xs:element>

            <xs:element name="sequencers" type="sequencers" minOccurs="0" maxOccurs="1">
                <xs:annotation>
                    <xs:documentation>The definition of the custom sequencers.</xs:documentation>
                </xs:annotation>
            </xs:element>

            <xs:element name="index-providers" type="index-providers" minOccurs="0" maxOccurs="1">
                <xs:annotation>
                    <xs:documentation>The definition of the index providers.</xs:documentation>
                </xs:annotation>
            </xs:element>

            <xs:element name="indexes" type="indexes" minOccurs="0" maxOccurs="1">
                <xs:annotation>
                    <xs:documentation>The definition of the indexes.</xs:documentation>
                </xs:annotation>
            </xs:element>

            <xs:element name="reindexing" type="reindexing" minOccurs="0" maxOccurs="1">
                <xs:annotation>
                    <xs:documentation>The definition of the reindexing configuration</xs:documentation>
                </xs:annotation>
            </xs:element>

            <xs:element name="text-extractors" type="text-extractors" minOccurs="0" maxOccurs="1">
                <xs:annotation>
                    <xs:documentation>The definition of the custom text extractors.</xs:documentation>
                </xs:annotation>
            </xs:element>

            <xs:element name="external-sources" type="external-sources" minOccurs="0" maxOccurs="1">
                <xs:annotation>
                    <xs:documentation>The definition of the external sources</xs:documentation>
                </xs:annotation>
            </xs:element>

            <xs:element name="journaling" type="journaling" minOccurs="0" maxOccurs="1">
                <xs:annotation>
                    <xs:documentation>The definition of the journaling mechanism.</xs:documentation>
                </xs:annotation>
            </xs:element>

            <xs:choice minOccurs="0" maxOccurs="1">
                <xs:element name="transient-binary-storage" type="transient-binary-storage">
                    <xs:annotation>
                        <xs:documentation>The binary files are stored in a temporary location which is cleared between server restarts</xs:documentation>
                    </xs:annotation>
                </xs:element>  
                <xs:element name="file-binary-storage" type="file-binary-storage">
                    <xs:annotation>
                        <xs:documentation>The binary files are stored on the local file system.</xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="db-binary-storage" type="db-binary-storage">
                    <xs:annotation>
                        <xs:documentation>The binary files are stored in a relational database.</xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="cassandra-binary-storage" type="cassandra-binary-storage">
                    <xs:annotation>
                        <xs:documentation>The binary files are stored in Cassandra.</xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="mongo-binary-storage" type="mongo-binary-storage">
                    <xs:annotation>
                        <xs:documentation>The binary files are stored in MongoDB.</xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="s3-binary-storage" type="s3-binary-storage">
                    <xs:annotation>
                        <xs:documentation>The binary files are stored in Amazon S3.</xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="composite-binary-storage" type="composite-binary-storage">
                    <xs:annotation>
                        <xs:documentation>The binary files are stored in a one of any number of named binary stores.
                        </xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="custom-binary-storage" type="custom-binary-storage">
                    <xs:annotation>
                        <xs:documentation>The binary files are stored in a custom system.</xs:documentation>
                    </xs:annotation>
                </xs:element>
            </xs:choice>

        </xs:sequence>

        <!-- Attributes for 'repository' -->

        <xs:attribute name="name" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>The name of the repository, which must be unique within the subsystem.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="jndi-name" type="xs:string">
            <xs:annotation>
                <xs:documentation>The name in JNDI where this repository is to be
                    registered. If no value set, the repository will not be
                    bound to 'jcr/local/{repositoryName}' (where '{repositoryName}' is the name
                    of this repository).
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="enable-monitoring" type="xs:boolean" default="true">
            <xs:annotation>
                <xs:documentation>Specifies whether the repository is to maintain the metrics that can be used
                    to monitor the performance and activities. The default value is 'true', meaning monitoring is
                    enabled.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="security-domain" type="xs:string" default="modeshape-security">
            <xs:annotation>
                <xs:documentation>The name of the security domain that should be used for JAAS authentication.
                    The default is the 'modeshape-security' security domain which uses the default ApplicationRealm security realm.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="anonymous-roles" type="roleNames" default="readonly">
            <xs:annotation>
                <xs:documentation>The space-separated names of the roles for anonymous users.
                    Anonymous logins will be disabled if the roles consists of an empty string.
                    By default, the role is 'readonly'.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="anonymous-username" type="xs:string" default="&lt;anonymous&gt;">
            <xs:annotation>
                <xs:documentation>The username for all anonymous users.
                    The username '&lt;anonymous&gt;' is used by default
                    (that is, 'anonymous' surrounded by angle brackets").
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="use-anonymous-upon-failed-authentication" type="xs:boolean" default="false">
            <xs:annotation>
                <xs:documentation>Indicates that failed authentication attempts will not result in a
                    LoginException but will instead fall back to anonymous access.
                    If anonymous access is not enabled, then failed login attempts will
                    throw a LoginException. The default value is 'false'.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="cluster-name" type="xs:string">
            <xs:annotation>
                <xs:documentation>
                    Defines the name of the communication channel used by this and other clustered repositories. This is 
                    required when a repository should be clustered.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="cluster-stack" type="xs:string">
            <xs:annotation>
                <xs:documentation>
                    Defines the name of the Wildlfy JGroups stack used by the repository when clustered. This is relative to 
                    the JGroups subsystem defined in Wildfly. 
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="cluster-config" type="xs:string">
            <xs:annotation>
                <xs:documentation>
                    Defines the JGroups configuration that should be used when clustering. This should only be used
                    when there isn't an explicit cluster-stack configured and should contain the full path to a JGroup XML file
                    For example: ${jboss.server.config.dir}/modeshape/jgroups.xml
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>  
        <xs:attribute name="cluster-locking" type="cluster-locking-enum">
            <xs:annotation>
                <xs:documentation>
                    Configures how ModeShape should obtain exclusive locks when running in a cluster. Defaults to JGroups 
                    (using JGroups' LockService) but can also be configured to use DB exclusive locks.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="garbage-collection-thread-pool" type="xs:string" use="optional" default="modeshape-gc">
            <xs:annotation>
                <xs:documentation>Name of the thread pool that should be used for background garbage collection
                    and recovery of unused storage space. Garbage collection can be relatively expensive, and is
                    only necessary to recover unused persistent storage space (of binary values). Therefore,
                    it is recommended to be done at most once per day during less-used time periods.
                    Thread pools are named globally within a single ModeShape subsystem, and by default all
                    repositories use the same thread pool for sequencing and indexing.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="garbage-collection-initial-time" type="garbage-collection-initial-time-type" use="optional"
                      default="00:00">
            <xs:annotation>
                <xs:documentation>The local time that the first garbage collection process should be run.
                    Garbage collection may be relatively expensive, as it involves scanning all persisted content,
                    so it's recommended that this be done durign off hours if possible. The format is "hh:mm", or
                    two-digit hours and two-digit minutes. By default, the value is "00:00" garbage
                    collection is run at midnight (local time) after the repository is started.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="garbage-collection-interval" type="xs:int" use="optional" default="24">
            <xs:annotation>
                <xs:documentation>The number of hours between garbage collection runs.
                    By default the interval is 24 hours (meaning it runs once per day).
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="document-optimization-thread-pool" type="xs:string" use="optional" default="modeshape-opt">
            <xs:annotation>
                <xs:documentation>Name of the thread pool that should be used to asynchronously optimize persisted 
                    node representations. This process is only required when nodes have large numbers of children,
                    as defined by the child count target. Thread pools are named globally within a single ModeShape 
                    engine, and by default all repositories use the same thread pool for document optimization.
                    DOCUMENT OPTIMIZATION IS A TECHNOLOGY PREVIEW AND SHOULD NOT YET BE USED IN PRODUCTION.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="document-optimization-initial-time" type="document-optimization-initial-time-type" use="optional"
                      default="02:00">
            <xs:annotation>
                <xs:documentation>The local time that the first document optimization process should be run.
                    Document optimization may be relatively expensive, as it involves scanning all persisted content,
                    so it's recommended that this be done during off hours if possible. The format is "hh:mm", or
                    two-digit hours and two-digit minutes. By default, the value is "02:00" garbage
                    collection is run at 2AM (local time) after the repository is started.
                    DOCUMENT OPTIMIZATION IS A TECHNOLOGY PREVIEW AND SHOULD NOT YET BE USED IN PRODUCTION.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="document-optimization-interval" type="xs:int" use="optional" default="24">
            <xs:annotation>
                <xs:documentation>The number of hours between document optimization runs.
                    By default the interval is 24 hours (meaning it runs once per day).
                    DOCUMENT OPTIMIZATION IS A TECHNOLOGY PREVIEW AND SHOULD NOT YET BE USED IN PRODUCTION.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="document-optimization-child-count-target" type="xs:positiveInteger" use="optional">
            <xs:annotation>
                <xs:documentation>The maximum number of children that are ideally stored within a single document 
                    (e.g., node document or separate page of children). A lower number might result in more pages
                    but faster load times for nodes when accessing a subset of the children, but getting particular
                    children or all children of a node will require reading multiple documents/pages. A larger 
                    number may increase the time required to read each document/page, but may reduce the total number 
                    of document/page reads necessary to load a particular child or all children of a node. 
                    There is no default because the performance is highly dependent upon application usage and access 
                    patterns. Therefore, we strongly recommend testing with various values. 
                    Optimization is only enabled with a valid value.
                    DOCUMENT OPTIMIZATION IS A TECHNOLOGY PREVIEW AND SHOULD NOT YET BE USED IN PRODUCTION.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="document-optimization-child-count-tolerance" type="xs:positiveInteger" use="optional">
            <xs:annotation>
                <xs:documentation>The range that the actual number of children in a document can vary above the 
                    target before the documents/pages are split, or below the target before documents/pages are merged. 
                    There is no default because the performance is highly dependent upon application usage and access 
                    patterns. Therefore, we strongly recommend testing with various values.
                    Optimization is only enabled with a valid value.
                    DOCUMENT OPTIMIZATION IS A TECHNOLOGY PREVIEW AND SHOULD NOT YET BE USED IN PRODUCTION.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="event-bus-size" type="xs:int" use="optional" default="1024">
            <xs:annotation>
                <xs:documentation>
                    The maximum number of events that can co-exit in the event bus, before blocking and waiting for the slowest consumer(s) 
                    to finish and free up subsequent slots. Should be a power of 2, or the system will auto-adjust to the closest power of 2
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>   
        <xs:attribute name="lock-timeout-millis" type="xs:long" use="optional" default="10000">
            <xs:annotation>
                <xs:documentation>
                    The maximum number of milliseconds to wait in order to obtain locks on repository nodes in case 
                    of concurrent writes. Defaults to 10 seconds. In highly-concurrent cases, this may be increased.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="depends-on" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>
                    A comma-separated list of module names on which the repository depends. These modules, if present in the
                    configuration,will be added to the classpath whenever the repository attempts to resolve external files like
                    node type definitions or initial content files
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="workspaces">
        <xs:annotation>
            <xs:documentation>The definition of the predefined workspaces that exist when the repository
                is started. The 'default-workspace' need not be predefined, since the default workspace
                must exist.
            </xs:documentation>
        </xs:annotation>
        <xs:sequence minOccurs="0" maxOccurs="unbounded">
            <xs:element name="workspace" minOccurs="0" maxOccurs="unbounded">
                <xs:annotation>
                    <xs:documentation>The definition of a predefined workspace that exists when the repository is started.
                    </xs:documentation>
                </xs:annotation>
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="initial-content" type="initial-content" minOccurs="0" maxOccurs="1">
                            <xs:annotation>
                                <xs:documentation>The path to the file which should be imported as initial content for this
                                    workspace
                                </xs:documentation>
                            </xs:annotation>
                        </xs:element>
                    </xs:sequence>
                    <xs:attribute name="name" type="xs:string" use="required">
                        <xs:annotation>
                            <xs:documentation>The name of the workspace.</xs:documentation>
                        </xs:annotation>
                    </xs:attribute>
                </xs:complexType>
            </xs:element>
            <xs:element name="initial-content" type="initial-content" minOccurs="0" maxOccurs="1">
                <xs:annotation>
                    <xs:documentation>The path to the file which should be imported as initial content by default for all new
                        workspaces
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
        <xs:attribute name="default-workspace" type="xs:string" use="optional" default="default">
            <xs:annotation>
                <xs:documentation>The name of the workspace that should be used when Sessions are created
                    without specifying an explicit workspace name.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="allow-workspace-creation" type="xs:boolean" use="optional" default="true">
            <xs:annotation>
                <xs:documentation>Specifies whether users can create additional workspaces beyond the predefined, system, and
                    default
                    workspaces. The default value is 'true'.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="cache-size" type="xs:integer" use="optional">
            <xs:annotation>
                <xs:documentation>
                   The maximum size of the workspace cache configuration. Must a positive integer. Defaults to 10k
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="journaling">
        <xs:annotation>
            <xs:documentation>The configuration for the change journal</xs:documentation>
        </xs:annotation>
        <xs:attribute name="enabled" type="xs:boolean" default="true">
            <xs:annotation>
                <xs:documentation>Whether the journal should be enabled or not. By default the journal is enabled.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="journal-relative-to" type="xs:string">
            <xs:annotation>
                <xs:documentation>The base directory in which to store journal contents. By default this path is jboss.server.data.dir/modeshape/repositoryName
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="journal-path" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>The folder within 'relative-to' where to store the journal contents.
                    If undefined, the path defaults to 'journal'.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="max-days-to-keep-records" type="xs:integer" use="optional" default="-1">
            <xs:annotation>
                <xs:documentation>The maximum number of days records should be kept on disk before removing them.
                    By default records are kept indefinitely.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="async-writes" type="xs:boolean" use="optional" default="false">
            <xs:annotation>
                <xs:documentation>Whether writes to disk should be done asynchronously or not.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="journal-gc-thread-pool" type="xs:string" use="optional" default="modeshape-journaling-gc">
            <xs:annotation>
                <xs:documentation>Name of the thread pool that should be used for removing older journal entries. This
                   is only useful when 'max-days-to-keep-records' has a positive value.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="journal-gc-initial-time" type="garbage-collection-initial-time-type" use="optional"
                      default="00:00">
            <xs:annotation>
                <xs:documentation>The local time that the first garbage collection process should be run.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="node-types">
        <xs:sequence minOccurs="0" maxOccurs="unbounded">
            <xs:element name="node-type" type="xs:string" minOccurs="1" maxOccurs="unbounded">
                <xs:annotation>
                    <xs:documentation>The uri of a CND file which will be loaded at repository startup</xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:simpleType name="initial-content">
        <xs:annotation>
            <xs:documentation>Specifies the path to the initial content file that should be loaded</xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string"/>
    </xs:simpleType>

    <xs:complexType name="authenticators">
        <xs:sequence minOccurs="0" maxOccurs="unbounded">
            <xs:element name="authenticator" type="authenticator" minOccurs="0" maxOccurs="unbounded">
                <xs:annotation>
                    <xs:documentation>The definition of an authenticator.</xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="authenticator">
        <xs:attributeGroup ref="implementation-class-attributes"/>
        <xs:attribute name="name" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>The name of the authenticator.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:anyAttribute namespace="##any" processContents="lax"/>
    </xs:complexType>

    <xs:complexType name="index-providers">
        <xs:sequence minOccurs="0" maxOccurs="unbounded">
            <xs:element name="index-provider" type="index-provider" minOccurs="0" maxOccurs="unbounded">
                <xs:annotation>
                    <xs:documentation>The definition of an index provider.</xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="db-persistence">
        <xs:attribute name="table-name" type="xs:string" use="optional" default="MODESHAPE_REPOSITORY">
            <xs:annotation>
                <xs:documentation>The name of the DB table where persistence data will be stored</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="create-on-start" type="xs:boolean" use="optional" default="true">
            <xs:annotation>
                <xs:documentation>Whether the DB table should be created at startup if it does not already exist</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="drop-on-exit" type="xs:boolean" use="optional" default="false">
            <xs:annotation>
                <xs:documentation>Whether the DB table should be dropped when the repository shuts down</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="fetch-size" type="xs:integer" use="optional" default="1000">
            <xs:annotation>
                <xs:documentation>The JDBC fetch size when loading data</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="url" type="xs:string" use="optional" default="jdbc:h2:mem:modeshape;DB_CLOSE_DELAY=0;">
            <xs:annotation>
                <xs:documentation>The DB connection URL. Either this or the datasource JNDI name should be set</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="driver" type="xs:string" use="optional" default="org.h2.Driver" >
            <xs:annotation>
                <xs:documentation>The fully qualified JDBC driver name</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="username" type="xs:string" use="optional" default="sa" >
            <xs:annotation>
                <xs:documentation>The username used for the JDBC connection authentication</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="password" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>The password used for the JDBC connection authentication</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="data-source-jndi-name" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>
                    Specifies the JNDI name of the JDBC data source that should be used to store the repository data.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="compress" type="xs:boolean" use="optional" default="false">
            <xs:annotation>
                <xs:documentation>Whether binary data stored in the database should be compressed or not</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="pool-size" type="xs:integer" use="optional" >
            <xs:annotation>
                <xs:documentation>The maximum size of the DB connection pool</xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="file-persistence">
        <xs:attribute name="path" type="xs:string" use="optional" default="${jboss.server.data.dir}/modeshape">
            <xs:annotation>
                <xs:documentation>
                    The absolute path on the FS where the repository data should be persisted. If not specified,
                    defaults to ${jboss.server.data.dir}/modeshape/${repository.name}
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="compress" type="xs:boolean" use="optional" default="true">
            <xs:annotation>
                <xs:documentation>
                    Whether data stored on disk should be compressed or not.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="custom-persistence">
        <xs:attribute name="type" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>The type of persistence</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="module" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>The name of the module containing the implementation class.</xs:documentation>
            </xs:annotation>
        </xs:attribute>        
        <xs:anyAttribute namespace="##any" processContents="lax"/>
    </xs:complexType>

    <xs:complexType name="index-provider">
        <xs:attributeGroup ref="implementation-class-attributes"/>
        <xs:attribute name="name" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>The name of the index-provider.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:anyAttribute namespace="##any" processContents="lax"/>
    </xs:complexType>

    <xs:complexType name="indexes">
        <xs:sequence minOccurs="0" maxOccurs="unbounded">
            <xs:element name="index" type="index-definition" minOccurs="0" maxOccurs="unbounded">
                <xs:annotation>
                    <xs:documentation>The definition of an index.</xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="index-definition">
        <xs:attribute name="name" type="xs:string">
            <xs:annotation>
                <xs:documentation>The name of the index.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="provider-name" type="xs:string">
            <xs:annotation>
                <xs:documentation>The name of the index provider. If there is no provider with the given name, then this
                  index will be disabled.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="kind" type="index-kind-enum" default="value">
            <xs:annotation>
                <xs:documentation>The kind of the index.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="synchronous" type="xs:boolean" default="true">
            <xs:annotation>
                <xs:documentation>Whether the index is updated synchronously within the save calls.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="node-type" type="xs:string" default="nt:base">
            <xs:annotation>
                <xs:documentation>The name of the node type to which this index applies. This index will include only those
                   nodes of this type.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="columns" type="xs:string">
            <xs:annotation>
                <xs:documentation>A comma-separated list of column definitions, where each column definition consists of a 
                   property name and in parentheses the property type. For example, 'jcr:mixin(STRING)' is a column definition 
                   that specifies the 'jcr:mixin' property and 'STRING' type.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="workspaces" type="xs:string">
            <xs:annotation>
                <xs:documentation>
                    The regular expression pattern that stipulates which workspaces this index is to be used for. 
                    By default, the pattern is '*', which means all workspaces. A literal string will match the exact workspace name. 
                    Any workspaces that do not match this pattern will not use this index.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:anyAttribute namespace="##any" processContents="lax"/>
    </xs:complexType>

    <xs:complexType name="reindexing">
        <xs:attribute name="async" type="xs:boolean" default="true">
            <xs:annotation>
                <xs:documentation>Whether the reindexing is performed asynchronously or not. Defaults to 'true'.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="mode" type="reindexing-mode" default="if_missing">
            <xs:annotation>
                <xs:documentation>
                    The type of reindexing to be performed: 'incremental' will only reindex the nodes which have been changed
                    since the last successful update of each provider, by using the journal.'if_missing' will reindex all the
                    content from the repository only if there is at least one out-of-date index for any provider.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="sequencers">
        <xs:sequence minOccurs="0" maxOccurs="unbounded">
            <xs:element name="sequencer" type="sequencer" minOccurs="0" maxOccurs="unbounded">
                <xs:annotation>
                    <xs:documentation>The definition of a sequencer.</xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
        <xs:attribute name="thread-pool-name" type="xs:string" use="optional" default="modeshape-sequencer">
            <xs:annotation>
                <xs:documentation>The name of the thread pool that generates sequencing threads.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="max-pool-size" type="xs:integer" use="optional" default="10">
            <xs:annotation>
                <xs:documentation>The maximum number of sequencing threads that can be spawned at the same time</xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="sequencer">
        <xs:sequence minOccurs="0" maxOccurs="unbounded">
            <xs:element name="path-expression" minOccurs="0" maxOccurs="unbounded">
                <xs:annotation>
                    <xs:documentation>An expression specifying the pattern for the input path of the properties to be sequenced
                        and the resulting output location.
                    </xs:documentation>
                </xs:annotation>
                <xs:simpleType>
                    <xs:restriction base="xs:string"/>
                </xs:simpleType>
            </xs:element>
        </xs:sequence>
        <xs:attributeGroup ref="implementation-class-attributes"/>
        <xs:attribute name="name" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>The name of the sequencer.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="path-expression" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>The description of the sequencer.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:anyAttribute namespace="##any" processContents="lax"/>
    </xs:complexType>

    <xs:complexType name="external-sources">
        <xs:sequence minOccurs="0" maxOccurs="unbounded">
            <xs:element name="source" type="source" minOccurs="0" maxOccurs="unbounded">
                <xs:annotation>
                    <xs:documentation>The definition of an external source.</xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="source">
        <xs:sequence minOccurs="0" maxOccurs="unbounded">
            <xs:element name="projection" minOccurs="0" maxOccurs="unbounded">
                <xs:annotation>
                    <xs:documentation>An expressions that describes a projection path expression, in the format
                        wsName:/projectedPath => externalPath
                    </xs:documentation>
                </xs:annotation>
                <xs:simpleType>
                    <xs:restriction base="xs:string"/>
                </xs:simpleType>
            </xs:element>
        </xs:sequence>
        <xs:attribute name="name" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>The name of the external source.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attributeGroup ref="implementation-class-attributes"/>
        <xs:attribute name="cacheable" type="xs:boolean" use="optional" default="true">
            <xs:annotation>
                <xs:documentation>
                    Whether nodes exposed by this external source should be cached by the repository or not. By default all
                    nodes are cached but certain external sources may want to prevent this and implement their own caching in 
                    order to avoid exposing stale data.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="readonly" type="xs:boolean" use="optional" default="false">
            <xs:annotation>
                <xs:documentation>Flag which indicates whether the external source is readonly or supports writing as well. By
                    default, a source support both reads and writes.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="exposeAsWorkspace" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>The name of the workspace exposing this external source.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>        
        <xs:attribute name="queryable" type="xs:boolean" use="optional" default="true">
            <xs:annotation>
                <xs:documentation>Flag which indicates whether the entire external content provided by this source should be
                    queryable or not by the repository. By default, it is.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:anyAttribute namespace="##any" processContents="lax"/>
    </xs:complexType>

    <xs:complexType name="text-extractors">
        <xs:sequence minOccurs="0" maxOccurs="unbounded">
            <xs:element name="text-extractor" type="text-extractor" minOccurs="0" maxOccurs="unbounded">
                <xs:annotation>
                    <xs:documentation>The definition of a text extractor.</xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
        <xs:attribute name="thread-pool-name" type="xs:string" use="optional" default="modeshape-text-extractor">
            <xs:annotation>
                <xs:documentation>The name of the thread pool that generates text extraction threads.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="max-pool-size" type="xs:integer" use="optional" default="5">
            <xs:annotation>
                <xs:documentation>The maximum number of text extraction threads that can be spawned at the same time</xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="text-extractor">
        <xs:attributeGroup ref="implementation-class-attributes"/>
        <xs:attribute name="name" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>The name of the extractor.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:anyAttribute namespace="##any" processContents="lax"/>
    </xs:complexType>

    <xs:complexType name="transient-binary-storage">
        <xs:attributeGroup ref="binary-storage-attributes"/>
    </xs:complexType>

    <xs:complexType name="file-binary-storage">
        <xs:attributeGroup ref="file-storage-attributes"/>
        <xs:attributeGroup ref="binary-storage-attributes"/>
    </xs:complexType>
   
     <xs:complexType name="cassandra-binary-storage">
        <xs:attributeGroup ref="cassandra-storage-attributes"/>
        <xs:attributeGroup ref="binary-storage-attributes"/>
    </xs:complexType>

    <xs:complexType name="mongo-binary-storage">
        <xs:attributeGroup ref="mongo-storage-attributes"/>
        <xs:attributeGroup ref="binary-storage-attributes"/>
    </xs:complexType>

    <xs:complexType name="s3-binary-storage">
        <xs:attributeGroup ref="s3-storage-attributes"/>
        <xs:attributeGroup ref="binary-storage-attributes"/>
    </xs:complexType>

    <xs:complexType name="nested-file-binary-storage">
        <xs:attributeGroup ref="file-storage-attributes"/>
        <xs:attributeGroup ref="nested-binary-storage-attributes"/>
    </xs:complexType>

    <xs:complexType name="db-binary-storage">
        <xs:attributeGroup ref="binary-storage-attributes"/>
        <xs:attribute name="data-source-jndi-name" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>Specifies the JNDI name of the JDBC data source that should be used to store the
                    binary values.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="nested-db-binary-storage">
        <xs:attributeGroup ref="nested-binary-storage-attributes"/>
        <xs:attribute name="data-source-jndi-name" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>Specifies the JNDI name of the JDBC data source that should be used to store the
                    binary values.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="custom-binary-storage">
        <xs:attributeGroup ref="implementation-class-attributes"/>
        <xs:attributeGroup ref="binary-storage-attributes"/>
        <xs:anyAttribute namespace="##any" processContents="lax"/>
    </xs:complexType>

    <xs:complexType name="nested-custom-binary-storage">
        <xs:attributeGroup ref="implementation-class-attributes"/>
        <xs:attributeGroup ref="nested-binary-storage-attributes"/>
        <xs:anyAttribute namespace="##any" processContents="lax"/>
    </xs:complexType>

    <xs:complexType name="composite-binary-storage">
        <xs:sequence minOccurs="1" maxOccurs="unbounded">
            <xs:choice minOccurs="1" maxOccurs="1">
                <xs:element name="file-binary-storage" type="nested-file-binary-storage">
                    <xs:annotation>
                        <xs:documentation>The binary files are stored on the local file system.</xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="db-binary-storage" type="nested-db-binary-storage">
                    <xs:annotation>
                        <xs:documentation>The binary files are stored in a relational database.</xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="custom-binary-storage" type="nested-custom-binary-storage">
                    <xs:annotation>
                        <xs:documentation>The binary files are stored in a custom system.</xs:documentation>
                    </xs:annotation>
                </xs:element>
            </xs:choice>
        </xs:sequence>
        <xs:attributeGroup ref="binary-storage-attributes"/>
    </xs:complexType>

    <!-- Global attribute groups -->

    <xs:attributeGroup name="implementation-class-attributes">
        <xs:attribute name="classname" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>The name of the Java implementation class.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="module" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>The name of the module containing the implementation class.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:attributeGroup>

    <xs:attributeGroup name="binary-storage-attributes">
        <xs:attribute name="min-value-size" type="xs:int" use="optional" default="4096">
            <xs:annotation>
                <xs:documentation>The size threshold that dictates whether binary values
                    should be stored in the binary store. Binary values smaller than this
                    value are stored with the node, whereas binary values with a size equal
                    to or greater than this limit will be stored separately from the node and in the
                    binary store, keyed by the SHA-1 hash of the value. This is a space and performance
                    optimization that stores each unique large value only once.
                    The default value is '4096' bytes, or 4 kilobytes.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="min-string-size" type="xs:int" use="optional">
            <xs:annotation>
                <xs:documentation>The size threshold that dictates whether String values
                    should be stored in the binary store. String values smaller than this
                    value are stored with the node, whereas string values with a size equal
                    to or greater than this limit will be stored separately from the node and in the
                    binary store, keyed by the SHA-1 hash of the value. This is a space and performance
                    optimization that stores each unique large value only once.
                    The default value is the value of 'min-value-size'.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>  
        <xs:attribute name="mime-type-detection" type="mime-type-detection" use="optional" default="content">
            <xs:annotation>
                <xs:documentation>
                    The mime type detector to use when automatically determining and setting the mimeType property
                    on mix:mimeType types. The possible values are: 'content' meaning the binary content (header) should be
                    read and mime-type determined based on that; 'name' only the name of the node which owns the binary property
                    should be taken into account; 'none' no mime type detection is performed.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:attributeGroup>

    <xs:attributeGroup name="nested-binary-storage-attributes">
        <xs:attribute name="store-name" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>A unique name for the binary store.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:attributeGroup>

    <xs:attributeGroup name="file-storage-attributes">
        <xs:attribute name="relative-to" type="xs:string" default="jboss.server.data.dir">
            <xs:annotation>
                <xs:documentation>The base directory in which to store the binary values.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="path" type="xs:string">
            <xs:annotation>
                <xs:documentation>This option defines the path on the file system
                    where the binary values are to be stored.
                    If specified, the value must be a valid path to a writable directory
                    on the file system, relative to the location indicated by the "relative-to" attribute.
                    If the path specifies a non-existant location, the
                    repository may attempt to create the missing directories.
                    If the specified location is not a readable and writable
                    directory (or cannot be created as such), then this will
                    generate an exception when the repository is created.
                    If undefined, the path defaults to 'modeshape/{repositoryName}/binaries'.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute> 
        <xs:attribute name="trash" type="xs:string">
            <xs:annotation>
                <xs:documentation>This option defines the path on the file system
                    where unused binary values are to be stored until completely removed from disk.
                    If specified, the value must be a valid path to a writable directory
                    on the file system, relative to the location indicated by the "relative-to" attribute.
                    If the path specifies a non-existant location, the
                    repository may attempt to create the missing directories.
                    If the specified location is not a readable and writable
                    directory (or cannot be created as such), then this will
                    generate an exception when the repository is created.
                    If undefined, the path defaults to 'modeshape/{repositoryName}/binaries/trash'.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:attributeGroup>
    <xs:attributeGroup name="cassandra-storage-attributes">
        <xs:attribute name="host" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>The address of the Cassandra server to connect to</xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:attributeGroup> 
    <xs:attributeGroup name="mongo-storage-attributes">
        <xs:attribute name="host" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>The MongoDB host name</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="port" type="xs:integer" use="required">
            <xs:annotation>
                <xs:documentation>The MongoDB port number</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="database" type="xs:string" default="ModeShape_BinaryStore" use="optional">
            <xs:annotation>
                <xs:documentation>The MongoDB database name where binaries will be stored</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="username" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>The DB user name</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="password" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>The DB user password</xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:attributeGroup>
    <xs:attributeGroup name="s3-storage-attributes">
        <xs:attribute name="username" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>The user name</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="password" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>The user password</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="bucket-name" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>The bucket name</xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:attributeGroup>
    <!-- Global simple types -->
    <xs:simpleType name="garbage-collection-initial-time-type">
        <xs:restriction base="xs:string">
            <xs:pattern value="(([0-1]\d)|([2][0-3])):[0-5]\d"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="document-optimization-initial-time-type">
        <xs:restriction base="xs:string">
            <xs:pattern value="(([0-1]\d)|([2][0-3])):[0-5]\d"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="roleNames">
        <xs:annotation>
            <xs:documentation>A list of role names.</xs:documentation>
        </xs:annotation>
        <xs:list itemType="xs:string"/>
    </xs:simpleType>
    <xs:simpleType name="index-kind-enum">
        <xs:restriction base="xs:string">
            <xs:enumeration value="value"/>
            <xs:enumeration value="unique"/>
            <xs:enumeration value="enumerated"/>
            <xs:enumeration value="text"/>
            <xs:enumeration value="nodetype"/>
        </xs:restriction>
    </xs:simpleType> 
    <xs:simpleType name="cluster-locking-enum">
        <xs:restriction base="xs:string">
            <xs:enumeration value="jgroups"/>
            <xs:enumeration value="db"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="reindexing-mode">
        <xs:restriction base="xs:string">
            <xs:enumeration value="incremental"/>
            <xs:enumeration value="if_missing"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="mime-type-detection">
        <xs:restriction base="xs:string">
            <xs:enumeration value="content"/>
            <xs:enumeration value="name"/>
            <xs:enumeration value="none"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>
   
 
