<?xml version="1.0"?>
<!--
  OASIS AMQP Version 1.0
  Part 3 : Messaging

  Committee Specification Draft 02 /
  Public Review Draft 02
  29 May 2012
    
  Specification URIs:
    
    This version:
        http://docs.oasis-open.org/amqp/core/v1.0/csprd02/amqp-core-messaging-v1.0-csprd02.xml (Authoritative)
        http://docs.oasis-open.org/amqp/core/v1.0/csprd02/amqp-core-messaging-v1.0-csprd02.html
        http://docs.oasis-open.org/amqp/core/v1.0/csprd02/amqp-core-complete-v1.0-csprd02.pdf
        
    Previous version:
        http://docs.oasis-open.org/amqp/core/v1.0/csprd01/amqp-core-messaging-v1.0-csprd01.xml (Authoritative)
        http://docs.oasis-open.org/amqp/core/v1.0/csprd01/amqp-core-messaging-v1.0-csprd01.html
        http://docs.oasis-open.org/amqp/core/v1.0/csprd01/amqp-core-complete-v1.0-csprd01.pdf

    Latest version:
        http://docs.oasis-open.org/amqp/core/v1.0/amqp-core-messaging-v1.0.xml (Authoritative)
        http://docs.oasis-open.org/amqp/core/v1.0/amqp-core-messaging-v1.0.html
        http://docs.oasis-open.org/amqp/core/v1.0/amqp-core-complete-v1.0.pdf
        
  Technical Committee:
        OASIS AMQP Technical Committee (http://www.oasis-open.org/committees/amqp)

  Chairs:
        Ram Jeyaraman (Ram.Jeyaraman@microsoft.com), Microsoft
        Angus Telfer (angus.telfer@inetco.com), INETCO Systems

  Editors:
        Robert Godfrey (robert.godfrey@jpmorgan.com), JPMorgan Chase & Co.
        David Ingham (David.Ingham@microsoft.com), Microsoft
        Rafael Schloming (rafaels@redhat.com), Red Hat

  Additional artifacts:
        This specification consists of the following documents:
        Part 0: Overview - Overview of the AMQP specification (amqp-core-overview-v1.0-csprd02.xml)
        Part 1: Types - AMQP type system and encoding (amqp-core-types-v1.0-csprd02.xml)
        Part 2: Transport - AMQP transport layer (amqp-core-transport-v1.0-csprd02.xml)
        Part 3: Messaging - AMQP Messaging Layer (this document)
        Part 4: Transactions - AMQP Transactions Layer (amqp-core-transactions-v1.0-csprd02.xml)
        Part 5: Security - AMQP Security Layers (amqp-core-security-v1.0-csprd02.xml)
        XML Document Type Definition (DTD) (amqp.dtd)

  Related work:
        This specification replaces or supersedes:
            http://www.amqp.org/specification/1.0/amqp-org-download
  
  Abstract:

    The Advanced Message Queuing Protocol (AMQP) is an open internet protocol for business
    messaging. It defines a binary wire-level protocol that allows for the reliable exchange
    of business messages between two parties.
    AMQP has a layered architecture and the specification is organized as a set of parts that
    reflects that architecture. Part 1 defines the AMQP type system and encoding. Part 2 defines
    the AMQP transport layer, an efficient, binary, peer-to-peer protocol for transporting messages
    between two processes over a network. Part 3 defines the AMQP message format, with a
    concrete encoding. Part 4 defines how interactions can be grouped within atomic
    transactions. Part 5 defines the AMQP security layers.
    
  Status:
    
    This document was last revised or approved by the OASIS AMQP Technical Committee on the above date. The level of
    approval is also listed above. Check the “Latest version” location noted above for possible
    later revisions of this document.

    Technical Committee members should send comments on this specification to the Technical
    Committee’s email list. Others should send comments to the Technical Committee by using the
    "Send A Comment" button on the Technical Committee's web page at
    http://www.oasis-open.org/committees/amqp/.

    For information on whether any patents have been disclosed that may be essential to implementing
    this specification, and any offers of patent licensing terms, please refer to the Intellectual
    Property Rights section of the Technical Committee web page
    (http://www.oasis-open.org/committees/amqp/ipr.php).
    
  Citation format:
    
    When referencing this specification the following citation format should be used:
    
    [amqp-core-messaging-v1.0]
    OASIS AMQP Version 1.0 Part 3 : Messaging. 29 May 2012. Committee Specification Draft 02 / Public Review Draft 02.
    http://docs.oasis-open.org/amqp/core/v1.0/csprd02/amqp-core-messaging-v1.0-csprd02.xml
    
  Notices:

  Copyright  OASIS Open 2012. All Rights Reserved.


  All capitalized terms in the following text have the meanings assigned to them in the OASIS
  Intellectual Property Rights Policy (the "OASIS IPR Policy"). The full Policy may be found at the
  OASIS website.


  This document and translations of it may be copied and furnished to others, and derivative works
  that comment on or otherwise explain it or assist in its implementation may be prepared, copied,
  published, and distributed, in whole or in part, without restriction of any kind, provided that
  the above copyright notice and this section are included on all such copies and derivative works.
  However, this document itself may not be modified in any way, including by removing the copyright
  notice or references to OASIS, except as needed for the purpose of developing any document or
  deliverable produced by an OASIS Technical Committee (in which case the rules applicable to
  copyrights, as set forth in the OASIS IPR Policy, must be followed) or as required to translate
  it into languages other than English.


  The limited permissions granted above are perpetual and will not be revoked by OASIS or its
  successors or assigns.


  This document and the information contained herein is provided on an "AS IS" basis and OASIS
  DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE
  USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP RIGHTS OR ANY IMPLIED WARRANTIES OF
  MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.


  OASIS requests that any OASIS Party or any other party that believes it has patent claims that
  would necessarily be infringed by implementations of this OASIS Committee Specification or OASIS
  Standard, to notify OASIS TC Administrator and provide an indication of its willingness to grant
  patent licenses to such patent claims in a manner consistent with the IPR Mode of the OASIS
  Technical Committee that produced this specification.


  OASIS invites any party to contact the OASIS TC Administrator if it is aware of a claim of
  ownership of any patent claims that would necessarily be infringed by implementations of this
  specification by a patent holder that is not willing to provide a license to such patent claims in
  a manner consistent with the IPR Mode of the OASIS Technical Committee that produced this
  specification. OASIS may include such claims on its website, but disclaims any obligation to do
  so.


  OASIS takes no position regarding the validity or scope of any intellectual property or other
  rights that might be claimed to pertain to the implementation or use of the technology described
  in this document or the extent to which any license under such rights might or might not be
  available; neither does it represent that it has made any effort to identify any such rights.
  Information on OASIS' procedures with respect to rights in any document or deliverable produced
  by an OASIS Technical Committee can be found on the OASIS website. Copies of claims of rights
  made available for publication and any assurances of licenses to be made available, or the result
  of an attempt made to obtain a general license or permission for the use of such proprietary
  rights by implementers or users of this OASIS Committee Specification or OASIS Standard, can be
  obtained from the OASIS TC Administrator. OASIS makes no representation that any information or
  list of intellectual property rights will at any time be complete, or that any claims in such list
  are, in fact, Essential Claims.


  The name "OASIS" is a trademark of OASIS, the owner and developer of this specification, and
  should be used only to refer to the organization and its official outputs. OASIS welcomes
  reference to, and implementation and use of, specifications, while reserving the right to enforce
  its marks against misleading uses. Please see http://www.oasis-open.org/who/trademark.php for above guidance.

     
-->
<amqp name="messaging" label="AMQP Messaging Layer">

  <section name="introduction" label="introduction to the Messaging layer">
    <doc>
      <p>
        The messaging layer builds on top of the concepts described in <xref type="part" name="types"/> and <xref type="part" name="transport"/>. The <xref type="part" name="transport">transport layer</xref> defines a number of extension points suitable for
        use in a variety of different messaging applications. The messaging layer specifies a
        standardized use of these to provide interoperable messaging capabilities. This standard
        covers:
      </p>

      <ul>
        <li>
          <p>message format</p>

          <ul>
            <li>
              <p>properties for the bare message</p>
            </li>

            <li>
              <p>formats for structured and unstructured sections in the bare message</p>
            </li>

            <li>
              <p>headers and footers for the annotated message</p>
            </li>
          </ul>
        </li>

        <li>
          <p>delivery states for messages traveling between nodes</p>
        </li>

        <li>
          <p>states for messages stored at a distribution node</p>
        </li>

        <li>
          <p>sources and targets</p>

          <ul>
            <li>
              <p>default disposition of transfers</p>
            </li>

            <li>
              <p>supported outcomes</p>
            </li>

            <li>
              <p>filtering of messages from a node</p>
            </li>

            <li>
              <p>distribution-mode for access to messages stored at a distribution node</p>
            </li>

            <li>
              <p>on-demand node creation</p>
            </li>
          </ul>
        </li>
      </ul>
    </doc>
  </section>

  <section name="message-format" title="Message Format" label="Message format definitions">

    <doc>
      <p>
        The term message is used with various connotations in the messaging world. The sender might
        like to think of the message as an immutable payload handed off to the messaging
        infrastructure for delivery. The receiver often thinks of the message as not only that
        immutable payload from the sender, but also various annotations supplied by the messaging
        infrastructure along the way. To avoid confusion we formally define the term <i>bare
        message</i> to mean the message as supplied by the sender and the term <i>annotated
        message</i> to mean the message as seen at the receiver.
      </p>

      <p>
        An <i>annotated message</i> consists of the bare message plus sections for annotation at the
        head and tail of the bare message. There are two classes of annotations: annotations that
        travel with the message indefinitely, and annotations that are consumed by the next node.
      </p>

      <p>
        The <i>bare message</i> consists of three sections: standard properties,
        application-properties, and application-data (the body).
      </p>

      <picture>
                                                      Bare Message
                                                            |
                                      .---------------------+--------------------.
                                      |                                          |
 +--------+-------------+-------------+------------+--------------+--------------+--------+
 | header | delivery-   | message-    | properties | application- | application- | footer |
 |        | annotations | annotations |            | properties   | data         |        |
 +--------+-------------+-------------+------------+--------------+--------------+--------+
 |                                                                                        |
 '-------------------------------------------+--------------------------------------------'
                                             |
                                      Annotated Message

      </picture>

      <p>
        The bare message is immutable within the AMQP network. That is, none of the sections can be
        changed by any node acting as an AMQP intermediary. If a section of the bare message is
        omitted, one MUST NOT be inserted by an intermediary. The exact encoding of sections of the
        bare message MUST NOT be modified. This preserves message hashes, HMACs and signatures based
        on the binary encoding of the bare message.
      </p>

      <p>
        The exact structure of a message, together with its encoding, is defined by the message
        format. This document defines the structure and semantics of message format
        <xref name="MESSAGE-FORMAT"/>. Altogether a message consists of the following sections:
      </p>

      <ul>
        <li>
          <p>
            Zero or one <xref name="header">header sections</xref>.
          </p>
        </li>
        <li>
          <p>
            Zero or one <xref name="delivery-annotations">delivery-annotation
            sections</xref>.
          </p>
        </li>
        <li>
          <p>
            Zero or one <xref name="message-annotations">message-annotation sections</xref>.
          </p>
        </li>
        <li>
          <p>
            Zero or one <xref name="properties">properties sections</xref>.
          </p>
        </li>
        <li>
          <p>
            Zero or one <xref name="application-properties">application-properties
            sections</xref>.
          </p>
        </li>
        <li>
          <p>
            The body consists of one of the following three choices:
            one or more <xref name="data"/> sections, one or more
             <xref name="amqp-sequence"/> sections, or a single <xref name="amqp-value"/> section.
          </p>
        </li>
        <li>
          <p>
            Zero or one <xref name="footer">footer sections</xref>.
          </p>
        </li>
      </ul>
    </doc>

    <type class="composite" name="header" source="list" provides="section" label="transport headers for a message">
      <doc>
        <p>
          The header section carries standard delivery details about the transfer of a message
          through the AMQP network. If the header section is omitted the receiver MUST assume the
          appropriate default values (or the meaning implied by no value being set) for the fields
          within the <xref name="header"/> unless other target or node specific defaults have
          otherwise been set.
        </p>
      </doc>

      <descriptor name="amqp:header:list" code="0x00000000:0x00000070"/>

      <field name="durable" type="boolean" label="specify durability requirements" default="false">
        <doc>
          <p>
            Durable messages MUST NOT be lost even if an intermediary is unexpectedly terminated and
            restarted. A target which is not capable of fulfilling this guarantee MUST NOT accept
            messages where the durable header is set to true: if the source allows the <xref name="rejected"/> outcome then the message SHOULD be rejected with the <xref type="type" name="amqp-error" choice="precondition-failed"/> error, otherwise the link MUST be
            detached by the receiver with the same error.
          </p>
        </doc>
      </field>

      <field name="priority" type="ubyte" label="relative message priority" default="4">
        <doc>
          <p>
            This field contains the relative message priority. Higher numbers indicate higher
            priority messages. Messages with higher priorities MAY be delivered before those with
            lower priorities.
          </p>

          <p>
            An AMQP intermediary implementing distinct priority levels MUST do so in the following
            manner:
          </p>

          <ul>
            <li>
              <p>
                If n distinct priorities are implemented and n is less than 10 -- priorities 0 to
                (5 - ceiling(n/2)) MUST be treated equivalently and MUST be the lowest effective
                priority. The priorities (4 + floor(n/2)) and above MUST be treated equivalently
                and MUST be the highest effective priority. The priorities (5 - ceiling(n/2)) to (4
                + floor(n/2)) inclusive MUST be treated as distinct priorities.
              </p>
            </li>

            <li>
              <p>
                If n distinct priorities are implemented and n is 10 or greater -- priorities 0 to
                (n - 1) MUST be distinct, and priorities n and above MUST be equivalent to priority
                (n - 1).
              </p>
            </li>
          </ul>

          <p>
            Thus, for example, if 2 distinct priorities are implemented, then levels 0 to 4 are
            equivalent, and levels 5 to 9 are equivalent and levels 4 and 5 are distinct. If 3
            distinct priorities are implements the 0 to 3 are equivalent, 5 to 9 are equivalent and
            3, 4 and 5 are distinct.
          </p>

          <p>
            This scheme ensures that if two priorities are distinct for a server which implements m
            separate priority levels they are also distinct for a server which implements n
            different priority levels where n &gt; m.
          </p>
        </doc>
      </field>

      <field name="ttl" type="milliseconds" label="time to live in ms">
        <doc>
          <p>
            Duration in milliseconds for which the message is to be considered "live". If this is
            set then a message expiration time will be computed based on the time of arrival at an
            intermediary. Messages that live longer than their expiration time will be discarded
            (or dead lettered). When a message is transmitted by an intermediary that was received
            with a ttl, the transmitted message's header SHOULD contain a ttl that is computed as
            the difference between the current time and the formerly computed message expiration
            time, i.e., the reduced ttl, so that messages will eventually die if they end up in a
            delivery loop.
          </p>
        </doc>
      </field>

      <field name="first-acquirer" type="boolean" label="" default="false">
        <doc>
          <p>
            If this value is true, then this message has not been acquired by any other link
            (see <xref name="distribution-nodes"/>). If this value is false, then this message MAY
            have previously been acquired by another link or links.
          </p>
        </doc>
      </field>

      <field name="delivery-count" type="uint" label="the number of prior unsuccessful delivery attempts" default="0">
        <doc>
          <p>
            The number of unsuccessful previous attempts to deliver this message. If this value is
            non-zero it can be taken as an indication that the delivery might be a duplicate. On
            first delivery, the value is zero. It is incremented upon an outcome being settled at
            the sender, according to rules defined for each outcome.
          </p>
        </doc>
      </field>

    </type>

    <type class="restricted" name="delivery-annotations" source="annotations" provides="section">
      <doc>
        <p>
          The delivery-annotations section is used for delivery-specific non-standard properties at
          the head of the message. Delivery annotations convey information from the sending peer to
          the receiving peer. If the recipient does not understand the annotation it cannot be acted
          upon and its effects (such as any implied propagation) cannot be acted upon. Annotations
          might be specific to one implementation, or common to multiple implementations. The
          capabilities negotiated on link <xref name="attach"/> and on the <xref name="source"/> and
          <xref name="target"/> SHOULD be used to establish which annotations a peer supports. A
          registry of defined annotations and their meanings is maintained
          [<xref name="AMQPDELANN">AMQPDELANN</xref>]. The symbolic key "rejected" is reserved for
          the use of communicating error information regarding rejected messages. Any values
          associated with the "rejected" key MUST be of type <xref type="type" name="error"/>.
        </p>

        <p>
          If the delivery-annotations section is omitted, it is equivalent to a delivery-annotations
          section containing an empty map of annotations.
        </p>
      </doc>

      <descriptor name="amqp:delivery-annotations:map" code="0x00000000:0x00000071"/>
    </type>

    <type class="restricted" name="message-annotations" source="annotations" provides="section">
      <doc>
        <p>
          The message-annotations section is used for properties of the message which are aimed at
          the infrastructure and SHOULD be propagated across every delivery step. Message
          annotations convey information about the message. Intermediaries MUST propagate the
          annotations unless the annotations are explicitly augmented or modified (e.g., by the use
          of the <xref name="modified"/> outcome).
        </p>

        <p>
          The capabilities negotiated on link <xref name="attach"/> and on the <xref name="source"/>
          and <xref name="target"/> can be used to establish which annotations a peer understands;
          however, in a network of AMQP intermediaries it might not be possible to know if every
          intermediary will understand the annotation. Note that for some annotations it might not
          be necessary for the intermediary to understand their purpose, i.e., they could be
          used purely as an attribute which can be filtered on.
        </p>

        <p>
          A registry of defined annotations and their meanings is maintained
          [<xref name="AMQPMESSANN">AMQPMESSANN</xref>].
        </p>

        <p>
          If the message-annotations section is omitted, it is equivalent to a message-annotations
          section containing an empty map of annotations.
        </p>
      </doc>

      <descriptor name="amqp:message-annotations:map" code="0x00000000:0x00000072"/>
    </type>

    <type class="composite" name="properties" source="list" provides="section" label="immutable properties of the message">
      <doc>
        <p>
          The properties section is used for a defined set of standard properties of the message.
          The properties section is part of the bare message; therefore, if retransmitted by an
          intermediary, it MUST remain unaltered.
        </p>
      </doc>

      <descriptor name="amqp:properties:list" code="0x00000000:0x00000073"/>

      <field name="message-id" type="*" requires="message-id" label="application message identifier">
        <doc>
          <p>
            Message-id, if set, uniquely identifies a message within the message system. The message
            producer is usually responsible for setting the message-id in such a way that it is
            assured to be globally unique. A broker MAY discard a message as a duplicate if the
            value of the message-id matches that of a previously received message sent to the same
            node.
          </p>
        </doc>
      </field>

      <field name="user-id" type="binary" label="creating user id">
        <doc>
          <p>
            The identity of the user responsible for producing the message. The client sets this
            value, and it MAY be authenticated by intermediaries.
          </p>
        </doc>
      </field>

      <field name="to" type="*" requires="address" label="the address of the node the message is destined for">
        <doc>
          <p>
            The to field identifies the node that is the intended destination of the message. On any
            given transfer this might not be the node at the receiving end of the link.
          </p>
        </doc>
      </field>

      <field name="subject" type="string" label="the subject of the message">
        <doc>
          <p>
            A common field for summary information about the message content and purpose.
          </p>
        </doc>
      </field>

      <field name="reply-to" type="*" requires="address" label="the node to send replies to">
        <doc>
          <p>The address of the node to send replies to.</p>
        </doc>
      </field>

      <field name="correlation-id" type="*" requires="message-id" label="application correlation identifier">
        <doc>
          <p>
            This is a client-specific id that can be used to mark or identify messages between
            clients.
          </p>
        </doc>
      </field>

      <field name="content-type" type="symbol" label="MIME content type">
        <doc>
          <p>
            The RFC-2046 [<xref name="RFC2046">RFC2046</xref>] MIME type for the message's
            application-data section (body). As per RFC-2046 [<xref name="RFC2046">RFC2046</xref>]
            this can contain a charset parameter defining the character encoding used: e.g.,
            'text/plain; charset="utf-8"'.
          </p>
          <p>
            For clarity, as per section 7.2.1 of RFC-2616 [<xref name="RFC2616">RFC2616</xref>],
            where the content type is unknown the content-type SHOULD NOT be set. This allows the
            recipient the opportunity to determine the actual type. Where the section is known to be
            truly opaque binary data, the content-type SHOULD be set to application/octet-stream.
          </p>
          <p>
            When using an application-data section with a section code other than <i>data</i>,
            content-type SHOULD NOT be set.
          </p>
        </doc>
      </field>

      <field name="content-encoding" type="symbol" label="MIME content type">
        <doc>
          <p>
            The content-encoding property is used as a modifier to the content-type.
            When present, its value indicates what additional content encodings have been applied
            to the application-data, and thus what decoding mechanisms need to be applied in order
            to obtain the media-type referenced by the content-type header field.
          </p>
          <p>
            Content-encoding is primarily used to allow a document to be compressed without
            losing the identity of its underlying content type.
          </p>
          <p>
            Content-encodings are to be interpreted as per section 3.5 of RFC 2616
            [<xref name="RFC2616">RFC2616</xref>]. Valid content-encodings are registered at
            IANA [<xref name="IANAHTTPPARAMS">IANAHTTPPARAMS</xref>].
          </p>
          <p>
            The content-encoding MUST NOT be set when the application-data section is other than
            <i>data</i>. The binary representation of all other application-data section types is
            defined completely in terms of the AMQP type system.
          </p>
          <p>
            Implementations MUST NOT use the <i>identity</i> encoding. Instead, implementations
            SHOULD NOT set this property. Implementations SHOULD NOT
            use the <i>compress</i> encoding, except as to remain compatible with messages
            originally sent with other protocols, e.g. HTTP or SMTP.
          </p>
          <p>
            Implementations SHOULD NOT specify multiple content-encoding values except as to
            be compatible with messages originally sent with other protocols, e.g. HTTP or SMTP.
          </p>
        </doc>
      </field>

      <field name="absolute-expiry-time" type="timestamp" label="the time when this message is considered expired">
        <doc>
          <p>
            An absolute time when this message is considered to be expired.
          </p>
        </doc>
      </field>

      <field name="creation-time" type="timestamp" label="the time when this message was created">
        <doc>
          <p>
            An absolute time when this message was created.
          </p>
        </doc>
      </field>

      <field name="group-id" type="string" label="the group this message belongs to">
        <doc>
          <p>
            Identifies the group the message belongs to.
          </p>
        </doc>
      </field>

      <field name="group-sequence" type="sequence-no" label="the sequence-no of this message within its group">
        <doc>
          <p>
            The relative position of this message within its group.
          </p>
        </doc>
      </field>

      <field name="reply-to-group-id" type="string" label="the group the reply message belongs to">
        <doc>
          <p>
            This is a client-specific id that is used so that client can send replies to this
            message to a specific group.
          </p>
        </doc>
      </field>

    </type>

    <type class="restricted" name="application-properties" source="map" provides="section">
      <doc>
        <p>
          The application-properties section is a part of the bare message used for structured
          application data. Intermediaries can use the data within this structure for the purposes
          of filtering or routing.
        </p>

        <p>
          The keys of this map are restricted to be of type <xref type="type" name="string"/> (which
          excludes the possibility of a null key) and the values are restricted to be of simple
          types only, that is, excluding <xref type="type" name="map"/>, <xref type="type" name="list"/>, and <xref type="type" name="array"/> types.
        </p>
      </doc>

      <descriptor name="amqp:application-properties:map" code="0x00000000:0x00000074"/>
    </type>

    <type class="restricted" name="data" source="binary" provides="section">
      <doc>
        <p>
          A data section contains opaque binary data.
        </p>
      </doc>

      <descriptor name="amqp:data:binary" code="0x00000000:0x00000075"/>
    </type>

    <type class="restricted" name="amqp-sequence" source="list" provides="section">
      <doc>
        <p>
          A sequence section contains an arbitrary number of structured data elements.
        </p>
      </doc>

      <descriptor name="amqp:amqp-sequence:list" code="0x00000000:0x00000076"/>
    </type>

    <type class="restricted" name="amqp-value" source="*" provides="section">
      <doc>
        <p>
          An amqp-value section contains a single AMQP value.
        </p>
      </doc>

      <descriptor name="amqp:amqp-value:*" code="0x00000000:0x00000077"/>
    </type>

    <type class="restricted" name="footer" source="annotations" provides="section" label="transport footers for a message">
      <doc>
        <p>
          The footer section is used for details about the message or delivery which can only be
          calculated or evaluated once the whole bare message has been constructed or seen (for
          example message hashes, HMACs, signatures and encryption details).
        </p>

        <p>
          A registry of defined footers and their meanings is maintained
          [<xref name="AMQPFOOTER">AMQPFOOTER</xref>].
        </p>
      </doc>

      <descriptor name="amqp:footer:map" code="0x00000000:0x00000078"/>
    </type>

    <type class="restricted" name="annotations" source="map">
      <doc>
        <p>
          The <i>annotations</i> type is a map where the keys are restricted to be of type <xref type="type" name="symbol"/> or of type <xref type="type" name="ulong"/>. All ulong keys,
          and all symbolic keys except those beginning with "x-" are reserved. Keys beginning with
          "x-opt-" MUST be ignored if not understood. On receiving an annotation key which is not
          understood, and which does not begin with "x-opt", the receiving AMQP container MUST
          detach the link with a <xref name="amqp-error" choice="not-implemented"/> error.
        </p>
      </doc>
    </type>

    <type class="restricted" name="message-id-ulong" source="ulong" provides="message-id"/>
    <type class="restricted" name="message-id-uuid" source="uuid" provides="message-id"/>
    <type class="restricted" name="message-id-binary" source="binary" provides="message-id"/>
    <type class="restricted" name="message-id-string" source="string" provides="message-id"/>

    <type class="restricted" name="address-string" source="string" provides="address" label="address of a node"/>

    <definition name="MESSAGE-FORMAT" value="0" label="the format + revision for the messages defined by this document">
      <doc>
        <p>
          This value goes into the message-format field of the transfer frame when transferring
          messages of the format defined herein.
        </p>
      </doc>
    </definition>
  </section>

  <section name="distribution-nodes" title="Distribution Nodes" label="common interface for nodes that store and distribute messages">

    <doc>
      <p>
        The messaging layer defines a set of states for a <i>distribution node</i>, defined as a
        node that stores messages for distribution. Not all nodes are distribution nodes; however,
        these definitions permit some standardized interaction with those nodes that do.
        The transitions between these states
        are controlled by the transfer of messages to/from a distribution node and the resulting
        terminal delivery state. Note that the state of a message at one distribution node does not
        affect the state of the same message at a separate node.
      </p>

      <p>
        By default a message will begin in the AVAILABLE state. Prior to initiating an
        <i>acquiring</i> transfer, the message will transition to the ACQUIRED state. Once in the
        ACQUIRED state, a message is ineligible for <i>acquiring</i> transfers to any other links.
      </p>

      <p>
        A message will remain ACQUIRED at the distribution node until the transfer is settled. The
        delivery state at the receiver determines how the message transitions when the transfer is
        settled. If the delivery state at the receiver is not yet known, (e.g., the link endpoint
        is destroyed before recovery occurs) the <i>default-outcome</i> of the source is used
        (see <xref name="source"/>).
      </p>

      <p>
        State transitions can also occur spontaneously at the distribution node. For example if a
        message with a ttl expires, the effect of expiry might be (depending on specific type and
        configuration of the distribution node) to move spontaneously from the AVAILABLE state into
        the ARCHIVED state. In this case any transfers of the message are transitioned to a terminal
        outcome at the distribution node regardless of receiver state.
      </p>

      <picture title="Message State Transitions">
                         +------------+
                      +-&gt;| AVAILABLE  |
                      |  +------------+
                      |        |
                      |        |
  terminal outcome:   |        |
  RELEASED/MODIFIED   |        | TRANSFER (acquiring)
                      |        |
                      |        |
                      |       \|/
                      |  +------------+
                      +--|  ACQUIRED  |
                         +------------+
                               |
                               |
                               |   terminal outcome:
                               |   ACCEPTED/REJECTED
                               |
                               |
                              \|/
                         +------------+
                         |  ARCHIVED  |
                         +------------+

      </picture>
    </doc>
  </section>

  <section name="delivery-state" title="Delivery State" label="the delivery states defined for messaging">
    <doc>
      <p>
        The messaging layer defines a concrete set of delivery states which can be used (via the
        <xref type="type" name="disposition"/> frame) to indicate the state of the message at the
        receiver. Delivery states can be either terminal or non-terminal. Once a delivery reaches a
        terminal delivery state, the state for that delivery will no longer change. A terminal
        delivery state is referred to as an <i>outcome</i>.
      </p>

      <p>
        The following outcomes are formally defined by the messaging layer to indicate the result of
        processing at the receiver:
      </p>

      <ul>
        <li>
          <p><xref name="accepted"/>: indicates successful processing at the receiver.</p>
        </li>
        <li>
          <p><xref name="rejected"/>: indicates an invalid and unprocessable message.</p>
        </li>
        <li>
          <p><xref name="released"/>: indicates that the message was not (and will not be)
            processed.</p>
        </li>
        <li>
          <p><xref name="modified"/>: indicates that the message was modified, but not
            processed.</p>
        </li>
      </ul>

      <p>
        The following non-terminal delivery-state is formally defined by the messaging layer for use
        during link recovery to allow the sender to resume the transfer of a large message without
        retransmitting all the message data:
      </p>

      <ul>
        <li>
          <p><xref name="received"/>: indicates partial message data seen by the receiver as well as
          the starting point for a resumed transfer.</p>
        </li>
      </ul>
    </doc>

    <type class="composite" name="received" source="list" provides="delivery-state">
      <descriptor name="amqp:received:list" code="0x00000000:0x00000023"/>
      <doc>
        <p>
          At the target the <xref name="received"/> state indicates the furthest point in the
          payload of the message which the target will not need to have resent if the link is
          resumed. At the source the <xref name="received"/> state represents the earliest point in
          the payload which the sender is able to resume transferring at in the case of link
          resumption. When resuming a delivery, if this state is set on the first <xref type="type" name="transfer"/> performative it indicates the offset in the payload at which the first
          resumed delivery is starting. The sender MUST NOT send the <xref name="received"/> state
          on <xref type="type" name="transfer"/> or <xref type="type" name="disposition"/>
          performatives except on the first <xref type="type" name="transfer"/> performative on a
          resumed delivery.
        </p>
      </doc>
      <field name="section-number" type="uint" mandatory="true">
        <doc>
          <p>
            When sent by the sender this indicates the first section of the message (with
            section-number 0 being the first section) for which data can be resent. Data from
            sections prior to the given section cannot be retransmitted for this delivery.
          </p>
          <p>
            When sent by the receiver this indicates the first section of the message for which
            all data might not yet have been received.
          </p>
        </doc>
      </field>
      <field name="section-offset" type="ulong" mandatory="true">
        <doc>
          <p>
            When sent by the sender this indicates the first byte of the encoded section data of the
            section given by section-number for which data can be resent (with section-offset 0
            being the first byte). Bytes from the same section prior to the given offset section
            cannot be retransmitted for this delivery.
          </p>
          <p>
            When sent by the receiver this indicates the first byte of the given section which has
            not yet been received. Note that if a receiver has received all of section number X
            (which contains N bytes of data), but none of section number X + 1, then it can indicate
            this by sending either Received(section-number=X, section-offset=N) or
            Received(section-number=X+1, section-offset=0). The state Received(section-number=0,
            section-offset=0) indicates that no message data at all has been transferred.
          </p>
        </doc>
      </field>
    </type>

    <type class="composite" name="accepted" source="list" provides="delivery-state, outcome" label="the accepted outcome">

      <descriptor name="amqp:accepted:list" code="0x00000000:0x00000024"/>

      <doc>
        <p>
          At the source the accepted state means that the message has been retired from the node,
          and transfer of payload data will not be able to be resumed if the link becomes suspended.
          A delivery can become accepted at the source even before all transfer frames have been
          sent, this does not imply that the remaining transfers for the delivery will not be sent -
          only the aborted flag on the <xref type="type" name="transfer"/> performative can be used
          to indicate a premature termination of the transfer.
        </p>
        <p>
          At the target, the accepted outcome is used to indicate that an incoming message has been
          successfully processed, and that the receiver of the message is expecting the sender to
          transition the delivery to the accepted state at the source.
        </p>
        <p>
          The accepted outcome does not increment the <i>delivery-count</i> in the header of the
          accepted message.
        </p>
      </doc>
    </type>

    <type class="composite" name="rejected" source="list" provides="delivery-state, outcome" label="the rejected outcome">

      <descriptor name="amqp:rejected:list" code="0x00000000:0x00000025"/>

      <doc>
        <p>
          At the target, the rejected outcome is used to indicate that an incoming message is
          invalid and therefore unprocessable. The rejected outcome when applied to a message will
          cause the <i>delivery-count</i> to be incremented in the header of the rejected message.
        </p>
        <p>
          At the source, the rejected outcome means that the target has informed the source that
          the message was rejected, and the source has taken the necessary action. The delivery
          SHOULD NOT ever spontaneously attain the rejected state at the source.
        </p>
      </doc>

      <field name="error" type="error" label="error that caused the message to be rejected">
        <doc>
          <p>
            This field contains diagnostic information about the cause of the message rejection.
          </p>
        </doc>
      </field>
    </type>

    <type class="composite" name="released" source="list" provides="delivery-state, outcome" label="the released outcome">

      <descriptor name="amqp:released:list" code="0x00000000:0x00000026"/>

      <doc>
        <p>
          At the source the released outcome means that the message is no longer acquired by the
          receiver, and has been made available for (re-)delivery to the same or other targets
          receiving from the node. The message is unchanged at the node (i.e., the
          <i>delivery-count</i> of the header of the released message MUST NOT be incremented). As
          released is a terminal outcome, transfer of payload data will not be able to be resumed
          if the link becomes suspended. A delivery can become released at the source even before
          all transfer frames have been sent. This does not imply that the remaining transfers for
          the delivery will not be sent. The source MAY spontaneously attain the released outcome
          for a message (for example the source might implement some sort of time-bound acquisition
          lock, after which the acquisition of a message at a node is revoked to allow for delivery
          to an alternative consumer).
        </p>
        <p>
          At the target, the released outcome is used to indicate that a given transfer was not and
          will not be acted upon.
        </p>
      </doc>

    </type>

    <type class="composite" name="modified" source="list" provides="delivery-state, outcome" label="the modified outcome">

      <descriptor name="amqp:modified:list" code="0x00000000:0x00000027"/>

      <doc>
        <p>
          At the source the modified outcome means that the message is no longer acquired by the
          receiver, and has been made available for (re-)delivery to the same or other targets
          receiving from the node. The message has been changed at the node in the ways indicated by
          the fields of the outcome. As modified is a terminal outcome, transfer of payload data
          will not be able to be resumed if the link becomes suspended. A delivery can become
          modified at the source even before all transfer frames have been sent. This does not imply
          that the remaining transfers for the delivery will not be sent. The source MAY
          spontaneously attain the modified outcome for a message (for example the source might
          implement some sort of time-bound acquisition lock, after which the acquisition of a
          message at a node is revoked to allow for delivery to an alternative consumer with the
          message modified in some way to denote the previous failed, e.g., with delivery-failed
          set to true).
        </p>
        <p>
          At the target, the modified outcome is used to indicate that a given transfer was not and
          will not be acted upon, and that the message SHOULD be modified in the specified ways at
          the node.
        </p>
      </doc>


      <field name="delivery-failed" type="boolean" label="count the transfer as an unsuccessful delivery attempt">
        <doc>
          <p>
            If the delivery-failed flag is set, any messages modified MUST have their
            delivery-count incremented.
          </p>
        </doc>
      </field>

      <field name="undeliverable-here" type="boolean" label="prevent redelivery">
        <doc>
          <p>
            If the undeliverable-here is set, then any messages released MUST NOT be redelivered to
            the modifying link endpoint.
          </p>
        </doc>
      </field>

      <field name="message-annotations" type="fields" label="message attributes">
        <doc>
          <p>
            Map containing attributes to combine with the existing <i>message-annotations</i> held
            in the message's header section. Where the existing message-annotations of the message
            contain an entry with the same key as an entry in this field, the value in this field
            associated with that key replaces the one in the existing headers; where the existing
            message-annotations has no such value, the value in this map is added.
          </p>
        </doc>
      </field>
    </type>

    <doc name="more-resuming-deliveries" title="Resuming Deliveries Using Delivery States">
      <p>
        <xref type="doc" name="resuming-deliveries"/> provides the general scheme for how two
        endpoints can re-establish state after link resumption was provided. The concrete
        delivery states defined above allow for a more comprehensive set of examples of link
        resumption.
      </p>
      <picture>
    Peer                                   Partner
    =======================================================================

    ATTACH(name=N, handle=1,   --+     +-- ATTACH(name=N, handle=2,
           role=sender,           \   /           role=receiver,
           source=X,               \ /            source=X,
           target=Y,                x             target=Y,
           unsettled=              / \            unsettled=
            { 1 -&gt; null,          /   \            { 2 -&gt; Received(3,0),
              2 -&gt; null,       &lt;-+     +-&gt;           3 -&gt; Accepted,
              3 -&gt; null,                             4 -&gt; null,
              4 -&gt; null,                             6 -&gt; Received(2,0),
              5 -&gt; Received(0,200),                  7 -&gt; Received(0,100),
              6 -&gt; Received(1,150),                  8 -&gt; Accepted,
              7 -&gt; Received(0,500),                  9 -&gt; null,
              8 -&gt; Received(3,5),                   11 -&gt; Received(1,2000),
              9 -&gt; Received(2,0),                   12 -&gt; Accepted,
             10 -&gt; Accepted,                        13 -&gt; Released,
             11 -&gt; Accepted,                        14 -&gt; null }
             12 -&gt; Accepted,
             13 -&gt; Accepted,
             14 -&gt; Accepted }

    -----------------------------------------------------------------------
    Key:

    Received(x,y) means Received(section-number=x, section-offset=y)

      </picture>
      <p>
        In this example, for delivery-tags 1 to 4 inclusive the sender indicates that it can resume
        sending from the start of the message.
      </p>
      <p>
        For delivery-tag 1, the receiver has no record of the delivery. To preserve "exactly once"
        or "at least once" delivery guarantees, the sender MUST resend the message; however, the
        delivery is not being resumed (since the receiver does not remember the delivery tag) so
        transfers MUST NOT have the resume flag set to true. If the sender were to mark the
        transfers as resumes then they would be ignored at the receiver.
      </p>
      <p>
        For delivery-tag 2, the receiver has retained some of the data making up the message, but
        not the whole. In order to complete the delivery the sender needs to resume sending from
        some point before or at the next position which the receiver is expecting.
      </p>
      <picture>
    TRANSFER(delivery-id=1,    ----------&gt; ** Append message data not     **
             delivery-tag=2,               ** seen previously to delivery **
        (1)  state=Received(3,0),          ** state.                      **
             resume=true)
    { ** payload ** }


    (1) state could be
        a) null, meaning that the transfer is being resumed from the first
           byte of section number 0 (and the receiver MUST ignore all data
           up to the first position it has not previously received).
        b) Received with section number 0, 1 or 2 and an offset, indicating
           that the payload data on the first frame of the resumed delivery
           starts at the given point, and that the receiver MUST ignore all
           data up to the first position it has not previously received.
        c) Received(3,0) indicating that the resumption will start at the
           first point which the receiver has not previously received.     </picture>
      <p>
        For delivery-tag 3, the receiver indicates that it has processed the delivery to the point
        where it desires a terminal outcome (in this case <xref name="accepted"/>). In this case
        the sender will either apply that outcome at the source, or in the rare case that it cannot
        apply that outcome, indicate the terminal outcome that has been applied. To do this the
        sender MUST send a resuming transfer to associate delivery-tag 3 with a delivery-id. On this
        transfer the sender SHOULD set the delivery-state at the source. If this is the same outcome
        as at the receiver then the sender MAY also send the resuming transfer as settled.
      </p>
      <picture>
    TRANSFER(delivery-id=2,    ----------&gt; ** Processes confirmation that **
             delivery-tag=3,               ** was accepted, and settles.  **
             settled=true,
             more=false,
             state=Accepted,
             resume=true)    </picture>
      <p>
        For delivery-tag 4, the receiver indicates that it is aware that the delivery had begun, but
        does not provide any indication that it has retained any data about that delivery except
        the fact of its existence. To preserve "exactly once" or "at least once" delivery
        guarantees, the sender MUST resend the whole message. Unlike the case with delivery-tag 1
        the resent delivery MUST be sent with the resume flag set to true and the delivery-tag set
        to 4. (While this use of null in the receivers map is valid, it is discouraged. It is
        RECOMMENDED that receiver SHOULD NOT retain such an entry in its map, in which case the
        situation would be as for delivery-tag 1 in this example).
      </p>
      <picture>
    TRANSFER(delivery-id=3,    ----------&gt; ** Processes in the same way   **
             delivery-tag=4,               ** as we be done for a non-    **
        (1)  state=null,                   ** resumed delivery.           **
             resume=true)
    { ** payload ** }


    (1) Alternatively (and equivalently) state could be
        Received(section-number=0, section-offset=0)    </picture>
      <p>
        For delivery-tags 5 to 9 inclusive the sender indicates that it can resume at some point
        beyond start of the message data. This is usually indicative of the fact that the receiver
        had previously confirmed reception of message data to the given point, removing
        responsibility from the sender to retain the ability to resend that data after resuming
        the link. The sender MAY still retain the ability to resend the message as a new delivery
        (i.e. it MAY not have completely discarded the data from which the original delivery was
        generated).
      </p>
      <p>
        For delivery-tag 5, the receiver has no record of the delivery. To preserve "exactly once"
        or "at least once" delivery guarantees, the sender MUST resend the message; however, the
        delivery is not being resumed (since the receiver does not remember the delivery tag) so
        transfers MUST NOT have the resume flag set to true. If the sender does not have enough
        data to resend the message, then the sender MAY take some action to indicate that it
        believes there is a possibility that there has been message loss, for example, notify
        the application.
      </p>
      <p>
        For delivery-tag 6, the receiver has retained some of the data making up the message, but
        not the whole. The first position within the message which the receiver has not received is
        after the first position at which the sender can resume sending. In order to complete the
        delivery the sender needs to resume sending from some point before or at the next position
        which the receiver is expecting.
      </p>
      <picture>
    TRANSFER(delivery-id=4,    ----------&gt; ** Append message data not     **
             delivery-tag=6,               ** seen previously to delivery **
        (1)  state=Received(2,0),          ** state.                      **
             resume=true)
    { ** payload ** }


    (1) state could be any point between Received(1,150) and Received(2,0)
        inclusive. The receiver MUST ignore all data up to the first
        position it has not previously received (i.e. section 2 offset 0).     </picture>
      <p>
        For delivery-tag 7, the receiver has retained some of the data making up the message, but
        not the whole. The first position within the message which the receiver has not received is
        before the first position at which the sender can resume sending. It is thus not possible
        for the sender to resume sending the message to completion. The only option available to the
        sender is to abort the transfer and to then (if possible) resend as a new delivery or else
        to report the possible message loss in some way if it cannot.
      </p>
      <picture>
    TRANSFER(delivery-id=5,    ----------&gt; ** Discard any state relating  **
             delivery-tag=7,               ** to the message delivery.    **
             resume=true,
             aborted=true)    </picture>
      <p>
        For delivery-tag 8, the receiver indicates that it has processed the delivery to the point
        where it desires a terminal outcome (in this case <xref name="accepted"/>). This is the
        same case as for delivery-tag 3.
      </p>
      <picture>
    TRANSFER(delivery-id=6,    ----------&gt; ** Processes confirmation that **
             delivery-tag=8,               ** was accepted, and settles.  **
             settled=true,
             more=false,
             state=Accepted,
             resume=true)   </picture>
      <p>
        For delivery-tag 9, the receiver indicates that it is aware that the delivery had begun, but
        does not provide any indication that it has retained any data about that delivery except
        the fact of its existence. This is the same case as for delivery-tag 7.
      </p>
      <picture>
    TRANSFER(delivery-id=7,    ----------&gt; ** Discard any state relating  **
             delivery-tag=9,               ** to the message delivery.    **
             resume=true,
             aborted=true)    </picture>
      <p>
        For delivery-tags 10 to 14 inclusive the sender indicates that it has reached a terminal
        outcome, namely <xref name="accepted"/>. Once the sender has arrived at a terminal outcome
        it MUST NOT change. As such, if a sender is capable of resuming a delivery (even if the only
        possible outcome of the delivery is a pre-defined terminal outcome such as <xref name="accepted"/>) it MUST NOT use this state as the value of the state in its unsettled map
        until it is sure that the receiver will not require the resending of the message data.
      </p>
      <p>
        For delivery-tag 10 the receiver has no record of the delivery. However, in contrast to the
        cases of delivery-tag 1 and delivery-tag 5, since it is known that the sender can only have
        arrived at this state through knowing that the receiver has received the whole message (or
        that the sender had spontaneously reached a terminal outcome with no possibility of
        resumption) there is no need to resend the message.
      </p>
      <p>
        For delivery-tag 11 it MUST be assumed that the sender spontaneously attained the terminal
        outcome (and is unable to resume). In this case the sender can simply abort the delivery
        as it cannot be resumed.
      </p>
      <picture>
    TRANSFER(delivery-id=8,    ----------&gt; ** Discard any state relating  **
             delivery-tag=11,              ** to the message delivery.    **
             resume=true,
             aborted=true)    </picture>
      <p>
        For delivery-tag 12 both the sender and receiver have attained the same view of the terminal
        outcome, but neither has settled. In this case the sender SHOULD simply settle the delivery.
      </p>
      <picture>
    TRANSFER(delivery-id=9,    ----------&gt; ** Locally settle the delivery **
             delivery-tag=12,
             settled=true,
             resume=true)    </picture>
      <p>
        For delivery-tag 13 the sender and receiver have both attained terminal outcomes, but the
        outcomes differ. In this case, since the outcome actually takes effect at the sender, it is
        the sender's view that is definitive. The sender thus MUST restate this as the terminal
        outcome, and the receiver SHOULD then echo this and settle.
      </p>
      <picture>
    TRANSFER(delivery-id=10    ----------&gt; ** Update any state affected   **
             delivery-tag=13,              ** by the actual outcome, then **
             settled=false,                ** settle the delivery         **
             state=Accepted
             resume=true)
                               &lt;---------- DISPOSITION(first=10, last=10,
                                                       state=Accepted,
                                                       settled=true)    </picture>
      <p>
        For delivery-tag 14 the case is essentially the same as for delivery-tag 11, as the null
        state at the receiver is essentially identical to having the state
        Received with section-number=0 and section-offset=0.
      </p>
      <picture>
    TRANSFER(delivery-id=11,   ----------&gt; ** Discard any state relating  **
             delivery-tag=14,              ** to the message delivery.    **
             resume=true,
             aborted=true)    </picture>

    </doc>
  </section>

  <section name="addressing" title="Sources and Targets" label="concrete sources and targets defined for messaging">
    <doc>
      <p>
        The messaging layer defines two concrete types (<xref type="type" name="source"/> and
        <xref type="type" name="target"/>) to be used as the <i>source</i> and <i>target</i> of a
        link. These types are supplied in the <i>source</i> and <i>target</i> fields of the
        <xref type="type" name="attach"/> frame when establishing or resuming link. The
        <xref type="type" name="source"/> is comprised of an address (which the container of the
        outgoing link endpoint will resolve to a node within that container) coupled with properties
        which determine:
      </p>

      <ul>
        <li>
          <p>
            which messages from the sending node will be sent on the link,
          </p>
        </li>

        <li>
          <p>
            how sending the message affects the state of that message at the sending node,
          </p>
        </li>

        <li>
          <p>
            the behavior of messages which have been transferred on the link, but have not yet
            reached a terminal state at the receiver, when the source is destroyed.
          </p>
        </li>
      </ul>
    </doc>

    <doc title="Filtering Messages">
      <p>
        A source can restrict the messages transferred from a source by specifying a filter.
        A filter can be thought of as a function which takes a message as input and returns a
        boolean value: true if the message will be accepted by the source, false otherwise.
        A <i>filter</i> MUST NOT change its return value for a message unless the state or
        annotations on the message at the node change (e.g., through an updated delivery state).
      </p>
    </doc>

    <doc title="Distribution Modes">
      <p>
        The source optionally defines a distribution-mode that informs and/or indicates how
        distribution nodes are to behave with respect to the link. The distribution-mode of a source
        determines how messages from a distribution node are distributed among its associated links.
        There are two defined distribution-modes: <i>move</i> and <i>copy</i>. When specified, the
        distribution-mode has two related effects on the behavior of a distribution node with
        respect to the link associated with the source.
      </p>

      <p>
        The <i>move</i> distribution-mode causes messages transferred from the distribution node to
        transition to the ACQUIRED state prior to transfer over the link, and subsequently to the
        ARCHIVED state when the transfer is settled with a successful outcome. The <i>copy</i>
        distribution-mode leaves the state of the message unchanged at the distribution node.
      </p>

      <p>
        A source MUST NOT resend a message which has previously been successfully transferred from
        the source, i.e., reached an ACCEPTED delivery state at the receiver. For a
        <i>move</i> link with a default configuration this is trivially achieved as such an end
        result will lead to the message in the ARCHIVED state on the node, and thus
        ineligible for transfer. For a <i>copy</i> link, state MUST be retained at the source to
        ensure compliance. In practice, for nodes which maintain a strict order on messages at the
        node, the state might simply be a record of the most recent message transferred.
      </p>

      <p>
        A registry of commonly defined non-standard distribution-modes and their meanings is
        maintained [<xref name="AMQPDISTMODE">AMQPDISTMODE</xref>].
      </p>
    </doc>

    <type class="composite" name="source" provides="source" source="list">
      <descriptor name="amqp:source:list" code="0x00000000:0x00000028"/>
      <doc>
        <p>
          For containers which do not implement address resolution (and do not admit spontaneous
          link attachment from their partners) but are instead only used as producers of messages,
          it is unnecessary to provide spurious detail on the source. For this purpose it is
          possible to use a "minimal" source in which all the fields are left unset.
        </p>
      </doc>
      <field name="address" type="*" requires="address" label="the address of the source">
        <doc>
          <p>
            The address of the source MUST NOT be set when sent on a <xref type="type" name="attach"/> frame sent by the receiving link endpoint where the dynamic flag is set
            to true (that is where the receiver is requesting the sender to create an addressable
            node).
          </p>
          <p>
            The address of the source MUST be set when sent on a <xref type="type" name="attach"/>
            frame sent by the sending link endpoint where the dynamic flag is set to true (that is
            where the sender has created an addressable node at the request of the receiver and is
            now communicating the address of that created node). The generated name of the address
            SHOULD include the link name and the container-id of the remote container to allow for
            ease of identification.
          </p>
        </doc>
      </field>

      <field name="durable" type="terminus-durability" default="none" label="indicates the durability of the terminus">
        <doc>
          <p>
            Indicates what state of the terminus will be retained durably: the state of durable
            messages, only existence and configuration of the terminus, or no state at all.
          </p>
        </doc>
      </field>

      <field name="expiry-policy" type="terminus-expiry-policy" default="session-end" label="the expiry policy of the source">
        <doc>
          <p>
            See <xref name="terminus-expiry-policy"/>.
          </p>
        </doc>
      </field>

      <field name="timeout" type="seconds" default="0" label="duration that an expiring source will be retained">
        <doc>
          <p>
            The source starts expiring as indicated by the expiry-policy.
          </p>
        </doc>
      </field>

      <field name="dynamic" type="boolean" default="false" label="request dynamic creation of a remote node">
        <doc>
          <p>
            When set to true by the receiving link endpoint, this field constitutes a request for
            the sending peer to dynamically create a node at the source. In this case the address
            field MUST NOT be set.
          </p>
          <p>
            When set to true by the sending link endpoint this field indicates creation of a
            dynamically created node. In this case the address field will contain the address of the
            created node. The generated address SHOULD include the link name and other available
            information on the initiator of the request (such as the remote container-id) in some
            recognizable form for ease of traceability.
          </p>
        </doc>
      </field>

      <field name="dynamic-node-properties" type="node-properties" label="properties of the dynamically created node">
        <doc>
          <p>
            If the dynamic field is not set to true this field MUST be left unset.
          </p>
          <p>
            When set by the receiving link endpoint, this field contains the desired properties of
            the node the receiver wishes to be created. When set by the sending link endpoint this
            field contains the actual properties of the dynamically created node. See <xref name="node-properties"/> for standard node properties. A registry of other commonly used
            node-properties and their meanings is maintained
            [<xref name="AMQPNODEPROP">AMQPNODEPROP</xref>].
          </p>
        </doc>
      </field>

      <field name="distribution-mode" type="symbol" requires="distribution-mode" label="the distribution mode of the link">
        <doc>
          <p>
            This field MUST be set by the sending end of the link if the endpoint supports more than
            one distribution-mode. This field MAY be set by the receiving end of the link to
            indicate a preference when a node supports multiple distribution modes.
          </p>
        </doc>
      </field>

      <field name="filter" type="filter-set" label="a set of predicates to filter the messages admitted onto the link">
        <doc>
          <p>
            See <xref name="filter-set"/>. The receiving endpoint sets its desired filter, the
            sending endpoint sets the filter actually in place (including any filters defaulted
            at the node). The receiving endpoint MUST check that the filter in place meets its
            needs and take responsibility for detaching if it does not.
          </p>
        </doc>
      </field>

      <field name="default-outcome" type="*" requires="outcome" label="default outcome for unsettled transfers">
        <doc>
          <p>
            Indicates the outcome to be used for transfers that have not reached a terminal state at
            the receiver when the transfer is settled, including when the source is destroyed. The
            value MUST be a valid outcome (e.g., <xref name="released"/> or
            <xref name="rejected"/>).
          </p>
        </doc>
      </field>

      <field name="outcomes" type="symbol" multiple="true" label="descriptors for the outcomes that can be chosen on this link">
        <doc>
          <p>
            The values in this field are the symbolic descriptors of the outcomes that can be chosen
            on this link. This field MAY be empty, indicating that the <i>default-outcome</i> will
            be assumed for all message transfers (if the default-outcome is not set, and no outcomes
            are provided, then the <xref name="accepted"/> outcome MUST be supported by the source).
          </p>
          <p>
            When present, the values MUST be a symbolic descriptor of a valid outcome, e.g.,
            "amqp:accepted:list".
          </p>
        </doc>
      </field>

      <field name="capabilities" type="symbol" multiple="true" label="the extension capabilities the sender supports/desires">
        <doc>
          <p>
            A registry of commonly defined source capabilities and their meanings is maintained
            [<xref name="AMQPSOURCECAP">AMQPSOURCECAP</xref>].
          </p>
        </doc>
      </field>
    </type>

    <type class="composite" name="target" provides="target" source="list">

      <descriptor name="amqp:target:list" code="0x00000000:0x00000029"/>

      <doc>
        <p>
          For containers which do not implement address resolution (and do not admit spontaneous
          link attachment from their partners) but are instead only used as consumers of messages,
          it is unnecessary to provide spurious detail on the source. For this purpose it is
          possible to use a "minimal" target in which all the fields are left unset.
        </p>
      </doc>

      <field name="address" type="*" requires="address" label="The address of the target.">
        <doc>
          <p>
            The address of the target MUST NOT be set when sent on a <xref type="type" name="attach"/> frame sent by the sending link endpoint where the dynamic flag is set
            to true (that is where the sender is requesting the receiver to create an addressable
            node).
          </p>
          <p>
            The address of the source MUST be set when sent on a <xref type="type" name="attach"/>
            frame sent by the receiving link endpoint where the dynamic flag is set to true (that
            is where the receiver has created an addressable node at the request of the sender and
            is now communicating the address of that created node). The generated name of the
            address SHOULD include the link name and the container-id of the remote container to
            allow for ease of identification.
          </p>
        </doc>
      </field>

      <field name="durable" type="terminus-durability" default="none" label="indicates the durability of the terminus">
        <doc>
          <p>
            Indicates what state of the terminus will be retained durably: the state of durable
            messages, only existence and configuration of the terminus, or no state at all.
          </p>
        </doc>
      </field>

      <field name="expiry-policy" type="terminus-expiry-policy" default="session-end" label="the expiry policy of the target">
        <doc>
          <p>
            See <xref name="terminus-expiry-policy"/>.
          </p>
        </doc>
      </field>

      <field name="timeout" type="seconds" default="0" label="duration that an expiring target will be retained">
        <doc>
          <p>
            The target starts expiring as indicated by the expiry-policy.
          </p>
        </doc>
      </field>

      <field name="dynamic" type="boolean" default="false" label="request dynamic creation of a remote node">
        <doc>
          <p>
            When set to true by the sending link endpoint, this field constitutes a request for
            the receiving peer to dynamically create a node at the target. In this case the address
            field MUST NOT be set.
          </p>
          <p>
            When set to true by the receiving link endpoint this field indicates creation of a
            dynamically created node. In this case the address field will contain the address of the
            created node. The generated address SHOULD include the link name and other available
            information on the initiator of the request (such as the remote container-id) in some
            recognizable form for ease of traceability.
          </p>
        </doc>
      </field>

      <field name="dynamic-node-properties" type="node-properties" label="properties of the dynamically created node">
        <doc>
          <p>
            If the dynamic field is not set to true this field MUST be left unset.
          </p>
          <p>
            When set by the sending link endpoint, this field contains the desired properties of
            the node the sender wishes to be created. When set by the receiving link endpoint this
            field contains the actual properties of the dynamically created node. See <xref name="node-properties"/> for standard node properties. A registry of other commonly used
            node-properties and their meanings is maintained
            [<xref name="AMQPNODEPROP">AMQPNODEPROP</xref>].
          </p>
        </doc>
      </field>

      <field name="capabilities" type="symbol" multiple="true" label="the extension capabilities the sender supports/desires">
        <doc>
          <p>
            A registry of commonly defined target capabilities and their meanings is maintained
            [<xref name="AMQPTARGETCAP">AMQPTARGETCAP</xref>].
          </p>
        </doc>
      </field>
    </type>

    <type class="restricted" name="terminus-durability" source="uint" label="durability policy for a terminus">
      <doc>
        <p>
          Determines which state of the terminus is held durably.
        </p>
      </doc>
      <choice name="none" value="0">
        <doc>
          <p>
            No terminus state is retained durably.
          </p>
        </doc>
      </choice>
      <choice name="configuration" value="1">
        <doc>
          <p>
            Only the existence and configuration of the terminus is retained durably.
          </p>
        </doc>
      </choice>
      <choice name="unsettled-state" value="2">
        <doc>
          <p>
            In addition to the existence and configuration of the terminus, the unsettled state for
            durable messages is retained durably.
          </p>
        </doc>
      </choice>
    </type>

    <type class="restricted" name="terminus-expiry-policy" source="symbol" label="expiry policy for a terminus">
      <doc>
        <p>
          Determines when the expiry timer of a terminus starts counting down from the timeout
          value. If the link is subsequently re-attached before the terminus is expired, then the
          count down is aborted. If the conditions for the terminus-expiry-policy are subsequently
          re-met, the expiry timer restarts from its originally configured timeout value.
        </p>
      </doc>
      <choice name="link-detach" value="link-detach">
        <doc>
          <p>
            The expiry timer starts when terminus is detached.
          </p>
        </doc>
      </choice>
      <choice name="session-end" value="session-end">
        <doc>
          <p>The expiry timer starts when the most recently associated session is ended.</p>
        </doc>
      </choice>
      <choice name="connection-close" value="connection-close">
        <doc>
          <p>The expiry timer starts when most recently associated connection is closed.</p>
        </doc>
      </choice>
      <choice name="never" value="never">
        <doc>
          <p>The terminus never expires.</p>
        </doc>
      </choice>
    </type>

    <type class="restricted" name="std-dist-mode" source="symbol" provides="distribution-mode" label="Link distribution policy">
      <doc>
        <p>
          Policies for distributing messages when multiple links are connected to the same node.
        </p>
      </doc>

      <choice name="move" value="move">
        <doc>
          <p>
            once successfully transferred over the link, the message will no longer be available to
            other links from the same node
          </p>
        </doc>
      </choice>

      <choice name="copy" value="copy">
        <doc>
          <p>
            once successfully transferred over the link, the message is still available for other
            links from the same node
          </p>
        </doc>
      </choice>
    </type>

    <type class="restricted" name="filter-set" source="map">
      <doc>
        <p>
          A set of named filters. Every key in the map MUST be of type <xref type="type" name="symbol"/>, every value MUST be either <xref type="type" name="null"/> or of a
          described type which provides the archetype <i>filter</i>. A filter acts as a function on
          a message which returns a boolean result indicating whether the message can pass through
          that filter or not.  A message will pass through a filter-set if and only if it passes
          through each of the named filters. If the value for a given key is null, this acts as if
          there were no such key present (i.e., all messages pass through the null filter).
        </p>
        <p>
          Filter types are a defined extension point. The filter types that a given
          <xref name="source"/> supports will be indicated by the capabilities of the
          <xref name="source"/>.
          A registry of commonly defined filter types and their capabilities is maintained
          [<xref name="AMQPFILTERS">AMQPFILTERS</xref>].
        </p>
      </doc>
    </type>

    <type class="restricted" name="node-properties" source="fields" label="properties of a node">
      <doc>
        <p>
          A symbol-keyed map containing properties of a node used when requesting creation or
          reporting the creation of a dynamic node.
        </p>
        <p>
          The following common properties are defined:
        </p>
        <dl>
          <dt>lifetime-policy</dt>
          <dd>
            <p>
              The lifetime of a dynamically generated node.
            </p>
            <p>
              Definitionally, the lifetime will never be less than the lifetime of the link which
              caused its creation, however it is possible to extend the lifetime of dynamically
              created node using a lifetime policy. The value of this entry MUST be of a type
              which provides the <i>lifetime-policy</i> archetype. The following standard
              <i>lifetime-policies</i> are defined below: <xref name="delete-on-close"/>,
              <xref name="delete-on-no-links"/>, <xref name="delete-on-no-messages"/> or
              <xref name="delete-on-no-links-or-messages"/>.
            </p>
          </dd>
          <dt>supported-dist-modes</dt>
          <dd>
            <p>
              The distribution modes that the node supports.
            </p>
            <p>
              The value of this entry MUST be one or more symbols which are valid
              <i>distribution-mode</i>s. That is, the value MUST be of the same type as would be
              valid in a field defined with the following attributes:
            </p>
            <p>
              <i>type="symbol" multiple="true" requires="distribution-mode"</i>
            </p>
          </dd>
        </dl>
      </doc>
    </type>

    <type class="composite" name="delete-on-close" source="list" provides="lifetime-policy" label="lifetime of dynamic node scoped to lifetime of link which caused creation">
      <doc>
        <p>
          A node dynamically created with this lifetime policy will be deleted at the point that
          the link which caused its creation ceases to exist.
        </p>
      </doc>

      <descriptor name="amqp:delete-on-close:list" code="0x00000000:0x0000002b"/>

    </type>

    <type class="composite" name="delete-on-no-links" source="list" provides="lifetime-policy" label="lifetime of dynamic node scoped to existence of links to the node">
      <doc>
        <p>
          A node dynamically created with this lifetime policy will be deleted at the point that
          there remain no links for which the node is either the source or target.
        </p>
      </doc>

      <descriptor name="amqp:delete-on-no-links:list" code="0x00000000:0x0000002c"/>

    </type>

    <type class="composite" name="delete-on-no-messages" source="list" provides="lifetime-policy" label="lifetime of dynamic node scoped to existence of messages on the node">
      <doc>
        <p>
          A node dynamically created with this lifetime policy will be deleted at the point that
          the link which caused its creation no longer exists and there remain no messages at the
          node.
        </p>
      </doc>

      <descriptor name="amqp:delete-on-no-messages:list" code="0x00000000:0x0000002d"/>

    </type>

    <type class="composite" name="delete-on-no-links-or-messages" source="list" provides="lifetime-policy" label="lifetime of node scoped to existence of messages on or links to the node">
      <doc>
        <p>
          A node dynamically created with this lifetime policy will be deleted at the point that
          the there are no links which have this node as their source or target, and there remain
          no messages at the node.
        </p>
      </doc>

      <descriptor name="amqp:delete-on-no-links-or-messages:list" code="0x00000000:0x0000002e"/>

    </type>

  </section>

</amqp>
