You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rg...@apache.org on 2007/01/04 09:33:51 UTC

svn commit: r492450 [4/5] - in /incubator/qpid/branches/new_persistence: java/ java/broker/src/main/java/org/apache/qpid/server/ java/broker/src/main/java/org/apache/qpid/server/queue/ java/client/src/main/java/org/apache/qpid/client/ java/cluster/src/...

Added: incubator/qpid/branches/new_persistence/specs/amqp.0-9.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/new_persistence/specs/amqp.0-9.xml?view=auto&rev=492450
==============================================================================
--- incubator/qpid/branches/new_persistence/specs/amqp.0-9.xml (added)
+++ incubator/qpid/branches/new_persistence/specs/amqp.0-9.xml Thu Jan  4 00:33:50 2007
@@ -0,0 +1,5185 @@
+<?xml version = "1.0"?>
+
+<!--
+    EDITORS: (PH)   Pieter Hintjens <ph...@imatix.com>
+    (KvdR) Kim van der Riet <ki...@redhat.com>
+
+    These editors have been assigned by the AMQP working group.
+    Please do not edit/commit this file without consulting with
+    one of the above editors.
+    ========================================================
+
+    TODOs
+        - see TODO comments in the text
+-->
+
+<!--
+    Copyright Notice
+    ================
+    (c) Copyright JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc.,
+    iMatix Corporation, IONA\ufffd Technologies, Red Hat, Inc.,
+    TWIST Process Innovations, and 29West Inc. 2006. All rights reserved.
+    
+    License
+    =======
+    JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc., iMatix 
+    Corporation, IONA Technologies, Red Hat, Inc., TWIST Process Innovations, and 
+    29West Inc. (collectively, the "Authors") each hereby grants to you a worldwide,
+    perpetual, royalty-free, nontransferable, nonexclusive license to
+    (i) copy, display, distribute and implement the Advanced Messaging Queue Protocol
+    ("AMQP") Specification and (ii) the Licensed Claims that are held by
+    the Authors, all for the purpose of implementing the Advanced Messaging
+    Queue Protocol Specification. Your license and any rights under this
+    Agreement will terminate immediately without notice from
+    any Author if you bring any claim, suit, demand, or action related to
+    the Advanced Messaging Queue Protocol Specification against any Author.
+    Upon termination, you shall destroy all copies of the Advanced Messaging
+    Queue Protocol Specification in your possession or control.
+
+    As used hereunder, "Licensed Claims" means those claims of a patent or
+    patent application, throughout the world, excluding design patents and
+    design registrations, owned or controlled, or that can be sublicensed
+    without fee and in compliance with the requirements of this
+    Agreement, by an Author or its affiliates now or at any
+    future time and which would necessarily be infringed by implementation
+    of the Advanced Messaging Queue Protocol Specification. A claim is
+    necessarily infringed hereunder only when it is not possible to avoid
+    infringing it because there is no plausible non-infringing alternative
+    for implementing the required portions of the Advanced Messaging Queue
+    Protocol Specification. Notwithstanding the foregoing, Licensed Claims
+    shall not include any claims other than as set forth above even if
+    contained in the same patent as Licensed Claims; or that read solely
+    on any implementations of any portion of the Advanced Messaging Queue
+    Protocol Specification that are not required by the Advanced Messaging
+    Queue Protocol Specification, or that, if licensed, would require a
+    payment of royalties by the licensor to unaffiliated third parties.
+    Moreover, Licensed Claims shall not include (i) any enabling technologies
+    that may be necessary to make or use any Licensed Product but are not
+    themselves expressly set forth in the Advanced Messaging Queue Protocol
+    Specification (e.g., semiconductor manufacturing technology, compiler
+    technology, object oriented technology, networking technology, operating
+    system technology, and the like); or (ii) the implementation of other
+    published standards developed elsewhere and merely referred to in the
+    body of the Advanced Messaging Queue Protocol Specification, or
+    (iii) any Licensed Product and any combinations thereof the purpose or
+    function of which is not required for compliance with the Advanced
+    Messaging Queue Protocol Specification. For purposes of this definition,
+    the Advanced Messaging Queue Protocol Specification shall be deemed to
+    include both architectural and interconnection requirements essential
+    for interoperability and may also include supporting source code artifacts
+    where such architectural, interconnection requirements and source code
+    artifacts are expressly identified as being required or documentation to
+    achieve compliance with the Advanced Messaging Queue Protocol Specification.
+    
+    As used hereunder, "Licensed Products" means only those specific portions
+    of products (hardware, software or combinations thereof) that implement
+    and are compliant with all relevant portions of the Advanced Messaging
+    Queue Protocol Specification.
+    
+    The following disclaimers, which you hereby also acknowledge as to any
+    use you may make of the Advanced Messaging Queue Protocol Specification:
+    
+    THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION IS PROVIDED "AS IS,"
+    AND THE AUTHORS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+    IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE
+    CONTENTS OF THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION ARE
+    SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF THE ADVANCED
+    MESSAGING QUEUE PROTOCOL SPECIFICATION WILL NOT INFRINGE ANY THIRD PARTY 
+    PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+    
+    THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL,
+    INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO ANY
+    USE, IMPLEMENTATION OR DISTRIBUTION OF THE ADVANCED MESSAGING QUEUE
+    PROTOCOL SPECIFICATION.
+    
+    The name and trademarks of the Authors may NOT be used in any manner,
+    including advertising or publicity pertaining to the Advanced Messaging
+    Queue Protocol Specification or its contents without specific, written
+    prior permission. Title to copyright in the Advanced Messaging Queue
+    Protocol Specification will at all times remain with the Authors.
+    
+    No other rights are granted by implication, estoppel or otherwise.
+    
+    Upon termination of your license or rights under this Agreement, you
+    shall destroy all copies of the Advanced Messaging Queue Protocol
+    Specification in your possession or control.
+    
+    Trademarks
+    ==========
+    "JPMorgan", "JPMorgan Chase", "Chase", the JPMorgan Chase logo and the
+    Octagon Symbol are trademarks of JPMorgan Chase & Co.
+    
+    IMATIX and the iMatix logo are trademarks of iMatix Corporation sprl.
+    
+    IONA, IONA Technologies, and the IONA logos are trademarks of IONA
+    Technologies PLC and/or its subsidiaries.
+    
+    LINUX is a trademark of Linus Torvalds. RED HAT and JBOSS are registered
+    trademarks of Red Hat, Inc. in the US and other countries.
+    
+    Java, all Java-based trademarks and OpenOffice.org are trademarks of
+    Sun Microsystems, Inc. in the United States, other countries, or both.
+    
+    Other company, product, or service names may be trademarks or service
+    marks of others.
+    
+    Links to full AMQP specification:
+    =================================
+    http://www.envoytech.org/spec/amq/
+    http://www.iona.com/opensource/amqp/
+    http://www.redhat.com/solutions/specifications/amqp/
+    http://www.twiststandards.org/tiki-index.php?page=AMQ
+    http://www.imatix.com/amqp
+-->
+
+<!--
+    <!DOCTYPE amqp SYSTEM "amqp.dtd">
+-->
+
+<!-- XML Notes
+
+    We use entities to indicate repetition; attributes to indicate properties.
+
+    We use the 'name' attribute as an identifier, usually within the context
+    of the surrounding entities.
+
+    We use spaces to seperate words in names, so that we can print names in
+    their natural form depending on the context - underlines for source code,
+    hyphens for written text, etc.
+
+    We do not enforce any particular validation mechanism but we support all
+    mechanisms.  The protocol definition conforms to a formal grammar that is
+    published seperately in several technologies.
+
+ -->
+
+<amqp major = "0" minor = "9" port = "5672" comment = "AMQ Protocol version 0-9">
+  <!--
+      ======================================================
+      ==       CONSTANTS
+      ======================================================
+  -->
+  <!-- Frame types -->
+  <constant name = "frame-method"     value = "1" />
+  <constant name = "frame-header"     value = "2" />
+  <constant name = "frame-body"       value = "3" />
+  <constant name = "frame-oob-method" value = "4" />
+  <constant name = "frame-oob-header" value = "5" />
+  <constant name = "frame-oob-body"   value = "6" />
+  <constant name = "frame-trace"      value = "7" />
+  <constant name = "frame-heartbeat"  value = "8" />
+
+  <!-- Protocol constants -->
+  <constant name = "frame-min-size"   value = "4096" />
+  <constant name = "frame-end"        value = "206" />
+
+  <!-- Reply codes -->
+  <constant name = "reply-success" value = "200">
+    <doc>
+      Indicates that the method completed successfully. This reply code is
+      reserved for future use - the current protocol design does not use positive
+      confirmation and reply codes are sent only in case of an error.
+    </doc>
+  </constant>
+
+  <constant name = "not-delivered" value = "310" class = "soft-error">
+    <doc>
+      The client asked for a specific message that is no longer available.
+      The message was delivered to another client, or was purged from the queue
+      for some other reason.
+    </doc>
+  </constant>
+
+  <constant name = "content-too-large" value = "311" class = "soft-error">
+    <doc>
+      The client attempted to transfer content larger than the server could accept
+      at the present time. The client may retry at a later time.
+    </doc>
+  </constant>
+
+  <constant name = "no-route" value = "312" class = "soft-error">
+    <doc>
+      When the exchange cannot route the result of a .Publish, most likely due
+      to an invalid routing key. Only when the mandatory flag is set.
+    </doc>
+  </constant>
+
+  <constant name = "no-consumers" value = "313" class = "soft-error">
+    <doc>
+      When the exchange cannot deliver to a consumer when the immediate flag is
+      set. As a result of pending data on the queue or the absence of any
+      consumers of the queue.
+    </doc>
+  </constant>
+
+  <constant name = "connection-forced" value = "320" class = "hard-error">
+    <doc>
+      An operator intervened to close the connection for some reason. The client
+      may retry at some later date.
+    </doc>
+  </constant>
+
+  <constant name = "invalid-path" value = "402" class = "hard-error">
+    <doc>
+      The client tried to work with an unknown virtual host.
+    </doc>
+  </constant>
+
+  <constant name = "access-refused" value = "403" class = "soft-error">
+    <doc>
+      The client attempted to work with a server entity to which it has no
+      access due to security settings.
+    </doc>
+  </constant>
+
+  <constant name = "not-found" value = "404" class = "soft-error">
+    <doc>The client attempted to work with a server entity that does not exist.</doc>
+  </constant>
+
+  <constant name = "resource-locked" value = "405" class = "soft-error">
+    <doc>
+      The client attempted to work with a server entity to which it has no
+      access because another client is working with it.
+    </doc>
+  </constant>
+
+  <constant name = "precondition-failed" value = "406" class = "soft-error">
+    <doc>
+      The client requested a method that was not allowed because some precondition
+      failed.
+    </doc>
+  </constant>
+
+  <constant name = "frame-error" value = "501" class = "hard-error">
+    <doc>
+      The client sent a malformed frame that the server could not decode. This
+      strongly implies a programming error in the client.
+    </doc>
+  </constant>
+
+  <constant name = "syntax-error" value = "502" class = "hard-error">
+    <doc>
+      The client sent a frame that contained illegal values for one or more
+      fields. This strongly implies a programming error in the client.
+    </doc>
+  </constant>
+
+  <constant name = "command-invalid" value = "503" class = "hard-error">
+    <doc>
+      The client sent an invalid sequence of frames, attempting to perform an
+      operation that was considered invalid by the server. This usually implies
+      a programming error in the client.
+    </doc>
+  </constant>
+
+  <constant name = "channel-error" value = "504" class = "hard-error">
+    <doc>
+      The client attempted to work with a channel that had not been correctly
+      opened. This most likely indicates a fault in the client layer.
+    </doc>
+  </constant>
+
+  <constant name = "resource-error" value = "506" class = "hard-error">
+    <doc>
+      The server could not complete the method because it lacked sufficient
+      resources. This may be due to the client creating too many of some type
+      of entity.
+    </doc>
+  </constant>
+
+  <constant name = "not-allowed" value = "530" class = "hard-error">
+    <doc>
+      The client tried to work with some entity in a manner that is prohibited
+      by the server, due to security settings or by some other criteria.
+    </doc>
+  </constant>
+
+  <constant name = "not-implemented" value = "540" class = "hard-error">
+    <doc>
+      The client tried to use functionality that is not implemented in the
+      server.
+    </doc>
+  </constant>
+
+  <constant name = "internal-error" value = "541" class = "hard-error">
+    <doc>
+      The server could not complete the method because of an internal error.
+      The server may require intervention by an operator in order to resume
+      normal operations.
+    </doc>
+  </constant>
+
+  <!--
+      ======================================================
+      ==       DOMAIN TYPES
+      ======================================================
+  -->
+
+  <domain name = "access-ticket" type = "short" label = "access ticket granted by server">
+    <doc>
+      An access ticket granted by the server for a certain set of access rights
+      within a specific realm. Access tickets are valid within the channel where
+      they were created, and expire when the channel closes.
+    </doc>
+    <assert check = "ne" value = "0" />
+  </domain>
+
+  <domain name = "class-id" type = "short" />
+
+  <domain name = "consumer-tag" type = "shortstr" label = "consumer tag">
+    <doc>
+      Identifier for the consumer, valid within the current connection.
+    </doc>
+  </domain>
+
+  <domain name = "delivery-tag" type = "longlong" label = "server-assigned delivery tag">
+    <doc>
+      The server-assigned and channel-specific delivery tag
+    </doc>
+    <rule name = "channel-local">
+      <doc>
+        The delivery tag is valid only within the channel from which the message was
+        received. I.e. a client MUST NOT receive a message on one channel and then
+        acknowledge it on another.
+      </doc>
+    </rule>
+    <rule name = "non-zero">
+      <doc>
+        The server MUST NOT use a zero value for delivery tags. Zero is reserved
+        for client use, meaning "all messages so far received".
+      </doc>
+    </rule>
+  </domain>
+
+  <domain name = "exchange-name" type = "shortstr" label = "exchange name">
+    <doc>
+      The exchange name is a client-selected string that identifies the exchange for publish
+      methods. Exchange names may consist of any mixture of digits, letters, and underscores.
+      Exchange names are scoped by the virtual host.
+    </doc>
+    <assert check = "length" value = "127" />
+  </domain>
+
+  <domain name = "known-hosts" type = "shortstr" label = "list of known hosts">
+    <doc>
+      Specifies the list of equivalent or alternative hosts that the server knows about,
+      which will normally include the current server itself. Clients can cache this
+      information and use it when reconnecting to a server after a failure.  This field
+      may be empty.
+    </doc>
+  </domain>
+
+  <domain name = "method-id" type = "short" />
+
+  <domain name = "no-ack" type = "bit" label = "no acknowledgement needed">
+    <doc>
+      If this field is set the server does not expect acknowledgements for
+      messages. That is, when a message is delivered to the client the server
+      automatically and silently acknowledges it on behalf of the client. This
+      functionality increases performance but at the cost of reliability.
+      Messages can get lost if a client dies before it can deliver them to the
+      application.
+    </doc>
+  </domain>
+
+  <domain name = "no-local" type = "bit" label = "do not deliver own messages">
+    <doc>
+      If the no-local field is set the server will not send messages to the connection that
+      published them.
+    </doc>
+  </domain>
+
+  <domain name = "path" type = "shortstr">
+    <doc>
+      Must start with a slash "/" and continue with path names separated by slashes. A path
+      name consists of any combination of at least one of [A-Za-z0-9] plus zero or more of
+      [.-_+!=:].
+    </doc>
+
+    <assert check = "notnull" />
+    <assert check = "syntax" rule = "path" />
+    <assert check = "length" value = "127" />
+  </domain>
+
+  <domain name = "peer-properties" type = "table">
+    <doc>
+      This string provides a set of peer properties, used for identification, debugging, and
+      general information.
+    </doc>
+  </domain>
+
+  <domain name = "queue-name" type = "shortstr" label = "queue name">
+    <doc>
+      The queue name identifies the queue within the vhost. Queue names may consist of any
+      mixture of digits, letters, and underscores.
+    </doc>
+    <assert check = "length" value = "127" />
+  </domain>
+
+  <domain name = "redelivered" type = "bit" label = "message is being redelivered">
+    <doc>
+      This indicates that the message has been previously delivered to this or
+      another client.
+    </doc>
+    <rule name = "implementation">
+      <doc>
+        The server SHOULD try to signal redelivered messages when it can. When
+        redelivering a message that was not successfully acknowledged, the server
+        SHOULD deliver it to the original client if possible.
+      </doc>
+      <doc type = "scenario">
+        Create a shared queue and publish a message to the queue.  Consume the
+        message using explicit acknowledgements, but do not acknowledge the
+        message.  Close the connection, reconnect, and consume from the queue
+        again.  The message should arrive with the redelivered flag set.
+      </doc>
+    </rule>
+    <rule name = "hinting">
+      <doc>
+        The client MUST NOT rely on the redelivered field but should take it as a
+        hint that the message may already have been processed. A fully robust
+        client must be able to track duplicate received messages on non-transacted,
+        and locally-transacted channels.
+      </doc>
+    </rule>
+  </domain>
+
+  <domain name = "reply-code" type = "short" label = "reply code from server">
+    <doc>
+      The reply code. The AMQ reply codes are defined as constants at the start
+      of this formal specification.
+    </doc>
+    <assert check = "notnull" />
+  </domain>
+
+  <domain name = "reply-text" type = "shortstr" label = "localised reply text">
+    <doc>
+      The localised reply text. This text can be logged as an aid to resolving
+      issues.
+    </doc>
+    <assert check = "notnull" />
+  </domain>
+
+  <domain name = "channel-id" type = "longstr" label = "unique identifier for a channel" />
+
+  <!-- Domains for the message class -->
+  <domain name = "duration" type = "longlong" label = "duration in milliseconds" />
+  <domain name = "offset" type = "longlong" label = "offset into a message body" />
+  <domain name = "reference" type = "longstr" label = "pointer to a message body" />
+  <domain name = "destination" type = "shortstr" label = "destination for a message">
+    <doc>
+      Specifies the destination to which the message is to be
+      transferred. The destination can be empty, meaning the
+      default exchange or consumer.
+    </doc>
+  </domain>
+  <domain name = "reject-code" type = "short" label = "reject code for transfer">
+    <rule name = "01">
+      <doc>
+        The reject code must be one of 0 (generic) or 1 (immediate
+        delivery was attempted but failed).
+      </doc>
+    </rule>
+  </domain>
+  <domain name = "reject-text" type = "shortstr" label = "informational text for message reject"/>
+  <domain name = "security-token" type = "longstr" label = "security token">
+    <doc>
+      Used for authentication, replay prevention, and encrypted bodies.
+    </doc>
+  </domain>
+
+  <!-- Elementary domains -->
+  <domain name = "bit"        type = "bit"       label = "single bit" />
+  <domain name = "octet"      type = "octet"     label = "single octet" />
+  <domain name = "short"      type = "short"     label = "16-bit integer" />
+  <domain name = "long"       type = "long"      label = "32-bit integer" />
+  <domain name = "longlong"   type = "longlong"  label = "64-bit integer" />
+  <domain name = "shortstr"   type = "shortstr"  label = "short string" />
+  <domain name = "longstr"    type = "longstr"   label = "long string" />
+  <domain name = "timestamp"  type = "timestamp" label = "64-bit timestamp" />
+  <domain name = "table"      type = "table"     label = "field table" />
+
+  <!-- ==  CONNECTION  ======================================================= -->
+
+  <!-- TODO 0.81 - the 'handler' attribute of methods needs to be reviewed, and if
+       no current implementations use it, removed. /PH 2006/07/20
+       -->
+
+  <class name = "connection" handler = "connection" index = "10" label = "work with socket connections">
+    <doc>
+      The connection class provides methods for a client to establish a network connection to
+      a server, and for both peers to operate the connection thereafter.
+    </doc>
+
+    <doc type = "grammar">
+      connection          = open-connection *use-connection close-connection
+      open-connection     = C:protocol-header
+                            S:START C:START-OK
+                            *challenge
+                            S:TUNE C:TUNE-OK
+                            C:OPEN S:OPEN-OK | S:REDIRECT
+      challenge           = S:SECURE C:SECURE-OK
+      use-connection      = *channel
+      close-connection    = C:CLOSE S:CLOSE-OK
+                          / S:CLOSE C:CLOSE-OK
+    </doc>
+
+    <chassis name = "server" implement = "MUST" />
+    <chassis name = "client" implement = "MUST" />
+
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+    <method name = "start" synchronous = "1" index = "10" label = "start connection negotiation">
+      <doc>
+        This method starts the connection negotiation process by telling the client the
+        protocol version that the server proposes, along with a list of security mechanisms
+        which the client can use for authentication.
+      </doc>
+
+      <rule name = "protocol-name">
+        <doc>
+          If the server cannot support the protocol specified in the protocol header,
+          it MUST close the socket connection without sending any response method.
+        </doc>
+        <doc type = "scenario">
+          The client sends a protocol header containing an invalid protocol name.
+          The server must respond by closing the connection.
+        </doc>
+      </rule>
+      <rule name = "server-support">
+        <doc>
+          The server MUST provide a protocol version that is lower than or equal to
+          that requested by the client in the protocol header.
+        </doc>
+        <doc type = "scenario">
+          The client requests a protocol version that is higher than any valid
+          implementation, e.g. 9.0.  The server must respond with a current
+          protocol version, e.g. 1.0.
+        </doc>
+      </rule>
+      <rule name = "client-support">
+        <doc>
+          If the client cannot handle the protocol version suggested by the server
+          it MUST close the socket connection.
+        </doc>
+        <doc type = "scenario">
+          The server sends a protocol version that is lower than any valid
+          implementation, e.g. 0.1.  The client must respond by closing the
+          connection.
+        </doc>
+      </rule>
+
+      <chassis name = "client" implement = "MUST" />
+      <response name = "start-ok" />
+
+      <field name = "version-major" domain = "octet" label = "protocol major version">
+        <doc>
+          The protocol version, major component, as transmitted in the AMQP protocol
+          header. This, combined with the protocol minor component fully describe the
+          protocol version, which is written in the format major-minor. Hence, with
+          major=1, minor=3, the protocol version would be "1-3".
+        </doc>
+      </field>
+
+      <field name = "version-minor" domain = "octet" label = "protocol minor version">
+        <doc>
+          The protocol version, minor component, as transmitted in the AMQP protocol
+          header. This, combined with the protocol major component fully describe the
+          protocol version, which is written in the format major-minor. Hence, with
+          major=1, minor=3, the protocol version would be "1-3".
+        </doc>
+      </field>
+
+      <field name = "server-properties" domain = "peer-properties" label = "server properties">
+        <rule name = "required-fields">
+          <doc>
+            The properties SHOULD contain at least these fields: "host", specifying the
+            server host name or address, "product", giving the name of the server product,
+            "version", giving the name of the server version, "platform", giving the name
+            of the operating system, "copyright", if appropriate, and "information", giving
+            other general information.
+          </doc>
+          <doc type = "scenario">
+            Client connects to server and inspects the server properties. It checks for
+            the presence of the required fields.
+          </doc>
+        </rule>
+      </field>
+
+      <field name = "mechanisms" domain = "longstr" label = "available security mechanisms">
+        <doc>
+          A list of the security mechanisms that the server supports, delimited by spaces.
+        </doc>
+        <assert check = "notnull" />
+      </field>
+
+      <field name = "locales" domain = "longstr" label = "available message locales">
+        <doc>
+          A list of the message locales that the server supports, delimited by spaces. The
+          locale defines the language in which the server will send reply texts.
+        </doc>
+        <rule name = "required-support">
+          <doc>
+            The server MUST support at least the en_US locale.
+          </doc>
+          <doc type = "scenario">
+            Client connects to server and inspects the locales field. It checks for
+            the presence of the required locale(s).
+          </doc>
+        </rule>
+        <assert check = "notnull" />
+      </field>
+    </method>
+
+    <method name = "start-ok" synchronous = "1" index = "11"
+      label = "select security mechanism and locale">
+      <doc>
+        This method selects a SASL security mechanism.
+      </doc>
+
+      <chassis name = "server" implement = "MUST" />
+
+      <field name = "client-properties" domain = "peer-properties" label = "client properties">
+        <rule name = "required-fields">
+          <!-- This rule is not testable from the client side -->
+          <doc>
+            The properties SHOULD contain at least these fields: "product", giving the name
+            of the client product, "version", giving the name of the client version, "platform",
+            giving the name of the operating system, "copyright", if appropriate, and
+            "information", giving other general information.
+          </doc>
+        </rule>
+      </field>
+
+      <field name = "mechanism" domain = "shortstr" label = "selected security mechanism">
+        <doc>
+          A single security mechanisms selected by the client, which must be one of those
+          specified by the server.
+        </doc>
+        <rule name = "security">
+          <doc>
+            The client SHOULD authenticate using the highest-level security profile it
+            can handle from the list provided by the server.
+          </doc>
+        </rule>
+        <rule name = "validity">
+          <doc>
+            If the mechanism field does not contain one of the security mechanisms
+            proposed by the server in the Start method, the server MUST close the
+            connection without sending any further data.
+          </doc>
+          <doc type = "scenario">
+            Client connects to server and sends an invalid security mechanism. The
+            server must respond by closing the connection (a socket close, with no
+            connection close negotiation).
+          </doc>
+        </rule>
+        <assert check = "notnull" />
+      </field>
+
+      <field name = "response" domain = "longstr" label = "security response data">
+        <doc>
+          A block of opaque data passed to the security mechanism. The contents of this
+          data are defined by the SASL security mechanism.
+        </doc>
+        <assert check = "notnull" />
+      </field>
+
+      <field name = "locale" domain = "shortstr" label = "selected message locale">
+        <doc>
+          A single message locale selected by the client, which must be one of those
+          specified by the server.
+        </doc>
+        <assert check = "notnull" />
+      </field>
+    </method>
+
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+    <method name = "secure" synchronous = "1" index = "20" label = "security mechanism challenge">
+      <doc>
+        The SASL protocol works by exchanging challenges and responses until both peers have
+        received sufficient information to authenticate each other. This method challenges
+        the client to provide more information.
+      </doc>
+
+      <chassis name = "client" implement = "MUST" />
+      <response name = "secure-ok" />
+
+      <field name = "challenge" domain = "longstr" label = "security challenge data">
+        <doc>
+          Challenge information, a block of opaque binary data passed to the security
+          mechanism.
+        </doc>
+      </field>
+    </method>
+
+    <method name = "secure-ok" synchronous = "1" index = "21" label = "security mechanism response">
+      <doc>
+        This method attempts to authenticate, passing a block of SASL data for the security
+        mechanism at the server side.
+      </doc>
+
+      <chassis name = "server" implement = "MUST" />
+
+      <field name = "response" domain = "longstr" label = "security response data">
+        <doc>
+          A block of opaque data passed to the security mechanism. The contents of this
+          data are defined by the SASL security mechanism.
+        </doc>
+        <assert check = "notnull" />
+      </field>
+    </method>
+
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+    <method name = "tune" synchronous = "1" index = "30"
+      label = "propose connection tuning parameters">
+      <doc>
+        This method proposes a set of connection configuration values to the client. The
+        client can accept and/or adjust these.
+      </doc>
+
+      <chassis name = "client" implement = "MUST" />
+
+      <response name = "tune-ok" />
+
+      <field name = "channel-max" domain = "short" label = "proposed maximum channels">
+        <doc>
+          The maximum total number of channels that the server allows per connection. Zero
+          means that the server does not impose a fixed limit, but the number of allowed
+          channels may be limited by available server resources.
+        </doc>
+      </field>
+
+      <field name = "frame-max" domain = "long" label = "proposed maximum frame size">
+        <doc>
+          The largest frame size that the server proposes for the connection. The client
+          can negotiate a lower value. Zero means that the server does not impose any
+          specific limit but may reject very large frames if it cannot allocate resources
+          for them.
+        </doc>
+        <rule name = "minimum">
+          <doc>
+            Until the frame-max has been negotiated, both peers MUST accept frames of up
+            to frame-min-size octets large, and the minimum negotiated value for frame-max
+            is also frame-min-size.
+          </doc>
+          <doc type = "scenario">
+            Client connects to server and sends a large properties field, creating a frame
+            of frame-min-size octets.  The server must accept this frame.
+          </doc>
+        </rule>
+      </field>
+
+      <field name = "heartbeat" domain = "short" label = "desired heartbeat delay">
+        <!-- TODO 0.82 - the heartbeat negotiation mechanism was changed during
+             implementation because the model documented here does not actually
+             work properly.  The best model we found is that the server proposes
+             a heartbeat value to the client; the client can reply with zero, meaning
+             'do not use heartbeats (as documented here), or can propose its own
+             heartbeat value, which the server should then accept.  This is different
+             from the model here which is disconnected - e.g. each side requests a
+             heartbeat independently.  Basically a connection is heartbeated in
+             both ways, or not at all, depending on whether both peers support
+             heartbeating or not, and the heartbeat value should itself be chosen
+             by the client so that remote links can get a higher value.  Also, the
+             actual heartbeat mechanism needs documentation, and is as follows: so
+             long as there is activity on a connection - in or out - both peers
+             assume the connection is active.  When there is no activity, each peer
+             must send heartbeat frames.  When no heartbeat frame is received after
+             N cycles (where N is at least 2), the connection can be considered to
+             have died. /PH 2006/07/19
+             -->
+        <doc>
+          The delay, in seconds, of the connection heartbeat that the server wants.
+          Zero means the server does not want a heartbeat.
+        </doc>
+      </field>
+    </method>
+
+    <method name = "tune-ok" synchronous = "1" index = "31"
+      label = "negotiate connection tuning parameters">
+      <doc>
+        This method sends the client's connection tuning parameters to the server.
+        Certain fields are negotiated, others provide capability information.
+      </doc>
+
+      <chassis name = "server" implement = "MUST" />
+
+      <field name = "channel-max" domain = "short" label = "negotiated maximum channels">
+        <doc>
+          The maximum total number of channels that the client will use per connection.
+        </doc>
+        <rule name = "upper-limit">
+          <doc>
+            If the client specifies a channel max that is higher than the value provided
+            by the server, the server MUST close the connection without attempting a
+            negotiated close.  The server may report the error in some fashion to assist
+            implementors.
+          </doc>
+        </rule>
+        <assert check = "notnull" />
+        <assert check = "le" method = "tune" field = "channel-max" />
+      </field>
+
+      <field name = "frame-max" domain = "long" label = "negotiated maximum frame size">
+        <doc>
+          The largest frame size that the client and server will use for the connection.
+          Zero means that the client does not impose any specific limit but may reject
+          very large frames if it cannot allocate resources for them. Note that the
+          frame-max limit applies principally to content frames, where large contents can
+          be broken into frames of arbitrary size.
+        </doc>
+        <rule name = "minimum">
+          <doc>
+            Until the frame-max has been negotiated, both peers MUST accept frames of up
+            to frame-min-size octets large, and the minimum negotiated value for frame-max
+            is also frame-min-size.
+          </doc>
+        </rule>
+        <rule name = "upper-limit">
+          <doc>
+            If the client specifies a frame max that is higher than the value provided
+            by the server, the server MUST close the connection without attempting a
+            negotiated close. The server may report the error in some fashion to assist
+            implementors.
+          </doc>
+        </rule>
+      </field>
+
+      <field name = "heartbeat" domain = "short" label = "desired heartbeat delay">
+        <doc>
+          The delay, in seconds, of the connection heartbeat that the client wants. Zero
+          means the client does not want a heartbeat.
+        </doc>
+      </field>
+    </method>
+
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+    <method name = "open" synchronous = "1" index = "40" label = "open connection to virtual host">
+      <doc>
+        This method opens a connection to a virtual host, which is a collection of
+        resources, and acts to separate multiple application domains within a server.
+        The server may apply arbitrary limits per virtual host, such as the number
+        of each type of entity that may be used, per connection and/or in total.
+      </doc>
+
+      <chassis name = "server" implement = "MUST" />
+      <response name = "open-ok" />
+      <response name = "redirect" />
+
+      <field name = "virtual-host" domain = "path" label = "virtual host name">
+        <!-- TODO 0.82 - the entire vhost model needs review. This concept was
+             prompted by the HTTP vhost concept but does not fit very well into
+             AMQP.  Currently we use the vhost as a "cluster identifier" which is
+             inaccurate usage. /PH 2006/07/19
+             -->
+        <assert check = "regexp" value = "^[a-zA-Z0-9/-_]+$" />
+        <doc>
+          The name of the virtual host to work with.
+        </doc>
+        <rule name = "separation">
+          <doc>
+            If the server supports multiple virtual hosts, it MUST enforce a full
+            separation of exchanges, queues, and all associated entities per virtual
+            host. An application, connected to a specific virtual host, MUST NOT be able
+            to access resources of another virtual host.
+          </doc>
+        </rule>
+        <rule name = "security">
+          <doc>
+            The server SHOULD verify that the client has permission to access the
+            specified virtual host.
+          </doc>
+        </rule>
+      </field>
+
+      <field name = "capabilities" domain = "shortstr" label = "required capabilities">
+        <doc>
+          The client can specify zero or more capability names, delimited by spaces.
+          The server can use this string to how to process the client's connection
+          request.
+        </doc>
+      </field>
+
+      <field name = "insist" domain = "bit" label = "insist on connecting to server">
+        <doc>
+          In a configuration with multiple collaborating servers, the server may respond
+          to a Connection.Open method with a Connection.Redirect. The insist option tells
+          the server that the client is insisting on a connection to the specified server.
+        </doc>
+        <rule name = "behaviour">
+          <doc>
+            When the client uses the insist option, the server MUST NOT respond with a
+            Connection.Redirect method.  If it cannot accept the client's connection
+            request it should respond by closing the connection with a suitable reply
+            code.
+          </doc>
+        </rule>
+      </field>
+    </method>
+
+    <method name = "open-ok" synchronous = "1" index = "41" label = "signal that connection is ready">
+      <doc>
+        This method signals to the client that the connection is ready for use.
+      </doc>
+      <chassis name = "client" implement = "MUST" />
+      <field name = "known-hosts" domain = "known-hosts" />
+    </method>
+
+    <method name = "redirect" synchronous = "1" index = "42" label = "redirects client to other server">
+      <doc>
+        This method redirects the client to another server, based on the requested virtual
+        host and/or capabilities.
+      </doc>
+      <rule name = "usage">
+        <doc>
+          When getting the Connection.Redirect method, the client SHOULD reconnect to
+          the host specified, and if that host is not present, to any of the hosts
+          specified in the known-hosts list.
+        </doc>
+      </rule>
+      <chassis name = "client" implement = "MUST" />
+      <field name = "host" domain = "shortstr" label = "server to connect to">
+        <doc>
+          Specifies the server to connect to. This is an IP address or a DNS name,
+          optionally followed by a colon and a port number. If no port number is
+          specified, the client should use the default port number for the protocol.
+        </doc>
+        <assert check = "notnull" />
+      </field>
+      <field name = "known-hosts" domain = "known-hosts" />
+    </method>
+
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+    <method name = "close" synchronous = "1" index = "50" label = "request a connection close">
+      <doc>
+        This method indicates that the sender wants to close the connection. This may be
+        due to internal conditions (e.g. a forced shut-down) or due to an error handling
+        a specific method, i.e. an exception. When a close is due to an exception, the
+        sender provides the class and method id of the method which caused the exception.
+      </doc>
+      <!-- TODO: the connection close mechanism needs to be reviewed from the ODF
+           documentation and better expressed as rules here. /PH 2006/07/20
+           -->
+      <rule name = "stability">
+        <doc>
+          After sending this method any received method except the Close-OK method MUST
+          be discarded.
+        </doc>
+      </rule>
+
+      <chassis name = "client" implement = "MUST" />
+      <chassis name = "server" implement = "MUST" />
+      <response name = "close-ok" />
+
+      <field name = "reply-code" domain = "reply-code" />
+      <field name = "reply-text" domain = "reply-text" />
+
+      <field name = "class-id" domain = "class-id" label = "failing method class">
+        <doc>
+          When the close is provoked by a method exception, this is the class of the
+          method.
+        </doc>
+      </field>
+
+      <field name = "method-id" domain = "method-id" label = "failing method ID">
+        <doc>
+          When the close is provoked by a method exception, this is the ID of the method.
+        </doc>
+      </field>
+    </method>
+
+    <method name = "close-ok" synchronous = "1" index = "51" label = "confirm a connection close">
+      <doc>
+        This method confirms a Connection.Close method and tells the recipient that it is
+        safe to release resources for the connection and close the socket.
+      </doc>
+      <rule name = "reporting">
+        <doc>
+          A peer that detects a socket closure without having received a Close-Ok
+          handshake method SHOULD log the error.
+        </doc>
+      </rule>
+      <chassis name = "client" implement = "MUST" />
+      <chassis name = "server" implement = "MUST" />
+    </method>
+  </class>
+
+  <!-- ==  CHANNEL  ========================================================== -->
+
+  <class name = "channel" handler = "channel" index = "20" label = "work with channels">
+    <doc>
+      The channel class provides methods for a client to establish a channel to a
+      server and for both peers to operate the channel thereafter.
+    </doc>
+
+    <doc type = "grammar">
+      channel             = open-channel *use-channel close-channel
+      open-channel        = C:OPEN S:OPEN-OK
+                          / C:RESUME S:OK
+      use-channel         = C:FLOW S:FLOW-OK
+                          / S:FLOW C:FLOW-OK
+                          / S:PING C:OK
+                          / C:PONG S:OK
+                          / C:PING S:OK
+                          / S:PONG C:OK
+                          / functional-class
+      close-channel       = C:CLOSE S:CLOSE-OK
+                          / S:CLOSE C:CLOSE-OK
+    </doc>
+
+    <chassis name = "server" implement = "MUST" />
+    <chassis name = "client" implement = "MUST" />
+
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+    <method name = "open" synchronous = "1" index = "10" label = "open a channel for use">
+      <doc>
+        This method opens a channel to the server.
+      </doc>
+      <rule name = "state" on-failure = "channel-error">
+        <doc>
+          The client MUST NOT use this method on an already-opened channel.
+        </doc>
+        <doc type = "scenario">
+          Client opens a channel and then reopens the same channel.
+        </doc>
+      </rule>
+      <chassis name = "server" implement = "MUST" />
+      <response name = "open-ok" />
+      <field name = "out-of-band" domain = "shortstr" label = "out-of-band settings">
+        <doc>
+          Configures out-of-band transfers on this channel. The syntax and meaning of this
+          field will be formally defined at a later date.
+        </doc>
+        <assert check = "null" />
+      </field>
+    </method>
+
+    <method name = "open-ok" synchronous = "1" index = "11" label = "signal that the channel is ready">
+      <doc>
+        This method signals to the client that the channel is ready for use.
+      </doc>
+      <chassis name = "client" implement = "MUST" />
+      <field name = "channel-id" domain = "channel-id" />
+    </method>
+
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+    <method name = "flow" synchronous = "1" index = "20" label = "enable/disable flow from peer">
+      <doc>
+        This method asks the peer to pause or restart the flow of content data. This is a
+        simple flow-control mechanism that a peer can use to avoid overflowing its queues or
+        otherwise finding itself receiving more messages than it can process. Note that this
+        method is not intended for window control. The peer that receives a disable flow
+        method should finish sending the current content frame, if any, then pause.
+      </doc>
+
+      <rule name = "initial-state">
+        <doc>
+          When a new channel is opened, it is active (flow is active). Some applications
+          assume that channels are inactive until started. To emulate this behaviour a
+          client MAY open the channel, then pause it.
+        </doc>
+      </rule>
+
+      <rule name = "bidirectional">
+        <doc>
+          When sending content frames, a peer SHOULD monitor the channel for incoming
+          methods and respond to a Channel.Flow as rapidly as possible.
+        </doc>
+      </rule>
+
+      <rule name = "throttling">
+        <doc>
+          A peer MAY use the Channel.Flow method to throttle incoming content data for
+          internal reasons, for example, when exchanging data over a slower connection.
+        </doc>
+      </rule>
+
+      <rule name = "expected-behaviour">
+        <doc>
+          The peer that requests a Channel.Flow method MAY disconnect and/or ban a peer
+          that does not respect the request.  This is to prevent badly-behaved clients
+          from overwhelming a broker.
+        </doc>
+      </rule>
+
+      <chassis name = "server" implement = "MUST" />
+      <chassis name = "client" implement = "MUST" />
+
+      <response name = "flow-ok" />
+
+      <field name = "active" domain = "bit" label = "start/stop content frames">
+        <doc>
+          If 1, the peer starts sending content frames. If 0, the peer stops sending
+          content frames.
+        </doc>
+      </field>
+    </method>
+
+    <method name = "flow-ok" index = "21" label = "confirm a flow method">
+      <doc>
+        Confirms to the peer that a flow command was received and processed.
+      </doc>
+      <chassis name = "server" implement = "MUST" />
+      <chassis name = "client" implement = "MUST" />
+      <field name = "active" domain = "bit" label = "current flow setting">
+        <doc>
+          Confirms the setting of the processed flow method: 1 means the peer will start
+          sending or continue to send content frames; 0 means it will not.
+        </doc>
+      </field>
+    </method>
+
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+    <method name = "close" synchronous = "1" index = "40" label = "request a channel close">
+      <doc>
+        This method indicates that the sender wants to close the channel. This may be due to
+        internal conditions (e.g. a forced shut-down) or due to an error handling a specific
+        method, i.e. an exception. When a close is due to an exception, the sender provides
+        the class and method id of the method which caused the exception.
+      </doc>
+
+      <!-- TODO: the channel close behaviour needs to be reviewed from the ODF
+           documentation and better expressed as rules here. /PH 2006/07/20
+           -->
+      <rule name = "stability">
+        <doc>
+          After sending this method any received method except the Close-OK method MUST
+          be discarded.
+        </doc>
+      </rule>
+
+      <chassis name = "client" implement = "MUST" />
+      <chassis name = "server" implement = "MUST" />
+      <response name = "close-ok" />
+
+      <field name = "reply-code" domain = "reply-code" />
+      <field name = "reply-text" domain = "reply-text" />
+
+      <field name = "class-id" domain = "class-id" label = "failing method class">
+        <doc>
+          When the close is provoked by a method exception, this is the class of the
+          method.
+        </doc>
+      </field>
+
+      <field name = "method-id" domain = "method-id" label = "failing method ID">
+        <doc>
+          When the close is provoked by a method exception, this is the ID of the method.
+        </doc>
+      </field>
+    </method>
+
+    <method name = "close-ok" synchronous = "1" index = "41" label = "confirm a channel close">
+      <doc>
+        This method confirms a Channel.Close method and tells the recipient that it is safe
+        to release resources for the channel.
+      </doc>
+      <rule name = "reporting">
+        <doc>
+          A peer that detects a socket closure without having received a Channel.Close-Ok
+          handshake method SHOULD log the error.
+        </doc>
+      </rule>
+      <chassis name = "client" implement = "MUST" />
+      <chassis name = "server" implement = "MUST" />
+    </method>
+
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+    <method name = "resume" index = "50" label = "resume an interrupted channel">
+      <doc>
+        This method resume a previously interrupted channel.
+      </doc>
+      <response name = "ok" />
+      <chassis name = "server" implement = "MAY" />
+      <field name = "channel-id" domain = "channel-id" />
+    </method>
+
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+    <method name = "ping" index = "60" label = "[WORK IN PROGRESS] initiates a pong">
+      <doc>
+        [WORK IN PROGRESS] Request that the recipient issue a pong request.
+      </doc>
+      <response name = "ok" />
+      <chassis name = "server" implement = "MUST" />
+      <chassis name = "client" implement = "MUST" />
+    </method>
+
+    <method name = "pong" index = "70" label = "[WORK IN PROGRESS] issued after receiving a ping">
+      <doc>
+        [WORK IN PROGRESS] Issued after a ping request is received. Note that this is a
+        request issued after receiving a ping, not a response to
+        receiving a ping.
+      </doc>
+      <response name = "ok" />
+      <chassis name = "server" implement = "MUST" />
+      <chassis name = "client" implement = "MUST" />
+    </method>
+
+    <method name = "ok" index = "80" label = "[WORK IN PROGRESS] signals normal completion">
+      <doc>
+        [WORK IN PROGRESS] Signals normal completion of a method.
+      </doc>
+      <chassis name = "server" implement = "MUST" />
+      <chassis name = "client" implement = "MUST" />
+    </method>
+  </class>
+
+  <!-- ==  ACCESS  =========================================================== -->
+
+  <!-- TODO 0.82 - this class must be implemented by two teams before we can
+       consider it matured.
+    -->
+
+  <class name = "access" handler = "connection" index = "30" label = "work with access tickets">
+    <doc>
+      The protocol control access to server resources using access tickets. A
+      client must explicitly request access tickets before doing work. An access
+      ticket grants a client the right to use a specific set of resources -
+      called a "realm" - in specific ways.
+    </doc>
+
+    <doc type = "grammar">
+      access              = C:REQUEST S:REQUEST-OK
+    </doc>
+
+    <chassis name = "server" implement = "MUST" />
+    <chassis name = "client" implement = "MUST" />
+
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+    <method name = "request" synchronous = "1" index = "10" label = "request an access ticket">
+      <doc>
+        This method requests an access ticket for an access realm. The server
+        responds by granting the access ticket. If the client does not have
+        access rights to the requested realm this causes a connection exception.
+        Access tickets are a per-channel resource.
+      </doc>
+
+      <chassis name = "server" implement = "MUST" />
+      <response name = "request-ok" />
+
+      <field name = "realm" domain = "shortstr" label = "name of requested realm">
+        <doc>
+          Specifies the name of the realm to which the client is requesting access.
+          The realm is a configured server-side object that collects a set of
+          resources (exchanges, queues, etc.).  If the channel has already requested
+          an access ticket onto this realm, the previous ticket is destroyed and a
+          new ticket is created with the requested access rights, if allowed.
+        </doc>
+        <rule name = "validity" on-failure = "access-refused">
+          <doc>
+            The client MUST specify a realm that is known to the server.  The server
+            makes an identical response for undefined realms as it does for realms
+            that are defined but inaccessible to this client.
+          </doc>
+          <doc type = "scenario">
+            Client specifies an undefined realm.
+          </doc>
+        </rule>
+      </field>
+
+      <field name = "exclusive" domain = "bit" label = "request exclusive access">
+        <doc>
+          Request exclusive access to the realm, meaning that this will be the only
+          channel that uses the realm's resources.
+        </doc>
+        <rule name = "validity" on-failure = "access-refused">
+          <doc>
+            The client MAY NOT request exclusive access to a realm that has active
+            access tickets, unless the same channel already had the only access
+            ticket onto that realm.
+          </doc>
+          <doc type = "scenario">
+            Client opens two channels and requests exclusive access to the same realm.
+          </doc>
+        </rule>
+      </field>
+      <field name = "passive" domain = "bit" label = "request passive access">
+        <doc>
+          Request message passive access to the specified access realm. Passive
+          access lets a client get information about resources in the realm but
+          not to make any changes to them.
+        </doc>
+      </field>
+      <field name = "active" domain = "bit" label = "request active access">
+        <doc>
+          Request message active access to the specified access realm. Active access lets
+          a client get create and delete resources in the realm.
+        </doc>
+      </field>
+      <field name = "write" domain = "bit" label = "request write access">
+        <doc>
+          Request write access to the specified access realm. Write access lets a client
+          publish messages to all exchanges in the realm.
+        </doc>
+      </field>
+      <field name = "read" domain = "bit" label = "request read access">
+        <doc>
+          Request read access to the specified access realm. Read access lets a client
+          consume messages from queues in the realm.
+        </doc>
+      </field>
+    </method>
+
+    <method name = "request-ok" synchronous = "1" index = "11" label = "grant access to server resources">
+      <doc>
+        This method provides the client with an access ticket. The access ticket is valid
+        within the current channel and for the lifespan of the channel.
+      </doc>
+      <rule name = "per-channel" on-failure = "not-allowed">
+        <doc>
+          The client MUST NOT use access tickets except within the same channel as
+          originally granted.
+        </doc>
+        <doc type = "scenario">
+          Client opens two channels, requests a ticket on one channel, and then
+          tries to use that ticket in a second channel.
+        </doc>
+      </rule>
+      <chassis name = "client" implement = "MUST" />
+      <field name = "ticket" domain = "access-ticket" />
+    </method>
+  </class>
+
+  <!-- ==  EXCHANGE  ========================================================= -->
+
+  <class name = "exchange" handler = "channel" index = "40" label = "work with exchanges">
+    <doc>
+      Exchanges match and distribute messages across queues. Exchanges can be configured in
+      the server or created at runtime.
+    </doc>
+
+    <doc type = "grammar">
+      exchange            = C:DECLARE  S:DECLARE-OK
+                          / C:DELETE   S:DELETE-OK
+    </doc>
+
+    <chassis name = "server" implement = "MUST" />
+    <chassis name = "client" implement = "MUST" />
+
+    <rule name = "required-types">
+      <doc>
+        The server MUST implement these standard exchange types: fanout, direct.
+      </doc>
+      <doc type = "scenario">
+        Client attempts to declare an exchange with each of these standard types.
+      </doc>
+    </rule>
+    <rule name = "recommended-types">
+      <doc>
+        The server SHOULD implement these standard exchange types: topic, headers.
+      </doc>
+      <doc type = "scenario">
+        Client attempts to declare an exchange with each of these standard types.
+      </doc>
+    </rule>
+    <rule name = "required-instances">
+      <doc>
+        The server MUST, in each virtual host, pre-declare an exchange instance
+        for each standard exchange type that it implements, where the name of the
+        exchange instance, if defined, is "amq." followed by the exchange type name.
+      </doc>
+      <doc>
+        The server MUST, in each virtual host, pre-declare at least two direct
+        exchange instances: one named "amq.direct", the other with no public name
+        that serves as a default  exchange for Publish methods.
+      </doc>
+      <doc type = "scenario">
+        Client creates a temporary queue and attempts to bind to each required
+        exchange instance ("amq.fanout", "amq.direct", "amq.topic", and "amq.headers"
+        if those types are defined).
+      </doc>
+    </rule>
+    <rule name = "default-exchange">
+      <doc>
+        The server MUST pre-declare a direct exchange with no public name to act as
+        the default exchange for content Publish methods and for default queue bindings.
+      </doc>
+      <doc type = "scenario">
+        Client checks that the default exchange is active by specifying a queue
+        binding with no exchange name, and publishing a message with a suitable
+        routing key but without specifying the exchange name, then ensuring that
+        the message arrives in the queue correctly.
+      </doc>
+    </rule>
+    <rule name = "default-access">
+      <doc>
+        The server MUST NOT allow clients to access the default exchange except
+        by specifying an empty exchange name in the Queue.Bind and content Publish
+        methods.
+      </doc>
+    </rule>
+    <rule name = "extensions">
+      <doc>
+        The server MAY implement other exchange types as wanted.
+      </doc>
+    </rule>
+
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+    <method name = "declare" synchronous = "1" index = "10" label = "verify exchange exists, create if needed">
+      <doc>
+        This method creates an exchange if it does not already exist, and if the exchange
+        exists, verifies that it is of the correct and expected class.
+      </doc>
+      <rule name = "minimum">
+        <doc>
+          The server SHOULD support a minimum of 16 exchanges per virtual host and
+          ideally, impose no limit except as defined by available resources.
+        </doc>
+        <doc type = "scenario">
+          The client creates as many exchanges as it can until the server reports
+          an error; the number of exchanges successfully created must be at least
+          sixteen.
+        </doc>
+      </rule>
+
+      <chassis name = "server" implement = "MUST" />
+      <response name = "declare-ok" />
+
+      <field name = "ticket" domain = "access-ticket">
+        <doc>
+          When a client defines a new exchange, this belongs to the access realm of the
+          ticket used. All further work done with that exchange must be done with an
+          access ticket for the same realm.
+        </doc>
+        <rule name = "validity" on-failure = "access-refused">
+          <doc>
+            The client MUST provide a valid access ticket giving "active" access to
+            the realm in which the exchange exists or will be created, or "passive"
+            access if the if-exists flag is set.
+          </doc>
+          <doc type = "scenario">
+            Client creates access ticket with wrong access rights and attempts to use
+            in this method.
+          </doc>
+        </rule>
+      </field>
+
+      <field name = "exchange" domain = "exchange-name">
+        <rule name = "reserved" on-failure = "access-refused">
+          <doc>
+            Exchange names starting with "amq." are reserved for pre-declared and
+            standardised exchanges. The client MUST NOT attempt to create an exchange
+            starting with "amq.".
+          </doc>
+          <doc type = "scenario">
+            TODO.
+          </doc>
+        </rule>
+        <assert check = "regexp" value = "^[a-zA-Z0-9-_.:]+$" />
+      </field>
+
+      <field name = "type" domain = "shortstr" label = "exchange type">
+        <doc>
+          Each exchange belongs to one of a set of exchange types implemented by the
+          server. The exchange types define the functionality of the exchange - i.e. how
+          messages are routed through it. It is not valid or meaningful to attempt to
+          change the type of an existing exchange.
+        </doc>
+        <rule name = "typed" on-failure = "not-allowed">
+          <doc>
+            Exchanges cannot be redeclared with different types.  The client MUST not
+            attempt to redeclare an existing exchange with a different type than used
+            in the original Exchange.Declare method.
+          </doc>
+          <doc type = "scenario">
+            TODO.
+          </doc>
+        </rule>
+        <rule name = "support" on-failure = "command-invalid">
+          <doc>
+            The client MUST NOT attempt to create an exchange with a type that the
+            server does not support.
+          </doc>
+          <doc type = "scenario">
+            TODO.
+          </doc>
+        </rule>
+        <assert check = "regexp" value = "^[a-zA-Z0-9-_.:]+$" />
+      </field>
+
+      <field name = "passive" domain = "bit" label = "do not create exchange">
+        <doc>
+          If set, the server will not create the exchange. The client can use this to
+          check whether an exchange exists without modifying the server state.
+        </doc>
+        <rule name = "not-found">
+          <doc>
+            If set, and the exchange does not already exist, the server MUST raise a
+            channel exception with reply code 404 (not found).
+          </doc>
+          <doc type = "scenario">
+            TODO.
+          </doc>
+        </rule>
+      </field>
+
+      <field name = "durable" domain = "bit" label = "request a durable exchange">
+        <doc>
+          If set when creating a new exchange, the exchange will be marked as durable.
+          Durable exchanges remain active when a server restarts. Non-durable exchanges
+          (transient exchanges) are purged if/when a server restarts.
+        </doc>
+        <rule name = "support">
+          <doc>
+            The server MUST support both durable and transient exchanges.
+          </doc>
+          <doc type = "scenario">
+            TODO.
+          </doc>
+        </rule>
+        <rule name = "sticky">
+          <doc>
+            The server MUST ignore the durable field if the exchange already exists.
+          </doc>
+          <doc type = "scenario">
+            TODO.
+          </doc>
+        </rule>
+      </field>
+
+      <!-- TODO 0.82 - clarify how this works; there is no way to cancel a binding
+           except by deleting a queue.
+         -->
+      <field name = "auto-delete" domain = "bit" label = "auto-delete when unused">
+        <doc>
+          If set, the exchange is deleted when all queues have finished using it.
+        </doc>
+        <rule name = "sticky">
+          <doc>
+            The server MUST ignore the auto-delete field if the exchange already
+            exists.
+          </doc>
+          <doc type = "scenario">
+            TODO.
+          </doc>
+        </rule>
+      </field>
+
+      <field name = "internal" domain = "bit" label = "create internal exchange">
+        <doc>
+          If set, the exchange may not be used directly by publishers, but only when bound
+          to other exchanges. Internal exchanges are used to construct wiring that is not
+          visible to applications.
+        </doc>
+      </field>
+
+      <field name = "nowait" domain = "bit" label = "do not send reply method">
+        <doc>
+          If set, the server will not respond to the method. The client should not wait
+          for a reply method. If the server could not complete the method it will raise a
+          channel or connection exception.
+        </doc>
+      </field>
+
+      <field name = "arguments" domain = "table" label = "arguments for declaration">
+        <doc>
+          A set of arguments for the declaration. The syntax and semantics of these
+          arguments depends on the server implementation. This field is ignored if passive
+          is 1.
+        </doc>
+      </field>
+    </method>
+
+    <method name = "declare-ok" synchronous = "1" index = "11" label = "confirm exchange declaration">
+      <doc>
+        This method confirms a Declare method and confirms the name of the exchange,
+        essential for automatically-named exchanges.
+      </doc>
+      <chassis name = "client" implement = "MUST" />
+    </method>
+
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+    <method name = "delete" synchronous = "1" index = "20" label = "delete an exchange">
+      <doc>
+        This method deletes an exchange. When an exchange is deleted all queue bindings on
+        the exchange are cancelled.
+      </doc>
+
+      <chassis name = "server" implement = "MUST" />
+      <response name = "delete-ok" />
+
+      <field name = "ticket" domain = "access-ticket">
+        <rule name = "validity" on-failure = "access-refused">
+          <doc>
+            The client MUST provide a valid access ticket giving "active" access
+            rights to the exchange's access realm.
+          </doc>
+          <doc type = "scenario">
+            Client creates access ticket with wrong access rights and attempts to use
+            in this method.
+          </doc>
+        </rule>
+      </field>
+
+      <field name = "exchange" domain = "exchange-name">
+        <rule name = "exists" on-failure = "not-found">
+          <doc>
+            The client MUST NOT attempt to delete an exchange that does not exist.
+          </doc>
+        </rule>
+        <assert check = "notnull" />
+      </field>
+
+      <!-- TODO 0.82 - discuss whether this option is useful or not.  I don't have
+           any real use case for it. /PH 2006-07-23.
+         -->
+      <field name = "if-unused" domain = "bit" label = "delete only if unused">
+        <doc>
+          If set, the server will only delete the exchange if it has no queue bindings. If
+          the exchange has queue bindings the server does not delete it but raises a
+          channel exception instead.
+        </doc>
+      </field>
+
+      <field name = "nowait" domain = "bit" label = "do not send a reply method">
+        <doc>
+          If set, the server will not respond to the method. The client should not wait
+          for a reply method. If the server could not complete the method it will raise a
+          channel or connection exception.
+        </doc>
+      </field>
+    </method>
+
+    <method name = "delete-ok" synchronous = "1" index = "21"
+      label = "confirm deletion of an exchange">
+      <doc>This method confirms the deletion of an exchange.</doc>
+      <chassis name = "client" implement = "MUST" />
+    </method>
+  </class>
+
+  <!-- ==  QUEUE  ============================================================ -->
+
+  <class name = "queue" handler = "channel" index = "50" label = "work with queues">
+    <doc>
+      Queues store and forward messages. Queues can be configured in the server or created at
+      runtime. Queues must be attached to at least one exchange in order to receive messages
+      from publishers.
+    </doc>
+
+    <doc type = "grammar">
+      queue               = C:DECLARE  S:DECLARE-OK
+                          / C:BIND     S:BIND-OK
+                          / C:PURGE    S:PURGE-OK
+                          / C:DELETE   S:DELETE-OK
+    </doc>
+
+    <chassis name = "server" implement = "MUST" />
+    <chassis name = "client" implement = "MUST" />
+
+    <rule name = "any-content">
+      <doc>
+        A server MUST allow any content class to be sent to any queue, in any mix, and
+        queue and deliver these content classes independently. Note that all methods
+        that fetch content off queues are specific to a given content class.
+      </doc>
+      <doc type = "scenario">
+        Client creates an exchange of each standard type and several queues that
+        it binds to each exchange. It must then successfully send each of the standard
+        content types to each of the available queues.
+      </doc>
+    </rule>
+
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+    <method name = "declare" synchronous = "1" index = "10" label = "declare queue, create if needed">
+      <doc>
+        This method creates or checks a queue. When creating a new queue the client can
+        specify various properties that control the durability of the queue and its
+        contents, and the level of sharing for the queue.
+      </doc>
+
+      <rule name = "default-binding">
+        <doc>
+          The server MUST create a default binding for a newly-created queue to the
+          default exchange, which is an exchange of type 'direct' and use the queue
+          name as the routing key.
+        </doc>
+        <doc type = "scenario">
+          Client creates a new queue, and then without explicitly binding it to an
+          exchange, attempts to send a message through the default exchange binding,
+          i.e. publish a message to the empty exchange, with the queue name as routing
+          key.
+        </doc>
+      </rule>
+
+      <!-- Rule test name: was "amq_queue_35" -->
+      <rule name = "minimum-queues">
+        <doc>
+          The server SHOULD support a minimum of 256 queues per virtual host and ideally,
+          impose no limit except as defined by available resources.
+        </doc>
+        <doc type = "scenario">
+          Client attempts to create as many queues as it can until the server reports
+          an error.  The resulting count must at least be 256.
+        </doc>
+      </rule>
+
+      <chassis name = "server" implement = "MUST" />
+      <response name = "declare-ok" />
+
+      <field name = "ticket" domain = "access-ticket">
+        <doc>
+          When a client defines a new queue, this belongs to the access realm of the
+          ticket used. All further work done with that queue must be done with an access
+          ticket for the same realm.
+        </doc>
+        <rule name = "validity" on-failure = "access-refused">
+          <doc>
+            The client MUST provide a valid access ticket giving "active" access to
+            the realm in which the queue exists or will be created.
+          </doc>
+          <doc type = "scenario">
+            Client creates access ticket with wrong access rights and attempts to use
+            in this method.
+          </doc>
+        </rule>
+      </field>
+
+      <field name = "queue" domain = "queue-name">
+        <rule name = "default-name">
+          <doc>
+            The queue name MAY be empty, in which case the server MUST create a new
+            queue with a unique generated name and return this to the client in the
+            Declare-Ok method.
+          </doc>
+          <doc type = "scenario">
+            Client attempts to create several queues with an empty name. The client then
+            verifies that the server-assigned names are unique and different.
+          </doc>
+        </rule>
+        <rule name = "reserved-prefix" on-failure = "not-allowed">
+          <doc>
+            Queue names starting with "amq." are reserved for pre-declared and
+            standardised server queues. A client MAY NOT attempt to declare a queue with a
+            name  that starts with "amq." and the passive option set to zero.
+          </doc>
+          <doc type = "scenario">
+            A client attempts to create a queue with a name starting with "amq." and with
+            the passive option set to zero.
+          </doc>
+        </rule>
+        <assert check = "regexp" value = "^[a-zA-Z0-9-_.:]*$" />
+      </field>
+
+      <field name = "passive" domain = "bit" label = "do not create queue">
+        <doc>
+          If set, the server will not create the queue. This field allows the client
+          to assert the presence of a queue without modifying the server state.
+        </doc>
+        <rule name = "passive" on-failure = "not-found">
+          <doc>
+            The client MAY ask the server to assert that a queue exists without
+            creating the queue if not.  If the queue does not exist, the server
+            treats this as a failure.
+          </doc>
+          <doc type = "scenario">
+            Client declares an existing queue with the passive option and expects
+            the server to respond with a declare-ok. Client then attempts to declare
+            a non-existent queue with the passive option, and the server must close
+            the channel with the correct reply-code.
+          </doc>
+        </rule>
+      </field>
+
+      <field name = "durable" domain = "bit" label = "request a durable queue">
+        <doc>
+          If set when creating a new queue, the queue will be marked as durable. Durable
+          queues remain active when a server restarts. Non-durable queues (transient
+          queues) are purged if/when a server restarts. Note that durable queues do not
+          necessarily hold persistent messages, although it does not make sense to send
+          persistent messages to a transient queue.
+        </doc>
+        <!-- Rule test name: was "amq_queue_03" -->
+        <rule name = "persistence">
+          <doc>The server MUST recreate the durable queue after a restart.</doc>
+
+          <!-- TODO: use 'client does something' rather than 'a client does something'. -->
+          <doc type = "scenario">
+            A client creates a durable queue. The server is then restarted. The client
+            then attempts to send a message to the queue. The message should be successfully
+            delivered.
+          </doc>
+        </rule>
+        <!-- Rule test name: was "amq_queue_36" -->
+        <rule name = "types">
+          <doc>The server MUST support both durable and transient queues.</doc>
+          <doc type = "scenario">
+            A client creates two named queues, one durable and one transient.
+          </doc>
+        </rule>
+        <!-- Rule test name: was "amq_queue_37" -->    
+        <rule name = "pre-existence">
+          <doc>The server MUST ignore the durable field if the queue already exists.</doc>
+          <doc type = "scenario">
+            A client creates two named queues, one durable and one transient. The client
+            then attempts to declare the two queues using the same names again, but reversing
+            the value of the durable flag in each case. Verify that the queues still exist
+            with the original durable flag values.
+            <!-- TODO: but how? -->
+          </doc>
+        </rule>
+      </field>
+
+      <field name = "exclusive" domain = "bit" label = "request an exclusive queue">
+        <doc>
+          Exclusive queues may only be consumed from by the current connection. Setting
+          the 'exclusive' flag always implies 'auto-delete'.
+        </doc>
+
+        <!-- Rule test name: was "amq_queue_38" -->
+        <rule name = "types">
+          <doc>
+            The server MUST support both exclusive (private) and non-exclusive (shared)
+            queues.
+          </doc>
+          <doc type = "scenario">
+            A client creates two named queues, one exclusive and one non-exclusive.
+          </doc>
+        </rule>
+
+        <!-- Rule test name: was "amq_queue_04" -->    
+        <rule name = "02" on-failure = "channel-error">
+          <doc>
+            The client MAY NOT attempt to declare any existing and exclusive queue
+            on multiple connections.
+          </doc>
+          <doc type = "scenario">
+            A client declares an exclusive named queue. A second client on a different
+            connection attempts to declare a queue of the same name.
+          </doc>
+        </rule>
+      </field>
+
+      <field name = "auto-delete" domain = "bit" label = "auto-delete queue when unused">
+        <doc>
+          If set, the queue is deleted when all consumers have finished using it. Last
+          consumer can be cancelled either explicitly or because its channel is closed. If
+          there was no consumer ever on the queue, it won't be deleted.
+        </doc>
+
+        <!-- Rule test name: was "amq_queue_31" -->
+        <rule name = "pre-existence">
+          <doc>
+            The server MUST ignore the auto-delete field if the queue already exists.
+          </doc>
+          <doc type = "scenario">
+            A client creates two named queues, one as auto-delete and one explicit-delete.
+            The client then attempts to declare the two queues using the same names again,
+            but reversing the value of the auto-delete field in each case. Verify that the
+            queues still exist with the original auto-delete flag values.
+            <!-- TODO: but how? -->
+          </doc>
+        </rule>
+      </field>
+
+      <field name = "nowait" domain = "bit" label = "do not send a reply method">
+        <doc>
+          If set, the server will not respond to the method. The client should not wait
+          for a reply method. If the server could not complete the method it will raise a
+          channel or connection exception.
+        </doc>
+      </field>
+
+      <field name = "arguments" domain = "table" label = "arguments for declaration">
+        <doc>
+          A set of arguments for the declaration. The syntax and semantics of these
+          arguments depends on the server implementation. This field is ignored if passive
+          is 1.
+        </doc>
+      </field>
+    </method>
+
+    <method name = "declare-ok" synchronous = "1" index = "11" label = "confirms a queue definition">
+      <doc>
+        This method confirms a Declare method and confirms the name of the queue, essential
+        for automatically-named queues.
+      </doc>
+      
+      <chassis name = "client" implement = "MUST" />
+      
+      <field name = "queue" domain = "queue-name">
+        <doc>
+          Reports the name of the queue. If the server generated a queue name, this field
+          contains that name.
+        </doc>
+        <assert check = "notnull" />
+      </field>
+
+      <field name = "message-count" domain = "long" label = "number of messages in queue">
+        <doc>
+          Reports the number of messages in the queue, which will be zero for
+          newly-created queues.
+        </doc>
+      </field>
+      
+      <field name = "consumer-count" domain = "long" label = "number of consumers">
+        <doc>
+          Reports the number of active consumers for the queue. Note that consumers can
+          suspend activity (Channel.Flow) in which case they do not appear in this count.
+        </doc>
+      </field>
+    </method>
+    
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+    
+    <method name = "bind" synchronous = "1" index = "20" label = "bind queue to an exchange">
+      <doc>
+        This method binds a queue to an exchange. Until a queue is bound it will not receive
+        any messages. In a classic messaging model, store-and-forward queues are bound to a
+        direct exchange and subscription queues are bound to a topic exchange.
+      </doc>
+
+      <!-- Rule test name: was "amq_queue_25" -->
+      <rule name = "duplicates">
+        <doc>
+          A server MUST allow ignore duplicate bindings - that is, two or more bind
+          methods for a specific queue, with identical arguments - without treating these
+          as an error.
+        </doc>
+        <doc type = "scenario">
+          A client binds a named queue to an exchange. The client then repeats the bind
+          (with identical arguments).
+        </doc>
+      </rule>
+
+      <!-- Rule test name: was "amq_queue_39" -->
+      <rule name = "failure">
+        <!--
+        TODO: Find correct on-failure code. The on-failure code returned should depend on why the bind
+        failed. Assuming that failures owing to bad parameters are covered in the rules relating
+        to those parameters, the only remaining reason for a failure would be the lack of
+        server resorces or some internal error - such as too many queues open. Would these
+        cases qualify as "resource error" 506 or "internal error" 541?
+        -->
+        <doc>If a bind fails, the server MUST raise a connection exception.</doc>
+        <doc type = "scenario">
+          TODO
+        </doc>
+      </rule>
+
+      <!-- Rule test name: was "amq_queue_12" -->
+      <rule name = "transient-exchange" on-failure = "not-allowed">
+        <doc>
+          The server MUST NOT allow a durable queue to bind to a transient exchange.
+        </doc>
+        <doc type = "scenario">
+          A client creates a transient exchange. The client then declares a named durable
+          queue and then attempts to bind the transient exchange to the durable queue.
+        </doc>
+      </rule>
+
+      <!-- Rule test name: was "amq_queue_13" -->
+      <rule name = "durable-exchange">
+        <doc>
+          Bindings for durable queues are automatically durable and the server SHOULD
+          restore such bindings after a server restart.
+        </doc>
+        <doc type = "scenario">
+          A server creates a named durable queue and binds it to a durable exchange. The
+          server is restarted. The client then attempts to use the queue/exchange combination.
+        </doc>
+      </rule>
+
+      <!-- Rule test name: was "amq_queue_17" -->
+      <rule name = "internal-exchange">
+        <doc>
+          If the client attempts to bind to an exchange that was declared as internal, the server
+          MUST raise a connection exception with reply code 530 (not allowed).
+        </doc>
+        <doc type = "scenario">
+          A client attempts to bind a named queue to an internal exchange.
+        </doc>
+      </rule>
+
+      <!-- Rule test name: was "amq_queue_40" -->
+      <rule name = "binding-count">
+        <doc>
+          The server SHOULD support at least 4 bindings per queue, and ideally, impose no
+          limit except as defined by available resources.
+        </doc>
+        <doc type = "scenario">
+          A client creates a named queue and attempts to bind it to 4 different non-internal
+          exchanges.
+        </doc>
+      </rule>
+      
+      <chassis name = "server" implement = "MUST" />
+
+      <response name = "bind-ok" />
+      
+      <field name = "ticket" domain = "access-ticket">
+        <doc>
+          The client provides a valid access ticket giving "active" access rights to the
+          queue's access realm.
+        </doc>
+      </field>
+      
+      <field name = "queue" domain = "queue-name">
+        <doc>
+          Specifies the name of the queue to bind. If the queue name is empty, refers to
+          the current queue for the channel, which is the last declared queue.
+        </doc>
+        
+        <rule name = "empty-queue" on-failure = "not-allowed">
+          <doc>
+            A client MUST NOT be allowed to bind a non-existent and unnamed queue (i.e.
+            empty queue name) to an exchange.
+          </doc>
+          <doc type = "scenario">
+            A client attempts to bind with an unnamed (empty) queue name to an exchange.
+          </doc>
+        </rule>
+        
+        <!-- Rule test name: was "amq_queue_26" -->    
+        <rule name = "queue-existence" on-failure = "not-found">
+          <doc>
+            A client MUST NOT be allowed to bind a non-existent queue (i.e. not previously
+            declared) to an exchange.
+          </doc>
+          <doc type = "scenario">
+            A client attempts to bind an undeclared queue name to an exchange.
+          </doc>
+        </rule>
+      </field>
+      
+      <field name = "exchange" domain = "exchange-name" label = "name of the exchange to bind to">
+        <!-- Rule test name: was "amq_queue_14" -->    
+        <rule name = "exchange-existence" on-failure = "not-found">
+          <doc>
+            A client MUST NOT be allowed to bind a queue to a non-existent exchange.
+          </doc>
+          <doc type = "scenario">
+            A client attempts to bind an named queue to a undeclared exchange.
+          </doc>
+        </rule>
+      </field>
+      
+      <field name = "routing-key" domain = "shortstr" label = "message routing key">
+        <doc>
+          Specifies the routing key for the binding. The routing key is used for routing
+          messages depending on the exchange configuration. Not all exchanges use a
+          routing key - refer to the specific exchange documentation.  If the queue name
+          is empty, the server uses the last queue declared on the channel.  If the
+          routing key is also empty, the server uses this queue name for the routing
+          key as well.  If the queue name is provided but the routing key is empty, the
+          server does the binding with that empty routing key.  The meaning of empty
+          routing keys depends on the exchange implementation.
+        </doc>
+        <rule name = "direct-exchange-key-matching">
+          <doc>
+            If a message queue binds to a direct exchange using routing key K and a

[... 3102 lines stripped ...]