diff --git a/coolamqp/attaches/publisher.py b/coolamqp/attaches/publisher.py
index 9915dbaf381c711cf8395f303d22b44accc46aa9..ef2cdeece638ec9d820c9220f0f687bfe7146328 100644
--- a/coolamqp/attaches/publisher.py
+++ b/coolamqp/attaches/publisher.py
@@ -12,9 +12,9 @@ from __future__ import absolute_import, division, print_function
 
 import collections
 import logging
-import warnings
-
+import struct
 import six
+import warnings
 
 from coolamqp.framing.definitions import ChannelOpenOk, BasicPublish, Basic, \
     BasicAck
diff --git a/coolamqp/clustering/cluster.py b/coolamqp/clustering/cluster.py
index 14262120343a8e28b74f3c8f8e1652c899913fb1..33d1bbeaeadc1a8f32cc20f9cdb813b83726d245 100644
--- a/coolamqp/clustering/cluster.py
+++ b/coolamqp/clustering/cluster.py
@@ -13,7 +13,8 @@ from coolamqp.attaches import Publisher, AttacheGroup, Consumer, Declarer
 from coolamqp.objects import Exchange
 from concurrent.futures import Future
 
-from coolamqp.clustering.events import ConnectionLost, MessageReceived, NothingMuch
+from coolamqp.clustering.events import ConnectionLost, MessageReceived, \
+    NothingMuch
 
 logger = logging.getLogger(__name__)
 
@@ -56,6 +57,7 @@ class Cluster(object):
             def decorated():
                 if not self.listener.terminating:
                     on_fail()
+
             self.on_fail = decorated
         else:
             self.on_fail = None
@@ -101,7 +103,8 @@ class Cluster(object):
         """
         fut = Future()
         fut.set_running_or_notify_cancel()  # it's running right now
-        on_message = on_message or (lambda rmsg: self.events.put_nowait(MessageReceived(rmsg)))
+        on_message = on_message or (
+            lambda rmsg: self.events.put_nowait(MessageReceived(rmsg)))
         con = Consumer(queue, on_message, future_to_notify=fut, *args, **kwargs)
         self.attache_group.add(con)
         return con, fut
@@ -115,7 +118,8 @@ class Cluster(object):
         """
         return self.decl.delete_queue(queue)
 
-    def publish(self, message, exchange=None, routing_key=u'', tx=None, confirm=None):
+    def publish(self, message, exchange=None, routing_key=u'', tx=None,
+                confirm=None):
         """
         Publish a message.
 
@@ -145,16 +149,20 @@ class Cluster(object):
             warnings.warn(u'Use confirm kwarg instead', DeprecationWarning)
 
             if confirm is not None:
-                raise RuntimeError(u'Using both tx= and confirm= at once does not make sense')
+                raise RuntimeError(
+                    u'Using both tx= and confirm= at once does not make sense')
         elif confirm is not None:
             tx = confirm
         else:
             tx = False
 
         try:
-            return (self.pub_tr if tx else self.pub_na).publish(message, exchange, routing_key)
+            return (self.pub_tr if tx else self.pub_na).publish(message,
+                                                                exchange,
+                                                                routing_key)
         except Publisher.UnusablePublisher:
-            raise NotImplementedError(u'Sorry, this functionality is not yet implemented!')
+            raise NotImplementedError(
+                u'Sorry, this functionality is not yet implemented!')
 
     def start(self, wait=True):
         """
@@ -180,7 +188,8 @@ class Cluster(object):
 
         self.events = six.moves.queue.Queue()  # for coolamqp.clustering.events.*
 
-        self.snr = SingleNodeReconnector(self.node, self.attache_group, self.listener)
+        self.snr = SingleNodeReconnector(self.node, self.attache_group,
+                                         self.listener)
         self.snr.on_fail.add(lambda: self.events.put_nowait(ConnectionLost()))
         if self.on_fail is not None:
             self.snr.on_fail.add(self.on_fail)
diff --git a/coolamqp/uplink/connection/__init__.py b/coolamqp/uplink/connection/__init__.py
index 8a07f01dcff33f918aa859559d29255aec4a4e9f..47cdf5eafbaa64c6704c8e9c53d02a4598f190cb 100644
--- a/coolamqp/uplink/connection/__init__.py
+++ b/coolamqp/uplink/connection/__init__.py
@@ -12,7 +12,7 @@ Connection is something that can:
 from __future__ import absolute_import, division, print_function
 
 from coolamqp.uplink.connection.connection import Connection
-from coolamqp.uplink.connection.states import ST_OFFLINE, ST_CONNECTING, \
-    ST_ONLINE
 from coolamqp.uplink.connection.watches import FailWatch, Watch, \
     HeaderOrBodyWatch, MethodWatch, AnyWatch
+from coolamqp.uplink.connection.states import ST_OFFLINE, ST_CONNECTING, \
+    ST_ONLINE
diff --git a/coolamqp/uplink/connection/connection.py b/coolamqp/uplink/connection/connection.py
index 8c8e9266a16c1480e0bd3091e4d99c36233e2e59..182f2d827e957462c98a5ef7cdb0ab87d91f393d 100644
--- a/coolamqp/uplink/connection/connection.py
+++ b/coolamqp/uplink/connection/connection.py
@@ -12,7 +12,8 @@ from coolamqp.framing.frames import AMQPMethodFrame
 from coolamqp.uplink.handshake import Handshaker
 from coolamqp.framing.definitions import ConnectionClose, ConnectionCloseOk
 from coolamqp.uplink.connection.watches import MethodWatch, Watch
-from coolamqp.uplink.connection.states import ST_ONLINE, ST_OFFLINE, ST_CONNECTING
+from coolamqp.uplink.connection.states import ST_ONLINE, ST_OFFLINE, \
+    ST_CONNECTING
 from coolamqp.objects import Callable
 
 logger = logging.getLogger(__name__)
@@ -105,7 +106,8 @@ class Connection(object):
 
         while True:
             try:
-                sock.connect((self.node_definition.host, self.node_definition.port))
+                sock.connect(
+                    (self.node_definition.host, self.node_definition.port))
             except socket.error as e:
                 time.sleep(0.5)  # Connection refused? Very bad things?
             else:
@@ -120,7 +122,8 @@ class Connection(object):
                                                              on_read=self.recvf.put,
                                                              on_fail=self.on_fail)
         self.sendf = SendingFramer(self.listener_socket.send)
-        self.watch_for_method(0, (ConnectionClose, ConnectionCloseOk), self.on_connection_close)
+        self.watch_for_method(0, (ConnectionClose, ConnectionCloseOk),
+                              self.on_connection_close)
 
         Handshaker(self, self.node_definition, self.on_connected)
 
@@ -169,7 +172,8 @@ class Connection(object):
 
         if isinstance(payload, ConnectionClose):
             self.send([AMQPMethodFrame(0, ConnectionCloseOk())])
