<grammar 
    xmlns="http://relaxng.org/ns/structure/1.0"
    xmlns:zope="http://namespaces.zope.org/zope"
    xmlns:browser="http://namespaces.zope.org/browser"
    xmlns:gts="http://namespaces.zope.org/gts" 
    xmlns:event="http://namespaces.zope.org/event"
    xmlns:help="http://namespaces.zope.org/help"
    xmlns:fssync="http://namespaces.zope.org/fssync"
    xmlns:meta="http://namespaces.zope.org/meta"
    xmlns:server-control="http://namespaces.zope.org/server-control"
    xmlns:tales="http://namespaces.zope.org/tales"
    xmlns:xmlrpc="http://namespaces.zope.org/xmlrpc"
    xmlns:rdb="http://namespaces.zope.org/rdb"
    xmlns:dav="http://namespaces.zope.org/dav"
    xmlns:workflow="http://namespaces.zope.org/workflow"
    xmlns:mail="http://namespaces.zope.org/mail"
    xmlns:xml="http://namespaces.zope.org/xml"
    xmlns:startup="http://namespaces.zope.org/startup"
    xmlns:code="http://namespaces.zope.org/code"
    xmlns:renderer="http://namespaces.zope.org/renderer">

  <start>
    <element name="zope:configure">
      <optional>
        <attribute name="i18n_domain" />
      </optional>
      <optional>
        <attribute name="package" />
      </optional>
      <ref name="configure_content" />
    </element>
  </start>

  <define name="sub_configure">
    <element name="zope:configure">
      <optional>
        <attribute name="i18n_domain" />
       </optional>
      <ref name="configure_content" />
    </element>
  </define>

  <define name="configure_content">
      <zeroOrMore>
      <choice>
        <!-- can nest this apparently to do i18n_domains -->
        <ref name="sub_configure" />

        <!-- core zcml namespace -->
        <ref name="include" />
        <ref name="includeOverrides" />
        <ref name="grant" />
        <ref name="principal" />
        <ref name="unauthenticatedPrincipal" />
        <ref name="role" />
        <!-- <ref name="permission" /> --> 
        <ref name="serviceType" />
        <ref name="content" />
        <ref name="adapter" />
        <ref name="view" />
        <ref name="defaultView" />
        <ref name="utility" />
        <ref name="service" />
        <ref name="class" />
        <ref name="hook" />
        <ref name="interface" />
        <ref name="permission" />
        <ref name="securityPolicy" />
        <ref name="factory" />
        <ref name="traversalNamespace" />
        <ref name="vocabulary" />

        <!-- browser -->
        <ref name="browser_defaultView" />
        <ref name="addform" />
        <ref name="editform" />
        <ref name="page" />
        <ref name="pages" />
        <ref name="menu" />
        <ref name="menuItem" />
        <ref name="menuItems" />
        <ref name="browser_view" />
        <ref name="icon" />
        <ref name="skin" />
        <ref name="resource" />
        
        <!-- help -->
        <ref name="register" />
        
        <!-- fssync -->
        <ref name="fssync_adapter" />

        <!-- gts -->      
        <ref name="registerTranslations" />
        <ref name="defaultLanguages" />

        <!-- event -->
        <ref name="subscribe" />
 
        <!-- meta -->
        <ref name="directives" />
        <ref name="top_directive" />

        <!-- server-control -->
        <ref name="registerShutdownHook" />

        <!-- tales -->
        <ref name="namespace" />

        <!-- xmlrpc -->
        <ref name="xmlrpc_view" />
        <ref name="xmlrpc_defaultView" />

        <!-- rdb -->
        <ref name="provideConnection" />

        <!-- dav -->
        <ref name="provideInterface" />

        <!-- workflow -->
        <ref name="importHandler" />
        <ref name="exportHandler" />

        <!-- mail -->
        <ref name="queuedService" />
        <ref name="directService" />
        <ref name="sendmailMailer" />
        <ref name="smtpMailer" />
 
        <!-- xml -->
        <ref name="schemaInterface" />

        <!-- startup -->
        <ref name="registerServerType" />
        <ref name="registerRequestFactory" />

        <!-- code -->
        <ref name="registerInterpreter" />

        <!-- renderer -->
        <ref name="sourcetype" />
        <ref name="renderer" />

      </choice>
      </zeroOrMore>
  </define>

  <!-- zcml -->

  <define name="include">
    <element name="zope:include">
      <optional>
        <!-- defaults to '.' package -->
        <attribute name="package" />
      </optional>
      <optional>
        <!-- defaults to 'configure.zcml' -->
        <attribute name="file" />
      </optional>
    </element>
  </define>

  <define name="includeOverrides">
    <element name="zope:includeOverrides">
      <attribute name="file" />
    </element>
  </define>

  <define name="grant">
    <element name="zope:grant">
      <optional>
        <attribute name="permission" />
      </optional>
      <optional>
        <attribute name="role" />
      </optional>
      <optional>
        <attribute name="principal" />
      </optional>
    </element>
  </define>

  <define name="principal">
    <element name="zope:principal">
      <attribute name="id" />
      <attribute name="title" />
      <optional>
        <attribute name="description" />
      </optional>
      <attribute name="login" />
      <attribute name="password" />
    </element>
  </define>

  <define name="unauthenticatedPrincipal">
    <element name="zope:unauthenticatedPrincipal">
      <attribute name="id" />
      <attribute name="title" />
    </element>
  </define>

  <define name="role">
    <element name="zope:role">
      <attribute name="id" />
      <attribute name="title" />
      <optional>
        <attribute name="description" />
      </optional>
    </element>
  </define>

  <define name="serviceType">
    <element name="zope:serviceType">
      <attribute name="id" />
      <attribute name="interface" />
    </element>
  </define>

  <define name="content">
    <element name="zope:content">
      <attribute name="class" />
      <interleave>
        <optional>
          <!-- perhaps mandatory? -->
          <element name="zope:factory">
            <optional>
              <attribute name="permission" />
            </optional>
            <optional>
              <attribute name="id" />
            </optional>
            <optional>
              <attribute name="title" />
            </optional>
            <optional>
              <attribute name="description" />
            </optional>
          </element>
        </optional>
        <zeroOrMore>
          <element name="zope:allow">
            <optional>
              <attribute name="interface" />
            </optional>
            <optional>
              <attribute name="attributes" />
            </optional>
          </element>
        </zeroOrMore>
        <zeroOrMore>
          <element name="zope:implements">
            <attribute name="interface" />
          </element>
        </zeroOrMore>
        <zeroOrMore>
          <ref name="require" />
        </zeroOrMore>
        </interleave>
    </element>
  </define>

  <define name="adapter">
    <element name="zope:adapter">
      <attribute name="for" />
      <attribute name="factory" />
      <attribute name="provides" />
      <optional>
        <attribute name="name" />
      </optional>
      <optional>
        <attribute name="permission" />
      </optional>
    </element>
  </define>

  <define name="view">
    <element name="zope:view">
      <attribute name="for" />
      <attribute name="name" />
      <attribute name="factory" />
      <attribute name="type" />
      <optional>
        <attribute name="permission" />
      </optional>
      <optional>
        <attribute name="allowed_interface" />
      </optional>
      <optional>
        <attribute name="allowed_attributes" />
      </optional>
    </element>
  </define>

  <define name="defaultView">
    <element name="zope:defaultView">
      <attribute name="for" />
      <attribute name="type" />
      <attribute name="name" />
      <attribute name="permission" />
      <attribute name="factory" />
      <optional>
        <attribute name="allowed_attributes" />
      </optional>
    </element>
  </define>

  <define name="utility">
    <element name="zope:utility">
      <attribute name="provides" />
      <optional>
        <attribute name="permission" />
      </optional>
      <optional>
        <attribute name="factory" />
      </optional>
      <optional>
        <attribute name="component" />
      </optional>
    </element>
  </define>

  <define name="service">
    <element name="zope:service">
      <attribute name="serviceType" />
      <attribute name="component" />
      <optional>
        <attribute name="permission" />
      </optional>
    </element>
  </define>

  <define name="hook">
    <element name="zope:hook">
      <attribute name="module" />
      <attribute name="name" />
      <attribute name="implementation" />
    </element>
  </define>

  <define name="interface">
    <element name="zope:interface">
      <attribute name="interface" />
    </element>
  </define>

  <define name="class">
    <element name="zope:class">
      <attribute name="class" />
      <ref name="require" />
    </element>
  </define>

  <define name="permission">
     <element name="zope:permission">
       <attribute name="id" />
       <attribute name="title" />
       <optional>
         <attribute name="description" />
       </optional>
     </element>
  </define>

  <define name="securityPolicy">
     <element name="zope:securityPolicy">
       <attribute name="component" />
     </element>
  </define>

  <define name="require">
    <element name="zope:require">
      <choice>
         <ref name="require_normal" />
         <ref name="require_like_class" />
      </choice>
     </element>
  </define>
  
  <define name="traversalNamespace">
    <element name="zope:traversalNamespace">
      <attribute name="name" />
      <attribute name="handler" />
    </element>
  </define>

  <define name="vocabulary">
    <element name="zope:vocabulary">
      <attribute name="name" />
      <attribute name="factory" />
      <optional>
        <attribute name="filter" />
      </optional>
      <optional>
        <attribute name="another" />
      </optional>
    </element>
  </define>

  <define name="require_normal">
    <attribute name="permission" />
      <optional>
        <attribute name="attributes" />
      </optional>
      <optional>
        <attribute name="interface" />
      </optional>
      <!-- XXX ? -->
      <optional>
        <attribute name="set_schema" />
      </optional>
      <optional>
        <attribute name="set_attributes" />
      </optional>
  </define>

  <define name="require_like_class">
    <attribute name="like_class" />
  </define>

  <define name="factory">
    <element name="zope:factory">
      <attribute name="component" />
      <attribute name="id" />
    </element>
  </define>

  
  <!-- browser -->
  <define name="browser_defaultView">
    <element name="browser:defaultView">
      <attribute name="name" />
      <optional>
        <attribute name="for" />
      </optional>
    </element>
  </define>

  <define name="addform">
    <element name="browser:addform">
      <attribute name="name" />
      <attribute name="schema" />
      <attribute name="permission" />
      <attribute name="content_factory" />
      <optional>
        <attribute name="menu" />
      </optional>
      <optional>
        <attribute name="for" />
      </optional>
      <optional>
        <attribute name="arguments" />
      </optional>
      <optional>
        <attribute name="keyword_arguments" />
      </optional>
      <optional>
        <attribute name="fields" />
      </optional>
      <optional>
        <attribute name="class" />
      </optional>
      <optional>
        <attribute name="label" />
      </optional>
      <optional>
        <attribute name="title" />
      </optional>
      <optional>
        <!-- XXX used anywhere? -->
        <attribute name="set_before_add" />
      </optional>
      <optional>
        <attribute name="set_after_add" />
      </optional>
      <optional>
        <attribute name="description" />
      </optional>
    </element>
  </define>

  <define name="editform">
    <element name="browser:editform">
      <attribute name="schema" />
      <attribute name="name" />
      <attribute name="permission" />
      <optional>
        <attribute name="menu" />
      </optional>
      <optional>
        <attribute name="for" />
      </optional>
      <optional>
        <attribute name="title" />
      </optional>
      <optional>
        <attribute name="template" />
      </optional>
      <optional>
        <attribute name="label" />
      </optional>
      <optional> 
        <attribute name="class" />
      </optional>
      <optional>
        <attribute name="fields" />
      </optional>
    </element>
  </define>

  <define name="menu">
    <element name="browser:menu">
      <attribute name="id" />
      <attribute name="title" />
      <optional>
        <attribute name="usage" />
      </optional>
    </element>
  </define>

  <define name="menuItem">
    <element name="browser:menuItem">
      <attribute name="menu" />
      <attribute name="for" />
      <attribute name="title" />
      <attribute name="action" />
      <optional>
        <attribute name="permission" />
      </optional>
      <optional>
        <attribute name="description" />
      </optional>
      <optional>
        <attribute name="filter" />
      </optional>
    </element>
  </define>

  <define name="menuItems">
    <element name="browser:menuItems">
      <attribute name="for" />
      <attribute name="menu" />
      <oneOrMore>
        <element name="browser:menuItem">
          <attribute name="title" />
          <attribute name="action" />
          <optional>
            <attribute name="filter" />
          </optional>
          <optional>
            <attribute name="permission" />
          </optional>
        </element>
      </oneOrMore>
    </element>
  </define>

  <define name="pages">
    <element name="browser:pages">
      <attribute name="for" />
      <attribute name="class" />
      <attribute name="permission" />
      <oneOrMore>
        <ref name="subpage" />
      </oneOrMore>
    </element>
  </define>

  <define name="browser_view">
    <element name="browser:view">
      <attribute name="for" />
      <attribute name="name" />
      <attribute name="class" />
      <attribute name="permission" />
      <optional>
        <attribute name="menu" />
      </optional>
      <optional>
        <attribute name="allowed_attributes" />
      </optional>
      <optional>
        <attribute name="title" />
      </optional>
      <zeroOrMore>
        <ref name="subpage" />
      </zeroOrMore>
    </element>
  </define>

  <define name="subpage">
    <element name="browser:page">
      <attribute name="name" />
      <optional>
        <attribute name="attribute" />
      </optional>
      <optional>
        <attribute name="template" />
      </optional>
      <optional>
        <attribute name="title" />
      </optional>
      <optional>
        <attribute name="menu" />
      </optional>
    </element>
  </define>

  <!-- XXX page directive defined in a different way if it's subpage -->
  <define name="page">
    <element name="browser:page">
      <attribute name="name" />
      <attribute name="for" />
      <attribute name="permission" />
      <optional>
        <attribute name="class" />
      </optional>
      <optional>
        <attribute name="title" />
      </optional>
      <optional>
        <attribute name="menu" />
      </optional>
      <optional>
        <attribute name="attribute" />
      </optional>
      <optional>
        <attribute name="template" />
      </optional>
      <optional>
        <attribute name="allowed_interface" />
      </optional>
      <optional>
        <attribute name="allowed_attributes" />
      </optional>
      <optional>
        <attribute name="layer" />
      </optional>
    </element>
  </define>

  <define name="icon">
    <element name="browser:icon">
      <attribute name="name" />
      <attribute name="for" />
      <attribute name="file" />
    </element>
  </define>

  <define name="skin">
    <element name="browser:skin">
      <attribute name="name" />
      <attribute name="layers" />
    </element>
  </define>

  <define name="resource">
    <element name="browser:resource">
      <attribute name="name" />
      <attribute name="file" />
      <optional>
        <attribute name="layer" />
      </optional>
    </element>
  </define>

  <!-- help -->
  <define name="register">
    <element name="help:register">
      <attribute name="id" />
      <attribute name="title" />
      <attribute name="doc_path" />
      <optional>
        <attribute name="for" />
      </optional>
      <optional>
        <attribute name="view" />
      </optional>
      <optional>
        <attribute name="parent" />
      </optional>
    </element>
  </define>

  <!-- fssync -->
  <define name="fssync_adapter">
    <element name="fssync:adapter">
      <attribute name="factory" />
      <optional>
        <attribute name="class" />
      </optional>
    </element>
  </define>

 
  <!-- gts -->
  <define name="registerTranslations">
    <element name="gts:registerTranslations">
      <attribute name="directory" />
    </element>
  </define>

  <define name="defaultLanguages">
    <element name="gts:defaultLanguages">
      <attribute name="languages" />
    </element>
  </define>

  <!-- event -->
  <define name="subscribe">
    <element name="event:subscribe">
      <attribute name="subscriber" />
      <attribute name="event_types" />
    </element>
  </define>

  <!-- meta -->

  <define name="top_directive">
    <element name="meta:directive">
      <attribute name="namespace" />
      <attribute name="name" />
      <attribute name="schema" />
      <attribute name="handler" />
    </element>
  </define>

  <define name="directives">
    <element name="meta:directives">
      <attribute name="namespace" />
      <oneOrMore>
        <choice>
          <ref name="directive" />
          <ref name="complexDirective" />
        </choice>
      </oneOrMore>
    </element>
  </define>

  <define name="directive">
    <element name="meta:directive">
      <attribute name="name" />
      <attribute name="schema" />
      <attribute name="handler" />
    </element>
  </define>

  <define name="complexDirective">
    <element name="meta:complexDirective">
      <attribute name="name" />
      <attribute name="schema" />
      <attribute name="handler" />
      <zeroOrMore>
        <ref name="subdirective" />
      </zeroOrMore>
    </element>
  </define>

  <define name="subdirective">
    <element name="meta:subdirective">
      <attribute name="name" />
      <attribute name="schema" />
     </element>
  </define>

  <!-- server-control -->
  <define name="registerShutdownHook">
    <element name="server-control:registerShutdownHook">
      <attribute name="name" />
      <attribute name="priority" />
      <attribute name="call" />
    </element>
  </define>

  <!-- tales -->
  <define name="namespace">
    <element name="tales:namespace">
      <attribute name="prefix" />
      <attribute name="interface" />
    </element>
  </define>

  <!-- xmlrpc -->
  <define name="xmlrpc_view">
    <element name="xmlrpc:view">
      <attribute name="name" />
      <attribute name="for" />
      <optional>
        <attribute name="class" />
      </optional>
      <optional>
        <attribute name="permission" />
      </optional>
      <optional>
        <attribute name="allowed_interface" />
      </optional>
      <optional>
        <attribute name="allowed_attributes" />
      </optional>
      <optional>
        <attribute name="factory" />
      </optional>
    </element>
  </define>

  <define name="xmlrpc_defaultView">
    <element name="xmlrpc:defaultView">
      <attribute name="name" />
      <attribute name="for" />
    </element>
  </define>

  <!-- rdb -->
  <define name="provideConnection">
    <element name="rdb:provideConnection">
      <attribute name="name" />
      <attribute name="component" />
      <attribute name="dsn" />
    </element>
  </define> 

  <!-- dav -->
  <define name="provideInterface">
    <element name="dav:provideInterface">
      <attribute name="for" />
      <attribute name="interface" />
    </element>
  </define>

  <!-- workflow -->
  <define name="importHandler">
    <element name="workflow:importHandler">
      <attribute name="interface" />
      <attribute name="factory" />
    </element>
  </define>

  <define name="exportHandler">
    <element name="workflow:exportHandler">
      <attribute name="interface" />
      <attribute name="factory" />
    </element>
  </define>

  <!-- mail -->
  <define name="queuedService">
    <element name="mail:queuedService">  
      <attribute name="name" />
      <attribute name="queuePath" />
      <attribute name="mailer" />
      <attribute name="permission" />
    </element>
  </define>

  <define name="directService"> 
    <element name="mail:directService">
      <attribute name="name" />
      <attribute name="mailer" />
      <attribute name="permission" />
    </element>
  </define>

  <define name="sendmailMailer">
    <element name="mail:sendmailMailer">
       <attribute name="id" />
       <optional>
         <attribute name="command" />
       </optional>
    </element>
  </define>

  <define name="smtpMailer">
    <element name="mail:smtpMailer">
      <attribute name="id" />
      <attribute name="hostname" />
      <optional>
        <attribute name="port" />
      </optional>
      <optional>
        <attribute name="username" />
      </optional>
      <optional>
        <attribute name="password" />
      </optional>
    </element>
  </define>

  <!-- xml -->
  <define name="schemaInterface">
    <element name="xml:schemaInterface">
      <attribute name="uri" />
    </element>
  </define>

  <!-- startup -->
  <define name="registerServerType">
    <element name="startup:registerServerType">
      <attribute name="name" />
      <attribute name="factory" />
      <attribute name="requestFactory" />
      <attribute name="logFactory" />
      <attribute name="defaultPort" />
      <attribute name="defaultVerbose" />
    </element>
 </define>

  <define name="registerRequestFactory"> 
    <element name="startup:registerRequestFactory">
      <attribute name="name" />
      <optional> 
        <attribute name="publication" />
      </optional>
      <optional>
        <attribute name="factory" />
      </optional>
      <optional>
        <attribute name="request" />
      </optional>
    </element>
  </define>

  <!-- code -->
  <define name="registerInterpreter">
    <element name="code:registerInterpreter">
      <attribute name="type" />
      <attribute name="component" />
    </element>
  </define>

  <!-- renderer -->
  <define name="sourcetype">
    <element name="renderer:sourcetype">
      <attribute name="title" />
      <attribute name="interface" />
      <attribute name="class" />
    </element>
  </define>
  
  <define name="renderer">
    <element name="renderer:renderer">
      <!-- XXX different case spelling for sourceType/sourcetype here -->
      <attribute name="sourceType" />
      <attribute name="for" />
      <attribute name="factory" />
    </element>
  </define>
 
</grammar>