-            logger.info(u'Broker closed our connection - code %s reason %s', payload.reply_code,
+            logger.info(u'Broker closed our connection - code %s reason %s',
+                        payload.reply_code,
                         payload.reply_text.tobytes().decode('utf8'))
 
         elif isinstance(payload, ConnectionCloseOk):
@@ -233,7 +237,8 @@ class Connection(object):
                     # print('watch',watch,'was cancelled')
                     continue
 
-                if ((not watch_triggered) or (not watch.oneshot)) and (not watch.cancelled):
+                if ((not watch_triggered) or (not watch.oneshot)) and (
+                not watch.cancelled):
                     # Watch remains alive if it was NOT triggered, or it's NOT a oneshot
                     alive_watches.append(watch)
 
@@ -260,7 +265,8 @@ class Connection(object):
                 # print('any watch', watch, 'was cancelled')
                 continue
 
-            if ((not watch_triggered) or (not watch.oneshot)) and (not watch.cancelled):
+            if ((not watch_triggered) or (not watch.oneshot)) and (
+            not watch.cancelled):
                 # Watch remains alive if it was NOT triggered, or it's NOT a oneshot
                 alive_watches.append(watch)
 
@@ -315,7 +321,8 @@ class Connection(object):
         self.watch(mw)
         return mw
 
-    def method_and_watch(self, channel_id, method_payload, method_or_methods, callback):
+    def method_and_watch(self, channel_id, method_payload, method_or_methods,
+                         callback):
         """
         A syntactic sugar for
 
diff --git a/docs/index.rst b/docs/index.rst
index 3fdbdb2ea98cc4cb85404ad04ff5127cc146e789..55c87213879ea90ee040a9c965f75d6e9c6870c3 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -2,11 +2,11 @@ Welcome to CoolAMQP's documentation!
 ====================================
 
 .. toctree::
-   :maxdepth: 2
-   :caption: Contents:
+:maxdepth: 2
+       :caption: Contents:
 
-   tutorial
-   caveats
+       tutorial
+       caveats
 
 
 Indices and tables
diff --git a/resources/amqp0-9-1.extended.xml b/resources/amqp0-9-1.extended.xml
index 7ba2d60d3bab985e47c48fa25e2b219bcbac1786..f7aca67cdaba8b9765f8636a86d1445cb2f5c308 100644
--- a/resources/amqp0-9-1.extended.xml
+++ b/resources/amqp0-9-1.extended.xml
@@ -156,3192 +156,3849 @@
 
  -->
 
-<amqp major = "0" minor = "9" revision = "1"
-    port = "5672" comment = "AMQ Protocol version 0-9-1">
-  <!--
+<amqp major="0" minor="9" revision="1"
+      port="5672" comment="AMQ Protocol version 0-9-1">
+    <!--
       ======================================================
       ==       CONSTANTS
       ======================================================
   -->
-  <!-- Frame types -->
-  <constant name = "frame-method"     value = "1" />
-  <constant name = "frame-header"     value = "2" />
-  <constant name = "frame-body"       value = "3" />
-  <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 = "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-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 sender sent a malformed frame that the recipient could not decode.
-      This strongly implies a programming error in the sending peer.
-    </doc>
-  </constant>
-
-  <constant name = "syntax-error" value = "502" class = "hard-error">
-    <doc>
-      The sender sent a frame that contained illegal values for one or more
-      fields. This strongly implies a programming error in the sending peer.
-    </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 = "unexpected-frame" value = "505" class = "hard-error">
-    <doc>
-      The peer sent a frame that was not expected, usually in the context of
-      a content header and body.  This strongly indicates a fault in the peer's
-      content processing.
-    </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 = "class-id" type = "short" />
-
-  <domain name = "consumer-tag" type = "shortstr" label = "consumer tag">
-    <doc>
-      Identifier for the consumer, valid within the current channel.
-    </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.
-    </doc>
-    <assert check = "length" value = "127" />
-    <assert check = "regexp" value = "^[a-zA-Z0-9-_.:]*$" />
-  </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
-      assumes the delivery will succeed and immediately dequeues it. This
-      functionality may increase performance but at the cost of reliability.
-      Messages can get lost if a client dies before they are delivered 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 = "no-wait" type = "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>
-  </domain>
-
-  <domain name = "path" type = "shortstr">
-    <doc>
-      Unconstrained.
-    </doc>
-    <assert check = "notnull" />
-    <assert check = "length" value = "127" />
-  </domain>
-
-  <domain name = "peer-properties" type = "table">
-    <doc>
-      This table 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.  In methods where the queue
-      name may be blank, and that has no specific significance, this refers to the
-      'current' queue for the channel, meaning the last queue that the client declared
-      on the channel.  If the client did not declare a queue, and the method needs a
-      queue name, this will result in a 502 (syntax error) channel exception.
-    </doc>
-    <assert check = "length" value = "127" />
-    <assert check = "regexp" value = "^[a-zA-Z0-9-_.:]*$" />
-  </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">
-        Declare 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 = "message-count" type = "long" label = "number of messages in queue">
-    <doc>
-      The number of messages in the queue, which will be zero for newly-declared
-      queues. This is the number of messages present in the queue, and committed
-      if the channel on which they were published is transacted, that are not
-      waiting acknowledgement.
-    </doc>
-  </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>
-
-  <!-- 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  ======================================================= -->
-
-  <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
-      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 respond with a valid protocol header and then close the socket
-          connection.
-        </doc>
-        <doc type = "scenario">
-          The client sends a protocol header containing an invalid protocol name.
-          The server MUST respond by sending a valid protocol header and then 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. 2.0.  The server must respond with a protocol header
-          indicating its supported 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 without sending any further data.
-        </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 without sending any further data.
-        </doc>
-      </rule>
-
-      <chassis name = "client" implement = "MUST" />
-      <response name = "start-ok" />
-
-      <field name = "version-major" domain = "octet" label = "protocol major version">
-        <doc>
-          The major version number can take any value from 0 to 99 as defined in the
-          AMQP specification.
-        </doc>
-      </field>
-
-      <field name = "version-minor" domain = "octet" label = "protocol minor version">
-        <doc>
-          The minor version number can take any value from 0 to 99 as defined in the
-          AMQP specification.
-        </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" />
+    <!-- Frame types -->
+    <constant name="frame-method" value="1"/>
+    <constant name="frame-header" value="2"/>
+    <constant name="frame-body" value="3"/>
+    <constant name="frame-heartbeat" value="8"/>
 
-      <response name = "tune-ok" />
+    <!-- Protocol constants -->
+    <constant name="frame-min-size" value="4096"/>
+    <constant name="frame-end" value="206"/>
 
-      <field name = "channel-max" domain = "short" label = "proposed maximum channels">
+    <!-- Reply codes -->
+    <constant name="reply-success" value="200">
         <doc>
-          Specifies highest channel number that the server permits.  Usable channel numbers
-          are in the range 1..channel-max.  Zero indicates no specified limit.
+            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>
-      </field>
+    </constant>
 
-      <field name = "frame-max" domain = "long" label = "proposed maximum frame size">
+    <constant name="content-too-large" value="311" class="soft-error">
         <doc>
-          The largest frame size that the server proposes for the connection, including
-          frame header and end-byte.  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.
+            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>
-        <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>
+    </constant>
 
-      <field name = "heartbeat" domain = "short" label = "desired heartbeat delay">
+    <constant name="no-consumers" value="313" class="soft-error">
         <doc>
-          The delay, in seconds, of the connection heartbeat that the server wants.
-          Zero means the server does not want a heartbeat.
+            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>
-      </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" />
+    </constant>
 
-      <field name = "channel-max" domain = "short" label = "negotiated maximum channels">
+    <constant name="connection-forced" value="320" class="hard-error">
         <doc>
-          The maximum total number of channels that the client will use per connection.
+            An operator intervened to close the connection for some reason. The
+            client
+            may retry at some later date.
         </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>
+    </constant>
 
-      <field name = "frame-max" domain = "long" label = "negotiated maximum frame size">
+    <constant name="invalid-path" value="402" class="hard-error">
         <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.
+            The client tried to work with an unknown virtual host.
         </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>
+    </constant>
 
-      <field name = "heartbeat" domain = "short" label = "desired heartbeat delay">
+    <constant name="access-refused" value="403" class="soft-error">
         <doc>
-          The delay, in seconds, of the connection heartbeat that the client wants. Zero
-          means the client does not want a heartbeat.
+            The client attempted to work with a server entity to which it has no
+            access due to security settings.
         </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" />
+    </constant>
 
-      <field name = "virtual-host" domain = "path" label = "virtual host name">
+    <constant name="not-found" value="404" class="soft-error">
         <doc>
-          The name of the virtual host to work with.
+            The client attempted to work with a server entity that does not
+            exist.
         </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>
-      <!-- Deprecated: "capabilities", must be zero -->
-      <field name = "reserved-1" type = "shortstr" reserved = "1" />
-      <!-- Deprecated: "insist", must be zero -->
-      <field name = "reserved-2" type = "bit" reserved = "1" />
-    </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" />
-      <!-- Deprecated: "known-hosts", must be zero -->
-      <field name = "reserved-1" type = "shortstr" reserved = "1" />
-    </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>
-      <rule name = "stability">
-        <doc>
-          After sending this method, any received methods except Close and Close-OK MUST
-          be discarded.  The response to receiving a Close after sending Close must be to
-          send Close-Ok.
-        </doc>
-      </rule>
+    </constant>
 
-      <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">
+    <constant name="resource-locked" value="405" class="soft-error">
         <doc>
-          When the close is provoked by a method exception, this is the class of the
-          method.
+            The client attempted to work with a server entity to which it has no
+            access because another client is working with it.
         </doc>
-      </field>
+    </constant>
 
-      <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>
-
-    <method name = "blocked" index = "60">
-      <doc>
-        This method indicates that a connection has been blocked
-        and does not accept new publishes.
-      </doc>
-      <chassis name = "server" implement = "MUST"/>
-      <chassis name = "client" implement = "MUST"/>
-      <field name = "reason" domain = "shortstr" />
-    </method>
-    <method name = "unblocked" index = "61">
-      <doc>
-        This method indicates that a connection has been unblocked
-        and now accepts publishes.
-      </doc>
-      <chassis name = "server" implement = "MUST"/>
-      <chassis name = "client" 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
-      use-channel         = C:FLOW S:FLOW-OK
-                          / S:FLOW C:FLOW-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" />
-      <!-- Deprecated: "out-of-band", must be zero -->
-      <field name = "reserved-1" type = "shortstr" reserved = "1" />
-    </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" />
-      <!-- Deprecated: "channel-id", must be zero -->
-      <field name = "reserved-1" type = "longstr" reserved = "1" />
-    </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 sent by
-        a consumer. 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. It does
-        not affect contents returned by Basic.Get-Ok methods.
-      </doc>
-
-      <rule name = "initial-state">
+    <constant name="precondition-failed" value="406" class="soft-error">
         <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.
+            The client requested a method that was not allowed because some
+            precondition
+            failed.
         </doc>
-      </rule>
+    </constant>
 
-      <rule name = "bidirectional">
+    <constant name="frame-error" value="501" class="hard-error">
         <doc>
-          When sending content frames, a peer SHOULD monitor the channel for incoming
-          methods and respond to a Channel.Flow as rapidly as possible.
+            The sender sent a malformed frame that the recipient could not
+            decode.
+            This strongly implies a programming error in the sending peer.
         </doc>
-      </rule>
+    </constant>
 
-      <rule name = "throttling">
+    <constant name="syntax-error" value="502" class="hard-error">
         <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.
+            The sender sent a frame that contained illegal values for one or
+            more
+            fields. This strongly implies a programming error in the sending
+            peer.
         </doc>
-      </rule>
+    </constant>
 
-      <rule name = "expected-behaviour">
+    <constant name="command-invalid" value="503" class="hard-error">
         <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 server.
+            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>
-      </rule>
+    </constant>
 
-      <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">
+    <constant name="channel-error" value="504" class="hard-error">
         <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.
+            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>
-      </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>
-      <rule name = "stability">
-        <doc>
-          After sending this method, any received methods except Close and Close-OK MUST
-          be discarded.  The response to receiving a Close after sending Close must be to
-          send Close-Ok.
-        </doc>
-      </rule>
-
-      <chassis name = "client" implement = "MUST" />
-      <chassis name = "server" implement = "MUST" />
-      <response name = "close-ok" />
+    </constant>
 
-      <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">
+    <constant name="unexpected-frame" value="505" class="hard-error">
         <doc>
-          When the close is provoked by a method exception, this is the class of the
-          method.
+            The peer sent a frame that was not expected, usually in the context
+            of
+            a content header and body. This strongly indicates a fault in the
+            peer's
+            content processing.
         </doc>
-      </field>
+    </constant>
 
-      <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">
+    <constant name="resource-error" value="506" class="hard-error">
         <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>
-  </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 declared at runtime.
-    </doc>
-
-    <doc type = "grammar">
-      exchange            = C:DECLARE  S:DECLARE-OK
-                          / C:DELETE   S:DELETE-OK
-                          / C:BIND     S:BIND-OK
-                          / C:UNBIND   S:UNBIND-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 declares 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 declares as many exchanges as it can until the server reports
-          an error; the number of exchanges successfully declared must be at least
-          sixteen.
+            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>
-      </rule>
-
-      <chassis name = "server" implement = "MUST" />
-      <response name = "declare-ok" />
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <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 MAY declare an exchange starting with
-            "amq." if the passive option is set, or the exchange already exists.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to declare a non-existing exchange starting with
-            "amq." and with the passive option set to zero.
-          </doc>
-        </rule>
-        <rule name = "syntax" on-failure = "precondition-failed">
-          <doc>
-            The exchange name consists of a non-empty sequence of these characters:
-            letters, digits, hyphen, underscore, period, or colon.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to declare an exchange with an illegal name.
-          </doc>
-        </rule>
-        <assert check = "notnull" />
-      </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 declare an exchange with a type that the
-            server does not support.
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
-        </rule>
-      </field>
+    </constant>
 
-      <field name = "passive" domain = "bit" label = "do not create exchange">
+    <constant name="not-allowed" value="530" class="hard-error">
         <doc>
-          If set, the server will reply with Declare-Ok if the exchange already
-          exists with the same name, and raise an error if not.  The client can
-          use this to check whether an exchange exists without modifying the
-          server state. When set, all other method fields except name and no-wait
-          are ignored.  A declare with both passive and no-wait has no effect.
-          Arguments are compared for semantic equivalence.
+            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>
-        <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>
-        <rule name = "equivalent">
-          <doc>
-            If not set and the exchange exists, the server MUST check that the
-            existing exchange has the same values for type, durable, and arguments
-            fields.  The server MUST respond with Declare-Ok if the requested
-            exchange matches these fields, and MUST raise a channel exception if
-            not.
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
-        </rule>
-      </field>
+    </constant>
 
-      <field name = "durable" domain = "bit" label = "request a durable exchange">
+    <constant name="not-implemented" value="540" class="hard-error">
         <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.
+            The client tried to use functionality that is not implemented in the
+            server.
         </doc>
-        <rule name = "support">
-          <doc>
-            The server MUST support both durable and transient exchanges.
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
-        </rule>
-      </field>
+    </constant>
 
-      <field name = "auto-delete" domain = "bit" label = "auto-delete when unused">
+    <constant name="internal-error" value="541" class="hard-error">
         <doc>
-          If set, the exchange is deleted when all queues have
-          finished using it.
+            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>
-        <rule name = "amq_exchange_02">
-          <doc>
-            The server SHOULD allow for a reasonable delay between the
-            point when it determines that an exchange is not being
-            used (or no longer used), and the point when it deletes
-            the exchange.  At the least it must allow a client to
-            create an exchange and then bind a queue to it, with a
-            small but non-zero delay between these two actions.
-          </doc>
-        </rule>
-        <rule name = "amq_exchange_25">
-          <doc>
-            The server MUST ignore the auto-delete field if the
-            exchange already exists.
-          </doc>
-        </rule>
-      </field>
+    </constant>
 
-      <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 = "no-wait" domain = "no-wait" />
-
-      <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.
-        </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" />
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <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>
-
-      <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>
-        <rule name = "in-use" on-failure = "precondition-failed">
-          <doc>
-            The server MUST NOT delete an exchange that has bindings on it, if the if-unused
-            field is true.
-          </doc>
-          <doc type = "scenario">
-            The client declares an exchange, binds a queue to it, then tries to delete it
-            setting if-unused to true.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "no-wait" domain = "no-wait" />
-    </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>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "bind" synchronous = "1" index = "30"
-            label = "bind exchange to an exchange">
-
-      <doc>This method binds an exchange to an exchange.</doc>
-
-      <rule name = "duplicates">
-        <doc>
-          A server MUST allow and ignore duplicate bindings - that is,
-          two or more bind methods for a specific exchanges, with
-          identical arguments - without treating these as an error.
-        </doc>
-        <doc type = "scenario">
-          A client binds an exchange to an exchange. The client then
-          repeats the bind (with identical arguments).
-        </doc>
-      </rule>
-
-      <rule name = "cyclical">
-        <doc>
-          A server MUST allow cycles of exchange bindings to be
-          created including allowing an exchange to be bound to
-          itself.
-        </doc>
-        <doc type = "scenario">
-          A client declares an exchange and binds it to itself.
-        </doc>
-      </rule>
-
-      <rule name = "unique">
-        <doc>
-          A server MUST not deliver the same message more than once to
-          a destination exchange, even if the topology of exchanges
-          and bindings results in multiple (even infinite) routes to
-          that exchange.
-        </doc>
-        <doc type = "scenario">
-          A client declares an exchange and binds it using multiple
-          bindings to the amq.topic exchange. The client then
-          publishes a message to the amq.topic exchange that matches
-          all the bindings.
-        </doc>
-      </rule>
-
-      <chassis name = "server" implement = "MUST"/>
-
-      <response name = "bind-ok"/>
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1"/>
-
-      <field name = "destination" domain = "exchange-name"
-             label = "name of the destination exchange to bind to">
-        <doc>Specifies the name of the destination exchange to bind.</doc>
-        <rule name = "exchange-existence" on-failure = "not-found">
-          <doc>
-            A client MUST NOT be allowed to bind a non-existent
-            destination exchange.
-          </doc>
-          <doc type = "scenario">
-            A client attempts to bind an undeclared exchange to an
-            exchange.
-          </doc>
-        </rule>
-        <rule name = "default-exchange">
-          <doc>
-            The server MUST accept a blank exchange name to mean the
-            default exchange.
-          </doc>
-          <doc type = "scenario">
-            The client declares an exchange and binds a blank exchange
-            name to it.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "source" domain = "exchange-name"
-             label = "name of the source exchange to bind to">
-        <doc>Specifies the name of the source exchange to bind.</doc>
-        <rule name = "exchange-existence" on-failure = "not-found">
-          <doc>
-            A client MUST NOT be allowed to bind a non-existent source
-            exchange.
-          </doc>
-          <doc type = "scenario">
-            A client attempts to bind an exchange to an undeclared
-            exchange.
-          </doc>
-        </rule>
-        <rule name = "default-exchange">
-          <doc>
-            The server MUST accept a blank exchange name to mean the
-            default exchange.
-          </doc>
-          <doc type = "scenario">
-            The client declares an exchange and binds it to a blank
-            exchange name.
-          </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.
-        </doc>
-      </field>
-
-      <field name = "no-wait" domain = "no-wait"/>
-
-      <field name = "arguments" domain = "table"
-             label = "arguments for binding">
-        <doc>
-          A set of arguments for the binding. The syntax and semantics
-          of these arguments depends on the exchange class.
-        </doc>
-      </field>
-    </method>
-
-    <method name="bind-ok" synchronous="1" index="31"
-            label = "confirm bind successful">
-      <doc>This method confirms that the bind was successful.</doc>
-
-      <chassis name="client" implement="MUST"/>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "unbind" synchronous = "1" index = "40"
-            label = "unbind an exchange from an exchange">
-      <doc>This method unbinds an exchange from an exchange.</doc>
-      <rule name = "01">
-        <doc>If a unbind fails, the server MUST raise a connection exception.</doc>
-      </rule>
-      <chassis name = "server" implement = "MUST"/>
-      <response name = "unbind-ok"/>
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1"/>
-
-      <field name = "destination" domain = "exchange-name">
-        <doc>Specifies the name of the destination exchange to unbind.</doc>
-        <rule name = "must-exist" on-failure = "not-found">
-          <doc>
-            The client MUST NOT attempt to unbind an exchange that
-            does not exist from an exchange.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to unbind a non-existent exchange from
-            an exchange.
-          </doc>
-        </rule>
-        <rule name = "default-exchange">
-          <doc>
-            The server MUST accept a blank exchange name to mean the
-            default exchange.
-          </doc>
-          <doc type = "scenario">
-            The client declares an exchange, binds a blank exchange
-            name to it, and then unbinds a blank exchange name from
-            it.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "source" domain = "exchange-name">
-        <doc>Specifies the name of the source exchange to unbind.</doc>
-        <rule name = "must-exist" on-failure = "not-found">
-          <doc>
-            The client MUST NOT attempt to unbind an exchange from an
-            exchange that does not exist.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to unbind an exchange from a
-            non-existent exchange.
-          </doc>
-        </rule>
-        <rule name = "default-exchange">
-          <doc>
-            The server MUST accept a blank exchange name to mean the
-            default exchange.
-          </doc>
-          <doc type = "scenario">
-            The client declares an exchange, binds an exchange to a
-            blank exchange name, and then unbinds an exchange from a
-            black exchange name.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "routing-key" domain = "shortstr"
-             label = "routing key of binding">
-        <doc>Specifies the routing key of the binding to unbind.</doc>
-      </field>
-
-      <field name = "no-wait" domain = "no-wait"/>
-
-      <field name = "arguments" domain = "table"
-             label = "arguments of binding">
-        <doc>Specifies the arguments of the binding to unbind.</doc>
-      </field>
-    </method>
-
-    <method name = "unbind-ok" synchronous = "1" index = "51"
-            label = "confirm unbind successful">
-      <doc>This method confirms that the unbind was successful.</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:UNBIND   S:UNBIND-OK
-                          / C:PURGE    S:PURGE-OK
-                          / C:DELETE   S:DELETE-OK
-    </doc>
-
-    <chassis name = "server" implement = "MUST" />
-    <chassis name = "client" implement = "MUST" />
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <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-declared 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 declares 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 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 declare 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" />
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <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 declare several queues with an empty name. The client then
-            verifies that the server-assigned names are unique and different.
-          </doc>
-        </rule>
-        <rule name = "reserved" on-failure = "access-refused">
-          <doc>
-            Queue names starting with "amq." are reserved for pre-declared and
-            standardised queues. The client MAY declare a queue starting with
-            "amq." if the passive option is set, or the queue already exists.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to declare a non-existing queue starting with
-            "amq." and with the passive option set to zero.
-          </doc>
-        </rule>
-        <rule name = "syntax" on-failure = "precondition-failed">
-          <doc>
-            The queue name can be empty, or a sequence of these characters:
-            letters, digits, hyphen, underscore, period, or colon.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to declare a queue with an illegal name.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "passive" domain = "bit" label = "do not create queue">
-        <doc>
-          If set, the server will reply with Declare-Ok if the queue already
-          exists with the same name, and raise an error if not.  The client can
-          use this to check whether a queue exists without modifying the
-          server state.  When set, all other method fields except name and no-wait
-          are ignored.  A declare with both passive and no-wait has no effect.
-          Arguments are compared for semantic equivalence.
-        </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>
-        <rule name = "equivalent">
-          <doc>
-            If not set and the queue exists, the server MUST check that the
-            existing queue has the same values for durable, exclusive, auto-delete,
-            and arguments fields.  The server MUST respond with Declare-Ok if the
-            requested queue matches these fields, and MUST raise a channel exception
-            if not.
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </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 name = "persistence">
-          <doc>The server MUST recreate the durable queue after a restart.</doc>
-
-          <doc type = "scenario">
-            Client declares 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 name = "types">
-          <doc>The server MUST support both durable and transient queues.</doc>
-          <doc type = "scenario">
-            A client declares two named queues, one durable and one transient.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "exclusive" domain = "bit" label = "request an exclusive queue">
-        <doc>
-          Exclusive queues may only be accessed by the current connection, and are
-          deleted when that connection closes.  Passive declaration of an exclusive
-          queue by other connections are not allowed.
-        </doc>
-
-        <rule name = "types">
-          <doc>
-            The server MUST support both exclusive (private) and non-exclusive (shared)
-            queues.
-          </doc>
-          <doc type = "scenario">
-            A client declares two named queues, one exclusive and one non-exclusive.
-          </doc>
-        </rule>
-
-        <rule name = "exclusive" on-failure = "resource-locked">
-          <doc>
-            The client MAY NOT attempt to use a queue that was declared as exclusive
-            by another still-open connection.
-          </doc>
-          <doc type = "scenario">
-            One client declares an exclusive queue. A second client on a different
-            connection attempts to declare, bind, consume, purge, delete, or 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.  The 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.  Applications can
-          explicitly delete auto-delete queues using the Delete method as normal.
-        </doc>
-
-        <rule name = "pre-existence">
-          <doc>
-            The server MUST ignore the auto-delete field if the queue already exists.
-          </doc>
-          <doc type = "scenario">
-            Client declares two named queues, one as auto-delete and one explicit-delete.
-            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.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "no-wait" domain = "no-wait" />
-
-      <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.
-        </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 = "message-count" />
-
-      <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 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 name = "unique">
-        <doc>
-          A server MUST not deliver the same message more than once to a queue, even if
-          the queue has multiple bindings that match the message.
-        </doc>
-        <doc type = "scenario">
-          A client declares a named queue and binds it using multiple bindings to the
-          amq.topic exchange. The client then publishes a message that matches all its
-          bindings.
-        </doc>
-      </rule>
+    <!--
+      ======================================================
+      ==       DOMAIN TYPES
+      ======================================================
+  -->
 
-      <rule name = "transient-exchange">
-        <doc>
-          The server MUST allow a durable queue to bind to a transient exchange.
-        </doc>
-        <doc type = "scenario">
-          A client declares 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>
+    <domain name="class-id" type="short"/>
 
-      <rule name = "durable-exchange">
+    <domain name="consumer-tag" type="shortstr" label="consumer tag">
         <doc>
-          Bindings of durable queues to durable exchanges are automatically durable
-          and the server MUST restore such bindings after a server restart.
+            Identifier for the consumer, valid within the current channel.
         </doc>
-        <doc type = "scenario">
-          A server declares 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>
+    </domain>
 
-      <rule name = "binding-count">
+    <domain name="delivery-tag" type="longlong"
+            label="server-assigned delivery tag">
         <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 declares a named queue and attempts to bind it to 4 different
-          exchanges.
+            The server-assigned and channel-specific delivery tag
         </doc>
-      </rule>
-
-      <chassis name = "server" implement = "MUST" />
-
-      <response name = "bind-ok" />
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <field name = "queue" domain = "queue-name">
-        <doc>Specifies the name of the queue to bind.</doc>
-        <rule name = "queue-known" on-failure = "not-found">
-          <doc>
-            The client MUST either specify a queue name or have previously declared a
-            queue on the same channel
-          </doc>
-          <doc type = "scenario">
-            The client opens a channel and attempts to bind an unnamed queue.
-          </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 = "must-exist" on-failure = "not-found">
-          <doc>
-            The client MUST NOT attempt to bind a queue that does not exist.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to bind a non-existent queue.
-          </doc>
+        <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>
-      </field>
-
-      <field name = "exchange" domain = "exchange-name" label = "name of the exchange to bind to">
-        <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>
-        <rule name = "default-exchange">
-          <doc>
-            The server MUST accept a blank exchange name to mean the default exchange.
-          </doc>
-          <doc type = "scenario">
-            The client declares a queue and binds it to a blank exchange name.
-          </doc>
-        </rule>
-      </field>
+    </domain>
 
-      <field name = "routing-key" domain = "shortstr" label = "message routing key">
+    <domain name="exchange-name" type="shortstr" label="exchange name">
         <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.
+            The exchange name is a client-selected string that identifies the
+            exchange for
+            publish methods.
         </doc>
-        <rule name = "direct-exchange-key-matching">
-          <doc>
-            If a message queue binds to a direct exchange using routing key K and a
-            publisher sends the exchange a message with routing key R, then the message
-            MUST be passed to the message queue if K = R.
-          </doc>
-        </rule>
-      </field>
+        <assert check="length" value="127"/>
+        <assert check="regexp" value="^[a-zA-Z0-9-_.:]*$"/>
+    </domain>
 
-      <field name = "no-wait" domain = "no-wait" />
+    <domain name="method-id" type="short"/>
 
-      <field name = "arguments" domain = "table" label = "arguments for binding">
+    <domain name="no-ack" type="bit" label="no acknowledgement needed">
         <doc>
-          A set of arguments for the binding. The syntax and semantics of these arguments
-          depends on the exchange class.
-        </doc>
-      </field>
-    </method>
-
-    <method name = "bind-ok" synchronous = "1" index = "21" label = "confirm bind successful">
-      <doc>This method confirms that the bind was successful.</doc>
-
-      <chassis name = "client" implement = "MUST" />
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "unbind" synchronous = "1" index = "50" label = "unbind a queue from an exchange">
-      <doc>This method unbinds a queue from an exchange.</doc>
-      <rule name = "01">
-        <doc>If a unbind fails, the server MUST raise a connection exception.</doc>
-      </rule>
-      <chassis name="server" implement="MUST"/>
-      <response name="unbind-ok"/>
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <field name = "queue" domain = "queue-name">
-        <doc>Specifies the name of the queue to unbind.</doc>
-        <rule name = "queue-known" on-failure = "not-found">
-          <doc>
-            The client MUST either specify a queue name or have previously declared a
-            queue on the same channel
-          </doc>
-          <doc type = "scenario">
-            The client opens a channel and attempts to unbind an unnamed queue.
-          </doc>
-        </rule>
-        <rule name = "must-exist" on-failure = "not-found">
-          <doc>
-            The client MUST NOT attempt to unbind a queue that does not exist.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to unbind a non-existent queue.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "exchange" domain = "exchange-name">
-        <doc>The name of the exchange to unbind from.</doc>
-        <rule name = "must-exist" on-failure = "not-found">
-          <doc>
-            The client MUST NOT attempt to unbind a queue from an exchange that
-            does not exist.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to unbind a queue from a non-existent exchange.
-          </doc>
-        </rule>
-        <rule name = "default-exchange">
-          <doc>
-            The server MUST accept a blank exchange name to mean the default exchange.
-          </doc>
-          <doc type = "scenario">
-            The client declares a queue and binds it to a blank exchange name.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "routing-key" domain = "shortstr" label = "routing key of binding">
-        <doc>Specifies the routing key of the binding to unbind.</doc>
-      </field>
-
-      <field name = "arguments" domain = "table" label = "arguments of binding">
-        <doc>Specifies the arguments of the binding to unbind.</doc>
-      </field>
-    </method>
-
-    <method name = "unbind-ok" synchronous = "1" index = "51" label = "confirm unbind successful">
-      <doc>This method confirms that the unbind was successful.</doc>
-      <chassis name = "client" implement = "MUST"/>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "purge" synchronous = "1" index = "30" label = "purge a queue">
-      <doc>
-        This method removes all messages from a queue which are not awaiting
-        acknowledgment.
-      </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
+            assumes the delivery will succeed and immediately dequeues it. This
+            functionality may increase performance but at the cost of
+            reliability.
+            Messages can get lost if a client dies before they are delivered to
+            the
+            application.
+        </doc>
+    </domain>
 
-      <rule name = "02">
+    <domain name="no-local" type="bit" label="do not deliver own messages">
         <doc>
-          The server MUST NOT purge messages that have already been sent to a client
-          but not yet acknowledged.
+            If the no-local field is set the server will not send messages to
+            the connection that
+            published them.
         </doc>
-      </rule>
+    </domain>
 
-      <rule name = "03">
+    <domain name="no-wait" type="bit" label="do not send reply method">
         <doc>
-          The server MAY implement a purge queue or log that allows system administrators
-          to recover accidentally-purged messages. The server SHOULD NOT keep purged
-          messages in the same storage spaces as the live messages since the volumes of
-          purged messages may get very large.
+            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>
-      </rule>
+    </domain>
 
-      <chassis name = "server" implement = "MUST" />
-
-      <response name = "purge-ok" />
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <field name = "queue" domain = "queue-name">
-        <doc>Specifies the name of the queue to purge.</doc>
-        <rule name = "queue-known" on-failure = "not-found">
-          <doc>
-            The client MUST either specify a queue name or have previously declared a
-            queue on the same channel
-          </doc>
-          <doc type = "scenario">
-            The client opens a channel and attempts to purge an unnamed queue.
-          </doc>
-        </rule>
-        <rule name = "must-exist" on-failure = "not-found">
-          <doc>
-            The client MUST NOT attempt to purge a queue that does not exist.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to purge a non-existent queue.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "no-wait" domain = "no-wait" />
-    </method>
-
-    <method name = "purge-ok" synchronous = "1" index = "31" label = "confirms a queue purge">
-      <doc>This method confirms the purge of a queue.</doc>
-
-      <chassis name = "client" implement = "MUST" />
-
-      <field name = "message-count" domain = "message-count">
+    <domain name="path" type="shortstr">
         <doc>
-          Reports the number of messages purged.
+            Unconstrained.
         </doc>
-      </field>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+        <assert check="notnull"/>
+        <assert check="length" value="127"/>
+    </domain>
 
-    <method name = "delete" synchronous = "1" index = "40" label = "delete a queue">
-      <doc>
-        This method deletes a queue. When a queue is deleted any pending messages are sent
-        to a dead-letter queue if this is defined in the server configuration, and all
-        consumers on the queue are cancelled.
-      </doc>
-
-      <rule name = "01">
+    <domain name="peer-properties" type="table">
         <doc>
-          The server SHOULD use a dead-letter queue to hold messages that were pending on
-          a deleted queue, and MAY provide facilities for a system administrator to move
-          these messages back to an active queue.
+            This table provides a set of peer properties, used for
+            identification, debugging,
+            and general information.
         </doc>
-      </rule>
-
-      <chassis name = "server" implement = "MUST" />
-
-      <response name = "delete-ok" />
+    </domain>
 
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <field name = "queue" domain = "queue-name">
-        <doc>Specifies the name of the queue to delete.</doc>
-        <rule name = "queue-known" on-failure = "not-found">
-          <doc>
-            The client MUST either specify a queue name or have previously declared a
-            queue on the same channel
-          </doc>
-          <doc type = "scenario">
-            The client opens a channel and attempts to delete an unnamed queue.
-          </doc>
-        </rule>
-        <rule name = "must-exist" on-failure = "not-found">
-          <doc>
-            The client MUST NOT attempt to delete a queue that does not exist.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to delete a non-existent queue.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "if-unused" domain = "bit" label = "delete only if unused">
-        <doc>
-          If set, the server will only delete the queue if it has no consumers. If the
-          queue has consumers the server does does not delete it but raises a channel
-          exception instead.
-        </doc>
-        <rule name = "in-use" on-failure = "precondition-failed">
-          <doc>
-            The server MUST NOT delete a queue that has consumers on it, if the if-unused
-            field is true.
-          </doc>
-          <doc type = "scenario">
-            The client declares a queue, and consumes from it, then tries to delete it
-            setting if-unused to true.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "if-empty" domain = "bit" label = "delete only if empty">
+    <domain name="queue-name" type="shortstr" label="queue name">
         <doc>
-          If set, the server will only delete the queue if it has no messages.
-        </doc>
-        <rule name = "not-empty" on-failure = "precondition-failed">
-          <doc>
-            The server MUST NOT delete a queue that has messages on it, if the
-            if-empty field is true.
-          </doc>
-          <doc type = "scenario">
-            The client declares a queue, binds it and publishes some messages into it,
-            then tries to delete it setting if-empty to true.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "no-wait" domain = "no-wait" />
-    </method>
-
-    <method name = "delete-ok" synchronous = "1" index = "41" label = "confirm deletion of a queue">
-      <doc>This method confirms the deletion of a queue.</doc>
-
-      <chassis name = "client" implement = "MUST" />
-
-      <field name = "message-count" domain = "message-count">
-        <doc>Reports the number of messages deleted.</doc>
-      </field>
-    </method>
-  </class>
-
-  <!-- ==  BASIC  ============================================================ -->
-
-  <class name = "basic" handler = "channel" index = "60" label = "work with basic content">
-    <doc>
-      The Basic class provides methods that support an industry-standard messaging model.
-    </doc>
-
-    <doc type = "grammar">
-      basic               = C:QOS S:QOS-OK
-                          / C:CONSUME S:CONSUME-OK
-                          / C:CANCEL S:CANCEL-OK
-                          / C:PUBLISH content
-                          / S:RETURN content
-                          / S:DELIVER content
-                          / C:GET ( S:GET-OK content / S:GET-EMPTY )
-                          / C:ACK
-                          / S:ACK
-                          / C:REJECT
-                          / C:NACK
-                          / S:NACK
-                          / C:RECOVER-ASYNC
-                          / C:RECOVER S:RECOVER-OK
-    </doc>
-
-    <chassis name = "server" implement = "MUST" />
-    <chassis name = "client" implement = "MAY" />
-
-    <rule name = "01">
-      <doc>
-        The server SHOULD respect the persistent property of basic messages and
-        SHOULD make a best-effort to hold persistent basic messages on a reliable
-        storage mechanism.
-      </doc>
-      <doc type = "scenario">
-        Send a persistent message to queue, stop server, restart server and then
-        verify whether message is still present.  Assumes that queues are durable.
-        Persistence without durable queues makes no sense.
-      </doc>
-    </rule>
-
-    <rule name = "02">
-      <doc>
-        The server MUST NOT discard a persistent basic message in case of a queue
-        overflow.
-      </doc>
-      <doc type = "scenario">
-        Declare a queue overflow situation with persistent messages and verify that
-        messages do not get lost (presumably the server will write them to disk).
-      </doc>
-    </rule>
-
-    <rule name = "03">
-      <doc>
-        The server MAY use the Channel.Flow method to slow or stop a basic message
-        publisher when necessary.
-      </doc>
-      <doc type = "scenario">
-        Declare a queue overflow situation with non-persistent messages and verify
-        whether the server responds with Channel.Flow or not. Repeat with persistent
-        messages.
-      </doc>
-    </rule>
-
-    <rule name = "04">
-      <doc>
-        The server MAY overflow non-persistent basic messages to persistent
-        storage.
-      </doc>
-      <!-- Test scenario: untestable -->
-    </rule>
-
-    <rule name = "05">
-      <doc>
-        The server MAY discard or dead-letter non-persistent basic messages on a
-        priority basis if the queue size exceeds some configured limit.
-      </doc>
-      <!-- Test scenario: untestable -->
-    </rule>
-
-    <rule name = "06">
-      <doc>
-        The server MUST implement at least 2 priority levels for basic messages,
-        where priorities 0-4 and 5-9 are treated as two distinct levels.
-      </doc>
-      <doc type = "scenario">
-        Send a number of priority 0 messages to a queue. Send one priority 9
-        message.  Consume messages from the queue and verify that the first message
-        received was priority 9.
-      </doc>
-    </rule>
-
-    <rule name = "07">
-      <doc>
-        The server MAY implement up to 10 priority levels.
-      </doc>
-      <doc type = "scenario">
-        Send a number of messages with mixed priorities to a queue, so that all
-        priority values from 0 to 9 are exercised. A good scenario would be ten
-        messages in low-to-high priority.  Consume from queue and verify how many
-        priority levels emerge.
-      </doc>
-    </rule>
-
-    <rule name = "08">
-      <doc>
-        The server MUST deliver messages of the same priority in order irrespective of
-        their individual persistence.
-      </doc>
-      <doc type = "scenario">
-        Send a set of messages with the same priority but different persistence
-        settings to a queue.  Consume and verify that messages arrive in same order
-        as originally published.
-      </doc>
-    </rule>
-
-    <rule name = "09">
-      <doc>
-        The server MUST support un-acknowledged delivery of Basic content, i.e.
-        consumers with the no-ack field set to TRUE.
-      </doc>
-    </rule>
-
-    <rule name = "10">
-      <doc>
-        The server MUST support explicitly acknowledged delivery of Basic content,
-        i.e. consumers with the no-ack field set to FALSE.
-      </doc>
-      <doc type = "scenario">
-        Declare a queue and a consumer using explicit acknowledgements.  Publish a
-        set of messages to the queue.  Consume the messages but acknowledge only
-        half of them.  Disconnect and reconnect, and consume from the queue.
-        Verify that the remaining messages are received.
-      </doc>
-    </rule>
-
-    <!--  These are the properties for a Basic content  -->
-
-    <!--  MIME typing -->
-    <field name = "content-type"    domain = "shortstr"   label = "MIME content type" />
-    <!--  MIME typing -->
-    <field name = "content-encoding" domain = "shortstr"  label = "MIME content encoding" />
-    <!--  For applications, and for header exchange routing -->
-    <field name = "headers"         domain = "table"      label = "message header field table" />
-    <!--  For queues that implement persistence -->
-    <field name = "delivery-mode"   domain = "octet"      label = "non-persistent (1) or persistent (2)" />
-    <!--  For queues that implement priorities -->
-    <field name = "priority"        domain = "octet"      label = "message priority, 0 to 9" />
-    <!--  For application use, no formal behaviour -->
-    <field name = "correlation-id"  domain = "shortstr"   label = "application correlation identifier" />
-    <!--  For application use, no formal behaviour but may hold the
+            The queue name identifies the queue within the vhost. In methods
+            where the queue
+            name may be blank, and that has no specific significance, this
+            refers to the
+            'current' queue for the channel, meaning the last queue that the
+            client declared
+            on the channel. If the client did not declare a queue, and the
+            method needs a
+            queue name, this will result in a 502 (syntax error) channel
+            exception.
+        </doc>
+        <assert check="length" value="127"/>
+        <assert check="regexp" value="^[a-zA-Z0-9-_.:]*$"/>
+    </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">
+                Declare 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="message-count" type="long"
+            label="number of messages in queue">
+        <doc>
+            The number of messages in the queue, which will be zero for
+            newly-declared
+            queues. This is the number of messages present in the queue, and
+            committed
+            if the channel on which they were published is transacted, that are
+            not
+            waiting acknowledgement.
+        </doc>
+    </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>
+
+    <!-- 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  ======================================================= -->
+
+    <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
+            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 respond with a valid protocol header and then close
+                    the socket
+                    connection.
+                </doc>
+                <doc type="scenario">
+                    The client sends a protocol header containing an invalid
+                    protocol name.
+                    The server MUST respond by sending a valid protocol header
+                    and then 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. 2.0. The server must respond with a
+                    protocol header
+                    indicating its supported 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 without sending any
+                    further data.
+                </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 without sending any further data.
+                </doc>
+            </rule>
+
+            <chassis name="client" implement="MUST"/>
+            <response name="start-ok"/>
+
+            <field name="version-major" domain="octet"
+                   label="protocol major version">
+                <doc>
+                    The major version number can take any value from 0 to 99 as
+                    defined in the
+                    AMQP specification.
+                </doc>
+            </field>
+
+            <field name="version-minor" domain="octet"
+                   label="protocol minor version">
+                <doc>
+                    The minor version number can take any value from 0 to 99 as
+                    defined in the
+                    AMQP specification.
+                </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>
+                    Specifies highest channel number that the server permits.
+                    Usable channel numbers
+                    are in the range 1..channel-max. Zero indicates no specified
+                    limit.
+                </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, including
+                    frame header and end-byte. 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">
+                <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"/>
+
+            <field name="virtual-host" domain="path" label="virtual host name">
+                <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>
+            <!-- Deprecated: "capabilities", must be zero -->
+            <field name="reserved-1" type="shortstr" reserved="1"/>
+            <!-- Deprecated: "insist", must be zero -->
+            <field name="reserved-2" type="bit" reserved="1"/>
+        </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"/>
+            <!-- Deprecated: "known-hosts", must be zero -->
+            <field name="reserved-1" type="shortstr" reserved="1"/>
+        </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>
+            <rule name="stability">
+                <doc>
+                    After sending this method, any received methods except Close
+                    and Close-OK MUST
+                    be discarded. The response to receiving a Close after
+                    sending Close must be to
+                    send Close-Ok.
+                </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>
+
+        <method name="blocked" index="60">
+            <doc>
+                This method indicates that a connection has been blocked
+                and does not accept new publishes.
+            </doc>
+            <chassis name="server" implement="MUST"/>
+            <chassis name="client" implement="MUST"/>
+            <field name="reason" domain="shortstr"/>
+        </method>
+        <method name="unblocked" index="61">
+            <doc>
+                This method indicates that a connection has been unblocked
+                and now accepts publishes.
+            </doc>
+            <chassis name="server" implement="MUST"/>
+            <chassis name="client" 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
+            use-channel = C:FLOW S:FLOW-OK
+            / S:FLOW C:FLOW-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"/>
+            <!-- Deprecated: "out-of-band", must be zero -->
+            <field name="reserved-1" type="shortstr" reserved="1"/>
+        </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"/>
+            <!-- Deprecated: "channel-id", must be zero -->
+            <field name="reserved-1" type="longstr" reserved="1"/>
+        </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 sent by
+                a consumer. 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. It does
+                not affect contents returned by Basic.Get-Ok methods.
+            </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 server.
+                </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>
+            <rule name="stability">
+                <doc>
+                    After sending this method, any received methods except Close
+                    and Close-OK MUST
+                    be discarded. The response to receiving a Close after
+                    sending Close must be to
+                    send Close-Ok.
+                </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>
+    </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 declared at runtime.
+        </doc>
+
+        <doc type="grammar">
+            exchange = C:DECLARE S:DECLARE-OK
+            / C:DELETE S:DELETE-OK
+            / C:BIND S:BIND-OK
+            / C:UNBIND S:UNBIND-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 declares 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 declares as many exchanges as it can until the
+                    server reports
+                    an error; the number of exchanges successfully declared must
+                    be at least
+                    sixteen.
+                </doc>
+            </rule>
+
+            <chassis name="server" implement="MUST"/>
+            <response name="declare-ok"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <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 MAY declare an
+                        exchange starting with
+                        "amq." if the passive option is set, or the exchange
+                        already exists.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to declare a non-existing exchange
+                        starting with
+                        "amq." and with the passive option set to zero.
+                    </doc>
+                </rule>
+                <rule name="syntax" on-failure="precondition-failed">
+                    <doc>
+                        The exchange name consists of a non-empty sequence of
+                        these characters:
+                        letters, digits, hyphen, underscore, period, or colon.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to declare an exchange with an
+                        illegal name.
+                    </doc>
+                </rule>
+                <assert check="notnull"/>
+            </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 declare an exchange with
+                        a type that the
+                        server does not support.
+                    </doc>
+                    <doc type="scenario">
+                        TODO.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="passive" domain="bit" label="do not create exchange">
+                <doc>
+                    If set, the server will reply with Declare-Ok if the
+                    exchange already
+                    exists with the same name, and raise an error if not. The
+                    client can
+                    use this to check whether an exchange exists without
+                    modifying the
+                    server state. When set, all other method fields except name
+                    and no-wait
+                    are ignored. A declare with both passive and no-wait has no
+                    effect.
+                    Arguments are compared for semantic equivalence.
+                </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>
+                <rule name="equivalent">
+                    <doc>
+                        If not set and the exchange exists, the server MUST
+                        check that the
+                        existing exchange has the same values for type, durable,
+                        and arguments
+                        fields. The server MUST respond with Declare-Ok if the
+                        requested
+                        exchange matches these fields, and MUST raise a channel
+                        exception if
+                        not.
+                    </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>
+            </field>
+
+            <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="amq_exchange_02">
+                    <doc>
+                        The server SHOULD allow for a reasonable delay between
+                        the
+                        point when it determines that an exchange is not being
+                        used (or no longer used), and the point when it deletes
+                        the exchange. At the least it must allow a client to
+                        create an exchange and then bind a queue to it, with a
+                        small but non-zero delay between these two actions.
+                    </doc>
+                </rule>
+                <rule name="amq_exchange_25">
+                    <doc>
+                        The server MUST ignore the auto-delete field if the
+                        exchange already exists.
+                    </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="no-wait" domain="no-wait"/>
+
+            <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.
+                </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"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <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>
+
+            <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>
+                <rule name="in-use" on-failure="precondition-failed">
+                    <doc>
+                        The server MUST NOT delete an exchange that has bindings
+                        on it, if the if-unused
+                        field is true.
+                    </doc>
+                    <doc type="scenario">
+                        The client declares an exchange, binds a queue to it,
+                        then tries to delete it
+                        setting if-unused to true.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="no-wait" domain="no-wait"/>
+        </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>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="bind" synchronous="1" index="30"
+                label="bind exchange to an exchange">
+
+            <doc>This method binds an exchange to an exchange.</doc>
+
+            <rule name="duplicates">
+                <doc>
+                    A server MUST allow and ignore duplicate bindings - that is,
+                    two or more bind methods for a specific exchanges, with
+                    identical arguments - without treating these as an error.
+                </doc>
+                <doc type="scenario">
+                    A client binds an exchange to an exchange. The client then
+                    repeats the bind (with identical arguments).
+                </doc>
+            </rule>
+
+            <rule name="cyclical">
+                <doc>
+                    A server MUST allow cycles of exchange bindings to be
+                    created including allowing an exchange to be bound to
+                    itself.
+                </doc>
+                <doc type="scenario">
+                    A client declares an exchange and binds it to itself.
+                </doc>
+            </rule>
+
+            <rule name="unique">
+                <doc>
+                    A server MUST not deliver the same message more than once to
+                    a destination exchange, even if the topology of exchanges
+                    and bindings results in multiple (even infinite) routes to
+                    that exchange.
+                </doc>
+                <doc type="scenario">
+                    A client declares an exchange and binds it using multiple
+                    bindings to the amq.topic exchange. The client then
+                    publishes a message to the amq.topic exchange that matches
+                    all the bindings.
+                </doc>
+            </rule>
+
+            <chassis name="server" implement="MUST"/>
+
+            <response name="bind-ok"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <field name="destination" domain="exchange-name"
+                   label="name of the destination exchange to bind to">
+                <doc>Specifies the name of the destination exchange to bind.
+                </doc>
+                <rule name="exchange-existence" on-failure="not-found">
+                    <doc>
+                        A client MUST NOT be allowed to bind a non-existent
+                        destination exchange.
+                    </doc>
+                    <doc type="scenario">
+                        A client attempts to bind an undeclared exchange to an
+                        exchange.
+                    </doc>
+                </rule>
+                <rule name="default-exchange">
+                    <doc>
+                        The server MUST accept a blank exchange name to mean the
+                        default exchange.
+                    </doc>
+                    <doc type="scenario">
+                        The client declares an exchange and binds a blank
+                        exchange
+                        name to it.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="source" domain="exchange-name"
+                   label="name of the source exchange to bind to">
+                <doc>Specifies the name of the source exchange to bind.</doc>
+                <rule name="exchange-existence" on-failure="not-found">
+                    <doc>
+                        A client MUST NOT be allowed to bind a non-existent
+                        source
+                        exchange.
+                    </doc>
+                    <doc type="scenario">
+                        A client attempts to bind an exchange to an undeclared
+                        exchange.
+                    </doc>
+                </rule>
+                <rule name="default-exchange">
+                    <doc>
+                        The server MUST accept a blank exchange name to mean the
+                        default exchange.
+                    </doc>
+                    <doc type="scenario">
+                        The client declares an exchange and binds it to a blank
+                        exchange name.
+                    </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.
+                </doc>
+            </field>
+
+            <field name="no-wait" domain="no-wait"/>
+
+            <field name="arguments" domain="table"
+                   label="arguments for binding">
+                <doc>
+                    A set of arguments for the binding. The syntax and semantics
+                    of these arguments depends on the exchange class.
+                </doc>
+            </field>
+        </method>
+
+        <method name="bind-ok" synchronous="1" index="31"
+                label="confirm bind successful">
+            <doc>This method confirms that the bind was successful.</doc>
+
+            <chassis name="client" implement="MUST"/>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="unbind" synchronous="1" index="40"
+                label="unbind an exchange from an exchange">
+            <doc>This method unbinds an exchange from an exchange.</doc>
+            <rule name="01">
+                <doc>If a unbind fails, the server MUST raise a connection
+                    exception.
+                </doc>
+            </rule>
+            <chassis name="server" implement="MUST"/>
+            <response name="unbind-ok"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <field name="destination" domain="exchange-name">
+                <doc>Specifies the name of the destination exchange to unbind.
+                </doc>
+                <rule name="must-exist" on-failure="not-found">
+                    <doc>
+                        The client MUST NOT attempt to unbind an exchange that
+                        does not exist from an exchange.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to unbind a non-existent exchange
+                        from
+                        an exchange.
+                    </doc>
+                </rule>
+                <rule name="default-exchange">
+                    <doc>
+                        The server MUST accept a blank exchange name to mean the
+                        default exchange.
+                    </doc>
+                    <doc type="scenario">
+                        The client declares an exchange, binds a blank exchange
+                        name to it, and then unbinds a blank exchange name from
+                        it.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="source" domain="exchange-name">
+                <doc>Specifies the name of the source exchange to unbind.</doc>
+                <rule name="must-exist" on-failure="not-found">
+                    <doc>
+                        The client MUST NOT attempt to unbind an exchange from
+                        an
+                        exchange that does not exist.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to unbind an exchange from a
+                        non-existent exchange.
+                    </doc>
+                </rule>
+                <rule name="default-exchange">
+                    <doc>
+                        The server MUST accept a blank exchange name to mean the
+                        default exchange.
+                    </doc>
+                    <doc type="scenario">
+                        The client declares an exchange, binds an exchange to a
+                        blank exchange name, and then unbinds an exchange from a
+                        black exchange name.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="routing-key" domain="shortstr"
+                   label="routing key of binding">
+                <doc>Specifies the routing key of the binding to unbind.</doc>
+            </field>
+
+            <field name="no-wait" domain="no-wait"/>
+
+            <field name="arguments" domain="table"
+                   label="arguments of binding">
+                <doc>Specifies the arguments of the binding to unbind.</doc>
+            </field>
+        </method>
+
+        <method name="unbind-ok" synchronous="1" index="51"
+                label="confirm unbind successful">
+            <doc>This method confirms that the unbind was successful.</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:UNBIND S:UNBIND-OK
+            / C:PURGE S:PURGE-OK
+            / C:DELETE S:DELETE-OK
+        </doc>
+
+        <chassis name="server" implement="MUST"/>
+        <chassis name="client" implement="MUST"/>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <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-declared 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 declares 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 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 declare 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"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <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 declare several queues with an empty
+                        name. The client then
+                        verifies that the server-assigned names are unique and
+                        different.
+                    </doc>
+                </rule>
+                <rule name="reserved" on-failure="access-refused">
+                    <doc>
+                        Queue names starting with "amq." are reserved for
+                        pre-declared and
+                        standardised queues. The client MAY declare a queue
+                        starting with
+                        "amq." if the passive option is set, or the queue
+                        already exists.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to declare a non-existing queue
+                        starting with
+                        "amq." and with the passive option set to zero.
+                    </doc>
+                </rule>
+                <rule name="syntax" on-failure="precondition-failed">
+                    <doc>
+                        The queue name can be empty, or a sequence of these
+                        characters:
+                        letters, digits, hyphen, underscore, period, or colon.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to declare a queue with an illegal
+                        name.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="passive" domain="bit" label="do not create queue">
+                <doc>
+                    If set, the server will reply with Declare-Ok if the queue
+                    already
+                    exists with the same name, and raise an error if not. The
+                    client can
+                    use this to check whether a queue exists without modifying
+                    the
+                    server state. When set, all other method fields except name
+                    and no-wait
+                    are ignored. A declare with both passive and no-wait has no
+                    effect.
+                    Arguments are compared for semantic equivalence.
+                </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>
+                <rule name="equivalent">
+                    <doc>
+                        If not set and the queue exists, the server MUST check
+                        that the
+                        existing queue has the same values for durable,
+                        exclusive, auto-delete,
+                        and arguments fields. The server MUST respond with
+                        Declare-Ok if the
+                        requested queue matches these fields, and MUST raise a
+                        channel exception
+                        if not.
+                    </doc>
+                    <doc type="scenario">
+                        TODO.
+                    </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 name="persistence">
+                    <doc>The server MUST recreate the durable queue after a
+                        restart.
+                    </doc>
+
+                    <doc type="scenario">
+                        Client declares 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 name="types">
+                    <doc>The server MUST support both durable and transient
+                        queues.
+                    </doc>
+                    <doc type="scenario">
+                        A client declares two named queues, one durable and one
+                        transient.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="exclusive" domain="bit"
+                   label="request an exclusive queue">
+                <doc>
+                    Exclusive queues may only be accessed by the current
+                    connection, and are
+                    deleted when that connection closes. Passive declaration of
+                    an exclusive
+                    queue by other connections are not allowed.
+                </doc>
+
+                <rule name="types">
+                    <doc>
+                        The server MUST support both exclusive (private) and
+                        non-exclusive (shared)
+                        queues.
+                    </doc>
+                    <doc type="scenario">
+                        A client declares two named queues, one exclusive and
+                        one non-exclusive.
+                    </doc>
+                </rule>
+
+                <rule name="exclusive" on-failure="resource-locked">
+                    <doc>
+                        The client MAY NOT attempt to use a queue that was
+                        declared as exclusive
+                        by another still-open connection.
+                    </doc>
+                    <doc type="scenario">
+                        One client declares an exclusive queue. A second client
+                        on a different
+                        connection attempts to declare, bind, consume, purge,
+                        delete, or 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. The 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. Applications can
+                    explicitly delete auto-delete queues using the Delete method
+                    as normal.
+                </doc>
+
+                <rule name="pre-existence">
+                    <doc>
+                        The server MUST ignore the auto-delete field if the
+                        queue already exists.
+                    </doc>
+                    <doc type="scenario">
+                        Client declares two named queues, one as auto-delete and
+                        one explicit-delete.
+                        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.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="no-wait" domain="no-wait"/>
+
+            <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.
+                </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="message-count"/>
+
+            <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 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 name="unique">
+                <doc>
+                    A server MUST not deliver the same message more than once to
+                    a queue, even if
+                    the queue has multiple bindings that match the message.
+                </doc>
+                <doc type="scenario">
+                    A client declares a named queue and binds it using multiple
+                    bindings to the
+                    amq.topic exchange. The client then publishes a message that
+                    matches all its
+                    bindings.
+                </doc>
+            </rule>
+
+            <rule name="transient-exchange">
+                <doc>
+                    The server MUST allow a durable queue to bind to a transient
+                    exchange.
+                </doc>
+                <doc type="scenario">
+                    A client declares 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 name="durable-exchange">
+                <doc>
+                    Bindings of durable queues to durable exchanges are
+                    automatically durable
+                    and the server MUST restore such bindings after a server
+                    restart.
+                </doc>
+                <doc type="scenario">
+                    A server declares 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 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 declares a named queue and attempts to bind it to 4
+                    different
+                    exchanges.
+                </doc>
+            </rule>
+
+            <chassis name="server" implement="MUST"/>
+
+            <response name="bind-ok"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <field name="queue" domain="queue-name">
+                <doc>Specifies the name of the queue to bind.</doc>
+                <rule name="queue-known" on-failure="not-found">
+                    <doc>
+                        The client MUST either specify a queue name or have
+                        previously declared a
+                        queue on the same channel
+                    </doc>
+                    <doc type="scenario">
+                        The client opens a channel and attempts to bind an
+                        unnamed queue.
+                    </doc>
+                </rule>
+                <rule name="must-exist" on-failure="not-found">
+                    <doc>
+                        The client MUST NOT attempt to bind a queue that does
+                        not exist.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to bind a non-existent queue.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="exchange" domain="exchange-name"
+                   label="name of the exchange to bind to">
+                <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>
+                <rule name="default-exchange">
+                    <doc>
+                        The server MUST accept a blank exchange name to mean the
+                        default exchange.
+                    </doc>
+                    <doc type="scenario">
+                        The client declares a queue and binds it to a blank
+                        exchange name.
+                    </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
+                        publisher sends the exchange a message with routing key
+                        R, then the message
+                        MUST be passed to the message queue if K = R.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="no-wait" domain="no-wait"/>
+
+            <field name="arguments" domain="table"
+                   label="arguments for binding">
+                <doc>
+                    A set of arguments for the binding. The syntax and semantics
+                    of these arguments
+                    depends on the exchange class.
+                </doc>
+            </field>
+        </method>
+
+        <method name="bind-ok" synchronous="1" index="21"
+                label="confirm bind successful">
+            <doc>This method confirms that the bind was successful.</doc>
+
+            <chassis name="client" implement="MUST"/>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="unbind" synchronous="1" index="50"
+                label="unbind a queue from an exchange">
+            <doc>This method unbinds a queue from an exchange.</doc>
+            <rule name="01">
+                <doc>If a unbind fails, the server MUST raise a connection
+                    exception.
+                </doc>
+            </rule>
+            <chassis name="server" implement="MUST"/>
+            <response name="unbind-ok"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <field name="queue" domain="queue-name">
+                <doc>Specifies the name of the queue to unbind.</doc>
+                <rule name="queue-known" on-failure="not-found">
+                    <doc>
+                        The client MUST either specify a queue name or have
+                        previously declared a
+                        queue on the same channel
+                    </doc>
+                    <doc type="scenario">
+                        The client opens a channel and attempts to unbind an
+                        unnamed queue.
+                    </doc>
+                </rule>
+                <rule name="must-exist" on-failure="not-found">
+                    <doc>
+                        The client MUST NOT attempt to unbind a queue that does
+                        not exist.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to unbind a non-existent queue.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="exchange" domain="exchange-name">
+                <doc>The name of the exchange to unbind from.</doc>
+                <rule name="must-exist" on-failure="not-found">
+                    <doc>
+                        The client MUST NOT attempt to unbind a queue from an
+                        exchange that
+                        does not exist.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to unbind a queue from a
+                        non-existent exchange.
+                    </doc>
+                </rule>
+                <rule name="default-exchange">
+                    <doc>
+                        The server MUST accept a blank exchange name to mean the
+                        default exchange.
+                    </doc>
+                    <doc type="scenario">
+                        The client declares a queue and binds it to a blank
+                        exchange name.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="routing-key" domain="shortstr"
+                   label="routing key of binding">
+                <doc>Specifies the routing key of the binding to unbind.</doc>
+            </field>
+
+            <field name="arguments" domain="table" label="arguments of binding">
+                <doc>Specifies the arguments of the binding to unbind.</doc>
+            </field>
+        </method>
+
+        <method name="unbind-ok" synchronous="1" index="51"
+                label="confirm unbind successful">
+            <doc>This method confirms that the unbind was successful.</doc>
+            <chassis name="client" implement="MUST"/>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="purge" synchronous="1" index="30" label="purge a queue">
+            <doc>
+                This method removes all messages from a queue which are not
+                awaiting
+                acknowledgment.
+            </doc>
+
+            <rule name="02">
+                <doc>
+                    The server MUST NOT purge messages that have already been
+                    sent to a client
+                    but not yet acknowledged.
+                </doc>
+            </rule>
+
+            <rule name="03">
+                <doc>
+                    The server MAY implement a purge queue or log that allows
+                    system administrators
+                    to recover accidentally-purged messages. The server SHOULD
+                    NOT keep purged
+                    messages in the same storage spaces as the live messages
+                    since the volumes of
+                    purged messages may get very large.
+                </doc>
+            </rule>
+
+            <chassis name="server" implement="MUST"/>
+
+            <response name="purge-ok"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <field name="queue" domain="queue-name">
+                <doc>Specifies the name of the queue to purge.</doc>
+                <rule name="queue-known" on-failure="not-found">
+                    <doc>
+                        The client MUST either specify a queue name or have
+                        previously declared a
+                        queue on the same channel
+                    </doc>
+                    <doc type="scenario">
+                        The client opens a channel and attempts to purge an
+                        unnamed queue.
+                    </doc>
+                </rule>
+                <rule name="must-exist" on-failure="not-found">
+                    <doc>
+                        The client MUST NOT attempt to purge a queue that does
+                        not exist.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to purge a non-existent queue.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="no-wait" domain="no-wait"/>
+        </method>
+
+        <method name="purge-ok" synchronous="1" index="31"
+                label="confirms a queue purge">
+            <doc>This method confirms the purge of a queue.</doc>
+
+            <chassis name="client" implement="MUST"/>
+
+            <field name="message-count" domain="message-count">
+                <doc>
+                    Reports the number of messages purged.
+                </doc>
+            </field>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="delete" synchronous="1" index="40" label="delete a queue">
+            <doc>
+                This method deletes a queue. When a queue is deleted any pending
+                messages are sent
+                to a dead-letter queue if this is defined in the server
+                configuration, and all
+                consumers on the queue are cancelled.
+            </doc>
+
+            <rule name="01">
+                <doc>
+                    The server SHOULD use a dead-letter queue to hold messages
+                    that were pending on
+                    a deleted queue, and MAY provide facilities for a system
+                    administrator to move
+                    these messages back to an active queue.
+                </doc>
+            </rule>
+
+            <chassis name="server" implement="MUST"/>
+
+            <response name="delete-ok"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <field name="queue" domain="queue-name">
+                <doc>Specifies the name of the queue to delete.</doc>
+                <rule name="queue-known" on-failure="not-found">
+                    <doc>
+                        The client MUST either specify a queue name or have
+                        previously declared a
+                        queue on the same channel
+                    </doc>
+                    <doc type="scenario">
+                        The client opens a channel and attempts to delete an
+                        unnamed queue.
+                    </doc>
+                </rule>
+                <rule name="must-exist" on-failure="not-found">
+                    <doc>
+                        The client MUST NOT attempt to delete a queue that does
+                        not exist.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to delete a non-existent queue.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="if-unused" domain="bit" label="delete only if unused">
+                <doc>
+                    If set, the server will only delete the queue if it has no
+                    consumers. If the
+                    queue has consumers the server does does not delete it but
+                    raises a channel
+                    exception instead.
+                </doc>
+                <rule name="in-use" on-failure="precondition-failed">
+                    <doc>
+                        The server MUST NOT delete a queue that has consumers on
+                        it, if the if-unused
+                        field is true.
+                    </doc>
+                    <doc type="scenario">
+                        The client declares a queue, and consumes from it, then
+                        tries to delete it
+                        setting if-unused to true.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="if-empty" domain="bit" label="delete only if empty">
+                <doc>
+                    If set, the server will only delete the queue if it has no
+                    messages.
+                </doc>
+                <rule name="not-empty" on-failure="precondition-failed">
+                    <doc>
+                        The server MUST NOT delete a queue that has messages on
+                        it, if the
+                        if-empty field is true.
+                    </doc>
+                    <doc type="scenario">
+                        The client declares a queue, binds it and publishes some
+                        messages into it,
+                        then tries to delete it setting if-empty to true.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="no-wait" domain="no-wait"/>
+        </method>
+
+        <method name="delete-ok" synchronous="1" index="41"
+                label="confirm deletion of a queue">
+            <doc>This method confirms the deletion of a queue.</doc>
+
+            <chassis name="client" implement="MUST"/>
+
+            <field name="message-count" domain="message-count">
+                <doc>Reports the number of messages deleted.</doc>
+            </field>
+        </method>
+    </class>
+
+    <!-- ==  BASIC  ============================================================ -->
+
+    <class name="basic" handler="channel" index="60"
+           label="work with basic content">
+        <doc>
+            The Basic class provides methods that support an industry-standard
+            messaging model.
+        </doc>
+
+        <doc type="grammar">
+            basic = C:QOS S:QOS-OK
+            / C:CONSUME S:CONSUME-OK
+            / C:CANCEL S:CANCEL-OK
+            / C:PUBLISH content
+            / S:RETURN content
+            / S:DELIVER content
+            / C:GET ( S:GET-OK content / S:GET-EMPTY )
+            / C:ACK
+            / S:ACK
+            / C:REJECT
+            / C:NACK
+            / S:NACK
+            / C:RECOVER-ASYNC
+            / C:RECOVER S:RECOVER-OK
+        </doc>
+
+        <chassis name="server" implement="MUST"/>
+        <chassis name="client" implement="MAY"/>
+
+        <rule name="01">
+            <doc>
+                The server SHOULD respect the persistent property of basic
+                messages and
+                SHOULD make a best-effort to hold persistent basic messages on a
+                reliable
+                storage mechanism.
+            </doc>
+            <doc type="scenario">
+                Send a persistent message to queue, stop server, restart server
+                and then
+                verify whether message is still present. Assumes that queues are
+                durable.
+                Persistence without durable queues makes no sense.
+            </doc>
+        </rule>
+
+        <rule name="02">
+            <doc>
+                The server MUST NOT discard a persistent basic message in case
+                of a queue
+                overflow.
+            </doc>
+            <doc type="scenario">
+                Declare a queue overflow situation with persistent messages and
+                verify that
+                messages do not get lost (presumably the server will write them
+                to disk).
+            </doc>
+        </rule>
+
+        <rule name="03">
+            <doc>
+                The server MAY use the Channel.Flow method to slow or stop a
+                basic message
+                publisher when necessary.
+            </doc>
+            <doc type="scenario">
+                Declare a queue overflow situation with non-persistent messages
+                and verify
+                whether the server responds with Channel.Flow or not. Repeat
+                with persistent
+                messages.
+            </doc>
+        </rule>
+
+        <rule name="04">
+            <doc>
+                The server MAY overflow non-persistent basic messages to
+                persistent
+                storage.
+            </doc>
+            <!-- Test scenario: untestable -->
+        </rule>
+
+        <rule name="05">
+            <doc>
+                The server MAY discard or dead-letter non-persistent basic
+                messages on a
+                priority basis if the queue size exceeds some configured limit.
+            </doc>
+            <!-- Test scenario: untestable -->
+        </rule>
+
+        <rule name="06">
+            <doc>
+                The server MUST implement at least 2 priority levels for basic
+                messages,
+                where priorities 0-4 and 5-9 are treated as two distinct levels.
+            </doc>
+            <doc type="scenario">
+                Send a number of priority 0 messages to a queue. Send one
+                priority 9
+                message. Consume messages from the queue and verify that the
+                first message
+                received was priority 9.
+            </doc>
+        </rule>
+
+        <rule name="07">
+            <doc>
+                The server MAY implement up to 10 priority levels.
+            </doc>
+            <doc type="scenario">
+                Send a number of messages with mixed priorities to a queue, so
+                that all
+                priority values from 0 to 9 are exercised. A good scenario would
+                be ten
+                messages in low-to-high priority. Consume from queue and verify
+                how many
+                priority levels emerge.
+            </doc>
+        </rule>
+
+        <rule name="08">
+            <doc>
+                The server MUST deliver messages of the same priority in order
+                irrespective of
+                their individual persistence.
+            </doc>
+            <doc type="scenario">
+                Send a set of messages with the same priority but different
+                persistence
+                settings to a queue. Consume and verify that messages arrive in
+                same order
+                as originally published.
+            </doc>
+        </rule>
+
+        <rule name="09">
+            <doc>
+                The server MUST support un-acknowledged delivery of Basic
+                content, i.e.
+                consumers with the no-ack field set to TRUE.
+            </doc>
+        </rule>
+
+        <rule name="10">
+            <doc>
+                The server MUST support explicitly acknowledged delivery of
+                Basic content,
+                i.e. consumers with the no-ack field set to FALSE.
+            </doc>
+            <doc type="scenario">
+                Declare a queue and a consumer using explicit acknowledgements.
+                Publish a
+                set of messages to the queue. Consume the messages but
+                acknowledge only
+                half of them. Disconnect and reconnect, and consume from the
+                queue.
+                Verify that the remaining messages are received.
+            </doc>
+        </rule>
+
+        <!--  These are the properties for a Basic content  -->
+
+        <!--  MIME typing -->
+        <field name="content-type" domain="shortstr" label="MIME content type"/>
+        <!--  MIME typing -->
+        <field name="content-encoding" domain="shortstr"
+               label="MIME content encoding"/>
+        <!--  For applications, and for header exchange routing -->
+        <field name="headers" domain="table"
+               label="message header field table"/>
+        <!--  For queues that implement persistence -->
+        <field name="delivery-mode" domain="octet"
+               label="non-persistent (1) or persistent (2)"/>
+        <!--  For queues that implement priorities -->
+        <field name="priority" domain="octet" label="message priority, 0 to 9"/>
+        <!--  For application use, no formal behaviour -->
+        <field name="correlation-id" domain="shortstr"
+               label="application correlation identifier"/>
+        <!--  For application use, no formal behaviour but may hold the
           name of a private response queue, when used in request messages -->
-    <field name = "reply-to"        domain = "shortstr"   label = "address to reply to" />
-    <!--  For implementation use, no formal behaviour -->
-    <field name = "expiration"      domain = "shortstr"   label = "message expiration specification" />
-    <!--  For application use, no formal behaviour -->
-    <field name = "message-id"      domain = "shortstr"   label = "application message identifier" />
-    <!--  For application use, no formal behaviour -->
-    <field name = "timestamp"       domain = "timestamp"  label = "message timestamp" />
-    <!--  For application use, no formal behaviour -->
-    <field name = "type"            domain = "shortstr"   label = "message type name" />
-    <!--  For application use, no formal behaviour -->
-    <field name = "user-id"         domain = "shortstr"   label = "creating user id" />
-    <!--  For application use, no formal behaviour -->
-    <field name = "app-id"          domain = "shortstr"   label = "creating application id" />
-    <!--  Deprecated, was old cluster-id property -->
-    <field name = "reserved"        domain = "shortstr"   label = "reserved, must be empty" />
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "qos" synchronous = "1" index = "10" label = "specify quality of service">
-      <doc>
-        This method requests a specific quality of service. The QoS can be specified for the
-        current channel or for all channels on the connection. The particular properties and
-        semantics of a qos method always depend on the content class semantics. Though the
-        qos method could in principle apply to both peers, it is currently meaningful only
-        for the server.
-      </doc>
-
-      <chassis name = "server" implement = "MUST" />
-      <response name = "qos-ok" />
-
-      <field name = "prefetch-size" domain = "long" label = "prefetch window in octets">
-        <doc>
-          The client can request that messages be sent in advance so that when the client
-          finishes processing a message, the following message is already held locally,
-          rather than needing to be sent down the channel. Prefetching gives a performance
-          improvement. This field specifies the prefetch window size in octets. The server
-          will send a message in advance if it is equal to or smaller in size than the
-          available prefetch size (and also falls into other prefetch limits). May be set
-          to zero, meaning "no specific limit", although other prefetch limits may still
-          apply. The prefetch-size is ignored if the no-ack option is set.
-        </doc>
-        <rule name = "01">
-          <doc>
-            The server MUST ignore this setting when the client is not processing any
-            messages - i.e. the prefetch size does not limit the transfer of single
-            messages to a client, only the sending in advance of more messages while
-            the client still has one or more unacknowledged messages.
-          </doc>
-          <doc type = "scenario">
-            Define a QoS prefetch-size limit and send a single message that exceeds
-            that limit.  Verify that the message arrives correctly.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "prefetch-count" domain = "short" label = "prefetch window in messages">
-        <doc>
-          Specifies a prefetch window in terms of whole messages. This field may be used
-          in combination with the prefetch-size field; a message will only be sent in
-          advance if both prefetch windows (and those at the channel and connection level)
-          allow it. The prefetch-count is ignored if the no-ack option is set.
-        </doc>
-        <rule name = "01">
-          <doc>
-            The server may send less data in advance than allowed by the client's
-            specified prefetch windows but it MUST NOT send more.
-          </doc>
-          <doc type = "scenario">
-            Define a QoS prefetch-size limit and a prefetch-count limit greater than
-            one.  Send multiple messages that exceed the prefetch size.  Verify that
-            no more than one message arrives at once.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "global" domain = "bit" label = "apply to entire connection">
-        <doc>
-          RabbitMQ has reinterpreted this field. The original
-          specification said: "By default the QoS settings apply to
-          the current channel only. If this field is set, they are
-          applied to the entire connection." Instead, RabbitMQ takes
-          global=false to mean that the QoS settings should apply
-          per-consumer (for new consumers on the channel; existing
-          ones being unaffected) and global=true to mean that the QoS
-          settings should apply per-channel.
-        </doc>
-      </field>
-    </method>
-
-    <method name = "qos-ok" synchronous = "1" index = "11" label = "confirm the requested qos">
-      <doc>
-        This method tells the client that the requested QoS levels could be handled by the
-        server. The requested QoS applies to all active consumers until a new QoS is
-        defined.
-      </doc>
-      <chassis name = "client" implement = "MUST" />
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "consume" synchronous = "1" index = "20" label = "start a queue consumer">
-      <doc>
-        This method asks the server to start a "consumer", which is a transient request for
-        messages from a specific queue. Consumers last as long as the channel they were
-        declared on, or until the client cancels them.
-      </doc>
-
-      <rule name = "01">
-        <doc>
-          The server SHOULD support at least 16 consumers per queue, and ideally, impose
-          no limit except as defined by available resources.
-        </doc>
-        <doc type = "scenario">
-          Declare a queue and create consumers on that queue until the server closes the
-          connection. Verify that the number of consumers created was at least sixteen
-          and report the total number.
-        </doc>
-      </rule>
-
-      <chassis name = "server" implement = "MUST" />
-      <response name = "consume-ok" />
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <field name = "queue" domain = "queue-name">
-        <doc>Specifies the name of the queue to consume from.</doc>
-      </field>
-
-      <field name = "consumer-tag" domain = "consumer-tag">
-        <doc>
-          Specifies the identifier for the consumer. The consumer tag is local to a
-          channel, so two clients can use the same consumer tags. If this field is
-          empty the server will generate a unique tag.
-        </doc>
-        <rule name = "01" on-failure = "not-allowed">
-          <doc>
-            The client MUST NOT specify a tag that refers to an existing consumer.
-          </doc>
-          <doc type = "scenario">
-            Attempt to create two consumers with the same non-empty tag, on the
-            same channel.
-          </doc>
-        </rule>
-        <rule name = "02" on-failure = "not-allowed">
-          <doc>
-            The consumer tag is valid only within the channel from which the
-            consumer was created. I.e. a client MUST NOT create a consumer in one
-            channel and then use it in another.
-          </doc>
-          <doc type = "scenario">
-            Attempt to create a consumer in one channel, then use in another channel,
-            in which consumers have also been created (to test that the server uses
-            unique consumer tags).
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "no-local" domain = "no-local" />
-
-      <field name = "no-ack" domain = "no-ack" />
-
-      <field name = "exclusive" domain = "bit" label = "request exclusive access">
-        <doc>
-          Request exclusive consumer access, meaning only this consumer can access the
-          queue.
-        </doc>
-
-        <rule name = "01" on-failure = "access-refused">
-          <doc>
-            The client MAY NOT gain exclusive access to a queue that already has
-            active consumers.
-          </doc>
-          <doc type = "scenario">
-            Open two connections to a server, and in one connection declare a shared
-            (non-exclusive) queue and then consume from the queue.  In the second
-            connection attempt to consume from the same queue using the exclusive
-            option.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "no-wait" domain = "no-wait" />
-
-      <field name = "arguments" domain = "table" label = "arguments for declaration">
-        <doc>
-          A set of arguments for the consume. The syntax and semantics of these
-          arguments depends on the server implementation.
-        </doc>
-      </field>
-    </method>
-
-    <method name = "consume-ok" synchronous = "1" index = "21" label = "confirm a new consumer">
-      <doc>
-        The server provides the client with a consumer tag, which is used by the client
-        for methods called on the consumer at a later stage.
-      </doc>
-      <chassis name = "client" implement = "MUST" />
-      <field name = "consumer-tag" domain = "consumer-tag">
-        <doc>
-          Holds the consumer tag specified by the client or provided by the server.
-        </doc>
-      </field>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "cancel" synchronous = "1" index = "30" label = "end a queue consumer">
-      <doc>
-        This method cancels a consumer. This does not affect already delivered
-        messages, but it does mean the server will not send any more messages for
-        that consumer. The client may receive an arbitrary number of messages in
-        between sending the cancel method and receiving the cancel-ok reply.
-
-        It may also be sent from the server to the client in the event
-        of the consumer being unexpectedly cancelled (i.e. cancelled
-        for any reason other than the server receiving the
-        corresponding basic.cancel from the client). This allows
-        clients to be notified of the loss of consumers due to events
-        such as queue deletion. Note that as it is not a MUST for
-        clients to accept this method from the server, it is advisable
-        for the broker to be able to identify those clients that are
-        capable of accepting the method, through some means of
-        capability negotiation.
-      </doc>
-
-      <rule name = "01">
-        <doc>
-          If the queue does not exist the server MUST ignore the cancel method, so
-          long as the consumer tag is valid for that channel.
-        </doc>
-        <doc type = "scenario">
-          TODO.
-        </doc>
-      </rule>
-
-      <chassis name = "server" implement = "MUST" />
-      <chassis name = "client" implement = "SHOULD" />
-      <response name = "cancel-ok" />
-
-      <field name = "consumer-tag" domain = "consumer-tag" />
-      <field name = "no-wait" domain = "no-wait" />
-    </method>
-
-    <method name = "cancel-ok" synchronous = "1" index = "31" label = "confirm a cancelled consumer">
-      <doc>
-        This method confirms that the cancellation was completed.
-      </doc>
-      <chassis name = "client" implement = "MUST" />
-      <chassis name = "server" implement = "MAY" />
-      <field name = "consumer-tag" domain = "consumer-tag" />
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "publish" content = "1" index = "40" label = "publish a message">
-      <doc>
-        This method publishes a message to a specific exchange. The message will be routed
-        to queues as defined by the exchange configuration and distributed to any active
-        consumers when the transaction, if any, is committed.
-      </doc>
-
-      <chassis name = "server" implement = "MUST" />
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <field name = "exchange" domain = "exchange-name">
-        <doc>
-          Specifies the name of the exchange to publish to. The exchange name can be
-          empty, meaning the default exchange. If the exchange name is specified, and that
-          exchange does not exist, the server will raise a channel exception.
-        </doc>
-
-        <rule name = "must-exist" on-failure = "not-found">
-          <doc>
-            The client MUST NOT attempt to publish a content to an exchange that
-            does not exist.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to publish a content to a non-existent exchange.
-          </doc>
-        </rule>
-        <rule name = "default-exchange">
-          <doc>
-            The server MUST accept a blank exchange name to mean the default exchange.
-          </doc>
-          <doc type = "scenario">
-            The client declares a queue and binds it to a blank exchange name.
-          </doc>
-        </rule>
-        <rule name = "02">
-          <doc>
-            If the exchange was declared as an internal exchange, the server MUST raise
-            a channel exception with a reply code 403 (access refused).
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
-        </rule>
-
-        <rule name = "03">
-          <doc>
-            The exchange MAY refuse basic content in which case it MUST raise a channel
-            exception with reply code 540 (not implemented).
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "routing-key" domain = "shortstr" label = "Message routing key">
-        <doc>
-          Specifies the routing key for the message. The routing key is used for routing
-          messages depending on the exchange configuration.
-        </doc>
-      </field>
-
-      <field name = "mandatory" domain = "bit" label = "indicate mandatory routing">
-        <doc>
-          This flag tells the server how to react if the message cannot be routed to a
-          queue. If this flag is set, the server will return an unroutable message with a
-          Return method. If this flag is zero, the server silently drops the message.
-        </doc>
-
-        <rule name = "01">
-          <doc>
-            The server SHOULD implement the mandatory flag.
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "immediate" domain = "bit" label = "request immediate delivery">
-        <doc>
-          This flag tells the server how to react if the message cannot be routed to a
-          queue consumer immediately. If this flag is set, the server will return an
-          undeliverable message with a Return method. If this flag is zero, the server
-          will queue the message, but with no guarantee that it will ever be consumed.
-        </doc>
-
-        <rule name = "01">
-          <doc>
-            The server SHOULD implement the immediate flag.
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
-        </rule>
-      </field>
-    </method>
-
-    <method name = "return" content = "1" index = "50" label = "return a failed message">
-      <doc>
-        This method returns an undeliverable message that was published with the "immediate"
-        flag set, or an unroutable message published with the "mandatory" flag set. The
-        reply code and text provide information about the reason that the message was
-        undeliverable.
-      </doc>
-
-      <chassis name = "client" implement = "MUST" />
-
-      <field name = "reply-code" domain = "reply-code" />
-      <field name = "reply-text" domain = "reply-text" />
-
-      <field name = "exchange" domain = "exchange-name">
-        <doc>
-          Specifies the name of the exchange that the message was originally published
-          to.  May be empty, meaning the default exchange.
-        </doc>
-      </field>
-
-      <field name = "routing-key" domain = "shortstr" label = "Message routing key">
-        <doc>
-          Specifies the routing key name specified when the message was published.
-        </doc>
-      </field>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "deliver" content = "1" index = "60"
-      label = "notify the client of a consumer message">
-      <doc>
-        This method delivers a message to the client, via a consumer. In the asynchronous
-        message delivery model, the client starts a consumer using the Consume method, then
-        the server responds with Deliver methods as and when messages arrive for that
-        consumer.
-      </doc>
-
-      <rule name = "01">
-        <doc>
-          The server SHOULD track the number of times a message has been delivered to
-          clients and when a message is redelivered a certain number of times - e.g. 5
-          times - without being acknowledged, the server SHOULD consider the message to be
-          unprocessable (possibly causing client applications to abort), and move the
-          message to a dead letter queue.
-        </doc>
-        <doc type = "scenario">
-          TODO.
-        </doc>
-      </rule>
-
-      <chassis name = "client" implement = "MUST" />
-
-      <field name = "consumer-tag" domain = "consumer-tag" />
-      <field name = "delivery-tag" domain = "delivery-tag" />
-      <field name = "redelivered" domain = "redelivered" />
-
-      <field name = "exchange" domain = "exchange-name">
-        <doc>
-          Specifies the name of the exchange that the message was originally published to.
-          May be empty, indicating the default exchange.
-        </doc>
-      </field>
-
-      <field name = "routing-key" domain = "shortstr" label = "Message routing key">
-        <doc>Specifies the routing key name specified when the message was published.</doc>
-      </field>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "get" synchronous = "1" index = "70" label = "direct access to a queue">
-      <doc>
-        This method provides a direct access to the messages in a queue using a synchronous
-        dialogue that is designed for specific types of application where synchronous
-        functionality is more important than performance.
-      </doc>
-
-      <response name = "get-ok" />
-      <response name = "get-empty" />
-      <chassis name = "server" implement = "MUST" />
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <field name = "queue" domain = "queue-name">
-        <doc>Specifies the name of the queue to get a message from.</doc>
-      </field>
-      <field name = "no-ack" domain = "no-ack" />
-    </method>
-
-    <method name = "get-ok" synchronous = "1" content = "1" index = "71"
-      label = "provide client with a message">
-      <doc>
-        This method delivers a message to the client following a get method. A message
-        delivered by 'get-ok' must be acknowledged unless the no-ack option was set in the
-        get method.
-      </doc>
-
-      <chassis name = "client" implement = "MAY" />
-
-      <field name = "delivery-tag" domain = "delivery-tag" />
-      <field name = "redelivered" domain = "redelivered" />
-      <field name = "exchange" domain = "exchange-name">
-        <doc>
-          Specifies the name of the exchange that the message was originally published to.
-          If empty, the message was published to the default exchange.
-        </doc>
-      </field>
-
-      <field name = "routing-key" domain = "shortstr" label = "Message routing key">
-        <doc>Specifies the routing key name specified when the message was published.</doc>
-      </field>
-
-      <field name = "message-count" domain = "message-count" />
-    </method>
-
-    <method name = "get-empty" synchronous = "1" index = "72"
-      label = "indicate no messages available">
-      <doc>
-        This method tells the client that the queue has no messages available for the
-        client.
-      </doc>
-      <chassis name = "client" implement = "MAY" />
-      <!-- Deprecated: "cluster-id", must be empty -->
-      <field name = "reserved-1" type = "shortstr" reserved = "1" />
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "ack" index = "80" label = "acknowledge one or more messages">
-      <doc>
-        When sent by the client, this method acknowledges one or more
-        messages delivered via the Deliver or Get-Ok methods.
-
-        When sent by server, this method acknowledges one or more
-        messages published with the Publish method on a channel in
-        confirm mode.
-
-        The acknowledgement can be for a single message or a set of
-        messages up to and including a specific message.
-      </doc>
-
-      <chassis name = "server" implement = "MUST" />
-      <chassis name ="client" implement = "MUST"/>
-
-      <field name = "delivery-tag" domain = "delivery-tag" />
-      <field name = "multiple" domain = "bit" label = "acknowledge multiple messages">
-        <doc>
-          If set to 1, the delivery tag is treated as "up to and
-          including", so that multiple messages can be acknowledged
-          with a single method. If set to zero, the delivery tag
-          refers to a single message. If the multiple field is 1, and
-          the delivery tag is zero, this indicates acknowledgement of
-          all outstanding messages.
-        </doc>
-        <rule name = "exists" on-failure = "precondition-failed">
-          <doc>
-            A message MUST not be acknowledged more than once.  The
-            receiving peer MUST validate that a non-zero delivery-tag
-            refers to a delivered message, and raise a channel
-            exception if this is not the case. On a transacted
-            channel, this check MUST be done immediately and not
-            delayed until a Tx.Commit.
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
-        </rule>
-      </field>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "reject" index = "90" label = "reject an incoming message">
-      <doc>
-        This method allows a client to reject a message. It can be used to interrupt and
-        cancel large incoming messages, or return untreatable messages to their original
-        queue.
-      </doc>
-
-      <rule name = "01">
-        <doc>
-          The server SHOULD be capable of accepting and process the Reject method while
-          sending message content with a Deliver or Get-Ok method. I.e. the server should
-          read and process incoming methods while sending output frames. To cancel a
-          partially-send content, the server sends a content body frame of size 1 (i.e.
-          with no data except the frame-end octet).
-        </doc>
-      </rule>
-
-      <rule name = "02">
-        <doc>
-          The server SHOULD interpret this method as meaning that the client is unable to
-          process the message at this time.
-        </doc>
-        <doc type = "scenario">
-          TODO.
-        </doc>
-      </rule>
-
-      <rule name = "03">
-        <doc>
-          The client MUST NOT use this method as a means of selecting messages to process.
-        </doc>
-        <doc type = "scenario">
-          TODO.
-        </doc>
-      </rule>
-
-      <chassis name = "server" implement = "MUST" />
-
-      <field name = "delivery-tag" domain = "delivery-tag" />
-
-      <field name = "requeue" domain = "bit" label = "requeue the message">
-        <doc>
-          If requeue is true, the server will attempt to requeue the message.  If requeue
-          is false or the requeue  attempt fails the messages are discarded or dead-lettered.
-        </doc>
-
-        <rule name = "01">
-          <doc>
-            The server MUST NOT deliver the message to the same client within the
-            context of the current channel. The recommended strategy is to attempt to
-            deliver the message to an alternative consumer, and if that is not possible,
-            to move the message to a dead-letter queue. The server MAY use more
-            sophisticated tracking to hold the message on the queue and redeliver it to
-            the same client at a later stage.
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
-        </rule>
-      </field>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "recover-async" index = "100" label = "redeliver unacknowledged messages"
-        deprecated = "1">
-      <doc>
-        This method asks the server to redeliver all unacknowledged messages on a
-        specified channel. Zero or more messages may be redelivered.  This method
-        is deprecated in favour of the synchronous Recover/Recover-Ok.
-      </doc>
-      <rule name = "01">
-        <doc>
-          The server MUST set the redelivered flag on all messages that are resent.
-        </doc>
-        <doc type = "scenario">
-          TODO.
-        </doc>
-      </rule>
-      <chassis name = "server" implement = "MAY" />
-      <field name = "requeue" domain = "bit" label = "requeue the message">
-        <doc>
-          If this field is zero, the message will be redelivered to the original
-          recipient. If this bit is 1, the server will attempt to requeue the message,
-          potentially then delivering it to an alternative subscriber.
-        </doc>
-      </field>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "recover" index = "110" label = "redeliver unacknowledged messages">
-      <doc>
-        This method asks the server to redeliver all unacknowledged messages on a
-        specified channel. Zero or more messages may be redelivered.  This method
-        replaces the asynchronous Recover.
-      </doc>
-      <rule name = "01">
-        <doc>
-          The server MUST set the redelivered flag on all messages that are resent.
-        </doc>
-        <doc type = "scenario">
-          TODO.
-        </doc>
-      </rule>
-      <chassis name = "server" implement = "MUST" />
-      <field name = "requeue" domain = "bit" label = "requeue the message">
-        <doc>
-          If this field is zero, the message will be redelivered to the original
-          recipient. If this bit is 1, the server will attempt to requeue the message,
-          potentially then delivering it to an alternative subscriber.
-        </doc>
-      </field>
-    </method>
-
-    <method name = "recover-ok" synchronous = "1" index = "111" label = "confirm recovery">
-      <doc>
-        This method acknowledges a Basic.Recover method.
-      </doc>
-      <chassis name = "client" implement = "MUST" />
-    </method>
-
-    <method name = "nack" index = "120" label = "reject one or more incoming messages">
-      <doc>
-        This method allows a client to reject one or more incoming messages. It can be
-        used to interrupt and cancel large incoming messages, or return untreatable
-        messages to their original queue.
-
-        This method is also used by the server to inform publishers on channels in
-        confirm mode of unhandled messages.  If a publisher receives this method, it
-        probably needs to republish the offending messages.
-      </doc>
-
-      <rule name = "01">
-        <doc>
-          The server SHOULD be capable of accepting and processing the Nack method while
-          sending message content with a Deliver or Get-Ok method. I.e. the server should
-          read and process incoming methods while sending output frames. To cancel a
-          partially-send content, the server sends a content body frame of size 1 (i.e.
-          with no data except the frame-end octet).
-        </doc>
-      </rule>
-
-      <rule name = "02">
-        <doc>
-          The server SHOULD interpret this method as meaning that the client is unable to
-          process the message at this time.
-        </doc>
-        <doc type = "scenario">
-          TODO.
-        </doc>
-      </rule>
-
-      <rule name = "03">
-        <doc>
-          The client MUST NOT use this method as a means of selecting messages to process.
-        </doc>
-        <doc type = "scenario">
-          TODO.
-        </doc>
-      </rule>
-
-      <rule name = "04">
-        <doc>
-          A client publishing messages to a channel in confirm mode SHOULD be capable of accepting
-          and somehow handling the Nack method.
-        </doc>
-        <doc type = "scenario">
-          TODO
-        </doc>
-      </rule>
-
-      <chassis name = "server" implement = "MUST" />
-      <chassis name = "client" implement = "MUST" />
-
-      <field name = "delivery-tag" domain = "delivery-tag" />
-
-      <field name = "multiple" domain = "bit" label = "reject multiple messages">
-        <doc>
-          If set to 1, the delivery tag is treated as "up to and
-          including", so that multiple messages can be rejected
-          with a single method. If set to zero, the delivery tag
-          refers to a single message. If the multiple field is 1, and
-          the delivery tag is zero, this indicates rejection of
-          all outstanding messages.
-        </doc>
-        <rule name = "exists" on-failure = "precondition-failed">
-          <doc>
-            A message MUST not be rejected more than once.  The
-            receiving peer MUST validate that a non-zero delivery-tag
-            refers to an unacknowledged, delivered message, and
-            raise a channel exception if this is not the case.
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "requeue" domain = "bit" label = "requeue the message">
-        <doc>
-          If requeue is true, the server will attempt to requeue the message.  If requeue
-          is false or the requeue  attempt fails the messages are discarded or dead-lettered.
-          Clients receiving the Nack methods should ignore this flag.
-        </doc>
-
-        <rule name = "01">
-          <doc>
-            The server MUST NOT deliver the message to the same client within the
-            context of the current channel. The recommended strategy is to attempt to
-            deliver the message to an alternative consumer, and if that is not possible,
-            to move the message to a dead-letter queue. The server MAY use more
-            sophisticated tracking to hold the message on the queue and redeliver it to
-            the same client at a later stage.
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
-        </rule>
-      </field>
-    </method>
-
-  </class>
-
-  <!-- ==  TX  =============================================================== -->
-
-  <class name = "tx" handler = "channel" index = "90" label = "work with transactions">
-    <doc>
-      The Tx class allows publish and ack operations to be batched into atomic
-      units of work.  The intention is that all publish and ack requests issued
-      within a transaction will complete successfully or none of them will.
-      Servers SHOULD implement atomic transactions at least where all publish
-      or ack requests affect a single queue.  Transactions that cover multiple
-      queues may be non-atomic, given that queues can be created and destroyed
-      asynchronously, and such events do not form part of any transaction.
-      Further, the behaviour of transactions with respect to the immediate and
-      mandatory flags on Basic.Publish methods is not defined.
-    </doc>
-
-    <rule name = "not multiple queues">
-      <doc>
-      Applications MUST NOT rely on the atomicity of transactions that
-      affect more than one queue.
-      </doc>
-    </rule>
-    <rule name = "not immediate">
-      <doc>
-      Applications MUST NOT rely on the behaviour of transactions that
-      include messages published with the immediate option.
-      </doc>
-    </rule>
-    <rule name = "not mandatory">
-      <doc>
-      Applications MUST NOT rely on the behaviour of transactions that
-      include messages published with the mandatory option.
-      </doc>
-    </rule>
-
-    <doc type = "grammar">
-      tx                  = C:SELECT S:SELECT-OK
-                          / C:COMMIT S:COMMIT-OK
-                          / C:ROLLBACK S:ROLLBACK-OK
-    </doc>
-
-    <chassis name = "server" implement = "SHOULD" />
-    <chassis name = "client" implement = "MAY" />
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "select" synchronous = "1" index = "10" label = "select standard transaction mode">
-      <doc>
-        This method sets the channel to use standard transactions. The client must use this
-        method at least once on a channel before using the Commit or Rollback methods.
-      </doc>
-      <chassis name = "server" implement = "MUST" />
-      <response name = "select-ok" />
-    </method>
-
-    <method name = "select-ok" synchronous = "1" index = "11" label = "confirm transaction mode">
-      <doc>
-        This method confirms to the client that the channel was successfully set to use
-        standard transactions.
-      </doc>
-      <chassis name = "client" implement = "MUST" />
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "commit" synchronous = "1" index = "20" label = "commit the current transaction">
-      <doc>
-        This method commits all message publications and acknowledgments performed in
-        the current transaction.  A new transaction starts immediately after a commit.
-      </doc>
-      <chassis name = "server" implement = "MUST" />
-      <response name = "commit-ok" />
-
-      <rule name = "transacted" on-failure = "precondition-failed">
-        <doc>
-          The client MUST NOT use the Commit method on non-transacted channels.
-        </doc>
-        <doc type = "scenario">
-          The client opens a channel and then uses Tx.Commit.
-        </doc>
-      </rule>
-    </method>
-
-    <method name = "commit-ok" synchronous = "1" index = "21" label = "confirm a successful commit">
-      <doc>
-        This method confirms to the client that the commit succeeded. Note that if a commit
-        fails, the server raises a channel exception.
-      </doc>
-      <chassis name = "client" implement = "MUST" />
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "rollback" synchronous = "1" index = "30"
-      label = "abandon the current transaction">
-      <doc>
-        This method abandons all message publications and acknowledgments performed in
-        the current transaction. A new transaction starts immediately after a rollback.
-        Note that unacked messages will not be automatically redelivered by rollback;
-        if that is required an explicit recover call should be issued.
-      </doc>
-      <chassis name = "server" implement = "MUST" />
-      <response name = "rollback-ok" />
-
-      <rule name = "transacted" on-failure = "precondition-failed">
-        <doc>
-          The client MUST NOT use the Rollback method on non-transacted channels.
-        </doc>
-        <doc type = "scenario">
-          The client opens a channel and then uses Tx.Rollback.
-        </doc>
-      </rule>
-    </method>
-
-    <method name = "rollback-ok" synchronous = "1" index = "31" label = "confirm successful rollback">
-      <doc>
-        This method confirms to the client that the rollback succeeded. Note that if an
-        rollback fails, the server raises a channel exception.
-      </doc>
-      <chassis name = "client" implement = "MUST" />
-    </method>
-  </class>
-
-  <!-- ==  CONFIRM  ========================================================== -->
-
-  <class name = "confirm" handler = "channel" index = "85" label = "work with confirms">
-    <doc>
-      The Confirm class allows publishers to put the channel in
-      confirm mode and subsequently be notified when messages have been
-      handled by the broker.  The intention is that all messages
-      published on a channel in confirm mode will be acknowledged at
-      some point.  By acknowledging a message the broker assumes
-      responsibility for it and indicates that it has done something
-      it deems reasonable with it.
-
-      Unroutable mandatory or immediate messages are acknowledged
-      right after the Basic.Return method. Messages are acknowledged
-      when all queues to which the message has been routed
-      have either delivered the message and received an
-      acknowledgement (if required), or enqueued the message (and
-      persisted it if required).
-
-      Published messages are assigned ascending sequence numbers,
-      starting at 1 with the first Confirm.Select method. The server
-      confirms messages by sending Basic.Ack methods referring to these
-      sequence numbers.
-    </doc>
-
-    <rule name = "all messages acknowledged">
-      <doc>
-        The server MUST acknowledge all messages received after the
-        channel was put into confirm mode.
-      </doc>
-    </rule>
-
-    <rule name = "all queues">
-      <doc>
-        The server MUST acknowledge a message only after it was
-        properly handled by all the queues it was delivered to.
-      </doc>
-    </rule>
-
-    <rule name = "unroutable messages">
-      <doc>
-        The server MUST acknowledge an unroutable mandatory or
-        immediate message only after it sends the Basic.Return.
-      </doc>
-    </rule>
-
-    <rule name = "time guarantees">
-      <doc>
-        No guarantees are made as to how soon a message is
-        acknowledged.  Applications SHOULD NOT make assumptions about
-        this.
-      </doc>
-    </rule>
-
-    <doc type = "grammar">
-      confirm            = C:SELECT S:SELECT-OK
-    </doc>
-
-    <chassis name = "server" implement = "SHOULD" />
-    <chassis name = "client" implement = "MAY" />
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name="select" synchronous="1" index="10">
-      select confirm mode (i.e. enable publisher acknowledgements)
-      <doc>
-        This method sets the channel to use publisher acknowledgements.
-        The client can only use this method on a non-transactional
-        channel.
-      </doc>
-      <chassis name="server" implement="MUST"/>
-      <response name="select-ok"/>
-      <field name = "nowait" type = "bit">
-        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="select-ok" synchronous="1" index="11">
-      acknowledge confirm mode
-      <doc>
-        This method confirms to the client that the channel was successfully
-        set to use publisher acknowledgements.
-      </doc>
-      <chassis name="client" implement="MUST"/>
-    </method>
-  </class>
+        <field name="reply-to" domain="shortstr" label="address to reply to"/>
+        <!--  For implementation use, no formal behaviour -->
+        <field name="expiration" domain="shortstr"
+               label="message expiration specification"/>
+        <!--  For application use, no formal behaviour -->
+        <field name="message-id" domain="shortstr"
+               label="application message identifier"/>
+        <!--  For application use, no formal behaviour -->
+        <field name="timestamp" domain="timestamp" label="message timestamp"/>
+        <!--  For application use, no formal behaviour -->
+        <field name="type" domain="shortstr" label="message type name"/>
+        <!--  For application use, no formal behaviour -->
+        <field name="user-id" domain="shortstr" label="creating user id"/>
+        <!--  For application use, no formal behaviour -->
+        <field name="app-id" domain="shortstr" label="creating application id"/>
+        <!--  Deprecated, was old cluster-id property -->
+        <field name="reserved" domain="shortstr"
+               label="reserved, must be empty"/>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="qos" synchronous="1" index="10"
+                label="specify quality of service">
+            <doc>
+                This method requests a specific quality of service. The QoS can
+                be specified for the
+                current channel or for all channels on the connection. The
+                particular properties and
+                semantics of a qos method always depend on the content class
+                semantics. Though the
+                qos method could in principle apply to both peers, it is
+                currently meaningful only
+                for the server.
+            </doc>
+
+            <chassis name="server" implement="MUST"/>
+            <response name="qos-ok"/>
+
+            <field name="prefetch-size" domain="long"
+                   label="prefetch window in octets">
+                <doc>
+                    The client can request that messages be sent in advance so
+                    that when the client
+                    finishes processing a message, the following message is
+                    already held locally,
+                    rather than needing to be sent down the channel. Prefetching
+                    gives a performance
+                    improvement. This field specifies the prefetch window size
+                    in octets. The server
+                    will send a message in advance if it is equal to or smaller
+                    in size than the
+                    available prefetch size (and also falls into other prefetch
+                    limits). May be set
+                    to zero, meaning "no specific limit", although other
+                    prefetch limits may still
+                    apply. The prefetch-size is ignored if the no-ack option is
+                    set.
+                </doc>
+                <rule name="01">
+                    <doc>
+                        The server MUST ignore this setting when the client is
+                        not processing any
+                        messages - i.e. the prefetch size does not limit the
+                        transfer of single
+                        messages to a client, only the sending in advance of
+                        more messages while
+                        the client still has one or more unacknowledged
+                        messages.
+                    </doc>
+                    <doc type="scenario">
+                        Define a QoS prefetch-size limit and send a single
+                        message that exceeds
+                        that limit. Verify that the message arrives correctly.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="prefetch-count" domain="short"
+                   label="prefetch window in messages">
+                <doc>
+                    Specifies a prefetch window in terms of whole messages. This
+                    field may be used
+                    in combination with the prefetch-size field; a message will
+                    only be sent in
+                    advance if both prefetch windows (and those at the channel
+                    and connection level)
+                    allow it. The prefetch-count is ignored if the no-ack option
+                    is set.
+                </doc>
+                <rule name="01">
+                    <doc>
+                        The server may send less data in advance than allowed by
+                        the client's
+                        specified prefetch windows but it MUST NOT send more.
+                    </doc>
+                    <doc type="scenario">
+                        Define a QoS prefetch-size limit and a prefetch-count
+                        limit greater than
+                        one. Send multiple messages that exceed the prefetch
+                        size. Verify that
+                        no more than one message arrives at once.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="global" domain="bit"
+                   label="apply to entire connection">
+                <doc>
+                    RabbitMQ has reinterpreted this field. The original
+                    specification said: "By default the QoS settings apply to
+                    the current channel only. If this field is set, they are
+                    applied to the entire connection." Instead, RabbitMQ takes
+                    global=false to mean that the QoS settings should apply
+                    per-consumer (for new consumers on the channel; existing
+                    ones being unaffected) and global=true to mean that the QoS
+                    settings should apply per-channel.
+                </doc>
+            </field>
+        </method>
+
+        <method name="qos-ok" synchronous="1" index="11"
+                label="confirm the requested qos">
+            <doc>
+                This method tells the client that the requested QoS levels could
+                be handled by the
+                server. The requested QoS applies to all active consumers until
+                a new QoS is
+                defined.
+            </doc>
+            <chassis name="client" implement="MUST"/>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="consume" synchronous="1" index="20"
+                label="start a queue consumer">
+            <doc>
+                This method asks the server to start a "consumer", which is a
+                transient request for
+                messages from a specific queue. Consumers last as long as the
+                channel they were
+                declared on, or until the client cancels them.
+            </doc>
+
+            <rule name="01">
+                <doc>
+                    The server SHOULD support at least 16 consumers per queue,
+                    and ideally, impose
+                    no limit except as defined by available resources.
+                </doc>
+                <doc type="scenario">
+                    Declare a queue and create consumers on that queue until the
+                    server closes the
+                    connection. Verify that the number of consumers created was
+                    at least sixteen
+                    and report the total number.
+                </doc>
+            </rule>
+
+            <chassis name="server" implement="MUST"/>
+            <response name="consume-ok"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <field name="queue" domain="queue-name">
+                <doc>Specifies the name of the queue to consume from.</doc>
+            </field>
+
+            <field name="consumer-tag" domain="consumer-tag">
+                <doc>
+                    Specifies the identifier for the consumer. The consumer tag
+                    is local to a
+                    channel, so two clients can use the same consumer tags. If
+                    this field is
+                    empty the server will generate a unique tag.
+                </doc>
+                <rule name="01" on-failure="not-allowed">
+                    <doc>
+                        The client MUST NOT specify a tag that refers to an
+                        existing consumer.
+                    </doc>
+                    <doc type="scenario">
+                        Attempt to create two consumers with the same non-empty
+                        tag, on the
+                        same channel.
+                    </doc>
+                </rule>
+                <rule name="02" on-failure="not-allowed">
+                    <doc>
+                        The consumer tag is valid only within the channel from
+                        which the
+                        consumer was created. I.e. a client MUST NOT create a
+                        consumer in one
+                        channel and then use it in another.
+                    </doc>
+                    <doc type="scenario">
+                        Attempt to create a consumer in one channel, then use in
+                        another channel,
+                        in which consumers have also been created (to test that
+                        the server uses
+                        unique consumer tags).
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="no-local" domain="no-local"/>
+
+            <field name="no-ack" domain="no-ack"/>
+
+            <field name="exclusive" domain="bit"
+                   label="request exclusive access">
+                <doc>
+                    Request exclusive consumer access, meaning only this
+                    consumer can access the
+                    queue.
+                </doc>
+
+                <rule name="01" on-failure="access-refused">
+                    <doc>
+                        The client MAY NOT gain exclusive access to a queue that
+                        already has
+                        active consumers.
+                    </doc>
+                    <doc type="scenario">
+                        Open two connections to a server, and in one connection
+                        declare a shared
+                        (non-exclusive) queue and then consume from the queue.
+                        In the second
+                        connection attempt to consume from the same queue using
+                        the exclusive
+                        option.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="no-wait" domain="no-wait"/>
+
+            <field name="arguments" domain="table"
+                   label="arguments for declaration">
+                <doc>
+                    A set of arguments for the consume. The syntax and semantics
+                    of these
+                    arguments depends on the server implementation.
+                </doc>
+            </field>
+        </method>
+
+        <method name="consume-ok" synchronous="1" index="21"
+                label="confirm a new consumer">
+            <doc>
+                The server provides the client with a consumer tag, which is
+                used by the client
+                for methods called on the consumer at a later stage.
+            </doc>
+            <chassis name="client" implement="MUST"/>
+            <field name="consumer-tag" domain="consumer-tag">
+                <doc>
+                    Holds the consumer tag specified by the client or provided
+                    by the server.
+                </doc>
+            </field>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="cancel" synchronous="1" index="30"
+                label="end a queue consumer">
+            <doc>
+                This method cancels a consumer. This does not affect already
+                delivered
+                messages, but it does mean the server will not send any more
+                messages for
+                that consumer. The client may receive an arbitrary number of
+                messages in
+                between sending the cancel method and receiving the cancel-ok
+                reply.
+
+                It may also be sent from the server to the client in the event
+                of the consumer being unexpectedly cancelled (i.e. cancelled
+                for any reason other than the server receiving the
+                corresponding basic.cancel from the client). This allows
+                clients to be notified of the loss of consumers due to events
+                such as queue deletion. Note that as it is not a MUST for
+                clients to accept this method from the server, it is advisable
+                for the broker to be able to identify those clients that are
+                capable of accepting the method, through some means of
+                capability negotiation.
+            </doc>
+
+            <rule name="01">
+                <doc>
+                    If the queue does not exist the server MUST ignore the
+                    cancel method, so
+                    long as the consumer tag is valid for that channel.
+                </doc>
+                <doc type="scenario">
+                    TODO.
+                </doc>
+            </rule>
+
+            <chassis name="server" implement="MUST"/>
+            <chassis name="client" implement="SHOULD"/>
+            <response name="cancel-ok"/>
+
+            <field name="consumer-tag" domain="consumer-tag"/>
+            <field name="no-wait" domain="no-wait"/>
+        </method>
+
+        <method name="cancel-ok" synchronous="1" index="31"
+                label="confirm a cancelled consumer">
+            <doc>
+                This method confirms that the cancellation was completed.
+            </doc>
+            <chassis name="client" implement="MUST"/>
+            <chassis name="server" implement="MAY"/>
+            <field name="consumer-tag" domain="consumer-tag"/>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="publish" content="1" index="40" label="publish a message">
+            <doc>
+                This method publishes a message to a specific exchange. The
+                message will be routed
+                to queues as defined by the exchange configuration and
+                distributed to any active
+                consumers when the transaction, if any, is committed.
+            </doc>
+
+            <chassis name="server" implement="MUST"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <field name="exchange" domain="exchange-name">
+                <doc>
+                    Specifies the name of the exchange to publish to. The
+                    exchange name can be
+                    empty, meaning the default exchange. If the exchange name is
+                    specified, and that
+                    exchange does not exist, the server will raise a channel
+                    exception.
+                </doc>
+
+                <rule name="must-exist" on-failure="not-found">
+                    <doc>
+                        The client MUST NOT attempt to publish a content to an
+                        exchange that
+                        does not exist.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to publish a content to a
+                        non-existent exchange.
+                    </doc>
+                </rule>
+                <rule name="default-exchange">
+                    <doc>
+                        The server MUST accept a blank exchange name to mean the
+                        default exchange.
+                    </doc>
+                    <doc type="scenario">
+                        The client declares a queue and binds it to a blank
+                        exchange name.
+                    </doc>
+                </rule>
+                <rule name="02">
+                    <doc>
+                        If the exchange was declared as an internal exchange,
+                        the server MUST raise
+                        a channel exception with a reply code 403 (access
+                        refused).
+                    </doc>
+                    <doc type="scenario">
+                        TODO.
+                    </doc>
+                </rule>
+
+                <rule name="03">
+                    <doc>
+                        The exchange MAY refuse basic content in which case it
+                        MUST raise a channel
+                        exception with reply code 540 (not implemented).
+                    </doc>
+                    <doc type="scenario">
+                        TODO.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="routing-key" domain="shortstr"
+                   label="Message routing key">
+                <doc>
+                    Specifies the routing key for the message. The routing key
+                    is used for routing
+                    messages depending on the exchange configuration.
+                </doc>
+            </field>
+
+            <field name="mandatory" domain="bit"
+                   label="indicate mandatory routing">
+                <doc>
+                    This flag tells the server how to react if the message
+                    cannot be routed to a
+                    queue. If this flag is set, the server will return an
+                    unroutable message with a
+                    Return method. If this flag is zero, the server silently
+                    drops the message.
+                </doc>
+
+                <rule name="01">
+                    <doc>
+                        The server SHOULD implement the mandatory flag.
+                    </doc>
+                    <doc type="scenario">
+                        TODO.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="immediate" domain="bit"
+                   label="request immediate delivery">
+                <doc>
+                    This flag tells the server how to react if the message
+                    cannot be routed to a
+                    queue consumer immediately. If this flag is set, the server
+                    will return an
+                    undeliverable message with a Return method. If this flag is
+                    zero, the server
+                    will queue the message, but with no guarantee that it will
+                    ever be consumed.
+                </doc>
+
+                <rule name="01">
+                    <doc>
+                        The server SHOULD implement the immediate flag.
+                    </doc>
+                    <doc type="scenario">
+                        TODO.
+                    </doc>
+                </rule>
+            </field>
+        </method>
+
+        <method name="return" content="1" index="50"
+                label="return a failed message">
+            <doc>
+                This method returns an undeliverable message that was published
+                with the "immediate"
+                flag set, or an unroutable message published with the
+                "mandatory" flag set. The
+                reply code and text provide information about the reason that
+                the message was
+                undeliverable.
+            </doc>
+
+            <chassis name="client" implement="MUST"/>
+
+            <field name="reply-code" domain="reply-code"/>
+            <field name="reply-text" domain="reply-text"/>
+
+            <field name="exchange" domain="exchange-name">
+                <doc>
+                    Specifies the name of the exchange that the message was
+                    originally published
+                    to. May be empty, meaning the default exchange.
+                </doc>
+            </field>
+
+            <field name="routing-key" domain="shortstr"
+                   label="Message routing key">
+                <doc>
+                    Specifies the routing key name specified when the message
+                    was published.
+                </doc>
+            </field>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="deliver" content="1" index="60"
+                label="notify the client of a consumer message">
+            <doc>
+                This method delivers a message to the client, via a consumer. In
+                the asynchronous
+                message delivery model, the client starts a consumer using the
+                Consume method, then
+                the server responds with Deliver methods as and when messages
+                arrive for that
+                consumer.
+            </doc>
+
+            <rule name="01">
+                <doc>
+                    The server SHOULD track the number of times a message has
+                    been delivered to
+                    clients and when a message is redelivered a certain number
+                    of times - e.g. 5
+                    times - without being acknowledged, the server SHOULD
+                    consider the message to be
+                    unprocessable (possibly causing client applications to
+                    abort), and move the
+                    message to a dead letter queue.
+                </doc>
+                <doc type="scenario">
+                    TODO.
+                </doc>
+            </rule>
+
+            <chassis name="client" implement="MUST"/>
+
+            <field name="consumer-tag" domain="consumer-tag"/>
+            <field name="delivery-tag" domain="delivery-tag"/>
+            <field name="redelivered" domain="redelivered"/>
+
+            <field name="exchange" domain="exchange-name">
+                <doc>
+                    Specifies the name of the exchange that the message was
+                    originally published to.
+                    May be empty, indicating the default exchange.
+                </doc>
+            </field>
+
+            <field name="routing-key" domain="shortstr"
+                   label="Message routing key">
+                <doc>Specifies the routing key name specified when the message
+                    was published.
+                </doc>
+            </field>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="get" synchronous="1" index="70"
+                label="direct access to a queue">
+            <doc>
+                This method provides a direct access to the messages in a queue
+                using a synchronous
+                dialogue that is designed for specific types of application
+                where synchronous
+                functionality is more important than performance.
+            </doc>
+
+            <response name="get-ok"/>
+            <response name="get-empty"/>
+            <chassis name="server" implement="MUST"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <field name="queue" domain="queue-name">
+                <doc>Specifies the name of the queue to get a message from.
+                </doc>
+            </field>
+            <field name="no-ack" domain="no-ack"/>
+        </method>
+
+        <method name="get-ok" synchronous="1" content="1" index="71"
+                label="provide client with a message">
+            <doc>
+                This method delivers a message to the client following a get
+                method. A message
+                delivered by 'get-ok' must be acknowledged unless the no-ack
+                option was set in the
+                get method.
+            </doc>
+
+            <chassis name="client" implement="MAY"/>
+
+            <field name="delivery-tag" domain="delivery-tag"/>
+            <field name="redelivered" domain="redelivered"/>
+            <field name="exchange" domain="exchange-name">
+                <doc>
+                    Specifies the name of the exchange that the message was
+                    originally published to.
+                    If empty, the message was published to the default exchange.
+                </doc>
+            </field>
+
+            <field name="routing-key" domain="shortstr"
+                   label="Message routing key">
+                <doc>Specifies the routing key name specified when the message
+                    was published.
+                </doc>
+            </field>
+
+            <field name="message-count" domain="message-count"/>
+        </method>
+
+        <method name="get-empty" synchronous="1" index="72"
+                label="indicate no messages available">
+            <doc>
+                This method tells the client that the queue has no messages
+                available for the
+                client.
+            </doc>
+            <chassis name="client" implement="MAY"/>
+            <!-- Deprecated: "cluster-id", must be empty -->
+            <field name="reserved-1" type="shortstr" reserved="1"/>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="ack" index="80" label="acknowledge one or more messages">
+            <doc>
+                When sent by the client, this method acknowledges one or more
+                messages delivered via the Deliver or Get-Ok methods.
+
+                When sent by server, this method acknowledges one or more
+                messages published with the Publish method on a channel in
+                confirm mode.
+
+                The acknowledgement can be for a single message or a set of
+                messages up to and including a specific message.
+            </doc>
+
+            <chassis name="server" implement="MUST"/>
+            <chassis name="client" implement="MUST"/>
+
+            <field name="delivery-tag" domain="delivery-tag"/>
+            <field name="multiple" domain="bit"
+                   label="acknowledge multiple messages">
+                <doc>
+                    If set to 1, the delivery tag is treated as "up to and
+                    including", so that multiple messages can be acknowledged
+                    with a single method. If set to zero, the delivery tag
+                    refers to a single message. If the multiple field is 1, and
+                    the delivery tag is zero, this indicates acknowledgement of
+                    all outstanding messages.
+                </doc>
+                <rule name="exists" on-failure="precondition-failed">
+                    <doc>
+                        A message MUST not be acknowledged more than once. The
+                        receiving peer MUST validate that a non-zero
+                        delivery-tag
+                        refers to a delivered message, and raise a channel
+                        exception if this is not the case. On a transacted
+                        channel, this check MUST be done immediately and not
+                        delayed until a Tx.Commit.
+                    </doc>
+                    <doc type="scenario">
+                        TODO.
+                    </doc>
+                </rule>
+            </field>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="reject" index="90" label="reject an incoming message">
+            <doc>
+                This method allows a client to reject a message. It can be used
+                to interrupt and
+                cancel large incoming messages, or return untreatable messages
+                to their original
+                queue.
+            </doc>
+
+            <rule name="01">
+                <doc>
+                    The server SHOULD be capable of accepting and process the
+                    Reject method while
+                    sending message content with a Deliver or Get-Ok method.
+                    I.e. the server should
+                    read and process incoming methods while sending output
+                    frames. To cancel a
+                    partially-send content, the server sends a content body
+                    frame of size 1 (i.e.
+                    with no data except the frame-end octet).
+                </doc>
+            </rule>
+
+            <rule name="02">
+                <doc>
+                    The server SHOULD interpret this method as meaning that the
+                    client is unable to
+                    process the message at this time.
+                </doc>
+                <doc type="scenario">
+                    TODO.
+                </doc>
+            </rule>
+
+            <rule name="03">
+                <doc>
+                    The client MUST NOT use this method as a means of selecting
+                    messages to process.
+                </doc>
+                <doc type="scenario">
+                    TODO.
+                </doc>
+            </rule>
+
+            <chassis name="server" implement="MUST"/>
+
+            <field name="delivery-tag" domain="delivery-tag"/>
+
+            <field name="requeue" domain="bit" label="requeue the message">
+                <doc>
+                    If requeue is true, the server will attempt to requeue the
+                    message. If requeue
+                    is false or the requeue attempt fails the messages are
+                    discarded or dead-lettered.
+                </doc>
+
+                <rule name="01">
+                    <doc>
+                        The server MUST NOT deliver the message to the same
+                        client within the
+                        context of the current channel. The recommended strategy
+                        is to attempt to
+                        deliver the message to an alternative consumer, and if
+                        that is not possible,
+                        to move the message to a dead-letter queue. The server
+                        MAY use more
+                        sophisticated tracking to hold the message on the queue
+                        and redeliver it to
+                        the same client at a later stage.
+                    </doc>
+                    <doc type="scenario">
+                        TODO.
+                    </doc>
+                </rule>
+            </field>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="recover-async" index="100"
+                label="redeliver unacknowledged messages"
+                deprecated="1">
+            <doc>
+                This method asks the server to redeliver all unacknowledged
+                messages on a
+                specified channel. Zero or more messages may be redelivered.
+                This method
+                is deprecated in favour of the synchronous Recover/Recover-Ok.
+            </doc>
+            <rule name="01">
+                <doc>
+                    The server MUST set the redelivered flag on all messages
+                    that are resent.
+                </doc>
+                <doc type="scenario">
+                    TODO.
+                </doc>
+            </rule>
+            <chassis name="server" implement="MAY"/>
+            <field name="requeue" domain="bit" label="requeue the message">
+                <doc>
+                    If this field is zero, the message will be redelivered to
+                    the original
+                    recipient. If this bit is 1, the server will attempt to
+                    requeue the message,
+                    potentially then delivering it to an alternative subscriber.
+                </doc>
+            </field>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="recover" index="110"
+                label="redeliver unacknowledged messages">
+            <doc>
+                This method asks the server to redeliver all unacknowledged
+                messages on a
+                specified channel. Zero or more messages may be redelivered.
+                This method
+                replaces the asynchronous Recover.
+            </doc>
+            <rule name="01">
+                <doc>
+                    The server MUST set the redelivered flag on all messages
+                    that are resent.
+                </doc>
+                <doc type="scenario">
+                    TODO.
+                </doc>
+            </rule>
+            <chassis name="server" implement="MUST"/>
+            <field name="requeue" domain="bit" label="requeue the message">
+                <doc>
+                    If this field is zero, the message will be redelivered to
+                    the original
+                    recipient. If this bit is 1, the server will attempt to
+                    requeue the message,
+                    potentially then delivering it to an alternative subscriber.
+                </doc>
+            </field>
+        </method>
+
+        <method name="recover-ok" synchronous="1" index="111"
+                label="confirm recovery">
+            <doc>
+                This method acknowledges a Basic.Recover method.
+            </doc>
+            <chassis name="client" implement="MUST"/>
+        </method>
+
+        <method name="nack" index="120"
+                label="reject one or more incoming messages">
+            <doc>
+                This method allows a client to reject one or more incoming
+                messages. It can be
+                used to interrupt and cancel large incoming messages, or return
+                untreatable
+                messages to their original queue.
+
+                This method is also used by the server to inform publishers on
+                channels in
+                confirm mode of unhandled messages. If a publisher receives this
+                method, it
+                probably needs to republish the offending messages.
+            </doc>
+
+            <rule name="01">
+                <doc>
+                    The server SHOULD be capable of accepting and processing the
+                    Nack method while
+                    sending message content with a Deliver or Get-Ok method.
+                    I.e. the server should
+                    read and process incoming methods while sending output
+                    frames. To cancel a
+                    partially-send content, the server sends a content body
+                    frame of size 1 (i.e.
+                    with no data except the frame-end octet).
+                </doc>
+            </rule>
+
+            <rule name="02">
+                <doc>
+                    The server SHOULD interpret this method as meaning that the
+                    client is unable to
+                    process the message at this time.
+                </doc>
+                <doc type="scenario">
+                    TODO.
+                </doc>
+            </rule>
+
+            <rule name="03">
+                <doc>
+                    The client MUST NOT use this method as a means of selecting
+                    messages to process.
+                </doc>
+                <doc type="scenario">
+                    TODO.
+                </doc>
+            </rule>
+
+            <rule name="04">
+                <doc>
+                    A client publishing messages to a channel in confirm mode
+                    SHOULD be capable of accepting
+                    and somehow handling the Nack method.
+                </doc>
+                <doc type="scenario">
+                    TODO
+                </doc>
+            </rule>
+
+            <chassis name="server" implement="MUST"/>
+            <chassis name="client" implement="MUST"/>
+
+            <field name="delivery-tag" domain="delivery-tag"/>
+
+            <field name="multiple" domain="bit"
+                   label="reject multiple messages">
+                <doc>
+                    If set to 1, the delivery tag is treated as "up to and
+                    including", so that multiple messages can be rejected
+                    with a single method. If set to zero, the delivery tag
+                    refers to a single message. If the multiple field is 1, and
+                    the delivery tag is zero, this indicates rejection of
+                    all outstanding messages.
+                </doc>
+                <rule name="exists" on-failure="precondition-failed">
+                    <doc>
+                        A message MUST not be rejected more than once. The
+                        receiving peer MUST validate that a non-zero
+                        delivery-tag
+                        refers to an unacknowledged, delivered message, and
+                        raise a channel exception if this is not the case.
+                    </doc>
+                    <doc type="scenario">
+                        TODO.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="requeue" domain="bit" label="requeue the message">
+                <doc>
+                    If requeue is true, the server will attempt to requeue the
+                    message. If requeue
+                    is false or the requeue attempt fails the messages are
+                    discarded or dead-lettered.
+                    Clients receiving the Nack methods should ignore this flag.
+                </doc>
+
+                <rule name="01">
+                    <doc>
+                        The server MUST NOT deliver the message to the same
+                        client within the
+                        context of the current channel. The recommended strategy
+                        is to attempt to
+                        deliver the message to an alternative consumer, and if
+                        that is not possible,
+                        to move the message to a dead-letter queue. The server
+                        MAY use more
+                        sophisticated tracking to hold the message on the queue
+                        and redeliver it to
+                        the same client at a later stage.
+                    </doc>
+                    <doc type="scenario">
+                        TODO.
+                    </doc>
+                </rule>
+            </field>
+        </method>
+
+    </class>
+
+    <!-- ==  TX  =============================================================== -->
+
+    <class name="tx" handler="channel" index="90"
+           label="work with transactions">
+        <doc>
+            The Tx class allows publish and ack operations to be batched into
+            atomic
+            units of work. The intention is that all publish and ack requests
+            issued
+            within a transaction will complete successfully or none of them
+            will.
+            Servers SHOULD implement atomic transactions at least where all
+            publish
+            or ack requests affect a single queue. Transactions that cover
+            multiple
+            queues may be non-atomic, given that queues can be created and
+            destroyed
+            asynchronously, and such events do not form part of any transaction.
+            Further, the behaviour of transactions with respect to the immediate
+            and
+            mandatory flags on Basic.Publish methods is not defined.
+        </doc>
+
+        <rule name="not multiple queues">
+            <doc>
+                Applications MUST NOT rely on the atomicity of transactions that
+                affect more than one queue.
+            </doc>
+        </rule>
+        <rule name="not immediate">
+            <doc>
+                Applications MUST NOT rely on the behaviour of transactions that
+                include messages published with the immediate option.
+            </doc>
+        </rule>
+        <rule name="not mandatory">
+            <doc>
+                Applications MUST NOT rely on the behaviour of transactions that
+                include messages published with the mandatory option.
+            </doc>
+        </rule>
+
+        <doc type="grammar">
+            tx = C:SELECT S:SELECT-OK
+            / C:COMMIT S:COMMIT-OK
+            / C:ROLLBACK S:ROLLBACK-OK
+        </doc>
+
+        <chassis name="server" implement="SHOULD"/>
+        <chassis name="client" implement="MAY"/>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="select" synchronous="1" index="10"
+                label="select standard transaction mode">
+            <doc>
+                This method sets the channel to use standard transactions. The
+                client must use this
+                method at least once on a channel before using the Commit or
+                Rollback methods.
+            </doc>
+            <chassis name="server" implement="MUST"/>
+            <response name="select-ok"/>
+        </method>
+
+        <method name="select-ok" synchronous="1" index="11"
+                label="confirm transaction mode">
+            <doc>
+                This method confirms to the client that the channel was
+                successfully set to use
+                standard transactions.
+            </doc>
+            <chassis name="client" implement="MUST"/>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="commit" synchronous="1" index="20"
+                label="commit the current transaction">
+            <doc>
+                This method commits all message publications and acknowledgments
+                performed in
+                the current transaction. A new transaction starts immediately
+                after a commit.
+            </doc>
+            <chassis name="server" implement="MUST"/>
+            <response name="commit-ok"/>
+
+            <rule name="transacted" on-failure="precondition-failed">
+                <doc>
+                    The client MUST NOT use the Commit method on non-transacted
+                    channels.
+                </doc>
+                <doc type="scenario">
+                    The client opens a channel and then uses Tx.Commit.
+                </doc>
+            </rule>
+        </method>
+
+        <method name="commit-ok" synchronous="1" index="21"
+                label="confirm a successful commit">
+            <doc>
+                This method confirms to the client that the commit succeeded.
+                Note that if a commit
+                fails, the server raises a channel exception.
+            </doc>
+            <chassis name="client" implement="MUST"/>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="rollback" synchronous="1" index="30"
+                label="abandon the current transaction">
+            <doc>
+                This method abandons all message publications and
+                acknowledgments performed in
+                the current transaction. A new transaction starts immediately
+                after a rollback.
+                Note that unacked messages will not be automatically redelivered
+                by rollback;
+                if that is required an explicit recover call should be issued.
+            </doc>
+            <chassis name="server" implement="MUST"/>
+            <response name="rollback-ok"/>
+
+            <rule name="transacted" on-failure="precondition-failed">
+                <doc>
+                    The client MUST NOT use the Rollback method on
+                    non-transacted channels.
+                </doc>
+                <doc type="scenario">
+                    The client opens a channel and then uses Tx.Rollback.
+                </doc>
+            </rule>
+        </method>
+
+        <method name="rollback-ok" synchronous="1" index="31"
+                label="confirm successful rollback">
+            <doc>
+                This method confirms to the client that the rollback succeeded.
+                Note that if an
+                rollback fails, the server raises a channel exception.
+            </doc>
+            <chassis name="client" implement="MUST"/>
+        </method>
+    </class>
+
+    <!-- ==  CONFIRM  ========================================================== -->
+
+    <class name="confirm" handler="channel" index="85"
+           label="work with confirms">
+        <doc>
+            The Confirm class allows publishers to put the channel in
+            confirm mode and subsequently be notified when messages have been
+            handled by the broker. The intention is that all messages
+            published on a channel in confirm mode will be acknowledged at
+            some point. By acknowledging a message the broker assumes
+            responsibility for it and indicates that it has done something
+            it deems reasonable with it.
+
+            Unroutable mandatory or immediate messages are acknowledged
+            right after the Basic.Return method. Messages are acknowledged
+            when all queues to which the message has been routed
+            have either delivered the message and received an
+            acknowledgement (if required), or enqueued the message (and
+            persisted it if required).
+
+            Published messages are assigned ascending sequence numbers,
+            starting at 1 with the first Confirm.Select method. The server
+            confirms messages by sending Basic.Ack methods referring to these
+            sequence numbers.
+        </doc>
+
+        <rule name="all messages acknowledged">
+            <doc>
+                The server MUST acknowledge all messages received after the
+                channel was put into confirm mode.
+            </doc>
+        </rule>
+
+        <rule name="all queues">
+            <doc>
+                The server MUST acknowledge a message only after it was
+                properly handled by all the queues it was delivered to.
+            </doc>
+        </rule>
+
+        <rule name="unroutable messages">
+            <doc>
+                The server MUST acknowledge an unroutable mandatory or
+                immediate message only after it sends the Basic.Return.
+            </doc>
+        </rule>
+
+        <rule name="time guarantees">
+            <doc>
+                No guarantees are made as to how soon a message is
+                acknowledged. Applications SHOULD NOT make assumptions about
+                this.
+            </doc>
+        </rule>
+
+        <doc type="grammar">
+            confirm = C:SELECT S:SELECT-OK
+        </doc>
+
+        <chassis name="server" implement="SHOULD"/>
+        <chassis name="client" implement="MAY"/>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="select" synchronous="1" index="10">
+            select confirm mode (i.e. enable publisher acknowledgements)
+            <doc>
+                This method sets the channel to use publisher acknowledgements.
+                The client can only use this method on a non-transactional
+                channel.
+            </doc>
+            <chassis name="server" implement="MUST"/>
+            <response name="select-ok"/>
+            <field name="nowait" type="bit">
+                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="select-ok" synchronous="1" index="11">
+            acknowledge confirm mode
+            <doc>
+                This method confirms to the client that the channel was
+                successfully
+                set to use publisher acknowledgements.
+            </doc>
+            <chassis name="client" implement="MUST"/>
+        </method>
+    </class>
 
 </amqp>
diff --git a/resources/amqp0-9-1.xml b/resources/amqp0-9-1.xml
index da785eb3bed370d7c11852fce8ef7fe7f366f2f6..2d56a5eb8d7aa5e3846f62929c8668430ecef71e 100644
--- a/resources/amqp0-9-1.xml
+++ b/resources/amqp0-9-1.xml
@@ -140,2704 +140,3335 @@
 
  -->
 
-<amqp major = "0" minor = "9" revision = "1"
-    port = "5672" comment = "AMQ Protocol version 0-9-1">
-  <!--
+<amqp major="0" minor="9" revision="1"
+      port="5672" comment="AMQ Protocol version 0-9-1">
+    <!--
       ======================================================
       ==       CONSTANTS
       ======================================================
   -->
-  <!-- Frame types -->
-  <constant name = "frame-method"     value = "1" />
-  <constant name = "frame-header"     value = "2" />
-  <constant name = "frame-body"       value = "3" />
-  <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 = "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-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 sender sent a malformed frame that the recipient could not decode.
-      This strongly implies a programming error in the sending peer.
-    </doc>
-  </constant>
-
-  <constant name = "syntax-error" value = "502" class = "hard-error">
-    <doc>
-      The sender sent a frame that contained illegal values for one or more
-      fields. This strongly implies a programming error in the sending peer.
-    </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 = "unexpected-frame" value = "505" class = "hard-error">
-    <doc>
-      The peer sent a frame that was not expected, usually in the context of
-      a content header and body.  This strongly indicates a fault in the peer's
-      content processing.
-    </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 = "class-id" type = "short" />
-
-  <domain name = "consumer-tag" type = "shortstr" label = "consumer tag">
-    <doc>
-      Identifier for the consumer, valid within the current channel.
-    </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.
-    </doc>
-    <assert check = "length" value = "127" />
-    <assert check = "regexp" value = "^[a-zA-Z0-9-_.:]*$" />
-  </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
-      assumes the delivery will succeed and immediately dequeues it. This
-      functionality may increase performance but at the cost of reliability.
-      Messages can get lost if a client dies before they are delivered 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 = "no-wait" type = "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>
-  </domain>
-
-  <domain name = "path" type = "shortstr">
-    <doc>
-      Unconstrained.
-    </doc>
-    <assert check = "notnull" />
-    <assert check = "length" value = "127" />
-  </domain>
-
-  <domain name = "peer-properties" type = "table">
-    <doc>
-      This table 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.  In methods where the queue
-      name may be blank, and that has no specific significance, this refers to the
-      'current' queue for the channel, meaning the last queue that the client declared
-      on the channel.  If the client did not declare a queue, and the method needs a
-      queue name, this will result in a 502 (syntax error) channel exception.
-    </doc>
-    <assert check = "length" value = "127" />
-    <assert check = "regexp" value = "^[a-zA-Z0-9-_.:]*$" />
-  </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">
-        Declare 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 = "message-count" type = "long" label = "number of messages in queue">
-    <doc>
-      The number of messages in the queue, which will be zero for newly-declared
-      queues. This is the number of messages present in the queue, and committed
-      if the channel on which they were published is transacted, that are not
-      waiting acknowledgement.
-    </doc>
-  </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>
-
-  <!-- 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  ======================================================= -->
-
-  <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
-      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 respond with a valid protocol header and then close the socket
-          connection.
-        </doc>
-        <doc type = "scenario">
-          The client sends a protocol header containing an invalid protocol name.
-          The server MUST respond by sending a valid protocol header and then 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. 2.0.  The server must respond with a protocol header
-          indicating its supported 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 without sending any further data.
-        </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 without sending any further data.
-        </doc>
-      </rule>
+    <!-- Frame types -->
+    <constant name="frame-method" value="1"/>
+    <constant name="frame-header" value="2"/>
+    <constant name="frame-body" value="3"/>
+    <constant name="frame-heartbeat" value="8"/>
 
-      <chassis name = "client" implement = "MUST" />
-      <response name = "start-ok" />
+    <!-- Protocol constants -->
+    <constant name="frame-min-size" value="4096"/>
+    <constant name="frame-end" value="206"/>
 
-      <field name = "version-major" domain = "octet" label = "protocol major version">
+    <!-- Reply codes -->
+    <constant name="reply-success" value="200">
         <doc>
-          The major version number can take any value from 0 to 99 as defined in the
-          AMQP specification.
+            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>
-      </field>
+    </constant>
 
-      <field name = "version-minor" domain = "octet" label = "protocol minor version">
+    <constant name="content-too-large" value="311" class="soft-error">
         <doc>
-          The minor version number can take any value from 0 to 99 as defined in the
-          AMQP specification.
+            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>
-      </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>
+    </constant>
 
-      <field name = "mechanisms" domain = "longstr" label = "available security mechanisms">
+    <constant name="no-consumers" value="313" class="soft-error">
         <doc>
-          A list of the security mechanisms that the server supports, delimited by spaces.
+            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>
-        <assert check = "notnull" />
-      </field>
+    </constant>
 
-      <field name = "locales" domain = "longstr" label = "available message locales">
+    <constant name="connection-forced" value="320" class="hard-error">
         <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.
+            An operator intervened to close the connection for some reason. The
+            client
+            may retry at some later date.
         </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>
+    </constant>
 
-      <field name = "mechanism" domain = "shortstr" label = "selected security mechanism">
+    <constant name="invalid-path" value="402" class="hard-error">
         <doc>
-          A single security mechanisms selected by the client, which must be one of those
-          specified by the server.
+            The client tried to work with an unknown virtual host.
         </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>
+    </constant>
 
-      <field name = "response" domain = "longstr" label = "security response data">
+    <constant name="access-refused" value="403" class="soft-error">
         <doc>
-          A block of opaque data passed to the security mechanism. The contents of this
-          data are defined by the SASL security mechanism.
+            The client attempted to work with a server entity to which it has no
+            access due to security settings.
         </doc>
-        <assert check = "notnull" />
-      </field>
+    </constant>
 
-      <field name = "locale" domain = "shortstr" label = "selected message locale">
+    <constant name="not-found" value="404" class="soft-error">
         <doc>
-          A single message locale selected by the client, which must be one of those
-          specified by the server.
+            The client attempted to work with a server entity that does not
+            exist.
         </doc>
-        <assert check = "notnull" />
-      </field>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+    </constant>
 
-    <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">
+    <constant name="resource-locked" value="405" class="soft-error">
         <doc>
-          Challenge information, a block of opaque binary data passed to the security
-          mechanism.
+            The client attempted to work with a server entity to which it has no
+            access because another client is working with it.
         </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>
+    </constant>
 
-      <chassis name = "server" implement = "MUST" />
-
-      <field name = "response" domain = "longstr" label = "security response data">
+    <constant name="precondition-failed" value="406" class="soft-error">
         <doc>
-          A block of opaque data passed to the security mechanism. The contents of this
-          data are defined by the SASL security mechanism.
+            The client requested a method that was not allowed because some
+            precondition
+            failed.
         </doc>
-        <assert check = "notnull" />
-      </field>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+    </constant>
 
-    <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">
+    <constant name="frame-error" value="501" class="hard-error">
         <doc>
-          Specifies highest channel number that the server permits.  Usable channel numbers
-          are in the range 1..channel-max.  Zero indicates no specified limit.
+            The sender sent a malformed frame that the recipient could not
+            decode.
+            This strongly implies a programming error in the sending peer.
         </doc>
-      </field>
+    </constant>
 
-      <field name = "frame-max" domain = "long" label = "proposed maximum frame size">
+    <constant name="syntax-error" value="502" class="hard-error">
         <doc>
-          The largest frame size that the server proposes for the connection, including
-          frame header and end-byte.  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.
+            The sender sent a frame that contained illegal values for one or
+            more
+            fields. This strongly implies a programming error in the sending
+            peer.
         </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>
+    </constant>
 
-      <field name = "heartbeat" domain = "short" label = "desired heartbeat delay">
+    <constant name="command-invalid" value="503" class="hard-error">
         <doc>
-          The delay, in seconds, of the connection heartbeat that the server wants.
-          Zero means the server does not want a heartbeat.
+            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>
-      </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>
+    </constant>
 
-      <chassis name = "server" implement = "MUST" />
-
-      <field name = "channel-max" domain = "short" label = "negotiated maximum channels">
+    <constant name="channel-error" value="504" class="hard-error">
         <doc>
-          The maximum total number of channels that the client will use per connection.
+            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>
-        <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>
+    </constant>
 
-      <field name = "frame-max" domain = "long" label = "negotiated maximum frame size">
+    <constant name="unexpected-frame" value="505" class="hard-error">
         <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.
+            The peer sent a frame that was not expected, usually in the context
+            of
+            a content header and body. This strongly indicates a fault in the
+            peer's
+            content processing.
         </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>
+    </constant>
 
-      <field name = "heartbeat" domain = "short" label = "desired heartbeat delay">
+    <constant name="resource-error" value="506" class="hard-error">
         <doc>
-          The delay, in seconds, of the connection heartbeat that the client wants. Zero
-          means the client does not want a heartbeat.
+            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>
-      </field>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+    </constant>
 
-    <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" />
-
-      <field name = "virtual-host" domain = "path" label = "virtual host name">
+    <constant name="not-allowed" value="530" class="hard-error">
         <doc>
-          The name of the virtual host to work with.
+            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>
-        <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>
-      <!-- Deprecated: "capabilities", must be zero -->
-      <field name = "reserved-1" type = "shortstr" reserved = "1" />
-      <!-- Deprecated: "insist", must be zero -->
-      <field name = "reserved-2" type = "bit" reserved = "1" />
-    </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" />
-      <!-- Deprecated: "known-hosts", must be zero -->
-      <field name = "reserved-1" type = "shortstr" reserved = "1" />
-    </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>
-      <rule name = "stability">
-        <doc>
-          After sending this method, any received methods except Close and Close-OK MUST
-          be discarded.  The response to receiving a Close after sending Close must be to
-          send Close-Ok.
-        </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
-      use-channel         = C:FLOW S:FLOW-OK
-                          / S:FLOW C:FLOW-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" />
-      <!-- Deprecated: "out-of-band", must be zero -->
-      <field name = "reserved-1" type = "shortstr" reserved = "1" />
-    </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" />
-      <!-- Deprecated: "channel-id", must be zero -->
-      <field name = "reserved-1" type = "longstr" reserved = "1" />
-    </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 sent by
-        a consumer. 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. It does
-        not affect contents returned by Basic.Get-Ok methods.
-      </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>
+    </constant>
 
-      <rule name = "throttling">
+    <constant name="not-implemented" value="540" class="hard-error">
         <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.
+            The client tried to use functionality that is not implemented in the
+            server.
         </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 server.
-        </doc>
-      </rule>
-
-      <chassis name = "server" implement = "MUST" />
-      <chassis name = "client" implement = "MUST" />
+    </constant>
 
-      <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>
-      <rule name = "stability">
+    <constant name="internal-error" value="541" class="hard-error">
         <doc>
-          After sending this method, any received methods except Close and Close-OK MUST
-          be discarded.  The response to receiving a Close after sending Close must be to
-          send Close-Ok.
+            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>
-      </rule>
+    </constant>
 
-      <chassis name = "client" implement = "MUST" />
-      <chassis name = "server" implement = "MUST" />
-      <response name = "close-ok" />
+    <!--
+      ======================================================
+      ==       DOMAIN TYPES
+      ======================================================
+  -->
 
-      <field name = "reply-code" domain = "reply-code" />
-      <field name = "reply-text" domain = "reply-text" />
+    <domain name="class-id" type="short"/>
 
-      <field name = "class-id" domain = "class-id" label = "failing method class">
+    <domain name="consumer-tag" type="shortstr" label="consumer tag">
         <doc>
-          When the close is provoked by a method exception, this is the class of the
-          method.
+            Identifier for the consumer, valid within the current channel.
         </doc>
-      </field>
+    </domain>
 
-      <field name = "method-id" domain = "method-id" label = "failing method ID">
+    <domain name="delivery-tag" type="longlong"
+            label="server-assigned delivery tag">
         <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>
-  </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 declared 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 declares 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 declares as many exchanges as it can until the server reports
-          an error; the number of exchanges successfully declared must be at least
-          sixteen.
+            The server-assigned and channel-specific delivery tag
         </doc>
-      </rule>
-
-      <chassis name = "server" implement = "MUST" />
-      <response name = "declare-ok" />
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <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 MAY declare an exchange starting with
-            "amq." if the passive option is set, or the exchange already exists.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to declare a non-existing exchange starting with
-            "amq." and with the passive option set to zero.
-          </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 = "syntax" on-failure = "precondition-failed">
-          <doc>
-            The exchange name consists of a non-empty sequence of these characters:
-            letters, digits, hyphen, underscore, period, or colon.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to declare an exchange with an illegal name.
-          </doc>
+        <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>
-        <assert check = "notnull" />
-      </field>
+    </domain>
 
-      <field name = "type" domain = "shortstr" label = "exchange type">
+    <domain name="exchange-name" type="shortstr" label="exchange name">
         <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.
+            The exchange name is a client-selected string that identifies the
+            exchange for
+            publish methods.
         </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 declare an exchange with a type that the
-            server does not support.
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
-        </rule>
-      </field>
+        <assert check="length" value="127"/>
+        <assert check="regexp" value="^[a-zA-Z0-9-_.:]*$"/>
+    </domain>
 
-      <field name = "passive" domain = "bit" label = "do not create exchange">
-        <doc>
-          If set, the server will reply with Declare-Ok if the exchange already
-          exists with the same name, and raise an error if not.  The client can
-          use this to check whether an exchange exists without modifying the
-          server state. When set, all other method fields except name and no-wait
-          are ignored.  A declare with both passive and no-wait has no effect.
-          Arguments are compared for semantic equivalence.
-        </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>
-        <rule name = "equivalent">
-          <doc>
-            If not set and the exchange exists, the server MUST check that the
-            existing exchange has the same values for type, durable, and arguments
-            fields.  The server MUST respond with Declare-Ok if the requested
-            exchange matches these fields, and MUST raise a channel exception if
-            not.
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
-        </rule>
-      </field>
+    <domain name="method-id" type="short"/>
 
-      <field name = "durable" domain = "bit" label = "request a durable exchange">
+    <domain name="no-ack" type="bit" label="no acknowledgement needed">
         <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.
+            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
+            assumes the delivery will succeed and immediately dequeues it. This
+            functionality may increase performance but at the cost of
+            reliability.
+            Messages can get lost if a client dies before they are delivered to
+            the
+            application.
         </doc>
-        <rule name = "support">
-          <doc>
-            The server MUST support both durable and transient exchanges.
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
-        </rule>
-      </field>
-
-      <!-- Deprecated: "auto-delete", must be zero -->
-      <field name = "reserved-2" type = "bit" reserved = "1" />
-      <!-- Deprecated: "internal", must be zero -->
-      <field name = "reserved-3" type = "bit" reserved = "1" />
-      <field name = "no-wait" domain = "no-wait" />
+    </domain>
 
-      <field name = "arguments" domain = "table" label = "arguments for declaration">
+    <domain name="no-local" type="bit" label="do not deliver own messages">
         <doc>
-          A set of arguments for the declaration. The syntax and semantics of these
-          arguments depends on the server implementation.
+            If the no-local field is set the server will not send messages to
+            the connection that
+            published them.
         </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" />
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <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>
+    </domain>
 
-      <field name = "if-unused" domain = "bit" label = "delete only if unused">
+    <domain name="no-wait" type="bit" label="do not send reply method">
         <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.
+            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>
-        <rule name = "in-use" on-failure = "precondition-failed">
-          <doc>
-            The server MUST NOT delete an exchange that has bindings on it, if the if-unused
-            field is true.
-          </doc>
-          <doc type = "scenario">
-            The client declares an exchange, binds a queue to it, then tries to delete it
-            setting if-unused to true.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "no-wait" domain = "no-wait" />
-    </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:UNBIND   S:UNBIND-OK
-                          / C:PURGE    S:PURGE-OK
-                          / C:DELETE   S:DELETE-OK
-    </doc>
-
-    <chassis name = "server" implement = "MUST" />
-    <chassis name = "client" implement = "MUST" />
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <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-declared 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 declares 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>
+    </domain>
 
-      <rule name = "minimum-queues">
+    <domain name="path" type="shortstr">
         <doc>
-          The server SHOULD support a minimum of 256 queues per virtual host and ideally,
-          impose no limit except as defined by available resources.
+            Unconstrained.
         </doc>
-        <doc type = "scenario">
-          Client attempts to declare 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" />
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <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 declare several queues with an empty name. The client then
-            verifies that the server-assigned names are unique and different.
-          </doc>
-        </rule>
-        <rule name = "reserved" on-failure = "access-refused">
-          <doc>
-            Queue names starting with "amq." are reserved for pre-declared and
-            standardised queues. The client MAY declare a queue starting with
-            "amq." if the passive option is set, or the queue already exists.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to declare a non-existing queue starting with
-            "amq." and with the passive option set to zero.
-          </doc>
-        </rule>
-        <rule name = "syntax" on-failure = "precondition-failed">
-          <doc>
-            The queue name can be empty, or a sequence of these characters:
-            letters, digits, hyphen, underscore, period, or colon.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to declare a queue with an illegal name.
-          </doc>
-        </rule>
-      </field>
+        <assert check="notnull"/>
+        <assert check="length" value="127"/>
+    </domain>
 
-      <field name = "passive" domain = "bit" label = "do not create queue">
+    <domain name="peer-properties" type="table">
         <doc>
-          If set, the server will reply with Declare-Ok if the queue already
-          exists with the same name, and raise an error if not.  The client can
-          use this to check whether a queue exists without modifying the
-          server state.  When set, all other method fields except name and no-wait
-          are ignored.  A declare with both passive and no-wait has no effect.
-          Arguments are compared for semantic equivalence.
+            This table provides a set of peer properties, used for
+            identification, debugging,
+            and general information.
         </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>
-        <rule name = "equivalent">
-          <doc>
-            If not set and the queue exists, the server MUST check that the
-            existing queue has the same values for durable, exclusive, auto-delete,
-            and arguments fields.  The server MUST respond with Declare-Ok if the
-            requested queue matches these fields, and MUST raise a channel exception
-            if not.
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
-        </rule>
-      </field>
+    </domain>
 
-      <field name = "durable" domain = "bit" label = "request a durable queue">
+    <domain name="queue-name" type="shortstr" label="queue name">
         <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.
+            The queue name identifies the queue within the vhost. In methods
+            where the queue
+            name may be blank, and that has no specific significance, this
+            refers to the
+            'current' queue for the channel, meaning the last queue that the
+            client declared
+            on the channel. If the client did not declare a queue, and the
+            method needs a
+            queue name, this will result in a 502 (syntax error) channel
+            exception.
         </doc>
+        <assert check="length" value="127"/>
+        <assert check="regexp" value="^[a-zA-Z0-9-_.:]*$"/>
+    </domain>
 
-        <rule name = "persistence">
-          <doc>The server MUST recreate the durable queue after a restart.</doc>
-
-          <doc type = "scenario">
-            Client declares 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 name = "types">
-          <doc>The server MUST support both durable and transient queues.</doc>
-          <doc type = "scenario">
-            A client declares two named queues, one durable and one transient.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "exclusive" domain = "bit" label = "request an exclusive queue">
+    <domain name="redelivered" type="bit" label="message is being redelivered">
         <doc>
-          Exclusive queues may only be accessed by the current connection, and are
-          deleted when that connection closes.  Passive declaration of an exclusive
-          queue by other connections are not allowed.
+            This indicates that the message has been previously delivered to
+            this or
+            another client.
         </doc>
-
-        <rule name = "types">
-          <doc>
-            The server MUST support both exclusive (private) and non-exclusive (shared)
-            queues.
-          </doc>
-          <doc type = "scenario">
-            A client declares two named queues, one exclusive and one non-exclusive.
-          </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">
+                Declare 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 = "exclusive" on-failure = "resource-locked">
-          <doc>
-            The client MAY NOT attempt to use a queue that was declared as exclusive
-            by another still-open connection.
-          </doc>
-          <doc type = "scenario">
-            One client declares an exclusive queue. A second client on a different
-            connection attempts to declare, bind, consume, purge, delete, or declare
-            a queue of the same name.
-          </doc>
+        <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>
-      </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.  The 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.  Applications can
-          explicitly delete auto-delete queues using the Delete method as normal.
-        </doc>
-
-        <rule name = "pre-existence">
-          <doc>
-            The server MUST ignore the auto-delete field if the queue already exists.
-          </doc>
-          <doc type = "scenario">
-            Client declares two named queues, one as auto-delete and one explicit-delete.
-            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.
-          </doc>
+    </domain>
+
+    <domain name="message-count" type="long"
+            label="number of messages in queue">
+        <doc>
+            The number of messages in the queue, which will be zero for
+            newly-declared
+            queues. This is the number of messages present in the queue, and
+            committed
+            if the channel on which they were published is transacted, that are
+            not
+            waiting acknowledgement.
+        </doc>
+    </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>
+
+    <!-- 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  ======================================================= -->
+
+    <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
+            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 respond with a valid protocol header and then close
+                    the socket
+                    connection.
+                </doc>
+                <doc type="scenario">
+                    The client sends a protocol header containing an invalid
+                    protocol name.
+                    The server MUST respond by sending a valid protocol header
+                    and then 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. 2.0. The server must respond with a
+                    protocol header
+                    indicating its supported 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 without sending any
+                    further data.
+                </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 without sending any further data.
+                </doc>
+            </rule>
+
+            <chassis name="client" implement="MUST"/>
+            <response name="start-ok"/>
+
+            <field name="version-major" domain="octet"
+                   label="protocol major version">
+                <doc>
+                    The major version number can take any value from 0 to 99 as
+                    defined in the
+                    AMQP specification.
+                </doc>
+            </field>
+
+            <field name="version-minor" domain="octet"
+                   label="protocol minor version">
+                <doc>
+                    The minor version number can take any value from 0 to 99 as
+                    defined in the
+                    AMQP specification.
+                </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>
+                    Specifies highest channel number that the server permits.
+                    Usable channel numbers
+                    are in the range 1..channel-max. Zero indicates no specified
+                    limit.
+                </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, including
+                    frame header and end-byte. 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">
+                <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"/>
+
+            <field name="virtual-host" domain="path" label="virtual host name">
+                <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>
+            <!-- Deprecated: "capabilities", must be zero -->
+            <field name="reserved-1" type="shortstr" reserved="1"/>
+            <!-- Deprecated: "insist", must be zero -->
+            <field name="reserved-2" type="bit" reserved="1"/>
+        </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"/>
+            <!-- Deprecated: "known-hosts", must be zero -->
+            <field name="reserved-1" type="shortstr" reserved="1"/>
+        </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>
+            <rule name="stability">
+                <doc>
+                    After sending this method, any received methods except Close
+                    and Close-OK MUST
+                    be discarded. The response to receiving a Close after
+                    sending Close must be to
+                    send Close-Ok.
+                </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
+            use-channel = C:FLOW S:FLOW-OK
+            / S:FLOW C:FLOW-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"/>
+            <!-- Deprecated: "out-of-band", must be zero -->
+            <field name="reserved-1" type="shortstr" reserved="1"/>
+        </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"/>
+            <!-- Deprecated: "channel-id", must be zero -->
+            <field name="reserved-1" type="longstr" reserved="1"/>
+        </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 sent by
+                a consumer. 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. It does
+                not affect contents returned by Basic.Get-Ok methods.
+            </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 server.
+                </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>
+            <rule name="stability">
+                <doc>
+                    After sending this method, any received methods except Close
+                    and Close-OK MUST
+                    be discarded. The response to receiving a Close after
+                    sending Close must be to
+                    send Close-Ok.
+                </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>
+    </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 declared 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>
-      </field>
-
-      <field name = "no-wait" domain = "no-wait" />
-
-      <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.
-        </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 = "message-count" />
-
-      <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 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 name = "unique">
-        <doc>
-          A server MUST not deliver the same message more than once to a queue, even if
-          the queue has multiple bindings that match the message.
-        </doc>
-        <doc type = "scenario">
-          A client declares a named queue and binds it using multiple bindings to the
-          amq.topic exchange. The client then publishes a message that matches all its
-          bindings.
-        </doc>
-      </rule>
-
-      <rule name = "transient-exchange">
-        <doc>
-          The server MUST allow a durable queue to bind to a transient exchange.
-        </doc>
-        <doc type = "scenario">
-          A client declares 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 name = "durable-exchange">
-        <doc>
-          Bindings of durable queues to durable exchanges are automatically durable
-          and the server MUST restore such bindings after a server restart.
-        </doc>
-        <doc type = "scenario">
-          A server declares 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 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 declares a named queue and attempts to bind it to 4 different
-          exchanges.
-        </doc>
-      </rule>
-
-      <chassis name = "server" implement = "MUST" />
-
-      <response name = "bind-ok" />
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <field name = "queue" domain = "queue-name">
-        <doc>Specifies the name of the queue to bind.</doc>
-        <rule name = "queue-known" on-failure = "not-found">
-          <doc>
-            The client MUST either specify a queue name or have previously declared a
-            queue on the same channel
-          </doc>
-          <doc type = "scenario">
-            The client opens a channel and attempts to bind an unnamed queue.
-          </doc>
+        <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 = "must-exist" on-failure = "not-found">
-          <doc>
-            The client MUST NOT attempt to bind a queue that does not exist.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to bind a non-existent queue.
-          </doc>
+        <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 declares 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>
-      </field>
-
-      <field name = "exchange" domain = "exchange-name" label = "name of the exchange to bind to">
-        <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 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-exchange">
-          <doc>
-            The server MUST accept a blank exchange name to mean the default exchange.
-          </doc>
-          <doc type = "scenario">
-            The client declares a queue and binds it to a blank exchange name.
-          </doc>
+        <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>
-      </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
-            publisher sends the exchange a message with routing key R, then the message
-            MUST be passed to the message queue if K = R.
-          </doc>
+        <rule name="extensions">
+            <doc>
+                The server MAY implement other exchange types as wanted.
+            </doc>
         </rule>
-      </field>
 
-      <field name = "no-wait" domain = "no-wait" />
-
-      <field name = "arguments" domain = "table" label = "arguments for binding">
-        <doc>
-          A set of arguments for the binding. The syntax and semantics of these arguments
-          depends on the exchange class.
-        </doc>
-      </field>
-    </method>
-
-    <method name = "bind-ok" synchronous = "1" index = "21" label = "confirm bind successful">
-      <doc>This method confirms that the bind was successful.</doc>
-
-      <chassis name = "client" implement = "MUST" />
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "unbind" synchronous = "1" index = "50" label = "unbind a queue from an exchange">
-      <doc>This method unbinds a queue from an exchange.</doc>
-      <rule name = "01">
-        <doc>If a unbind fails, the server MUST raise a connection exception.</doc>
-      </rule>
-      <chassis name="server" implement="MUST"/>
-      <response name="unbind-ok"/>
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <field name = "queue" domain = "queue-name">
-        <doc>Specifies the name of the queue to unbind.</doc>
-        <rule name = "queue-known" on-failure = "not-found">
-          <doc>
-            The client MUST either specify a queue name or have previously declared a
-            queue on the same channel
-          </doc>
-          <doc type = "scenario">
-            The client opens a channel and attempts to unbind an unnamed queue.
-          </doc>
-        </rule>
-        <rule name = "must-exist" on-failure = "not-found">
-          <doc>
-            The client MUST NOT attempt to unbind a queue that does not exist.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to unbind a non-existent queue.
-          </doc>
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <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 declares as many exchanges as it can until the
+                    server reports
+                    an error; the number of exchanges successfully declared must
+                    be at least
+                    sixteen.
+                </doc>
+            </rule>
+
+            <chassis name="server" implement="MUST"/>
+            <response name="declare-ok"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <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 MAY declare an
+                        exchange starting with
+                        "amq." if the passive option is set, or the exchange
+                        already exists.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to declare a non-existing exchange
+                        starting with
+                        "amq." and with the passive option set to zero.
+                    </doc>
+                </rule>
+                <rule name="syntax" on-failure="precondition-failed">
+                    <doc>
+                        The exchange name consists of a non-empty sequence of
+                        these characters:
+                        letters, digits, hyphen, underscore, period, or colon.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to declare an exchange with an
+                        illegal name.
+                    </doc>
+                </rule>
+                <assert check="notnull"/>
+            </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 declare an exchange with
+                        a type that the
+                        server does not support.
+                    </doc>
+                    <doc type="scenario">
+                        TODO.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="passive" domain="bit" label="do not create exchange">
+                <doc>
+                    If set, the server will reply with Declare-Ok if the
+                    exchange already
+                    exists with the same name, and raise an error if not. The
+                    client can
+                    use this to check whether an exchange exists without
+                    modifying the
+                    server state. When set, all other method fields except name
+                    and no-wait
+                    are ignored. A declare with both passive and no-wait has no
+                    effect.
+                    Arguments are compared for semantic equivalence.
+                </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>
+                <rule name="equivalent">
+                    <doc>
+                        If not set and the exchange exists, the server MUST
+                        check that the
+                        existing exchange has the same values for type, durable,
+                        and arguments
+                        fields. The server MUST respond with Declare-Ok if the
+                        requested
+                        exchange matches these fields, and MUST raise a channel
+                        exception if
+                        not.
+                    </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>
+            </field>
+
+            <!-- Deprecated: "auto-delete", must be zero -->
+            <field name="reserved-2" type="bit" reserved="1"/>
+            <!-- Deprecated: "internal", must be zero -->
+            <field name="reserved-3" type="bit" reserved="1"/>
+            <field name="no-wait" domain="no-wait"/>
+
+            <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.
+                </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"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <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>
+
+            <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>
+                <rule name="in-use" on-failure="precondition-failed">
+                    <doc>
+                        The server MUST NOT delete an exchange that has bindings
+                        on it, if the if-unused
+                        field is true.
+                    </doc>
+                    <doc type="scenario">
+                        The client declares an exchange, binds a queue to it,
+                        then tries to delete it
+                        setting if-unused to true.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="no-wait" domain="no-wait"/>
+        </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:UNBIND S:UNBIND-OK
+            / C:PURGE S:PURGE-OK
+            / C:DELETE S:DELETE-OK
+        </doc>
+
+        <chassis name="server" implement="MUST"/>
+        <chassis name="client" implement="MUST"/>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <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-declared 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 declares 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 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 declare 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"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <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 declare several queues with an empty
+                        name. The client then
+                        verifies that the server-assigned names are unique and
+                        different.
+                    </doc>
+                </rule>
+                <rule name="reserved" on-failure="access-refused">
+                    <doc>
+                        Queue names starting with "amq." are reserved for
+                        pre-declared and
+                        standardised queues. The client MAY declare a queue
+                        starting with
+                        "amq." if the passive option is set, or the queue
+                        already exists.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to declare a non-existing queue
+                        starting with
+                        "amq." and with the passive option set to zero.
+                    </doc>
+                </rule>
+                <rule name="syntax" on-failure="precondition-failed">
+                    <doc>
+                        The queue name can be empty, or a sequence of these
+                        characters:
+                        letters, digits, hyphen, underscore, period, or colon.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to declare a queue with an illegal
+                        name.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="passive" domain="bit" label="do not create queue">
+                <doc>
+                    If set, the server will reply with Declare-Ok if the queue
+                    already
+                    exists with the same name, and raise an error if not. The
+                    client can
+                    use this to check whether a queue exists without modifying
+                    the
+                    server state. When set, all other method fields except name
+                    and no-wait
+                    are ignored. A declare with both passive and no-wait has no
+                    effect.
+                    Arguments are compared for semantic equivalence.
+                </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>
+                <rule name="equivalent">
+                    <doc>
+                        If not set and the queue exists, the server MUST check
+                        that the
+                        existing queue has the same values for durable,
+                        exclusive, auto-delete,
+                        and arguments fields. The server MUST respond with
+                        Declare-Ok if the
+                        requested queue matches these fields, and MUST raise a
+                        channel exception
+                        if not.
+                    </doc>
+                    <doc type="scenario">
+                        TODO.
+                    </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 name="persistence">
+                    <doc>The server MUST recreate the durable queue after a
+                        restart.
+                    </doc>
+
+                    <doc type="scenario">
+                        Client declares 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 name="types">
+                    <doc>The server MUST support both durable and transient
+                        queues.
+                    </doc>
+                    <doc type="scenario">
+                        A client declares two named queues, one durable and one
+                        transient.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="exclusive" domain="bit"
+                   label="request an exclusive queue">
+                <doc>
+                    Exclusive queues may only be accessed by the current
+                    connection, and are
+                    deleted when that connection closes. Passive declaration of
+                    an exclusive
+                    queue by other connections are not allowed.
+                </doc>
+
+                <rule name="types">
+                    <doc>
+                        The server MUST support both exclusive (private) and
+                        non-exclusive (shared)
+                        queues.
+                    </doc>
+                    <doc type="scenario">
+                        A client declares two named queues, one exclusive and
+                        one non-exclusive.
+                    </doc>
+                </rule>
+
+                <rule name="exclusive" on-failure="resource-locked">
+                    <doc>
+                        The client MAY NOT attempt to use a queue that was
+                        declared as exclusive
+                        by another still-open connection.
+                    </doc>
+                    <doc type="scenario">
+                        One client declares an exclusive queue. A second client
+                        on a different
+                        connection attempts to declare, bind, consume, purge,
+                        delete, or 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. The 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. Applications can
+                    explicitly delete auto-delete queues using the Delete method
+                    as normal.
+                </doc>
+
+                <rule name="pre-existence">
+                    <doc>
+                        The server MUST ignore the auto-delete field if the
+                        queue already exists.
+                    </doc>
+                    <doc type="scenario">
+                        Client declares two named queues, one as auto-delete and
+                        one explicit-delete.
+                        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.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="no-wait" domain="no-wait"/>
+
+            <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.
+                </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="message-count"/>
+
+            <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 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 name="unique">
+                <doc>
+                    A server MUST not deliver the same message more than once to
+                    a queue, even if
+                    the queue has multiple bindings that match the message.
+                </doc>
+                <doc type="scenario">
+                    A client declares a named queue and binds it using multiple
+                    bindings to the
+                    amq.topic exchange. The client then publishes a message that
+                    matches all its
+                    bindings.
+                </doc>
+            </rule>
+
+            <rule name="transient-exchange">
+                <doc>
+                    The server MUST allow a durable queue to bind to a transient
+                    exchange.
+                </doc>
+                <doc type="scenario">
+                    A client declares 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 name="durable-exchange">
+                <doc>
+                    Bindings of durable queues to durable exchanges are
+                    automatically durable
+                    and the server MUST restore such bindings after a server
+                    restart.
+                </doc>
+                <doc type="scenario">
+                    A server declares 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 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 declares a named queue and attempts to bind it to 4
+                    different
+                    exchanges.
+                </doc>
+            </rule>
+
+            <chassis name="server" implement="MUST"/>
+
+            <response name="bind-ok"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <field name="queue" domain="queue-name">
+                <doc>Specifies the name of the queue to bind.</doc>
+                <rule name="queue-known" on-failure="not-found">
+                    <doc>
+                        The client MUST either specify a queue name or have
+                        previously declared a
+                        queue on the same channel
+                    </doc>
+                    <doc type="scenario">
+                        The client opens a channel and attempts to bind an
+                        unnamed queue.
+                    </doc>
+                </rule>
+                <rule name="must-exist" on-failure="not-found">
+                    <doc>
+                        The client MUST NOT attempt to bind a queue that does
+                        not exist.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to bind a non-existent queue.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="exchange" domain="exchange-name"
+                   label="name of the exchange to bind to">
+                <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>
+                <rule name="default-exchange">
+                    <doc>
+                        The server MUST accept a blank exchange name to mean the
+                        default exchange.
+                    </doc>
+                    <doc type="scenario">
+                        The client declares a queue and binds it to a blank
+                        exchange name.
+                    </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
+                        publisher sends the exchange a message with routing key
+                        R, then the message
+                        MUST be passed to the message queue if K = R.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="no-wait" domain="no-wait"/>
+
+            <field name="arguments" domain="table"
+                   label="arguments for binding">
+                <doc>
+                    A set of arguments for the binding. The syntax and semantics
+                    of these arguments
+                    depends on the exchange class.
+                </doc>
+            </field>
+        </method>
+
+        <method name="bind-ok" synchronous="1" index="21"
+                label="confirm bind successful">
+            <doc>This method confirms that the bind was successful.</doc>
+
+            <chassis name="client" implement="MUST"/>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="unbind" synchronous="1" index="50"
+                label="unbind a queue from an exchange">
+            <doc>This method unbinds a queue from an exchange.</doc>
+            <rule name="01">
+                <doc>If a unbind fails, the server MUST raise a connection
+                    exception.
+                </doc>
+            </rule>
+            <chassis name="server" implement="MUST"/>
+            <response name="unbind-ok"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <field name="queue" domain="queue-name">
+                <doc>Specifies the name of the queue to unbind.</doc>
+                <rule name="queue-known" on-failure="not-found">
+                    <doc>
+                        The client MUST either specify a queue name or have
+                        previously declared a
+                        queue on the same channel
+                    </doc>
+                    <doc type="scenario">
+                        The client opens a channel and attempts to unbind an
+                        unnamed queue.
+                    </doc>
+                </rule>
+                <rule name="must-exist" on-failure="not-found">
+                    <doc>
+                        The client MUST NOT attempt to unbind a queue that does
+                        not exist.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to unbind a non-existent queue.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="exchange" domain="exchange-name">
+                <doc>The name of the exchange to unbind from.</doc>
+                <rule name="must-exist" on-failure="not-found">
+                    <doc>
+                        The client MUST NOT attempt to unbind a queue from an
+                        exchange that
+                        does not exist.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to unbind a queue from a
+                        non-existent exchange.
+                    </doc>
+                </rule>
+                <rule name="default-exchange">
+                    <doc>
+                        The server MUST accept a blank exchange name to mean the
+                        default exchange.
+                    </doc>
+                    <doc type="scenario">
+                        The client declares a queue and binds it to a blank
+                        exchange name.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="routing-key" domain="shortstr"
+                   label="routing key of binding">
+                <doc>Specifies the routing key of the binding to unbind.</doc>
+            </field>
+
+            <field name="arguments" domain="table" label="arguments of binding">
+                <doc>Specifies the arguments of the binding to unbind.</doc>
+            </field>
+        </method>
+
+        <method name="unbind-ok" synchronous="1" index="51"
+                label="confirm unbind successful">
+            <doc>This method confirms that the unbind was successful.</doc>
+            <chassis name="client" implement="MUST"/>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="purge" synchronous="1" index="30" label="purge a queue">
+            <doc>
+                This method removes all messages from a queue which are not
+                awaiting
+                acknowledgment.
+            </doc>
+
+            <rule name="02">
+                <doc>
+                    The server MUST NOT purge messages that have already been
+                    sent to a client
+                    but not yet acknowledged.
+                </doc>
+            </rule>
+
+            <rule name="03">
+                <doc>
+                    The server MAY implement a purge queue or log that allows
+                    system administrators
+                    to recover accidentally-purged messages. The server SHOULD
+                    NOT keep purged
+                    messages in the same storage spaces as the live messages
+                    since the volumes of
+                    purged messages may get very large.
+                </doc>
+            </rule>
+
+            <chassis name="server" implement="MUST"/>
+
+            <response name="purge-ok"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <field name="queue" domain="queue-name">
+                <doc>Specifies the name of the queue to purge.</doc>
+                <rule name="queue-known" on-failure="not-found">
+                    <doc>
+                        The client MUST either specify a queue name or have
+                        previously declared a
+                        queue on the same channel
+                    </doc>
+                    <doc type="scenario">
+                        The client opens a channel and attempts to purge an
+                        unnamed queue.
+                    </doc>
+                </rule>
+                <rule name="must-exist" on-failure="not-found">
+                    <doc>
+                        The client MUST NOT attempt to purge a queue that does
+                        not exist.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to purge a non-existent queue.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="no-wait" domain="no-wait"/>
+        </method>
+
+        <method name="purge-ok" synchronous="1" index="31"
+                label="confirms a queue purge">
+            <doc>This method confirms the purge of a queue.</doc>
+
+            <chassis name="client" implement="MUST"/>
+
+            <field name="message-count" domain="message-count">
+                <doc>
+                    Reports the number of messages purged.
+                </doc>
+            </field>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="delete" synchronous="1" index="40" label="delete a queue">
+            <doc>
+                This method deletes a queue. When a queue is deleted any pending
+                messages are sent
+                to a dead-letter queue if this is defined in the server
+                configuration, and all
+                consumers on the queue are cancelled.
+            </doc>
+
+            <rule name="01">
+                <doc>
+                    The server SHOULD use a dead-letter queue to hold messages
+                    that were pending on
+                    a deleted queue, and MAY provide facilities for a system
+                    administrator to move
+                    these messages back to an active queue.
+                </doc>
+            </rule>
+
+            <chassis name="server" implement="MUST"/>
+
+            <response name="delete-ok"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <field name="queue" domain="queue-name">
+                <doc>Specifies the name of the queue to delete.</doc>
+                <rule name="queue-known" on-failure="not-found">
+                    <doc>
+                        The client MUST either specify a queue name or have
+                        previously declared a
+                        queue on the same channel
+                    </doc>
+                    <doc type="scenario">
+                        The client opens a channel and attempts to delete an
+                        unnamed queue.
+                    </doc>
+                </rule>
+                <rule name="must-exist" on-failure="not-found">
+                    <doc>
+                        The client MUST NOT attempt to delete a queue that does
+                        not exist.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to delete a non-existent queue.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="if-unused" domain="bit" label="delete only if unused">
+                <doc>
+                    If set, the server will only delete the queue if it has no
+                    consumers. If the
+                    queue has consumers the server does does not delete it but
+                    raises a channel
+                    exception instead.
+                </doc>
+                <rule name="in-use" on-failure="precondition-failed">
+                    <doc>
+                        The server MUST NOT delete a queue that has consumers on
+                        it, if the if-unused
+                        field is true.
+                    </doc>
+                    <doc type="scenario">
+                        The client declares a queue, and consumes from it, then
+                        tries to delete it
+                        setting if-unused to true.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="if-empty" domain="bit" label="delete only if empty">
+                <doc>
+                    If set, the server will only delete the queue if it has no
+                    messages.
+                </doc>
+                <rule name="not-empty" on-failure="precondition-failed">
+                    <doc>
+                        The server MUST NOT delete a queue that has messages on
+                        it, if the
+                        if-empty field is true.
+                    </doc>
+                    <doc type="scenario">
+                        The client declares a queue, binds it and publishes some
+                        messages into it,
+                        then tries to delete it setting if-empty to true.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="no-wait" domain="no-wait"/>
+        </method>
+
+        <method name="delete-ok" synchronous="1" index="41"
+                label="confirm deletion of a queue">
+            <doc>This method confirms the deletion of a queue.</doc>
+
+            <chassis name="client" implement="MUST"/>
+
+            <field name="message-count" domain="message-count">
+                <doc>Reports the number of messages deleted.</doc>
+            </field>
+        </method>
+    </class>
+
+    <!-- ==  BASIC  ============================================================ -->
+
+    <class name="basic" handler="channel" index="60"
+           label="work with basic content">
+        <doc>
+            The Basic class provides methods that support an industry-standard
+            messaging model.
+        </doc>
+
+        <doc type="grammar">
+            basic = C:QOS S:QOS-OK
+            / C:CONSUME S:CONSUME-OK
+            / C:CANCEL S:CANCEL-OK
+            / C:PUBLISH content
+            / S:RETURN content
+            / S:DELIVER content
+            / C:GET ( S:GET-OK content / S:GET-EMPTY )
+            / C:ACK
+            / C:REJECT
+            / C:RECOVER-ASYNC
+            / C:RECOVER S:RECOVER-OK
+        </doc>
+
+        <chassis name="server" implement="MUST"/>
+        <chassis name="client" implement="MAY"/>
+
+        <rule name="01">
+            <doc>
+                The server SHOULD respect the persistent property of basic
+                messages and
+                SHOULD make a best-effort to hold persistent basic messages on a
+                reliable
+                storage mechanism.
+            </doc>
+            <doc type="scenario">
+                Send a persistent message to queue, stop server, restart server
+                and then
+                verify whether message is still present. Assumes that queues are
+                durable.
+                Persistence without durable queues makes no sense.
+            </doc>
         </rule>
-      </field>
-
-      <field name = "exchange" domain = "exchange-name">
-        <doc>The name of the exchange to unbind from.</doc>
-        <rule name = "must-exist" on-failure = "not-found">
-          <doc>
-            The client MUST NOT attempt to unbind a queue from an exchange that
-            does not exist.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to unbind a queue from a non-existent exchange.
-          </doc>
-        </rule>
-        <rule name = "default-exchange">
-          <doc>
-            The server MUST accept a blank exchange name to mean the default exchange.
-          </doc>
-          <doc type = "scenario">
-            The client declares a queue and binds it to a blank exchange name.
-          </doc>
-        </rule>
-      </field>
-
-      <field name = "routing-key" domain = "shortstr" label = "routing key of binding">
-        <doc>Specifies the routing key of the binding to unbind.</doc>
-      </field>
-
-      <field name = "arguments" domain = "table" label = "arguments of binding">
-        <doc>Specifies the arguments of the binding to unbind.</doc>
-      </field>
-    </method>
-
-    <method name = "unbind-ok" synchronous = "1" index = "51" label = "confirm unbind successful">
-      <doc>This method confirms that the unbind was successful.</doc>
-      <chassis name = "client" implement = "MUST"/>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "purge" synchronous = "1" index = "30" label = "purge a queue">
-      <doc>
-        This method removes all messages from a queue which are not awaiting
-        acknowledgment.
-      </doc>
-
-      <rule name = "02">
-        <doc>
-          The server MUST NOT purge messages that have already been sent to a client
-          but not yet acknowledged.
-        </doc>
-      </rule>
 
-      <rule name = "03">
-        <doc>
-          The server MAY implement a purge queue or log that allows system administrators
-          to recover accidentally-purged messages. The server SHOULD NOT keep purged
-          messages in the same storage spaces as the live messages since the volumes of
-          purged messages may get very large.
-        </doc>
-      </rule>
-
-      <chassis name = "server" implement = "MUST" />
-
-      <response name = "purge-ok" />
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <field name = "queue" domain = "queue-name">
-        <doc>Specifies the name of the queue to purge.</doc>
-        <rule name = "queue-known" on-failure = "not-found">
-          <doc>
-            The client MUST either specify a queue name or have previously declared a
-            queue on the same channel
-          </doc>
-          <doc type = "scenario">
-            The client opens a channel and attempts to purge an unnamed queue.
-          </doc>
-        </rule>
-        <rule name = "must-exist" on-failure = "not-found">
-          <doc>
-            The client MUST NOT attempt to purge a queue that does not exist.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to purge a non-existent queue.
-          </doc>
+        <rule name="02">
+            <doc>
+                The server MUST NOT discard a persistent basic message in case
+                of a queue
+                overflow.
+            </doc>
+            <doc type="scenario">
+                Declare a queue overflow situation with persistent messages and
+                verify that
+                messages do not get lost (presumably the server will write them
+                to disk).
+            </doc>
         </rule>
-      </field>
-
-      <field name = "no-wait" domain = "no-wait" />
-    </method>
-
-    <method name = "purge-ok" synchronous = "1" index = "31" label = "confirms a queue purge">
-      <doc>This method confirms the purge of a queue.</doc>
-
-      <chassis name = "client" implement = "MUST" />
 
-      <field name = "message-count" domain = "message-count">
-        <doc>
-          Reports the number of messages purged.
-        </doc>
-      </field>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "delete" synchronous = "1" index = "40" label = "delete a queue">
-      <doc>
-        This method deletes a queue. When a queue is deleted any pending messages are sent
-        to a dead-letter queue if this is defined in the server configuration, and all
-        consumers on the queue are cancelled.
-      </doc>
-
-      <rule name = "01">
-        <doc>
-          The server SHOULD use a dead-letter queue to hold messages that were pending on
-          a deleted queue, and MAY provide facilities for a system administrator to move
-          these messages back to an active queue.
-        </doc>
-      </rule>
-
-      <chassis name = "server" implement = "MUST" />
-
-      <response name = "delete-ok" />
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <field name = "queue" domain = "queue-name">
-        <doc>Specifies the name of the queue to delete.</doc>
-        <rule name = "queue-known" on-failure = "not-found">
-          <doc>
-            The client MUST either specify a queue name or have previously declared a
-            queue on the same channel
-          </doc>
-          <doc type = "scenario">
-            The client opens a channel and attempts to delete an unnamed queue.
-          </doc>
-        </rule>
-        <rule name = "must-exist" on-failure = "not-found">
-          <doc>
-            The client MUST NOT attempt to delete a queue that does not exist.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to delete a non-existent queue.
-          </doc>
+        <rule name="03">
+            <doc>
+                The server MAY use the Channel.Flow method to slow or stop a
+                basic message
+                publisher when necessary.
+            </doc>
+            <doc type="scenario">
+                Declare a queue overflow situation with non-persistent messages
+                and verify
+                whether the server responds with Channel.Flow or not. Repeat
+                with persistent
+                messages.
+            </doc>
         </rule>
-      </field>
 
-      <field name = "if-unused" domain = "bit" label = "delete only if unused">
-        <doc>
-          If set, the server will only delete the queue if it has no consumers. If the
-          queue has consumers the server does does not delete it but raises a channel
-          exception instead.
-        </doc>
-        <rule name = "in-use" on-failure = "precondition-failed">
-          <doc>
-            The server MUST NOT delete a queue that has consumers on it, if the if-unused
-            field is true.
-          </doc>
-          <doc type = "scenario">
-            The client declares a queue, and consumes from it, then tries to delete it
-            setting if-unused to true.
-          </doc>
+        <rule name="04">
+            <doc>
+                The server MAY overflow non-persistent basic messages to
+                persistent
+                storage.
+            </doc>
+            <!-- Test scenario: untestable -->
         </rule>
-      </field>
 
-      <field name = "if-empty" domain = "bit" label = "delete only if empty">
-        <doc>
-          If set, the server will only delete the queue if it has no messages.
-        </doc>
-        <rule name = "not-empty" on-failure = "precondition-failed">
-          <doc>
-            The server MUST NOT delete a queue that has messages on it, if the
-            if-empty field is true.
-          </doc>
-          <doc type = "scenario">
-            The client declares a queue, binds it and publishes some messages into it,
-            then tries to delete it setting if-empty to true.
-          </doc>
+        <rule name="05">
+            <doc>
+                The server MAY discard or dead-letter non-persistent basic
+                messages on a
+                priority basis if the queue size exceeds some configured limit.
+            </doc>
+            <!-- Test scenario: untestable -->
         </rule>
-      </field>
-
-      <field name = "no-wait" domain = "no-wait" />
-    </method>
-
-    <method name = "delete-ok" synchronous = "1" index = "41" label = "confirm deletion of a queue">
-      <doc>This method confirms the deletion of a queue.</doc>
-
-      <chassis name = "client" implement = "MUST" />
-
-      <field name = "message-count" domain = "message-count">
-        <doc>Reports the number of messages deleted.</doc>
-      </field>
-    </method>
-  </class>
-
-  <!-- ==  BASIC  ============================================================ -->
-
-  <class name = "basic" handler = "channel" index = "60" label = "work with basic content">
-    <doc>
-      The Basic class provides methods that support an industry-standard messaging model.
-    </doc>
-
-    <doc type = "grammar">
-      basic               = C:QOS S:QOS-OK
-                          / C:CONSUME S:CONSUME-OK
-                          / C:CANCEL S:CANCEL-OK
-                          / C:PUBLISH content
-                          / S:RETURN content
-                          / S:DELIVER content
-                          / C:GET ( S:GET-OK content / S:GET-EMPTY )
-                          / C:ACK
-                          / C:REJECT
-                          / C:RECOVER-ASYNC
-                          / C:RECOVER S:RECOVER-OK
-    </doc>
-
-    <chassis name = "server" implement = "MUST" />
-    <chassis name = "client" implement = "MAY" />
-
-    <rule name = "01">
-      <doc>
-        The server SHOULD respect the persistent property of basic messages and
-        SHOULD make a best-effort to hold persistent basic messages on a reliable
-        storage mechanism.
-      </doc>
-      <doc type = "scenario">
-        Send a persistent message to queue, stop server, restart server and then
-        verify whether message is still present.  Assumes that queues are durable.
-        Persistence without durable queues makes no sense.
-      </doc>
-    </rule>
-
-    <rule name = "02">
-      <doc>
-        The server MUST NOT discard a persistent basic message in case of a queue
-        overflow.
-      </doc>
-      <doc type = "scenario">
-        Declare a queue overflow situation with persistent messages and verify that
-        messages do not get lost (presumably the server will write them to disk).
-      </doc>
-    </rule>
-
-    <rule name = "03">
-      <doc>
-        The server MAY use the Channel.Flow method to slow or stop a basic message
-        publisher when necessary.
-      </doc>
-      <doc type = "scenario">
-        Declare a queue overflow situation with non-persistent messages and verify
-        whether the server responds with Channel.Flow or not. Repeat with persistent
-        messages.
-      </doc>
-    </rule>
-
-    <rule name = "04">
-      <doc>
-        The server MAY overflow non-persistent basic messages to persistent
-        storage.
-      </doc>
-      <!-- Test scenario: untestable -->
-    </rule>
-
-    <rule name = "05">
-      <doc>
-        The server MAY discard or dead-letter non-persistent basic messages on a
-        priority basis if the queue size exceeds some configured limit.
-      </doc>
-      <!-- Test scenario: untestable -->
-    </rule>
-
-    <rule name = "06">
-      <doc>
-        The server MUST implement at least 2 priority levels for basic messages,
-        where priorities 0-4 and 5-9 are treated as two distinct levels.
-      </doc>
-      <doc type = "scenario">
-        Send a number of priority 0 messages to a queue. Send one priority 9
-        message.  Consume messages from the queue and verify that the first message
-        received was priority 9.
-      </doc>
-    </rule>
-
-    <rule name = "07">
-      <doc>
-        The server MAY implement up to 10 priority levels.
-      </doc>
-      <doc type = "scenario">
-        Send a number of messages with mixed priorities to a queue, so that all
-        priority values from 0 to 9 are exercised. A good scenario would be ten
-        messages in low-to-high priority.  Consume from queue and verify how many
-        priority levels emerge.
-      </doc>
-    </rule>
-
-    <rule name = "08">
-      <doc>
-        The server MUST deliver messages of the same priority in order irrespective of
-        their individual persistence.
-      </doc>
-      <doc type = "scenario">
-        Send a set of messages with the same priority but different persistence
-        settings to a queue.  Consume and verify that messages arrive in same order
-        as originally published.
-      </doc>
-    </rule>
-
-    <rule name = "09">
-      <doc>
-        The server MUST support un-acknowledged delivery of Basic content, i.e.
-        consumers with the no-ack field set to TRUE.
-      </doc>
-    </rule>
-
-    <rule name = "10">
-      <doc>
-        The server MUST support explicitly acknowledged delivery of Basic content,
-        i.e. consumers with the no-ack field set to FALSE.
-      </doc>
-      <doc type = "scenario">
-        Declare a queue and a consumer using explicit acknowledgements.  Publish a
-        set of messages to the queue.  Consume the messages but acknowledge only
-        half of them.  Disconnect and reconnect, and consume from the queue.
-        Verify that the remaining messages are received.
-      </doc>
-    </rule>
-
-    <!--  These are the properties for a Basic content  -->
-
-    <!--  MIME typing -->
-    <field name = "content-type"    domain = "shortstr"   label = "MIME content type" />
-    <!--  MIME typing -->
-    <field name = "content-encoding" domain = "shortstr"  label = "MIME content encoding" />
-    <!--  For applications, and for header exchange routing -->
-    <field name = "headers"         domain = "table"      label = "message header field table" />
-    <!--  For queues that implement persistence -->
-    <field name = "delivery-mode"   domain = "octet"      label = "non-persistent (1) or persistent (2)" />
-    <!--  For queues that implement priorities -->
-    <field name = "priority"        domain = "octet"      label = "message priority, 0 to 9" />
-    <!--  For application use, no formal behaviour -->
-    <field name = "correlation-id"  domain = "shortstr"   label = "application correlation identifier" />
-    <!--  For application use, no formal behaviour but may hold the
-          name of a private response queue, when used in request messages -->
-    <field name = "reply-to"        domain = "shortstr"   label = "address to reply to" />
-    <!--  For implementation use, no formal behaviour -->
-    <field name = "expiration"      domain = "shortstr"   label = "message expiration specification" />
-    <!--  For application use, no formal behaviour -->
-    <field name = "message-id"      domain = "shortstr"   label = "application message identifier" />
-    <!--  For application use, no formal behaviour -->
-    <field name = "timestamp"       domain = "timestamp"  label = "message timestamp" />
-    <!--  For application use, no formal behaviour -->
-    <field name = "type"            domain = "shortstr"   label = "message type name" />
-    <!--  For application use, no formal behaviour -->
-    <field name = "user-id"         domain = "shortstr"   label = "creating user id" />
-    <!--  For application use, no formal behaviour -->
-    <field name = "app-id"          domain = "shortstr"   label = "creating application id" />
-    <!--  Deprecated, was old cluster-id property -->
-    <field name = "reserved"        domain = "shortstr"   label = "reserved, must be empty" />
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "qos" synchronous = "1" index = "10" label = "specify quality of service">
-      <doc>
-        This method requests a specific quality of service. The QoS can be specified for the
-        current channel or for all channels on the connection. The particular properties and
-        semantics of a qos method always depend on the content class semantics. Though the
-        qos method could in principle apply to both peers, it is currently meaningful only
-        for the server.
-      </doc>
-
-      <chassis name = "server" implement = "MUST" />
-      <response name = "qos-ok" />
-
-      <field name = "prefetch-size" domain = "long" label = "prefetch window in octets">
-        <doc>
-          The client can request that messages be sent in advance so that when the client
-          finishes processing a message, the following message is already held locally,
-          rather than needing to be sent down the channel. Prefetching gives a performance
-          improvement. This field specifies the prefetch window size in octets. The server
-          will send a message in advance if it is equal to or smaller in size than the
-          available prefetch size (and also falls into other prefetch limits). May be set
-          to zero, meaning "no specific limit", although other prefetch limits may still
-          apply. The prefetch-size is ignored if the no-ack option is set.
-        </doc>
-        <rule name = "01">
-          <doc>
-            The server MUST ignore this setting when the client is not processing any
-            messages - i.e. the prefetch size does not limit the transfer of single
-            messages to a client, only the sending in advance of more messages while
-            the client still has one or more unacknowledged messages.
-          </doc>
-          <doc type = "scenario">
-            Define a QoS prefetch-size limit and send a single message that exceeds
-            that limit.  Verify that the message arrives correctly.
-          </doc>
-        </rule>
-      </field>
 
-      <field name = "prefetch-count" domain = "short" label = "prefetch window in messages">
-        <doc>
-          Specifies a prefetch window in terms of whole messages. This field may be used
-          in combination with the prefetch-size field; a message will only be sent in
-          advance if both prefetch windows (and those at the channel and connection level)
-          allow it. The prefetch-count is ignored if the no-ack option is set.
-        </doc>
-        <rule name = "01">
-          <doc>
-            The server may send less data in advance than allowed by the client's
-            specified prefetch windows but it MUST NOT send more.
-          </doc>
-          <doc type = "scenario">
-            Define a QoS prefetch-size limit and a prefetch-count limit greater than
-            one.  Send multiple messages that exceed the prefetch size.  Verify that
-            no more than one message arrives at once.
-          </doc>
+        <rule name="06">
+            <doc>
+                The server MUST implement at least 2 priority levels for basic
+                messages,
+                where priorities 0-4 and 5-9 are treated as two distinct levels.
+            </doc>
+            <doc type="scenario">
+                Send a number of priority 0 messages to a queue. Send one
+                priority 9
+                message. Consume messages from the queue and verify that the
+                first message
+                received was priority 9.
+            </doc>
         </rule>
-      </field>
-
-      <field name = "global" domain = "bit" label = "apply to entire connection">
-        <doc>
-          By default the QoS settings apply to the current channel only. If this field is
-          set, they are applied to the entire connection.
-        </doc>
-      </field>
-    </method>
-
-    <method name = "qos-ok" synchronous = "1" index = "11" label = "confirm the requested qos">
-      <doc>
-        This method tells the client that the requested QoS levels could be handled by the
-        server. The requested QoS applies to all active consumers until a new QoS is
-        defined.
-      </doc>
-      <chassis name = "client" implement = "MUST" />
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "consume" synchronous = "1" index = "20" label = "start a queue consumer">
-      <doc>
-        This method asks the server to start a "consumer", which is a transient request for
-        messages from a specific queue. Consumers last as long as the channel they were
-        declared on, or until the client cancels them.
-      </doc>
-
-      <rule name = "01">
-        <doc>
-          The server SHOULD support at least 16 consumers per queue, and ideally, impose
-          no limit except as defined by available resources.
-        </doc>
-        <doc type = "scenario">
-          Declare a queue and create consumers on that queue until the server closes the
-          connection. Verify that the number of consumers created was at least sixteen
-          and report the total number.
-        </doc>
-      </rule>
-
-      <chassis name = "server" implement = "MUST" />
-      <response name = "consume-ok" />
 
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <field name = "queue" domain = "queue-name">
-        <doc>Specifies the name of the queue to consume from.</doc>
-      </field>
-
-      <field name = "consumer-tag" domain = "consumer-tag">
-        <doc>
-          Specifies the identifier for the consumer. The consumer tag is local to a
-          channel, so two clients can use the same consumer tags. If this field is
-          empty the server will generate a unique tag.
-        </doc>
-        <rule name = "01" on-failure = "not-allowed">
-          <doc>
-            The client MUST NOT specify a tag that refers to an existing consumer.
-          </doc>
-          <doc type = "scenario">
-            Attempt to create two consumers with the same non-empty tag, on the
-            same channel.
-          </doc>
-        </rule>
-        <rule name = "02" on-failure = "not-allowed">
-          <doc>
-            The consumer tag is valid only within the channel from which the
-            consumer was created. I.e. a client MUST NOT create a consumer in one
-            channel and then use it in another.
-          </doc>
-          <doc type = "scenario">
-            Attempt to create a consumer in one channel, then use in another channel,
-            in which consumers have also been created (to test that the server uses
-            unique consumer tags).
-          </doc>
+        <rule name="07">
+            <doc>
+                The server MAY implement up to 10 priority levels.
+            </doc>
+            <doc type="scenario">
+                Send a number of messages with mixed priorities to a queue, so
+                that all
+                priority values from 0 to 9 are exercised. A good scenario would
+                be ten
+                messages in low-to-high priority. Consume from queue and verify
+                how many
+                priority levels emerge.
+            </doc>
         </rule>
-      </field>
-
-      <field name = "no-local" domain = "no-local" />
-
-      <field name = "no-ack" domain = "no-ack" />
-
-      <field name = "exclusive" domain = "bit" label = "request exclusive access">
-        <doc>
-          Request exclusive consumer access, meaning only this consumer can access the
-          queue.
-        </doc>
 
-        <rule name = "01" on-failure = "access-refused">
-          <doc>
-            The client MAY NOT gain exclusive access to a queue that already has
-            active consumers.
-          </doc>
-          <doc type = "scenario">
-            Open two connections to a server, and in one connection declare a shared
-            (non-exclusive) queue and then consume from the queue.  In the second
-            connection attempt to consume from the same queue using the exclusive
-            option.
-          </doc>
+        <rule name="08">
+            <doc>
+                The server MUST deliver messages of the same priority in order
+                irrespective of
+                their individual persistence.
+            </doc>
+            <doc type="scenario">
+                Send a set of messages with the same priority but different
+                persistence
+                settings to a queue. Consume and verify that messages arrive in
+                same order
+                as originally published.
+            </doc>
         </rule>
-      </field>
-
-      <field name = "no-wait" domain = "no-wait" />
-
-      <field name = "arguments" domain = "table" label = "arguments for declaration">
-        <doc>
-          A set of arguments for the consume. The syntax and semantics of these
-          arguments depends on the server implementation.
-        </doc>
-      </field>
-    </method>
-
-    <method name = "consume-ok" synchronous = "1" index = "21" label = "confirm a new consumer">
-      <doc>
-        The server provides the client with a consumer tag, which is used by the client
-        for methods called on the consumer at a later stage.
-      </doc>
-      <chassis name = "client" implement = "MUST" />
-      <field name = "consumer-tag" domain = "consumer-tag">
-        <doc>
-          Holds the consumer tag specified by the client or provided by the server.
-        </doc>
-      </field>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "cancel" synchronous = "1" index = "30" label = "end a queue consumer">
-      <doc>
-        This method cancels a consumer. This does not affect already delivered
-        messages, but it does mean the server will not send any more messages for
-        that consumer. The client may receive an arbitrary number of messages in
-        between sending the cancel method and receiving the cancel-ok reply.
-      </doc>
-
-      <rule name = "01">
-        <doc>
-          If the queue does not exist the server MUST ignore the cancel method, so
-          long as the consumer tag is valid for that channel.
-        </doc>
-        <doc type = "scenario">
-          TODO.
-        </doc>
-      </rule>
-
-      <chassis name = "server" implement = "MUST" />
-      <response name = "cancel-ok" />
-
-      <field name = "consumer-tag" domain = "consumer-tag" />
-      <field name = "no-wait" domain = "no-wait" />
-    </method>
-
-    <method name = "cancel-ok" synchronous = "1" index = "31" label = "confirm a cancelled consumer">
-      <doc>
-        This method confirms that the cancellation was completed.
-      </doc>
-      <chassis name = "client" implement = "MUST" />
-      <field name = "consumer-tag" domain = "consumer-tag" />
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "publish" content = "1" index = "40" label = "publish a message">
-      <doc>
-        This method publishes a message to a specific exchange. The message will be routed
-        to queues as defined by the exchange configuration and distributed to any active
-        consumers when the transaction, if any, is committed.
-      </doc>
-
-      <chassis name = "server" implement = "MUST" />
 
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <field name = "exchange" domain = "exchange-name">
-        <doc>
-          Specifies the name of the exchange to publish to. The exchange name can be
-          empty, meaning the default exchange. If the exchange name is specified, and that
-          exchange does not exist, the server will raise a channel exception.
-        </doc>
-
-        <rule name = "must-exist" on-failure = "not-found">
-          <doc>
-            The client MUST NOT attempt to publish a content to an exchange that
-            does not exist.
-          </doc>
-          <doc type = "scenario">
-            The client attempts to publish a content to a non-existent exchange.
-          </doc>
-        </rule>
-        <rule name = "default-exchange">
-          <doc>
-            The server MUST accept a blank exchange name to mean the default exchange.
-          </doc>
-          <doc type = "scenario">
-            The client declares a queue and binds it to a blank exchange name.
-          </doc>
-        </rule>
-        <rule name = "02">
-          <doc>
-            If the exchange was declared as an internal exchange, the server MUST raise
-            a channel exception with a reply code 403 (access refused).
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
+        <rule name="09">
+            <doc>
+                The server MUST support un-acknowledged delivery of Basic
+                content, i.e.
+                consumers with the no-ack field set to TRUE.
+            </doc>
         </rule>
 
-        <rule name = "03">
-          <doc>
-            The exchange MAY refuse basic content in which case it MUST raise a channel
-            exception with reply code 540 (not implemented).
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
+        <rule name="10">
+            <doc>
+                The server MUST support explicitly acknowledged delivery of
+                Basic content,
+                i.e. consumers with the no-ack field set to FALSE.
+            </doc>
+            <doc type="scenario">
+                Declare a queue and a consumer using explicit acknowledgements.
+                Publish a
+                set of messages to the queue. Consume the messages but
+                acknowledge only
+                half of them. Disconnect and reconnect, and consume from the
+                queue.
+                Verify that the remaining messages are received.
+            </doc>
         </rule>
-      </field>
 
-      <field name = "routing-key" domain = "shortstr" label = "Message routing key">
-        <doc>
-          Specifies the routing key for the message. The routing key is used for routing
-          messages depending on the exchange configuration.
-        </doc>
-      </field>
-
-      <field name = "mandatory" domain = "bit" label = "indicate mandatory routing">
-        <doc>
-          This flag tells the server how to react if the message cannot be routed to a
-          queue. If this flag is set, the server will return an unroutable message with a
-          Return method. If this flag is zero, the server silently drops the message.
-        </doc>
-
-        <rule name = "01">
-          <doc>
-            The server SHOULD implement the mandatory flag.
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
+        <!--  These are the properties for a Basic content  -->
+
+        <!--  MIME typing -->
+        <field name="content-type" domain="shortstr" label="MIME content type"/>
+        <!--  MIME typing -->
+        <field name="content-encoding" domain="shortstr"
+               label="MIME content encoding"/>
+        <!--  For applications, and for header exchange routing -->
+        <field name="headers" domain="table"
+               label="message header field table"/>
+        <!--  For queues that implement persistence -->
+        <field name="delivery-mode" domain="octet"
+               label="non-persistent (1) or persistent (2)"/>
+        <!--  For queues that implement priorities -->
+        <field name="priority" domain="octet" label="message priority, 0 to 9"/>
+        <!--  For application use, no formal behaviour -->
+        <field name="correlation-id" domain="shortstr"
+               label="application correlation identifier"/>
+        <!--  For application use, no formal behaviour but may hold the
+          name of a private response queue, when used in request messages -->
+        <field name="reply-to" domain="shortstr" label="address to reply to"/>
+        <!--  For implementation use, no formal behaviour -->
+        <field name="expiration" domain="shortstr"
+               label="message expiration specification"/>
+        <!--  For application use, no formal behaviour -->
+        <field name="message-id" domain="shortstr"
+               label="application message identifier"/>
+        <!--  For application use, no formal behaviour -->
+        <field name="timestamp" domain="timestamp" label="message timestamp"/>
+        <!--  For application use, no formal behaviour -->
+        <field name="type" domain="shortstr" label="message type name"/>
+        <!--  For application use, no formal behaviour -->
+        <field name="user-id" domain="shortstr" label="creating user id"/>
+        <!--  For application use, no formal behaviour -->
+        <field name="app-id" domain="shortstr" label="creating application id"/>
+        <!--  Deprecated, was old cluster-id property -->
+        <field name="reserved" domain="shortstr"
+               label="reserved, must be empty"/>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="qos" synchronous="1" index="10"
+                label="specify quality of service">
+            <doc>
+                This method requests a specific quality of service. The QoS can
+                be specified for the
+                current channel or for all channels on the connection. The
+                particular properties and
+                semantics of a qos method always depend on the content class
+                semantics. Though the
+                qos method could in principle apply to both peers, it is
+                currently meaningful only
+                for the server.
+            </doc>
+
+            <chassis name="server" implement="MUST"/>
+            <response name="qos-ok"/>
+
+            <field name="prefetch-size" domain="long"
+                   label="prefetch window in octets">
+                <doc>
+                    The client can request that messages be sent in advance so
+                    that when the client
+                    finishes processing a message, the following message is
+                    already held locally,
+                    rather than needing to be sent down the channel. Prefetching
+                    gives a performance
+                    improvement. This field specifies the prefetch window size
+                    in octets. The server
+                    will send a message in advance if it is equal to or smaller
+                    in size than the
+                    available prefetch size (and also falls into other prefetch
+                    limits). May be set
+                    to zero, meaning "no specific limit", although other
+                    prefetch limits may still
+                    apply. The prefetch-size is ignored if the no-ack option is
+                    set.
+                </doc>
+                <rule name="01">
+                    <doc>
+                        The server MUST ignore this setting when the client is
+                        not processing any
+                        messages - i.e. the prefetch size does not limit the
+                        transfer of single
+                        messages to a client, only the sending in advance of
+                        more messages while
+                        the client still has one or more unacknowledged
+                        messages.
+                    </doc>
+                    <doc type="scenario">
+                        Define a QoS prefetch-size limit and send a single
+                        message that exceeds
+                        that limit. Verify that the message arrives correctly.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="prefetch-count" domain="short"
+                   label="prefetch window in messages">
+                <doc>
+                    Specifies a prefetch window in terms of whole messages. This
+                    field may be used
+                    in combination with the prefetch-size field; a message will
+                    only be sent in
+                    advance if both prefetch windows (and those at the channel
+                    and connection level)
+                    allow it. The prefetch-count is ignored if the no-ack option
+                    is set.
+                </doc>
+                <rule name="01">
+                    <doc>
+                        The server may send less data in advance than allowed by
+                        the client's
+                        specified prefetch windows but it MUST NOT send more.
+                    </doc>
+                    <doc type="scenario">
+                        Define a QoS prefetch-size limit and a prefetch-count
+                        limit greater than
+                        one. Send multiple messages that exceed the prefetch
+                        size. Verify that
+                        no more than one message arrives at once.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="global" domain="bit"
+                   label="apply to entire connection">
+                <doc>
+                    By default the QoS settings apply to the current channel
+                    only. If this field is
+                    set, they are applied to the entire connection.
+                </doc>
+            </field>
+        </method>
+
+        <method name="qos-ok" synchronous="1" index="11"
+                label="confirm the requested qos">
+            <doc>
+                This method tells the client that the requested QoS levels could
+                be handled by the
+                server. The requested QoS applies to all active consumers until
+                a new QoS is
+                defined.
+            </doc>
+            <chassis name="client" implement="MUST"/>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="consume" synchronous="1" index="20"
+                label="start a queue consumer">
+            <doc>
+                This method asks the server to start a "consumer", which is a
+                transient request for
+                messages from a specific queue. Consumers last as long as the
+                channel they were
+                declared on, or until the client cancels them.
+            </doc>
+
+            <rule name="01">
+                <doc>
+                    The server SHOULD support at least 16 consumers per queue,
+                    and ideally, impose
+                    no limit except as defined by available resources.
+                </doc>
+                <doc type="scenario">
+                    Declare a queue and create consumers on that queue until the
+                    server closes the
+                    connection. Verify that the number of consumers created was
+                    at least sixteen
+                    and report the total number.
+                </doc>
+            </rule>
+
+            <chassis name="server" implement="MUST"/>
+            <response name="consume-ok"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <field name="queue" domain="queue-name">
+                <doc>Specifies the name of the queue to consume from.</doc>
+            </field>
+
+            <field name="consumer-tag" domain="consumer-tag">
+                <doc>
+                    Specifies the identifier for the consumer. The consumer tag
+                    is local to a
+                    channel, so two clients can use the same consumer tags. If
+                    this field is
+                    empty the server will generate a unique tag.
+                </doc>
+                <rule name="01" on-failure="not-allowed">
+                    <doc>
+                        The client MUST NOT specify a tag that refers to an
+                        existing consumer.
+                    </doc>
+                    <doc type="scenario">
+                        Attempt to create two consumers with the same non-empty
+                        tag, on the
+                        same channel.
+                    </doc>
+                </rule>
+                <rule name="02" on-failure="not-allowed">
+                    <doc>
+                        The consumer tag is valid only within the channel from
+                        which the
+                        consumer was created. I.e. a client MUST NOT create a
+                        consumer in one
+                        channel and then use it in another.
+                    </doc>
+                    <doc type="scenario">
+                        Attempt to create a consumer in one channel, then use in
+                        another channel,
+                        in which consumers have also been created (to test that
+                        the server uses
+                        unique consumer tags).
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="no-local" domain="no-local"/>
+
+            <field name="no-ack" domain="no-ack"/>
+
+            <field name="exclusive" domain="bit"
+                   label="request exclusive access">
+                <doc>
+                    Request exclusive consumer access, meaning only this
+                    consumer can access the
+                    queue.
+                </doc>
+
+                <rule name="01" on-failure="access-refused">
+                    <doc>
+                        The client MAY NOT gain exclusive access to a queue that
+                        already has
+                        active consumers.
+                    </doc>
+                    <doc type="scenario">
+                        Open two connections to a server, and in one connection
+                        declare a shared
+                        (non-exclusive) queue and then consume from the queue.
+                        In the second
+                        connection attempt to consume from the same queue using
+                        the exclusive
+                        option.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="no-wait" domain="no-wait"/>
+
+            <field name="arguments" domain="table"
+                   label="arguments for declaration">
+                <doc>
+                    A set of arguments for the consume. The syntax and semantics
+                    of these
+                    arguments depends on the server implementation.
+                </doc>
+            </field>
+        </method>
+
+        <method name="consume-ok" synchronous="1" index="21"
+                label="confirm a new consumer">
+            <doc>
+                The server provides the client with a consumer tag, which is
+                used by the client
+                for methods called on the consumer at a later stage.
+            </doc>
+            <chassis name="client" implement="MUST"/>
+            <field name="consumer-tag" domain="consumer-tag">
+                <doc>
+                    Holds the consumer tag specified by the client or provided
+                    by the server.
+                </doc>
+            </field>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="cancel" synchronous="1" index="30"
+                label="end a queue consumer">
+            <doc>
+                This method cancels a consumer. This does not affect already
+                delivered
+                messages, but it does mean the server will not send any more
+                messages for
+                that consumer. The client may receive an arbitrary number of
+                messages in
+                between sending the cancel method and receiving the cancel-ok
+                reply.
+            </doc>
+
+            <rule name="01">
+                <doc>
+                    If the queue does not exist the server MUST ignore the
+                    cancel method, so
+                    long as the consumer tag is valid for that channel.
+                </doc>
+                <doc type="scenario">
+                    TODO.
+                </doc>
+            </rule>
+
+            <chassis name="server" implement="MUST"/>
+            <response name="cancel-ok"/>
+
+            <field name="consumer-tag" domain="consumer-tag"/>
+            <field name="no-wait" domain="no-wait"/>
+        </method>
+
+        <method name="cancel-ok" synchronous="1" index="31"
+                label="confirm a cancelled consumer">
+            <doc>
+                This method confirms that the cancellation was completed.
+            </doc>
+            <chassis name="client" implement="MUST"/>
+            <field name="consumer-tag" domain="consumer-tag"/>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="publish" content="1" index="40" label="publish a message">
+            <doc>
+                This method publishes a message to a specific exchange. The
+                message will be routed
+                to queues as defined by the exchange configuration and
+                distributed to any active
+                consumers when the transaction, if any, is committed.
+            </doc>
+
+            <chassis name="server" implement="MUST"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <field name="exchange" domain="exchange-name">
+                <doc>
+                    Specifies the name of the exchange to publish to. The
+                    exchange name can be
+                    empty, meaning the default exchange. If the exchange name is
+                    specified, and that
+                    exchange does not exist, the server will raise a channel
+                    exception.
+                </doc>
+
+                <rule name="must-exist" on-failure="not-found">
+                    <doc>
+                        The client MUST NOT attempt to publish a content to an
+                        exchange that
+                        does not exist.
+                    </doc>
+                    <doc type="scenario">
+                        The client attempts to publish a content to a
+                        non-existent exchange.
+                    </doc>
+                </rule>
+                <rule name="default-exchange">
+                    <doc>
+                        The server MUST accept a blank exchange name to mean the
+                        default exchange.
+                    </doc>
+                    <doc type="scenario">
+                        The client declares a queue and binds it to a blank
+                        exchange name.
+                    </doc>
+                </rule>
+                <rule name="02">
+                    <doc>
+                        If the exchange was declared as an internal exchange,
+                        the server MUST raise
+                        a channel exception with a reply code 403 (access
+                        refused).
+                    </doc>
+                    <doc type="scenario">
+                        TODO.
+                    </doc>
+                </rule>
+
+                <rule name="03">
+                    <doc>
+                        The exchange MAY refuse basic content in which case it
+                        MUST raise a channel
+                        exception with reply code 540 (not implemented).
+                    </doc>
+                    <doc type="scenario">
+                        TODO.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="routing-key" domain="shortstr"
+                   label="Message routing key">
+                <doc>
+                    Specifies the routing key for the message. The routing key
+                    is used for routing
+                    messages depending on the exchange configuration.
+                </doc>
+            </field>
+
+            <field name="mandatory" domain="bit"
+                   label="indicate mandatory routing">
+                <doc>
+                    This flag tells the server how to react if the message
+                    cannot be routed to a
+                    queue. If this flag is set, the server will return an
+                    unroutable message with a
+                    Return method. If this flag is zero, the server silently
+                    drops the message.
+                </doc>
+
+                <rule name="01">
+                    <doc>
+                        The server SHOULD implement the mandatory flag.
+                    </doc>
+                    <doc type="scenario">
+                        TODO.
+                    </doc>
+                </rule>
+            </field>
+
+            <field name="immediate" domain="bit"
+                   label="request immediate delivery">
+                <doc>
+                    This flag tells the server how to react if the message
+                    cannot be routed to a
+                    queue consumer immediately. If this flag is set, the server
+                    will return an
+                    undeliverable message with a Return method. If this flag is
+                    zero, the server
+                    will queue the message, but with no guarantee that it will
+                    ever be consumed.
+                </doc>
+
+                <rule name="01">
+                    <doc>
+                        The server SHOULD implement the immediate flag.
+                    </doc>
+                    <doc type="scenario">
+                        TODO.
+                    </doc>
+                </rule>
+            </field>
+        </method>
+
+        <method name="return" content="1" index="50"
+                label="return a failed message">
+            <doc>
+                This method returns an undeliverable message that was published
+                with the "immediate"
+                flag set, or an unroutable message published with the
+                "mandatory" flag set. The
+                reply code and text provide information about the reason that
+                the message was
+                undeliverable.
+            </doc>
+
+            <chassis name="client" implement="MUST"/>
+
+            <field name="reply-code" domain="reply-code"/>
+            <field name="reply-text" domain="reply-text"/>
+
+            <field name="exchange" domain="exchange-name">
+                <doc>
+                    Specifies the name of the exchange that the message was
+                    originally published
+                    to. May be empty, meaning the default exchange.
+                </doc>
+            </field>
+
+            <field name="routing-key" domain="shortstr"
+                   label="Message routing key">
+                <doc>
+                    Specifies the routing key name specified when the message
+                    was published.
+                </doc>
+            </field>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="deliver" content="1" index="60"
+                label="notify the client of a consumer message">
+            <doc>
+                This method delivers a message to the client, via a consumer. In
+                the asynchronous
+                message delivery model, the client starts a consumer using the
+                Consume method, then
+                the server responds with Deliver methods as and when messages
+                arrive for that
+                consumer.
+            </doc>
+
+            <rule name="01">
+                <doc>
+                    The server SHOULD track the number of times a message has
+                    been delivered to
+                    clients and when a message is redelivered a certain number
+                    of times - e.g. 5
+                    times - without being acknowledged, the server SHOULD
+                    consider the message to be
+                    unprocessable (possibly causing client applications to
+                    abort), and move the
+                    message to a dead letter queue.
+                </doc>
+                <doc type="scenario">
+                    TODO.
+                </doc>
+            </rule>
+
+            <chassis name="client" implement="MUST"/>
+
+            <field name="consumer-tag" domain="consumer-tag"/>
+            <field name="delivery-tag" domain="delivery-tag"/>
+            <field name="redelivered" domain="redelivered"/>
+
+            <field name="exchange" domain="exchange-name">
+                <doc>
+                    Specifies the name of the exchange that the message was
+                    originally published to.
+                    May be empty, indicating the default exchange.
+                </doc>
+            </field>
+
+            <field name="routing-key" domain="shortstr"
+                   label="Message routing key">
+                <doc>Specifies the routing key name specified when the message
+                    was published.
+                </doc>
+            </field>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="get" synchronous="1" index="70"
+                label="direct access to a queue">
+            <doc>
+                This method provides a direct access to the messages in a queue
+                using a synchronous
+                dialogue that is designed for specific types of application
+                where synchronous
+                functionality is more important than performance.
+            </doc>
+
+            <response name="get-ok"/>
+            <response name="get-empty"/>
+            <chassis name="server" implement="MUST"/>
+
+            <!-- Deprecated: "ticket", must be zero -->
+            <field name="reserved-1" type="short" reserved="1"/>
+
+            <field name="queue" domain="queue-name">
+                <doc>Specifies the name of the queue to get a message from.
+                </doc>
+            </field>
+            <field name="no-ack" domain="no-ack"/>
+        </method>
+
+        <method name="get-ok" synchronous="1" content="1" index="71"
+                label="provide client with a message">
+            <doc>
+                This method delivers a message to the client following a get
+                method. A message
+                delivered by 'get-ok' must be acknowledged unless the no-ack
+                option was set in the
+                get method.
+            </doc>
+
+            <chassis name="client" implement="MAY"/>
+
+            <field name="delivery-tag" domain="delivery-tag"/>
+            <field name="redelivered" domain="redelivered"/>
+            <field name="exchange" domain="exchange-name">
+                <doc>
+                    Specifies the name of the exchange that the message was
+                    originally published to.
+                    If empty, the message was published to the default exchange.
+                </doc>
+            </field>
+
+            <field name="routing-key" domain="shortstr"
+                   label="Message routing key">
+                <doc>Specifies the routing key name specified when the message
+                    was published.
+                </doc>
+            </field>
+
+            <field name="message-count" domain="message-count"/>
+        </method>
+
+        <method name="get-empty" synchronous="1" index="72"
+                label="indicate no messages available">
+            <doc>
+                This method tells the client that the queue has no messages
+                available for the
+                client.
+            </doc>
+            <chassis name="client" implement="MAY"/>
+            <!-- Deprecated: "cluster-id", must be empty -->
+            <field name="reserved-1" type="shortstr" reserved="1"/>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="ack" index="80" label="acknowledge one or more messages">
+            <doc>
+                This method acknowledges one or more messages delivered via the
+                Deliver or Get-Ok
+                methods. The client can ask to confirm a single message or a set
+                of messages up to
+                and including a specific message.
+            </doc>
+
+            <chassis name="server" implement="MUST"/>
+
+            <field name="delivery-tag" domain="delivery-tag"/>
+            <field name="multiple" domain="bit"
+                   label="acknowledge multiple messages">
+                <doc>
+                    If set to 1, the delivery tag is treated as "up to and
+                    including", so that the
+                    client can acknowledge multiple messages with a single
+                    method. If set to zero,
+                    the delivery tag refers to a single message. If the multiple
+                    field is 1, and the
+                    delivery tag is zero, tells the server to acknowledge all
+                    outstanding messages.
+                </doc>
+                <rule name="exists" on-failure="precondition-failed">
+                    <doc>
+                        The server MUST validate that a non-zero delivery-tag
+                        refers to a delivered
+                        message, and raise a channel exception if this is not
+                        the case. On a transacted
+                        channel, this check MUST be done immediately and not
+                        delayed until a Tx.Commit.
+                        Specifically, a client MUST not acknowledge the same
+                        message more than once.
+                    </doc>
+                    <doc type="scenario">
+                        TODO.
+                    </doc>
+                </rule>
+            </field>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="reject" index="90" label="reject an incoming message">
+            <doc>
+                This method allows a client to reject a message. It can be used
+                to interrupt and
+                cancel large incoming messages, or return untreatable messages
+                to their original
+                queue.
+            </doc>
+
+            <rule name="01">
+                <doc>
+                    The server SHOULD be capable of accepting and process the
+                    Reject method while
+                    sending message content with a Deliver or Get-Ok method.
+                    I.e. the server should
+                    read and process incoming methods while sending output
+                    frames. To cancel a
+                    partially-send content, the server sends a content body
+                    frame of size 1 (i.e.
+                    with no data except the frame-end octet).
+                </doc>
+            </rule>
+
+            <rule name="02">
+                <doc>
+                    The server SHOULD interpret this method as meaning that the
+                    client is unable to
+                    process the message at this time.
+                </doc>
+                <doc type="scenario">
+                    TODO.
+                </doc>
+            </rule>
+
+            <rule name="03">
+                <doc>
+                    The client MUST NOT use this method as a means of selecting
+                    messages to process.
+                </doc>
+                <doc type="scenario">
+                    TODO.
+                </doc>
+            </rule>
+
+            <chassis name="server" implement="MUST"/>
+
+            <field name="delivery-tag" domain="delivery-tag"/>
+
+            <field name="requeue" domain="bit" label="requeue the message">
+                <doc>
+                    If requeue is true, the server will attempt to requeue the
+                    message. If requeue
+                    is false or the requeue attempt fails the messages are
+                    discarded or dead-lettered.
+                </doc>
+
+                <rule name="01">
+                    <doc>
+                        The server MUST NOT deliver the message to the same
+                        client within the
+                        context of the current channel. The recommended strategy
+                        is to attempt to
+                        deliver the message to an alternative consumer, and if
+                        that is not possible,
+                        to move the message to a dead-letter queue. The server
+                        MAY use more
+                        sophisticated tracking to hold the message on the queue
+                        and redeliver it to
+                        the same client at a later stage.
+                    </doc>
+                    <doc type="scenario">
+                        TODO.
+                    </doc>
+                </rule>
+            </field>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="recover-async" index="100"
+                label="redeliver unacknowledged messages"
+                deprecated="1">
+            <doc>
+                This method asks the server to redeliver all unacknowledged
+                messages on a
+                specified channel. Zero or more messages may be redelivered.
+                This method
+                is deprecated in favour of the synchronous Recover/Recover-Ok.
+            </doc>
+            <rule name="01">
+                <doc>
+                    The server MUST set the redelivered flag on all messages
+                    that are resent.
+                </doc>
+                <doc type="scenario">
+                    TODO.
+                </doc>
+            </rule>
+            <chassis name="server" implement="MAY"/>
+            <field name="requeue" domain="bit" label="requeue the message">
+                <doc>
+                    If this field is zero, the message will be redelivered to
+                    the original
+                    recipient. If this bit is 1, the server will attempt to
+                    requeue the message,
+                    potentially then delivering it to an alternative subscriber.
+                </doc>
+            </field>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="recover" index="110"
+                label="redeliver unacknowledged messages">
+            <doc>
+                This method asks the server to redeliver all unacknowledged
+                messages on a
+                specified channel. Zero or more messages may be redelivered.
+                This method
+                replaces the asynchronous Recover.
+            </doc>
+            <rule name="01">
+                <doc>
+                    The server MUST set the redelivered flag on all messages
+                    that are resent.
+                </doc>
+                <doc type="scenario">
+                    TODO.
+                </doc>
+            </rule>
+            <chassis name="server" implement="MUST"/>
+            <field name="requeue" domain="bit" label="requeue the message">
+                <doc>
+                    If this field is zero, the message will be redelivered to
+                    the original
+                    recipient. If this bit is 1, the server will attempt to
+                    requeue the message,
+                    potentially then delivering it to an alternative subscriber.
+                </doc>
+            </field>
+        </method>
+
+        <method name="recover-ok" synchronous="1" index="111"
+                label="confirm recovery">
+            <doc>
+                This method acknowledges a Basic.Recover method.
+            </doc>
+            <chassis name="client" implement="MUST"/>
+        </method>
+    </class>
+
+    <!-- ==  TX  =============================================================== -->
+
+    <class name="tx" handler="channel" index="90"
+           label="work with transactions">
+        <doc>
+            The Tx class allows publish and ack operations to be batched into
+            atomic
+            units of work. The intention is that all publish and ack requests
+            issued
+            within a transaction will complete successfully or none of them
+            will.
+            Servers SHOULD implement atomic transactions at least where all
+            publish
+            or ack requests affect a single queue. Transactions that cover
+            multiple
+            queues may be non-atomic, given that queues can be created and
+            destroyed
+            asynchronously, and such events do not form part of any transaction.
+            Further, the behaviour of transactions with respect to the immediate
+            and
+            mandatory flags on Basic.Publish methods is not defined.
+        </doc>
+
+        <rule name="not multiple queues">
+            <doc>
+                Applications MUST NOT rely on the atomicity of transactions that
+                affect more than one queue.
+            </doc>
         </rule>
-      </field>
-
-      <field name = "immediate" domain = "bit" label = "request immediate delivery">
-        <doc>
-          This flag tells the server how to react if the message cannot be routed to a
-          queue consumer immediately. If this flag is set, the server will return an
-          undeliverable message with a Return method. If this flag is zero, the server
-          will queue the message, but with no guarantee that it will ever be consumed.
-        </doc>
-
-        <rule name = "01">
-          <doc>
-            The server SHOULD implement the immediate flag.
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
+        <rule name="not immediate">
+            <doc>
+                Applications MUST NOT rely on the behaviour of transactions that
+                include messages published with the immediate option.
+            </doc>
         </rule>
-      </field>
-    </method>
-
-    <method name = "return" content = "1" index = "50" label = "return a failed message">
-      <doc>
-        This method returns an undeliverable message that was published with the "immediate"
-        flag set, or an unroutable message published with the "mandatory" flag set. The
-        reply code and text provide information about the reason that the message was
-        undeliverable.
-      </doc>
-
-      <chassis name = "client" implement = "MUST" />
-
-      <field name = "reply-code" domain = "reply-code" />
-      <field name = "reply-text" domain = "reply-text" />
-
-      <field name = "exchange" domain = "exchange-name">
-        <doc>
-          Specifies the name of the exchange that the message was originally published
-          to.  May be empty, meaning the default exchange.
-        </doc>
-      </field>
-
-      <field name = "routing-key" domain = "shortstr" label = "Message routing key">
-        <doc>
-          Specifies the routing key name specified when the message was published.
-        </doc>
-      </field>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "deliver" content = "1" index = "60"
-      label = "notify the client of a consumer message">
-      <doc>
-        This method delivers a message to the client, via a consumer. In the asynchronous
-        message delivery model, the client starts a consumer using the Consume method, then
-        the server responds with Deliver methods as and when messages arrive for that
-        consumer.
-      </doc>
-
-      <rule name = "01">
-        <doc>
-          The server SHOULD track the number of times a message has been delivered to
-          clients and when a message is redelivered a certain number of times - e.g. 5
-          times - without being acknowledged, the server SHOULD consider the message to be
-          unprocessable (possibly causing client applications to abort), and move the
-          message to a dead letter queue.
-        </doc>
-        <doc type = "scenario">
-          TODO.
-        </doc>
-      </rule>
-
-      <chassis name = "client" implement = "MUST" />
-
-      <field name = "consumer-tag" domain = "consumer-tag" />
-      <field name = "delivery-tag" domain = "delivery-tag" />
-      <field name = "redelivered" domain = "redelivered" />
-
-      <field name = "exchange" domain = "exchange-name">
-        <doc>
-          Specifies the name of the exchange that the message was originally published to.
-          May be empty, indicating the default exchange.
-        </doc>
-      </field>
-
-      <field name = "routing-key" domain = "shortstr" label = "Message routing key">
-        <doc>Specifies the routing key name specified when the message was published.</doc>
-      </field>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "get" synchronous = "1" index = "70" label = "direct access to a queue">
-      <doc>
-        This method provides a direct access to the messages in a queue using a synchronous
-        dialogue that is designed for specific types of application where synchronous
-        functionality is more important than performance.
-      </doc>
-
-      <response name = "get-ok" />
-      <response name = "get-empty" />
-      <chassis name = "server" implement = "MUST" />
-
-      <!-- Deprecated: "ticket", must be zero -->
-      <field name = "reserved-1" type = "short" reserved = "1" />
-
-      <field name = "queue" domain = "queue-name">
-        <doc>Specifies the name of the queue to get a message from.</doc>
-      </field>
-      <field name = "no-ack" domain = "no-ack" />
-    </method>
-
-    <method name = "get-ok" synchronous = "1" content = "1" index = "71"
-      label = "provide client with a message">
-      <doc>
-        This method delivers a message to the client following a get method. A message
-        delivered by 'get-ok' must be acknowledged unless the no-ack option was set in the
-        get method.
-      </doc>
-
-      <chassis name = "client" implement = "MAY" />
-
-      <field name = "delivery-tag" domain = "delivery-tag" />
-      <field name = "redelivered" domain = "redelivered" />
-      <field name = "exchange" domain = "exchange-name">
-        <doc>
-          Specifies the name of the exchange that the message was originally published to.
-          If empty, the message was published to the default exchange.
-        </doc>
-      </field>
-
-      <field name = "routing-key" domain = "shortstr" label = "Message routing key">
-        <doc>Specifies the routing key name specified when the message was published.</doc>
-      </field>
-
-      <field name = "message-count" domain = "message-count" />
-    </method>
-
-    <method name = "get-empty" synchronous = "1" index = "72"
-      label = "indicate no messages available">
-      <doc>
-        This method tells the client that the queue has no messages available for the
-        client.
-      </doc>
-      <chassis name = "client" implement = "MAY" />
-      <!-- Deprecated: "cluster-id", must be empty -->
-      <field name = "reserved-1" type = "shortstr" reserved = "1" />
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "ack" index = "80" label = "acknowledge one or more messages">
-      <doc>
-        This method acknowledges one or more messages delivered via the Deliver or Get-Ok
-        methods. The client can ask to confirm a single message or a set of messages up to
-        and including a specific message.
-      </doc>
-
-      <chassis name = "server" implement = "MUST" />
-
-      <field name = "delivery-tag" domain = "delivery-tag" />
-      <field name = "multiple" domain = "bit" label = "acknowledge multiple messages">
-        <doc>
-          If set to 1, the delivery tag is treated as "up to and including", so that the
-          client can acknowledge multiple messages with a single method. If set to zero,
-          the delivery tag refers to a single message. If the multiple field is 1, and the
-          delivery tag is zero, tells the server to acknowledge all outstanding messages.
-        </doc>
-        <rule name = "exists" on-failure = "precondition-failed">
-          <doc>
-            The server MUST validate that a non-zero delivery-tag refers to a delivered
-            message, and raise a channel exception if this is not the case.  On a transacted
-            channel, this check MUST be done immediately and not delayed until a Tx.Commit.
-            Specifically, a client MUST not acknowledge the same message more than once.
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
+        <rule name="not mandatory">
+            <doc>
+                Applications MUST NOT rely on the behaviour of transactions that
+                include messages published with the mandatory option.
+            </doc>
         </rule>
-      </field>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "reject" index = "90" label = "reject an incoming message">
-      <doc>
-        This method allows a client to reject a message. It can be used to interrupt and
-        cancel large incoming messages, or return untreatable messages to their original
-        queue.
-      </doc>
-
-      <rule name = "01">
-        <doc>
-          The server SHOULD be capable of accepting and process the Reject method while
-          sending message content with a Deliver or Get-Ok method. I.e. the server should
-          read and process incoming methods while sending output frames. To cancel a
-          partially-send content, the server sends a content body frame of size 1 (i.e.
-          with no data except the frame-end octet).
-        </doc>
-      </rule>
-
-      <rule name = "02">
-        <doc>
-          The server SHOULD interpret this method as meaning that the client is unable to
-          process the message at this time.
-        </doc>
-        <doc type = "scenario">
-          TODO.
-        </doc>
-      </rule>
-
-      <rule name = "03">
-        <doc>
-          The client MUST NOT use this method as a means of selecting messages to process.
-        </doc>
-        <doc type = "scenario">
-          TODO.
-        </doc>
-      </rule>
-
-      <chassis name = "server" implement = "MUST" />
-
-      <field name = "delivery-tag" domain = "delivery-tag" />
-
-      <field name = "requeue" domain = "bit" label = "requeue the message">
-        <doc>
-          If requeue is true, the server will attempt to requeue the message.  If requeue
-          is false or the requeue  attempt fails the messages are discarded or dead-lettered.
-        </doc>
 
-        <rule name = "01">
-          <doc>
-            The server MUST NOT deliver the message to the same client within the
-            context of the current channel. The recommended strategy is to attempt to
-            deliver the message to an alternative consumer, and if that is not possible,
-            to move the message to a dead-letter queue. The server MAY use more
-            sophisticated tracking to hold the message on the queue and redeliver it to
-            the same client at a later stage.
-          </doc>
-          <doc type = "scenario">
-            TODO.
-          </doc>
-        </rule>
-      </field>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "recover-async" index = "100" label = "redeliver unacknowledged messages"
-        deprecated = "1">
-      <doc>
-        This method asks the server to redeliver all unacknowledged messages on a
-        specified channel. Zero or more messages may be redelivered.  This method
-        is deprecated in favour of the synchronous Recover/Recover-Ok.
-      </doc>
-      <rule name = "01">
-        <doc>
-          The server MUST set the redelivered flag on all messages that are resent.
-        </doc>
-        <doc type = "scenario">
-          TODO.
-        </doc>
-      </rule>
-      <chassis name = "server" implement = "MAY" />
-      <field name = "requeue" domain = "bit" label = "requeue the message">
-        <doc>
-          If this field is zero, the message will be redelivered to the original
-          recipient. If this bit is 1, the server will attempt to requeue the message,
-          potentially then delivering it to an alternative subscriber.
-        </doc>
-      </field>
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "recover" index = "110" label = "redeliver unacknowledged messages">
-      <doc>
-        This method asks the server to redeliver all unacknowledged messages on a
-        specified channel. Zero or more messages may be redelivered.  This method
-        replaces the asynchronous Recover.
-      </doc>
-      <rule name = "01">
-        <doc>
-          The server MUST set the redelivered flag on all messages that are resent.
-        </doc>
-        <doc type = "scenario">
-          TODO.
-        </doc>
-      </rule>
-      <chassis name = "server" implement = "MUST" />
-      <field name = "requeue" domain = "bit" label = "requeue the message">
-        <doc>
-          If this field is zero, the message will be redelivered to the original
-          recipient. If this bit is 1, the server will attempt to requeue the message,
-          potentially then delivering it to an alternative subscriber.
-        </doc>
-      </field>
-    </method>
-
-    <method name = "recover-ok" synchronous = "1" index = "111" label = "confirm recovery">
-      <doc>
-        This method acknowledges a Basic.Recover method.
-      </doc>
-      <chassis name = "client" implement = "MUST" />
-    </method>
-  </class>
-
-  <!-- ==  TX  =============================================================== -->
-
-  <class name = "tx" handler = "channel" index = "90" label = "work with transactions">
-    <doc>
-      The Tx class allows publish and ack operations to be batched into atomic
-      units of work.  The intention is that all publish and ack requests issued
-      within a transaction will complete successfully or none of them will.
-      Servers SHOULD implement atomic transactions at least where all publish
-      or ack requests affect a single queue.  Transactions that cover multiple
-      queues may be non-atomic, given that queues can be created and destroyed
-      asynchronously, and such events do not form part of any transaction.
-      Further, the behaviour of transactions with respect to the immediate and
-      mandatory flags on Basic.Publish methods is not defined.
-    </doc>
-
-    <rule name = "not multiple queues">
-      <doc>
-      Applications MUST NOT rely on the atomicity of transactions that
-      affect more than one queue.
-      </doc>
-    </rule>
-    <rule name = "not immediate">
-      <doc>
-      Applications MUST NOT rely on the behaviour of transactions that
-      include messages published with the immediate option.
-      </doc>
-    </rule>
-    <rule name = "not mandatory">
-      <doc>
-      Applications MUST NOT rely on the behaviour of transactions that
-      include messages published with the mandatory option.
-      </doc>
-    </rule>
-
-    <doc type = "grammar">
-      tx                  = C:SELECT S:SELECT-OK
-                          / C:COMMIT S:COMMIT-OK
-                          / C:ROLLBACK S:ROLLBACK-OK
-    </doc>
-
-    <chassis name = "server" implement = "SHOULD" />
-    <chassis name = "client" implement = "MAY" />
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "select" synchronous = "1" index = "10" label = "select standard transaction mode">
-      <doc>
-        This method sets the channel to use standard transactions. The client must use this
-        method at least once on a channel before using the Commit or Rollback methods.
-      </doc>
-      <chassis name = "server" implement = "MUST" />
-      <response name = "select-ok" />
-    </method>
-
-    <method name = "select-ok" synchronous = "1" index = "11" label = "confirm transaction mode">
-      <doc>
-        This method confirms to the client that the channel was successfully set to use
-        standard transactions.
-      </doc>
-      <chassis name = "client" implement = "MUST" />
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "commit" synchronous = "1" index = "20" label = "commit the current transaction">
-      <doc>
-        This method commits all message publications and acknowledgments performed in
-        the current transaction.  A new transaction starts immediately after a commit.
-      </doc>
-      <chassis name = "server" implement = "MUST" />
-      <response name = "commit-ok" />
-
-      <rule name = "transacted" on-failure = "precondition-failed">
-        <doc>
-          The client MUST NOT use the Commit method on non-transacted channels.
-        </doc>
-        <doc type = "scenario">
-          The client opens a channel and then uses Tx.Commit.
-        </doc>
-      </rule>
-    </method>
-
-    <method name = "commit-ok" synchronous = "1" index = "21" label = "confirm a successful commit">
-      <doc>
-        This method confirms to the client that the commit succeeded. Note that if a commit
-        fails, the server raises a channel exception.
-      </doc>
-      <chassis name = "client" implement = "MUST" />
-    </method>
-
-    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-    <method name = "rollback" synchronous = "1" index = "30"
-      label = "abandon the current transaction">
-      <doc>
-        This method abandons all message publications and acknowledgments performed in
-        the current transaction. A new transaction starts immediately after a rollback.
-        Note that unacked messages will not be automatically redelivered by rollback;
-        if that is required an explicit recover call should be issued.
-      </doc>
-      <chassis name = "server" implement = "MUST" />
-      <response name = "rollback-ok" />
-
-      <rule name = "transacted" on-failure = "precondition-failed">
-        <doc>
-          The client MUST NOT use the Rollback method on non-transacted channels.
-        </doc>
-        <doc type = "scenario">
-          The client opens a channel and then uses Tx.Rollback.
-        </doc>
-      </rule>
-    </method>
-
-    <method name = "rollback-ok" synchronous = "1" index = "31" label = "confirm successful rollback">
-      <doc>
-        This method confirms to the client that the rollback succeeded. Note that if an
-        rollback fails, the server raises a channel exception.
-      </doc>
-      <chassis name = "client" implement = "MUST" />
-    </method>
-  </class>
+        <doc type="grammar">
+            tx = C:SELECT S:SELECT-OK
+            / C:COMMIT S:COMMIT-OK
+            / C:ROLLBACK S:ROLLBACK-OK
+        </doc>
+
+        <chassis name="server" implement="SHOULD"/>
+        <chassis name="client" implement="MAY"/>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="select" synchronous="1" index="10"
+                label="select standard transaction mode">
+            <doc>
+                This method sets the channel to use standard transactions. The
+                client must use this
+                method at least once on a channel before using the Commit or
+                Rollback methods.
+            </doc>
+            <chassis name="server" implement="MUST"/>
+            <response name="select-ok"/>
+        </method>
+
+        <method name="select-ok" synchronous="1" index="11"
+                label="confirm transaction mode">
+            <doc>
+                This method confirms to the client that the channel was
+                successfully set to use
+                standard transactions.
+            </doc>
+            <chassis name="client" implement="MUST"/>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="commit" synchronous="1" index="20"
+                label="commit the current transaction">
+            <doc>
+                This method commits all message publications and acknowledgments
+                performed in
+                the current transaction. A new transaction starts immediately
+                after a commit.
+            </doc>
+            <chassis name="server" implement="MUST"/>
+            <response name="commit-ok"/>
+
+            <rule name="transacted" on-failure="precondition-failed">
+                <doc>
+                    The client MUST NOT use the Commit method on non-transacted
+                    channels.
+                </doc>
+                <doc type="scenario">
+                    The client opens a channel and then uses Tx.Commit.
+                </doc>
+            </rule>
+        </method>
+
+        <method name="commit-ok" synchronous="1" index="21"
+                label="confirm a successful commit">
+            <doc>
+                This method confirms to the client that the commit succeeded.
+                Note that if a commit
+                fails, the server raises a channel exception.
+            </doc>
+            <chassis name="client" implement="MUST"/>
+        </method>
+
+        <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+        <method name="rollback" synchronous="1" index="30"
+                label="abandon the current transaction">
+            <doc>
+                This method abandons all message publications and
+                acknowledgments performed in
+                the current transaction. A new transaction starts immediately
+                after a rollback.
+                Note that unacked messages will not be automatically redelivered
+                by rollback;
+                if that is required an explicit recover call should be issued.
+            </doc>
+            <chassis name="server" implement="MUST"/>
+            <response name="rollback-ok"/>
+
+            <rule name="transacted" on-failure="precondition-failed">
+                <doc>
+                    The client MUST NOT use the Rollback method on
+                    non-transacted channels.
+                </doc>
+                <doc type="scenario">
+                    The client opens a channel and then uses Tx.Rollback.
+                </doc>
+            </rule>
+        </method>
+
+        <method name="rollback-ok" synchronous="1" index="31"
+                label="confirm successful rollback">
+            <doc>
+                This method confirms to the client that the rollback succeeded.
+                Note that if an
+                rollback fails, the server raises a channel exception.
+            </doc>
+            <chassis name="client" implement="MUST"/>
+        </method>
+    </class>
 
 </amqp>
diff --git a/setup.cfg b/setup.cfg
index be77f9a4977a5d19c733738ad8992edbff218e8d..67cef602512486973824bb66b08eb6f628dacb9b 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,7 +1,7 @@
 [metadata]
 description-file = README.md
 name = CoolAMQP
-version = 0.92
+version = 0.93a1
 license = MIT License
 classifiers = 
     Programming Language :: Python
diff --git a/tests/run.py b/tests/run.py
index e574f3cff37721b4c3b6f73748aaf7b738bc28e3..8a9f1a004294088672771881725738d84092b5a0 100644
--- a/tests/run.py
+++ b/tests/run.py
@@ -1,23 +1,22 @@
 # coding=UTF-8
 from __future__ import absolute_import, division, print_function
 import time, logging, threading
-from coolamqp.objects import Message, MessageProperties, NodeDefinition, Queue, Exchange
+from coolamqp.objects import Message, MessageProperties, NodeDefinition, Queue, \
+    Exchange
 from coolamqp.exceptions import AMQPError
 from coolamqp.clustering import Cluster
 
 import time
 
-
 NODE = NodeDefinition('127.0.0.1', 'guest', 'guest', heartbeat=20)
 logging.basicConfig(level=logging.DEBUG)
 
 amqp = Cluster([NODE])
 amqp.start(wait=True)
 
-
 q = Queue(u'lolwut', auto_delete=True, exclusive=True)
-c,f=amqp.consume(q, no_ack=True, body_receive_mode=1)
+c, f = amqp.consume(q, no_ack=True, body_receive_mode=1)
 
-#time.sleep(30)
+# time.sleep(30)
 
-#amqp.shutdown(True)
+# amqp.shutdown(True)
diff --git a/tests/test_clustering/__init__.py b/tests/test_clustering/__init__.py
index 1c762b12fd99adc2f7d4e5137c5b872079457510..db0a0a6db68923bea6cabb6a4005abf5fdb90ffb 100644
--- a/tests/test_clustering/__init__.py
+++ b/tests/test_clustering/__init__.py
@@ -4,5 +4,3 @@ import six
 import logging
 
 logger = logging.getLogger(__name__)
-
-
diff --git a/tests/test_clustering/test_a.py b/tests/test_clustering/test_a.py
index 48c5e0dcb932f95b3317119ba028387da5e2806a..2f4fd62a40f247628f70fff5fc21bd6ce83fd029 100644
--- a/tests/test_clustering/test_a.py
+++ b/tests/test_clustering/test_a.py
@@ -7,7 +7,8 @@ import six
 import os
 import unittest
 import time, logging, threading, monotonic
-from coolamqp.objects import Message, MessageProperties, NodeDefinition, Queue, ReceivedMessage, Exchange
+from coolamqp.objects import Message, MessageProperties, NodeDefinition, Queue, \
+    ReceivedMessage, Exchange
 from coolamqp.clustering import Cluster, MessageReceived, NothingMuch
 
 import time
@@ -17,7 +18,6 @@ logging.basicConfig(level=logging.DEBUG)
 
 
 class TestA(unittest.TestCase):
-
     def setUp(self):
         self.c = Cluster([NODE])
         self.c.start()
@@ -38,14 +38,15 @@ class TestA(unittest.TestCase):
         con, fut = self.c.consume(Queue(u'hello', exclusive=True))
         fut.result()
 
-        data = six.binary_type(os.urandom(20*1024*1024+1423))
+        data = six.binary_type(os.urandom(20 * 1024 * 1024 + 1423))
 
-        self.c.publish(Message(data), routing_key=b'hello', confirm=True).result()
+        self.c.publish(Message(data), routing_key=b'hello',
+                       confirm=True).result()
 
-#        rmsg = self.c.drain(3)
-#        rmsg.ack()
+    #        rmsg = self.c.drain(3)
+    #        rmsg.ack()
 
-#        self.assertEquals(rmsg.body, data)
+    #        self.assertEquals(rmsg.body, data)
 
     def test_actually_waits(self):
         a = monotonic.monotonic()
@@ -54,7 +55,6 @@ class TestA(unittest.TestCase):
 
         self.assertTrue(monotonic.monotonic() - a >= 4)
 
-
     def test_set_qos_but_later(self):
         con, fut = self.c.consume(Queue(u'hello', exclusive=True))
 
@@ -68,23 +68,23 @@ class TestA(unittest.TestCase):
         time.sleep(1)
         self.assertEquals(con.qos, (0, 110))
 
-
     def test_anonymq(self):
-        q = Queue(exchange=Exchange(u'ooo', type=b'fanout', auto_delete=True), auto_delete=True)
+        q = Queue(exchange=Exchange(u'ooo', type=b'fanout', auto_delete=True),
+                  auto_delete=True)
 
         c, f = self.c.consume(q)
 
         f.result()
 
     def test_send_recv_zerolen(self):
-
         P = {'q': False}
 
         def ok(e):
             self.assertIsInstance(e, ReceivedMessage)
             P['q'] = True
 
-        con, fut = self.c.consume(Queue(u'hello', exclusive=True), on_message=ok, no_ack=True)
+        con, fut = self.c.consume(Queue(u'hello', exclusive=True),
+                                  on_message=ok, no_ack=True)
         fut.result()
         self.c.publish(Message(b''), routing_key=u'hello', tx=True).result()
 
@@ -93,46 +93,48 @@ class TestA(unittest.TestCase):
         self.assertTrue(P['q'])
 
     def test_message_with_propos_confirm(self):
-
         P = {'q': False}
 
         def ok(e):
             self.assertIsInstance(e, ReceivedMessage)
             self.assertEquals(e.body, b'hello')
-            #bcoz u can compare memoryviews to their providers :D
+            # bcoz u can compare memoryviews to their providers :D
             self.assertEquals(e.properties.content_type, b'text/plain')
             self.assertEquals(e.properties.content_encoding, b'utf8')
             P['q'] = True
 
-        con, fut = self.c.consume(Queue(u'hello', exclusive=True), on_message=ok, no_ack=True)
+        con, fut = self.c.consume(Queue(u'hello', exclusive=True),
+                                  on_message=ok, no_ack=True)
         fut.result()
         self.c.publish(Message(b'hello', properties={
             'content_type': b'text/plain',
             'content_encoding': b'utf8'
         }), routing_key=u'hello', confirm=True).result()
 
-        self.assertRaises(RuntimeError, lambda: self.c.publish(Message(b'hello', properties={
-            'content_type': b'text/plain',
-            'content_encoding': b'utf8'
-        }), routing_key=u'hello', confirm=True, tx=True).result())
+        self.assertRaises(RuntimeError,
+                          lambda: self.c.publish(Message(b'hello', properties={
+                              'content_type': b'text/plain',
+                              'content_encoding': b'utf8'
+                          }), routing_key=u'hello', confirm=True,
+                                                 tx=True).result())
 
         time.sleep(1)
 
         self.assertTrue(P['q'])
 
     def test_message_with_propos(self):
-
         P = {'q': False}
 
         def ok(e):
             self.assertIsInstance(e, ReceivedMessage)
             self.assertEquals(e.body, b'hello')
-            #bcoz u can compare memoryviews to their providers :D
+            # bcoz u can compare memoryviews to their providers :D
             self.assertEquals(e.properties.content_type, b'text/plain')
             self.assertEquals(e.properties.content_encoding, b'utf8')
             P['q'] = True
 
-        con, fut = self.c.consume(Queue(u'hello', exclusive=True), on_message=ok, no_ack=True)
+        con, fut = self.c.consume(Queue(u'hello', exclusive=True),
+                                  on_message=ok, no_ack=True)
         fut.result()
         self.c.publish(Message(b'hello', properties={
             'content_type': b'text/plain',
@@ -143,7 +145,6 @@ class TestA(unittest.TestCase):
 
         self.assertTrue(P['q'])
 
-
     def test_send_recv_nonzerolen(self):
         """with callback function"""
 
@@ -154,9 +155,11 @@ class TestA(unittest.TestCase):
             self.assertEquals(e.body, b'hello')
             P['q'] = True
 
-        con, fut = self.c.consume(Queue(u'hello', exclusive=True), on_message=ok, no_ack=True)
+        con, fut = self.c.consume(Queue(u'hello', exclusive=True),
+                                  on_message=ok, no_ack=True)
         fut.result()
-        self.c.publish(Message(b'hello'), routing_key=u'hello', tx=True).result()
+        self.c.publish(Message(b'hello'), routing_key=u'hello',
+                       tx=True).result()
 
         time.sleep(1)
 
@@ -208,12 +211,14 @@ class TestA(unittest.TestCase):
         self.assertEquals(b''.join(x.tobytes() for x in m.body), data)
 
     def test_consumer_cancel(self):
-        con, fut = self.c.consume(Queue(u'hello', exclusive=True, auto_delete=True))
+        con, fut = self.c.consume(
+            Queue(u'hello', exclusive=True, auto_delete=True))
         fut.result()
         con.cancel().result()
 
     def test_drain_1(self):
-        con, fut = self.c.consume(Queue(u'hello', exclusive=True, auto_delete=True))
+        con, fut = self.c.consume(
+            Queue(u'hello', exclusive=True, auto_delete=True))
         fut.result()
 
         self.c.publish(Message(b'ioi'), routing_key=u'hello')
diff --git a/tests/test_clustering/test_double.py b/tests/test_clustering/test_double.py
index ca6cbefdbf509dd612c33104ea0fdbbce9642eb8..c6ae6beaf8c9d5886fef2c2969b8a03365a86b1a 100644
--- a/tests/test_clustering/test_double.py
+++ b/tests/test_clustering/test_double.py
@@ -6,17 +6,17 @@ from __future__ import print_function, absolute_import, division
 import six
 import unittest
 import time, logging, threading
-from coolamqp.objects import Message, MessageProperties, NodeDefinition, Queue, ReceivedMessage
+from coolamqp.objects import Message, MessageProperties, NodeDefinition, Queue, \
+    ReceivedMessage
 from coolamqp.clustering import Cluster
+
 NODE = NodeDefinition('127.0.0.1', 'guest', 'guest', heartbeat=20)
 from coolamqp.exceptions import AMQPError, RESOURCE_LOCKED
 
-
 logging.basicConfig(level=logging.DEBUG)
 
 
 class TestDouble(unittest.TestCase):
-
     def setUp(self):
         self.c1 = Cluster([NODE])
         self.c1.start()
@@ -28,7 +28,8 @@ class TestDouble(unittest.TestCase):
         self.c1.shutdown()
         self.c2.shutdown()
 
-    @unittest.skip("Since RabbitMQ does not support queue deletion, you need to do this manually")
+    @unittest.skip(
+        "Since RabbitMQ does not support queue deletion, you need to do this manually")
     def test_ccn(self):
         """
         Will consumer cancel itself after Consumer Cancel Notification?
@@ -44,7 +45,7 @@ class TestDouble(unittest.TestCase):
         con1, fut1 = self.c1.consume(q1)
         fut1.result()
 
-#        self.c2.delete_queue(q1) #.result()
+        #        self.c2.delete_queue(q1) #.result()
 
         time.sleep(30)
         self.assertTrue(con1.cancelled)
@@ -57,7 +58,8 @@ class TestDouble(unittest.TestCase):
         fut.result()
 
         try:
-            con2, fut2 = self.c2.consume(q, fail_on_first_time_resource_locked=True)
+            con2, fut2 = self.c2.consume(q,
+                                         fail_on_first_time_resource_locked=True)
             fut2.result()
         except AMQPError as e:
             self.assertEquals(e.reply_code, RESOURCE_LOCKED)
diff --git a/tests/test_clustering/test_exchanges.py b/tests/test_clustering/test_exchanges.py
index 1a6e7a83f8e216fc5a163bd0168f82e4f678ccdc..65b028768191a656efcfd985a71f567ceb09fb77 100644
--- a/tests/test_clustering/test_exchanges.py
+++ b/tests/test_clustering/test_exchanges.py
@@ -3,12 +3,13 @@ from __future__ import print_function, absolute_import, division
 import six
 import unittest
 import time, logging, threading
-from coolamqp.objects import Message, MessageProperties, NodeDefinition, Queue, ReceivedMessage, Exchange
+from coolamqp.objects import Message, MessageProperties, NodeDefinition, Queue, \
+    ReceivedMessage, Exchange
 from coolamqp.clustering import Cluster, MessageReceived, NothingMuch
 from coolamqp.exceptions import AMQPError
 import time
 
-#todo handle bad auth
+# todo handle bad auth
 NODE = NodeDefinition('127.0.0.1', 'guest', 'guest', heartbeat=20)
 logging.basicConfig(level=logging.DEBUG)
 
@@ -28,8 +29,10 @@ class TestExchanges(unittest.TestCase):
     def test_fanout(self):
         x = Exchange(u'jola', type='direct', auto_delete=True)
 
-        c1, f1 = self.c.consume(Queue('one', exchange=x, exclusive=True), no_ack=True)
-        c2, f2 = self.c.consume(Queue('two', exchange=x, exclusive=True), no_ack=True)
+        c1, f1 = self.c.consume(Queue('one', exchange=x, exclusive=True),
+                                no_ack=True)
+        c2, f2 = self.c.consume(Queue('two', exchange=x, exclusive=True),
+                                no_ack=True)
 
         f1.result()
         f2.result()
@@ -39,9 +42,3 @@ class TestExchanges(unittest.TestCase):
         self.assertIsInstance(self.c.drain(2), MessageReceived)
         self.assertIsInstance(self.c.drain(2), MessageReceived)
         self.assertIsInstance(self.c.drain(2), NothingMuch)
-
-
-
-
-
-        
diff --git a/tests/test_clustering/test_things.py b/tests/test_clustering/test_things.py
index e158e0406194101802f96504a6ce9ef93612f33f..061bf436a2a81027d684e321f97dfe6e9a34d15a 100644
--- a/tests/test_clustering/test_things.py
+++ b/tests/test_clustering/test_things.py
@@ -4,19 +4,22 @@ from __future__ import print_function, absolute_import, division
 import six
 import unittest
 import time, logging, threading, monotonic, warnings
-from coolamqp.objects import Message, MessageProperties, NodeDefinition, Queue, ReceivedMessage, Exchange
+from coolamqp.objects import Message, MessageProperties, NodeDefinition, Queue, \
+    ReceivedMessage, Exchange
 from coolamqp.clustering import Cluster, MessageReceived, NothingMuch
 
 import time
+
 NODE = NodeDefinition('127.0.0.1', 'guest', 'guest', heartbeat=20)
 logging.basicConfig(level=logging.DEBUG)
 
 
 class TestConnecting(unittest.TestCase):
-
     def test_on_fail(self):
         q = {'failed': False}
-        c = Cluster(NodeDefinition('127.0.0.1', 'xguest', 'xguest', heartbeat=20), on_fail=lambda: q.update(failed=True))
+        c = Cluster(
+            NodeDefinition('127.0.0.1', 'xguest', 'xguest', heartbeat=20),
+            on_fail=lambda: q.update(failed=True))
         c.start()
         time.sleep(5)
         c.shutdown()
@@ -54,7 +57,7 @@ class TestConnecting(unittest.TestCase):
                               user='guest',
                               password='guest')
 
-        self.assertEquals(node.virtual_host, '/')   # default
+        self.assertEquals(node.virtual_host, '/')  # default
 
     def test_amqpconnstring_port(self):
         node = NodeDefinition('amqp://lol:lol@lol:4123/vhost')
diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py
index 516ff965e963fb5e4feaf50475f7b0d2077122ea..33c11786d5aec6ad818b54e9dd2485671e723383 100644
--- a/tests/test_exceptions.py
+++ b/tests/test_exceptions.py
@@ -13,4 +13,3 @@ class TestExcs(unittest.TestCase):
         self.assertTrue(u'100' in str(e))
         self.assertTrue(u'wtf' in str(e))
         self.assertTrue(repr(e).startswith(u'AMQPError'))
-
diff --git a/tests/test_framing/test_compilation.py b/tests/test_framing/test_compilation.py
index 51840518a40453d0bbbc9b88a13e6fec9d9f4e09..90632c48724f4628d4061994af8f5062d57180c6 100644
--- a/tests/test_framing/test_compilation.py
+++ b/tests/test_framing/test_compilation.py
@@ -6,6 +6,7 @@ import unittest
 
 class TestCompilation(unittest.TestCase):
     def test_comp(self):
-        from coolamqp.framing.compilation.compile_definitions import compile_definitions
-        compile_definitions(xml_file='resources/amqp0-9-1.extended.xml', out_file='/tmp/definitions.py')
-        
+        from coolamqp.framing.compilation.compile_definitions import \
+            compile_definitions
+        compile_definitions(xml_file='resources/amqp0-9-1.extended.xml',
+                            out_file='/tmp/definitions.py')
diff --git a/tests/test_objects.py b/tests/test_objects.py
index e3a109d0ef84031ec3b61bed2fbebc59d73a8f50..f7e5569d0aee2945218cc2c03f6109420aabc914 100644
--- a/tests/test_objects.py
+++ b/tests/test_objects.py
@@ -10,7 +10,6 @@ from coolamqp.objects import NodeDefinition, MessageProperties
 
 class TestObjects(unittest.TestCase):
     def test_node_definition_from_amqp(self):
-
         n1 = NodeDefinition(u'amqp://ala:ma@kota/psa')
 
         self.assertEquals(n1.user, u'ala')
diff --git a/tests/utils.py b/tests/utils.py
index 422c366707b99a82d48c9ffda46155bbf50a5938..17481f70a2f76883c6ca007f735b1f8d409af23f 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -6,7 +6,8 @@ import socket
 import collections
 import monotonic
 
-from coolamqp import Cluster, ClusterNode, ConnectionUp, ConnectionDown, ConnectionUp, ConsumerCancelled
+from coolamqp import Cluster, ClusterNode, ConnectionUp, ConnectionDown, \
+    ConnectionUp, ConsumerCancelled
 from coolamqp.backends.base import AMQPBackend, ConnectionFailedError
 
 
@@ -21,7 +22,7 @@ class CoolAMQPTestCase(unittest.TestCase):
     Base class for all CoolAMQP tests. Creates na AMQP connection, provides methods
     for easy interfacing, and other utils.
     """
-    INIT_AMQP = True      # override on child classes
+    INIT_AMQP = True  # override on child classes
 
     def setUp(self):
         if self.INIT_AMQP:
@@ -50,7 +51,7 @@ class CoolAMQPTestCase(unittest.TestCase):
             if type(q) in types:
                 types.remove(type(q))
         if len(types) > 0:
-            self.fail('Not found %s' % (''.join(map(str, types)), ))
+            self.fail('Not found %s' % (''.join(map(str, types)),))
 
     def drainTo(self, type_, timeout, forbidden=[ConsumerCancelled]):
         """
@@ -72,7 +73,7 @@ class CoolAMQPTestCase(unittest.TestCase):
             q = self.amqp.drain(1)
             if isinstance(q, type_):
                 return q
-        self.fail('Did not find %s' % (type_, ))
+        self.fail('Did not find %s' % (type_,))
 
     def takes_less_than(self, max_time):
         """
@@ -87,14 +88,14 @@ class CoolAMQPTestCase(unittest.TestCase):
         return TakesLessThanCM(self, max_time)
 
     # ======failures
-    def single_fail_amqp(self):    # insert single failure
+    def single_fail_amqp(self):  # insert single failure
         sock = self.amqp.thread.backend.channel.connection.transport.sock
         self.amqp.thread.backend.channel.connection.transport.sock = FailbowlSocket()
         self.amqp.thread.backend.channel.connection = None  # 'connection already closed' or sth like that
 
         sock.close()
 
-    def fail_amqp(self):    # BROKER DEAD: SWITCH ON
+    def fail_amqp(self):  # BROKER DEAD: SWITCH ON
 
         self.old_backend = self.amqp.backend
         self.amqp.backend = FailbowlBackend
@@ -104,15 +105,15 @@ class CoolAMQPTestCase(unittest.TestCase):
         del self.old_backend
 
     def restart_rmq(self):  # simulate a broker restart
-       self.fail_amqp()
-       self.single_fail_amqp()
-       time.sleep(3)
-       self.unfail_amqp()
+        self.fail_amqp()
+        self.single_fail_amqp()
+        time.sleep(3)
+        self.unfail_amqp()
 
-       self.drainTo([ConnectionDown, ConnectionUp], [5, 20])
+        self.drainTo([ConnectionDown, ConnectionUp], [5, 20])
 
     def new_amqp_connection(self, consume_connectionup=True):
-       return AMQPConnectionCM(self, consume_connectionup=consume_connectionup)
+        return AMQPConnectionCM(self, consume_connectionup=consume_connectionup)
 
 
 class TakesLessThanCM(object):
@@ -122,7 +123,7 @@ class TakesLessThanCM(object):
 
     def __enter__(self, testCase, max_time):
         self.started_at = time.time()
-        return lambda: time.time() - self.started_at > self.max_time    # is_late
+        return lambda: time.time() - self.started_at > self.max_time  # is_late
 
     def __exit__(self, tp, v, tb):
         self.test.assertLess(time.time() - self.started_at, self.max_time)
@@ -138,6 +139,7 @@ class AMQPConnectionCM(object):
             amqp2.consume(...)
 
     """
+
     def __init__(self, testCase, consume_connectionup):
         self.test = testCase
         self.consume_connectionup = consume_connectionup
@@ -162,7 +164,7 @@ class FailbowlBackend(AMQPBackend):
 class FailbowlSocket(object):
     def __getattr__(self, item):
         def failbowl(*args, **kwargs):
-            time.sleep(1)   # hang and fail
+            time.sleep(1)  # hang and fail
             raise socket.error
 
         def sleeper(*args, **kwargs):
@@ -172,4 +174,3 @@ class FailbowlSocket(object):
             return sleeper
         else:
             return failbowl
-