<?xml version="1.0" ?>
<node name="/Channel_Interface_Messages"
  xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
  <tp:copyright>Copyright © 2008–2010 Collabora Ltd.</tp:copyright>
  <tp:copyright>Copyright © 2008–2010 Nokia Corporation</tp:copyright>
  <tp:license xmlns="http://www.w3.org/1999/xhtml">
    <p>This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.</p>

<p>This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.</p>

<p>You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
USA.</p>
  </tp:license>
  <interface
    name="org.freedesktop.Telepathy.Channel.Interface.Messages">
    <tp:requires interface="org.freedesktop.Telepathy.Channel.Type.Text"/>
    <tp:added version="0.17.16">(as stable API)</tp:added>

    <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
      <p>This interface extends the <tp:dbus-ref
          namespace='org.freedesktop.Telepathy.Channel.Type'>Text</tp:dbus-ref>
        interface to support more general messages, including:</p>

      <ul>
        <li>messages with attachments (like MIME multipart/mixed)</li>
        <li>groups of alternatives (like MIME multipart/alternative)</li>
        <li>delivery reports (which replace <tp:dbus-ref
            namespace="org.freedesktop.Telepathy.Channel.Type">Text.SendError</tp:dbus-ref>),
          addding support for protocols where the message content is not echoed
          back to the sender on failure and for receiving positive
          acknowledgements, as well as ensuring that incoming delivery reports
          are not lost if no client is handling the channel yet;</li>
        <li>any extra types of message we need in future</li>
      </ul>

      <p>Incoming messages, outgoing messages, and delivery reports are all
        represented as lists of <tp:type>Message_Part</tp:type> structures,
        with a format reminiscent of e-mail. Messages are sent by calling
        <tp:member-ref>SendMessage</tp:member-ref>; outgoing messages are
        announced to other clients which may be interested in the channel by
        the <tp:member-ref>MessageSent</tp:member-ref> signal. Incoming
        messages and delivery reports are signalled by
        <tp:member-ref>MessageReceived</tp:member-ref>, and are stored in the
        the <tp:member-ref>PendingMessages</tp:member-ref> property until
        acknowledged by calling <tp:dbus-ref
          namespace="org.freedesktop.Telepathy.Channel.Type">Text.AcknowledgePendingMessages</tp:dbus-ref>.
        Only the <tp:dbus-ref
          namespace="org.freedesktop.Telepathy.Client">Handler</tp:dbus-ref>
        for a channel should acknowledge messages; <tp:dbus-ref
          namespace="org.freedesktop.Telepathy.Client">Observer</tp:dbus-ref>s
        (such as loggers) and <tp:dbus-ref
          namespace="org.freedesktop.Telepathy.Client">Approver</tp:dbus-ref>s
        for the channel may listen for incoming messages, and send messages of their own, but SHOULD NOT acknowledge messages.</p>

      <tp:rationale>
        <p>If observers were allowed to acknowledge messages, then messages
          might have been acknowledged before the handler even got to see the
          channel, and hence could not be shown to the user.</p>
      </tp:rationale>

      <p>If this interface is present, clients that support it SHOULD
        listen for the <tp:member-ref>MessageSent</tp:member-ref> and
        <tp:member-ref>MessageReceived</tp:member-ref> signals, and
        ignore the <tp:dbus-ref
          namespace="org.freedesktop.Telepathy.Channel.Type.Text">Sent</tp:dbus-ref>,
        <tp:dbus-ref
          namespace="org.freedesktop.Telepathy.Channel.Type.Text">SendError</tp:dbus-ref>
        and <tp:dbus-ref
          namespace="org.freedesktop.Telepathy.Channel.Type.Text">Received</tp:dbus-ref>
        signals on the Text interface (which are guaranteed to duplicate
        signals from this interface).</p>

      <p>Although this specification supports formatted (rich-text)
        messages with unformatted alternatives, implementations SHOULD NOT
        attempt to send formatted messages until the Telepathy specification
        has also been extended to cover capability discovery for message
        formatting.</p>

      <tp:rationale>
        We intend to expose all rich-text messages as XHTML-IM, but on some
        protocols, formatting is an extremely limited subset of that format
        (e.g. there are protocols where foreground/background colours, font
        and size can be set, but only for entire messages).
        Until we can tell UIs what controls to offer to the user, it's
        unfriendly to offer the user controls that may have no effect.
      </tp:rationale>
    </tp:docstring>

    <property name="SupportedContentTypes" type="as" access="read"
      tp:name-for-bindings="Supported_Content_Types"
      tp:immutable="yes">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>A list of MIME types supported by this channel, with more preferred
          MIME types appearing earlier in the list. The list MAY include "*/*"
          to indicate that attachments with arbitrary MIME types can be sent.
          This list MUST NOT be empty, since all Messages implementations
          MUST accept messages containing a single "text/plain" part.</p>

        <p>Items in this list MUST be normalized to lower-case.</p>

        <p>Some examples of how this property interacts with the
          <tp:member-ref>MessagePartSupportFlags</tp:member-ref>:</p>

        <dl>
          <dt>A simple IM implementation: only plain text messages are
            allowed</dt>
          <dd>SupportedContentTypes = ['text/plain'],
            MessagePartSupportFlags = 0</dd>

          <dt>Formatted text with a plain text alternative is allowed (see the
            HTML interface draft)</dt>
          <dd>SupportedContentTypes = ['text/html', 'text/plain'],
            MessagePartSupportFlags = 0</dd>

          <dt>JPEG or PNG images may be sent, but without any attached
            text</dt>
          <dd>SupportedContentTypes = ['text/plain', 'image/jpeg',
            'image/png'], MessagePartSupportFlags = 0</dd>

          <dt>Unformatted text to which an optional JPEG or PNG image may be
            attached</dt>
          <dd>SupportedContentTypes = ['text/plain', 'image/jpeg',
            'image/png'], MessagePartSupportFlags = One_Attachment</dd>

          <dt>Formatted text to which arbitrarily many images may be
            attached</dt>
          <dd>SupportedContentTypes = ['text/html', 'text/plain', 'image/jpeg',
            'image/png', 'image/x-ms-bmp'], MessagePartSupportFlags =
            One_Attachment | Multiple_Attachments</dd>

          <dt>A full SIP implementation: arbitrary MIME messages are
            allowed</dt>
          <dd>SupportedContentTypes = ['*/*'], MessagePartSupportFlags =
            One_Attachment | Multiple_Attachments</dd>
        </dl>
      </tp:docstring>
    </property>

    <property name="MessageTypes" type="au"
      tp:type="Channel_Text_Message_Type[]" access="read"
      tp:name-for-bindings="Message_Types"
      tp:immutable="yes">
      <tp:added version="0.21.5">
        This supersedes <tp:dbus-ref namespace="ofdT.Channel.Type.Text"
          >GetMessageTypes</tp:dbus-ref>; fall back to that method for
        compatibility with older connection managers.
      </tp:added>
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>A list of message types which may be sent on this channel.</p>
      </tp:docstring>
    </property>

    <property name="MessagePartSupportFlags" type="u"
      tp:type="Message_Part_Support_Flags" access="read"
      tp:name-for-bindings="Message_Part_Support_Flags"
      tp:immutable="yes">
      <tp:docstring>
        Flags indicating the level of support for message parts on this
        channel.
      </tp:docstring>
    </property>

    <tp:flags name="Message_Part_Support_Flags"
      value-prefix="Message_Part_Support_Flag" type="u">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Flags indicating the level of support for message parts on this
          channel. They are designed such that setting more flags always
          implies that the channel has more capabilities.</p>

        <p>If no flags are set, this indicates that messages may contain
          a single message part whose content-type is any of the types
          from SupportedContentTypes, possibly with some alternatives.</p>

        <p>There is no flag indicating support for alternatives. This is
          because the SendMessage implementation can always accept messages
          containing alternatives, even if the underlying protocol does not,
          by deleting all alternatives except the first (most preferred)
          that is supported.</p>

        <tp:rationale>
          Each of the flags so far implies the previous flag, so we could
          have used a simple enumeration here; however, we've defined
          the message-part support indicator as a flag set for future
          expansion.
        </tp:rationale>

        <p>See <tp:member-ref>SupportedContentTypes</tp:member-ref> for some
          examples.</p>
      </tp:docstring>

      <tp:flag suffix="One_Attachment" value="1">
        <tp:docstring>
          <tp:member-ref>SendMessage</tp:member-ref> will accept messages
          containing a textual message body,
          plus a single attachment of any type listed in the
          SupportedContentTypes property. It does not make sense for this
          flag to be set if Message_Part_Support_Flag_Data_Only is not also set
          (because the connection manager can trivially provide an empty text
          part if necessary).
        </tp:docstring>
      </tp:flag>
      <tp:flag suffix="Multiple_Attachments" value="2">
        <tp:docstring>
          SendMessage will accept messages containing a textual message body,
          plus an arbitrary number of attachments of any type listed in the
          SupportedContentTypes property. It does not make sense for this
          flag to be set if Message_Part_Support_Flag_One_Attachment is not
          also set.
        </tp:docstring>
      </tp:flag>
    </tp:flags>

    <tp:mapping name="Message_Part" array-name="Message_Part_List"
      array-depth="2">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Part of a message's content. In practice, this mapping never
          appears in isolation: incoming messages are represented by a list of
          <tp:type>Message_Part</tp:type> mappings in the
          <tp:member-ref>MessageReceived</tp:member-ref> signal, and outgoing
          messages are passed to <tp:member-ref>SendMessage</tp:member-ref> as
          a list of these mappings.</p>

        <p>The first part of the message contains "headers", which refer
          to the entire message. The second and subsequent parts contain the
          message's content, including plain text, formatted text and/or
          attached files. Well-known keys for the header and body parts are
          defined by the <tp:type>Message_Header_Key</tp:type> and
          <tp:type>Message_Body_Key</tp:type> types, respectively.  It is an
          error for a connection manager to put keys referring to the message
          as a whole in the second or subsequent Message_Part, or keys intended
          for body parts in the first Message_Part; clients MUST recover from
          this error by ignoring these mis-placed keys.</p>

        <tp:rationale>
          <p>Instead of representing messages as aa{sv} where the first
            dictionary is special (a dictionary of headers), we could have
            used a signature like (a{sv}aa{sv}) to separate out the headers
            and the body parts.</p>

          <p>However, this would make access to the messages more awkward.
            In Python, the syntax for access to a header field would remain
            <code>message[0]['message-type']</code>, but access to a body
            field in the second body part would change from
            <code>message[2]['content'] to message[1][1]['content']</code>. In
            GLib, the message would change from being a
            <code>GPtrArray(GHashTable)</code> to being a
            <code>GValueArray(GHashTable, GPtrArray(GHashTable))</code> which
            is rather inconvenient to dereference.</p>
        </tp:rationale>

        <p>In any group of parts with the same non-empty value for the
          <tt>alternative</tt> key (which represent alternative versions of the
          same content), more faithful versions of the intended message MUST
          come before less faithful versions (note that this order is the
          opposite of MIME <tt>multipart/alternative</tt> parts). Clients
          SHOULD display the first alternative that they understand.</p>

        <tp:rationale>
          <p>Specifying the preference order means that if the underlying
            protocol doesn't support alternatives, the CM can safely delete
            everything apart from the first supported alternative when
            sending messages.</p>

          <p>The order is the reverse of MIME because MIME's rationale for
            placing the "plainest" part first (legibility in pre-MIME UAs)
            does not apply to us, and placing the most preferred part
            first simplifies display (a client can iterate the message
            in order, display the first alternative that it understands,
            and skip displaying all subsequent parts with the same
            "alternative" key).</p>
        </tp:rationale>

        <p>Clients SHOULD present all parts that are not redundant
          alternatives in the order they appear in this array, possibly
          excluding parts that are referenced by another displayed part.
          It is implementation-specific how the parts are presented to the
          user.</p>

        <tp:rationale>
          <p>This allows CMs to assume that all parts are actually shown to
            the user, even if they are not explicitly referenced - we do
            not yet recommend formatted text, and there is no way for
            plain text to reference an attachment since it has no concept of
            markup or references. This also forces clients to do something
            sensible with messages that consist entirely of "attachments",
            with no "body" at all.</p>

          <p>For instance, when displaying the above example, a client that
            understands the HTML part should display the JPEG image once,
            between the two lines "Here is a photo of my cat:" and
            "Isn't it cute?"; it may additionally present the image in some
            way for a second time, after "Isn't it cute?", or may choose
            not to.</p>

          <p>A client that does not understand HTML, displaying the same
            message, should display the plain-text part, followed by the JPEG
            image.</p>
        </tp:rationale>

        <p>Connection managers, clients and extensions to this specification
          SHOULD NOT include <tp:type>Handle</tp:type>s as values in a
          Message_Part, except for <code>message-sender</code> in the
          header.</p>

        <tp:rationale>
          <p>Reference-counting handles in clients becomes problematic if
            the channel proxy cannot know whether particular map values
            are handles or not.</p>
        </tp:rationale>

        <h4>Example messages</h4>

        <p>A rich-text message, with an embedded image, might be represented
          as:</p>

          <pre>
[
  {
    'message-token': '9de9546a-3400-4419-a505-3ea270cb834c',
    'message-sender': 42,
    'message-sent': 1210067943,
    'message-received': 1210067947,
    'message-type': 0,              # = Channel_Text_Message_Type_Normal
    'pending-message-id': 437,
  },
  { 'alternative': 'main',
    'content-type': 'text/html',
    'content': 'Here is a photo of my cat:&lt;br /&gt;' +
               '&lt;img src="cid:catphoto" alt="lol!" /&gt;' +
               '&lt;br /&gt;Isn't it cute?',
  },
  { 'alternative': 'main',
    'content-type': 'text/plain',
    'content': 'Here is a photo of my cat:\n[IMG: lol!]\nIsn't it cute?',
  },
  { 'identifier': 'catphoto',
    'content-type': 'image/jpeg',
    'size': 101000,
    'needs-retrieval': True,
  },
]</pre>

        <p>telepathy-ring, Nokia's GSM connection manager, represents vCards
          sent via SMS as:</p>

        <pre>
[
  {
    'message-token': '9de9546a-3400-4419-a505-3ea270cb834c',
    'message-sender': 42,
    'message-sent': 1210067943,
    'message-received': 1210067947,
    'message-type': 0,              # = Channel_Text_Message_Type_Normal
    'pending-message-id': 437,
  },
  { 'content-type': 'text/x-vcard',
    'content': [ 0x66, 0x69, 0x71, ...], # vCard data as an array of bytes
  },
]</pre>

        <h3>Delivery reports</h3>

        <div>
          <p>Delivery reports are also represented as messages with the
            <tt>message-type</tt> header mapping to
            <tp:type>Channel_Text_Message_Type</tp:type> Delivery_Report.
            Delivery reports SHOULD contain the <tt>message-sender</tt> header,
            mapping to the intended recipient of the original message, if
            possible; other headers specific to delivery reports are defined by
            the <tp:type>Delivery_Report_Header_Key</tp:type> type. The second
            and subsequent parts, if present, are a human-readable report from
            the IM service.</p>

          <p>For backwards- and forwards-compatibility, whenever a delivery
            error report is signalled—that is, with <tt>delivery-status</tt>
            mapping to <tp:type>Delivery_Status</tp:type> Temporarily_Failed or
            Permanently_Failed—<tp:dbus-ref
              namespace="org.freedesktop.Telepathy.Channel.Type.Text">SendError</tp:dbus-ref>
            SHOULD also be emitted; whenever <tp:dbus-ref
              namespace="org.freedesktop.Telepathy.Channel.Type.Text">SendError</tp:dbus-ref>
            is emitted, a delivery report MUST also be signalled.
            Delivery report messages on this interface MUST be represented in
            emissions of <tp:dbus-ref
              namespace="org.freedesktop.Telepathy.Channel.Type.Text">Received</tp:dbus-ref>
            as messages with the Non_Text_Content
            <tp:type>Channel_Text_Message_Flags</tp:type>; clients which
            understand this interface SHOULD ignore the SendError signal in
            favour of listening for delivery reports, as mentioned in the
            introduction.</p>

          <p>The result of attempting to send delivery reports using
            <tp:member-ref>SendMessage</tp:member-ref> is currently
            undefined.</p>

          <h4>Example delivery reports</h4>

          <dl>
            <dt>A minimal delivery report indicating permanent failure of the
              sent message whose token was
              <code>b9a991bd-8845-4d7f-a704-215186f43bb4</code> for an unknown
              reason</dt>
            <dd><pre>
[{
# header
'message-sender': 123,
'message-type': Channel_Text_Message_Type_Delivery_Report,
'delivery-status': Delivery_Status_Permanently_Failed,
'delivery-token': 'b9a991bd-8845-4d7f-a704-215186f43bb4',
}
# no body
]</pre></dd>

            <dt>A delivery report where the failed message is echoed back to the
              sender rather than being referenced by ID, and the failure reason
              is that this protocol cannot send messages to offline contacts
              such as the contact with handle 123</dt>
            <dd><pre>
[{ # header
'message-sender': 123,
'message-type': Channel_Text_Message_Type_Delivery_Report,
'delivery-status': Delivery_Status_Temporarily_Failed,
'delivery-error': Channel_Text_Send_Error_Offline,
'delivery-echo':
    [{ # header of original message
    'message-sender': 1,
    'message-sent': 1210067943,
    },
    { # body of original message
    'content-type': 'text/plain',
    'content': 'Hello, world!',
    }]
  ],

# no body
]</pre></dd>

            <dt>A maximally complex delivery report: the server reports a
              bilingual human-readable failure message because the user sent
              a message "Hello, world!" with token
              <code>b9a991bd-8845-4d7f-a704-215186f43bb4</code> to a contact
              with handle 123, but that handle represents a contact who does not
              actually exist</dt>
            <dd><pre>
[{ # header
'message-sender': 123,
'message-type': Channel_Text_Message_Type_Delivery_Report,
'delivery-status': Delivery_Status_Permanently_Failed,
'delivery-error': Channel_Text_Send_Error_Invalid_Contact,
'delivery-token': 'b9a991bd-8845-4d7f-a704-215186f43bb4',
'delivery-echo':
    [{ # header of original message
    'message-sender': 1,
    'message-sent': 1210067943,
    },
    { # body of original message
    'content-type': 'text/plain',
    'content': 'Hello, world!',
    }]
  ],
},
{ # message from server (alternative in English)
'alternative': '404',
'content-type': 'text/plain',
'lang': 'en',
'content': 'I have no contact with that name',
},
{ # message from server (alternative in German)
'alternative': '404'.
'content-type': 'text/plain',
'lang': 'de',
'content', 'Ich habe keinen Kontakt mit diesem Namen',
}
]</pre></dd>

            <dt>A minimal delivery report indicating successful delivery
              of the sent message whose token was
              <code>b9a991bd-8845-4d7f-a704-215186f43bb4</code></dt>
            <dd><pre>
[{
# header
'message-sender': 123,
'message-type': Channel_Text_Message_Type_Delivery_Report,
'delivery-status': Delivery_Status_Delivered,
'delivery-token': 'b9a991bd-8845-4d7f-a704-215186f43bb4',
}
# no body
]</pre></dd>

          </dl>

        </div>
      </tp:docstring>

      <tp:member name="Key" type="s">
        <tp:docstring>
          A key, which SHOULD be one of the well-known keys specified by
          <tp:type>Message_Header_Key</tp:type>,
          <tp:type>Message_Body_Key</tp:type> or
          <tp:type>Delivery_Report_Header_Key</tp:type> if possible.
        </tp:docstring>
      </tp:member>

      <tp:member name="Value" type="v">
        <tp:docstring>
          The value corresponding to the given key, which SHOULD be one of the
          specified types for well-known keys.
        </tp:docstring>
      </tp:member>
    </tp:mapping>

    <tp:simple-type type="s" name="Message_Header_Key">
      <tp:added version="0.19.8"/>
      <tp:changed version="0.21.5">
        Removed <tt>protocol-token</tt>—which had never been implemented—and
        respecified <tt>message-token</tt> not to have unimplementable
        uniqueness guarantees.
      </tp:changed>

      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Well-known keys for the first <tp:type>Message_Part</tp:type> of a
          message, which contains metadata about the message as a whole, along
          with the corresponding value types. Some keys make sense for both
          incoming and outgoing messages, while others are only meaningful for
          one or the other.</p>

          <dl>
            <dt>message-token (s -
              <tp:type>Protocol_Message_Token</tp:type>)
            </dt>
            <dd>
              <p>An opaque identifier for the message, as used by the
                underlying protocol. For outgoing messages, this SHOULD be
                globally unique; for incoming messages, this is <em>not</em>
                guaranteed to uniquely identify a message, <em>even within the
                scope of a single channel or contact</em>; the only guarantee
                made is that two messages with different <tt>message-token</tt>
                headers are different messages.</p>

              <p>Clients wishing to determine whether a new message with the
                <tt>scrollback</tt> header matches a previously-logged message
                with the same <tt>message-token</tt> SHOULD compare the
                message's sender, contents, <tt>message-sent</tt> or
                <tt>message-received</tt> timestamp, etc. Note that, in XMPP,
                the server only supplies a timestamp for scrollback messages,
                not for messages received while you are in a room; thus,
                non-scrollback messages will lack a <tt>message-sent</tt>
                timestamp.</p>

              <tp:rationale>
                <p>In practice, most protocols do not provide globally-unique
                  identifiers for messages. Connection managers, being
                  stateless, do not have the necessary information — namely, IM
                  logs — to generate reliable unique tokens for messages.</p>

                <p>For instance, some XMPP clients (including Gabble) stamp
                  messages they send with unique identifiers, but others number
                  outgoing messages in a conversation from 1 upwards.</p>
              </tp:rationale>
            </dd>

            <dt>message-sent (x - <tp:type>Unix_Timestamp64</tp:type>)</dt>
            <dd>The time the message was sent (if unavailable, the time
              it arrived at a central server MAY be used). Omitted if no
              reasonable approximation is available; SHOULD always be present
              on outgoing messages.</dd>

            <dt>message-received (x - <tp:type>Unix_Timestamp64</tp:type>)</dt>
            <dd>The time the message was received locally. SHOULD always
              be present.</dd>

            <dt>message-sender (u - <tp:type>Contact_Handle</tp:type>)</dt>
            <dd>The contact who sent the message. If 0 or omitted, the contact
              who sent the message could not be determined.</dd>

            <dt>message-sender-id (s)</dt>
            <dd>The identifier of the contact who sent the message,
              i.e. the result of calling <tp:dbus-ref
                namespace="ofdT.Connection">InspectHandles</tp:dbus-ref>
              on <code>message-sender</code>. If omitted, clients MUST
              fall back to looking at <code>message-sender</code>.</dd>

            <dt>sender-nickname (s)</dt>
            <dd>The nickname chosen by the sender of the message, which can be
              different for each message in a conversation.</dd>

            <dt>message-type (u - <tp:type>Channel_Text_Message_Type</tp:type>)
            </dt>
            <dd>The type of message; if omitted,
              Channel_Text_Message_Type_Normal MUST be assumed. MAY
              be omitted for normal chat messages.</dd>

            <dt>supersedes (s – <tp:type>Protocol_Message_Token</tp:type>)</dt>
            <dd>If present, this message supersedes a previous message,
              identified by its <tt>message-token</tt> header. The user
              interface MAY, for example, choose to replace the superseded
              message with this message, or grey out the superseded message.

              <tp:rationale>Skype, for example, allows the user to amend
                messages they have already sent (to correct typos,
                etc.).</tp:rationale>

              Connection Managers SHOULD represent repeatedly edited messages
              in the following form:
              <pre>
                message {token = a};
                message {token = b, supersedes = a};
                message {token = c, supersedes = a};
              </pre>

              <tp:rationale>The alternative form is:
                <pre>
                  message {token = a};
                  message {token = b, supersedes = a};
                  message {token = c, supersedes = b};
                </pre>
                but it is more difficult to implement in UIs/loggers, and it
                breaks irrecoverably if message b is lost. If a CM is forced
                to use this form, it should be tested extensively for
                interoperability with existing clients.
                </tp:rationale>

              Clients should deal gracefully if the original message gets
              lost, but one or more corrections to it get through:
              <pre>
                message {token = x} gets lost;
                message {token = y, supersedes = x};
                message {token = z, supersedes = x};
              </pre>

              <tp:rationale>This is the form that CMs will use to mean "I know
                that this message was edited, but I don't know what it
                originally said." It is often in the interests of the
                remote side for message x to be lost (e.g. to hide
                embarassing mistakes or sensitive information) so it might not
                be possible to retrieve it (even on protocols with reliable
                message-delivery guarantees).</tp:rationale></dd>

            <dt>original-message-sent (x - <tp:type>Unix_Timestamp64</tp:type>)</dt>
            <dd>The <tt>message-sent</tt> header of the message that this
              one supersedes.
              This key should only be present if <tt>supersedes</tt> is also
              present. It MAY be used as a hint to help clients locate the
              original message in its logs. If present, comparing the tuple
              (original-message-sent, supersedes) with (message-sent,
              message-token) SHOULD be enough to uniquely
              identify the original message.</dd>

            <dt>original-message-received (x - <tp:type>Unix_Timestamp64</tp:type>)</dt>
            <dd>The <tt>message-received</tt> header of the message that this
              one supersedes.
              This key should only be present if <tt>supersedes</tt> is also
              present. It MAY be used as a hint in a similar way to
              <tt>original-message-sent</tt>.</dd>

            <dt>pending-message-id (u - <tp:type>Message_ID</tp:type>)</dt>
            <dd>The incoming message ID. This MUST NOT be present on outgoing
              messages. Clients SHOULD NOT store this key - it is only valid
              for as long as the message remains unacknowledged.</dd>

            <dt>interface (s - <tp:type>DBus_Interface</tp:type>)</dt>
            <dd>This message is specific to the given interface, which is
              neither Text nor Messages. It SHOULD be ignored if that
              interface is not supported. (Note that an 'interface' key
              can also appear on the second and subsequent parts, where
              it indicates that that part (only) should be ignored if
              unsupported.)</dd>

            <dt>scrollback (b)</dt>
            <dd>If present and true, the incoming message was part of a
              replay of message history (this matches the Scrollback flag in
              <tp:type>Channel_Text_Message_Flags</tp:type>). This flag
              does not make sense on outgoing messages and SHOULD NOT
              appear there.</dd>

            <dt>rescued (b)</dt>
            <dd>If present and true, the incoming message has been seen in
              a previous channel during the lifetime of the Connection,
              but had not been acknowledged when that channel closed, causing
              an identical channel (in which the message now appears) to open.
              This matches the Rescued flag in
              <tp:type>Channel_Text_Message_Flags</tp:type>; it
              does not make sense on outgoing messages, and SHOULD NOT
              appear there.</dd>
          </dl>

      </tp:docstring>
    </tp:simple-type>

    <tp:simple-type type="s" name="Message_Body_Key">
      <tp:added version="0.19.8"/>
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Well-known keys for the second and subsequent
          <tp:type>Message_Part</tp:type>s of a message, which contain the
          message content, along with the corresponding value types.</p>

          <dl>
            <dt>identifier (s —
              <tp:type>Protocol_Content_Identifier</tp:type>)</dt>
            <dd>An opaque identifier for this part.
              Parts of a message MAY reference other parts by treating
              this identifier as if it were a MIME Content-ID and using
              the cid: URI scheme.</dd>

            <dt>alternative (s)</dt>
            <dd>
              <p>If present, this part of the message is an alternative for
                all other parts with the same value for "alternative".
                Clients SHOULD only display one of them (this is expected to
                be used for XHTML messages in a future version of this
                specification).</p>

              <p>If omitted, this part is not an alternative for any other
                part.</p>

              <p>Parts of a message MAY reference the group of alternatives
                as a whole (i.e. a reference to whichever of them is chosen)
                by treating this identifier as if it were the MIME Content-ID
                of a multipart/alternative part, and using the cid: URI
                scheme.</p>
            </dd>

            <dt>content-type (s)</dt>
            <dd>
              <p>The MIME type of this part. See the documentation
                for <tp:member-ref>MessageReceived</tp:member-ref> and
                <tp:member-ref>MessageSent</tp:member-ref> for notes on the
                special status of "text/plain" parts.</p>

              <p>Connection managers MUST NOT signal parts without a
                'content-type' key; if a protocol provides no way to determine
                the MIME type, the connection manager is responsible for
                guessing it, but MAY fall back to "text/plain" for text and
                "application/octet-stream" for non-text.</p>

              <p>Clients MUST ignore parts without a 'content-type' key, which
                are reserved for future expansion.</p>

              <p>When sending messages, clients SHOULD normalize the
                content-type to lower case, but connection managers SHOULD NOT
                rely on this. When signalling sent or received messages,
                connection managers MUST normalize the content-type to lower
                case.</p>
            </dd>

            <dt>lang (s)</dt>
            <dd>The natural language of this part, identified by a
              RFC 3066 language tag.

              <tp:rationale>
                XMPP allows alternative-selection by language as well as
                by content-type.
              </tp:rationale>
            </dd>

            <dt>size (u)</dt>
            <dd>The size in bytes (if needs-retrieval is true, this MAY be an
              estimated or approximate size). SHOULD be omitted if 'content'
              is provided.

              <tp:rationale>
                There's no point in providing the size if you're already
                providing all the content.
              </tp:rationale>
            </dd>

            <dt>thumbnail (b)</dt>
            <dd>
              <p>This part is a thumbnail. To represent an image together with
                its thumbnail in a single message, there should be one part for
                the full image followed by a part for the thumbnail (following
                the “more complete versions first” requirement), with the same
                'alternative' value. For example:</p>

              <pre>
[ ... ,
  { 'alternative': 'catphoto',
    'content-type': 'image/jpeg',
    'size': 150000,
    'content': [0xFF, 0xD8, ... 0xFF 0xD9],
  },
  { 'alternative': 'catphoto',
    'content-type': 'image/jpeg'
    'size': 1024,
    'thumbnail': True,
    'content': [0xFF, 0xD8, ... 0xFF 0xD9],
  },
  ...
]</pre>
            </dd>

            <dt>needs-retrieval (b)</dt>
            <dd>If false or omitted, the connection
              manager already holds this part in memory. If present and true,
              this part must be retrieved on demand (like MIME's
              <tt>message/external-body</tt>) by a mechanism to be defined later.

              <tp:rationale>The mechanism was meant to be
                <tp:member-ref>GetPendingMessageContent</tp:member-ref>, but
                that didn't work out. It's worth leaving the header in in
                preparation for a future mechanism.
              </tp:rationale>
            </dd>

            <dt>truncated (b)</dt>
            <dd>The content available via the 'content' key has been truncated
              by the server or connection manager (equivalent to
              Channel_Text_Message_Flag_Truncated in the Text interface).
            </dd>

            <dt>content (s or ay)</dt>
            <dd>The part's content, if it is available and
              sufficiently small to include here (implies that
              'needs-retrieval' is false or omitted). Otherwise, omitted.
              If the part is human-readable text or HTML, the value for this
              key MUST be a UTF-8 string (D-Bus signature 's').
              If the part is not text, the value MUST be a byte-array
              (D-Bus signature 'ay'). If the part is a text-based format
              that is not the main body of the message (e.g. an iCalendar
              or an attached XML document), the value SHOULD be a UTF-8 string,
              transcoding from another charset to UTF-8 if necessary, but
              MAY be a byte-array (of unspecified character set) if
              transcoding fails or the source charset is not known.</dd>

              <!-- FIXME: "sufficiently small to include" is not currently
              defined; we should add some API so clients can tell the
                CM how large a message it should emit in the signal.-->

            <dt>interface (s - <tp:type>DBus_Interface</tp:type>)</dt>
            <dd>This part is specific to the given interface, which is
              neither Text nor Messages. It SHOULD be ignored if that
              interface is not supported. (Note that an 'interface' key
              can also appear on the first part, where it indicates that the
              entire message should be ignored if unsupported.)</dd>
          </dl>
      </tp:docstring>
    </tp:simple-type>

    <tp:simple-type type="s" name="Delivery_Report_Header_Key">
      <tp:added version="0.19.8"/>
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Well-known keys for the first <tp:type>Message_Part</tp:type> of a
          delivery report, along with the corresponding value types. Some of
          these are special-cases of headers defined by
          <tp:type>Message_Header_Key</tp:type>.</p>

          <dl>
            <dt>message-sender (u - <tp:type>Contact_Handle</tp:type>, as
              defined by <tp:type>Message_Header_Key</tp:type>)</dt>
            <dd>MUST be the intended recipient of the original message, if
              available (zero or omitted if the intended recipient is
              unavailable or is not a contact, e.g. a chatroom), even if the
              delivery report actually came from an intermediate server.</dd>

            <dt>message-type (u - <tp:type>Channel_Text_Message_Type</tp:type>,
              as defined by <tp:type>Message_Header_Key</tp:type>)</dt>
            <dd>MUST be Channel_Text_Message_Type_Delivery_Report.</dd>

            <dt>delivery-status (u - <tp:type>Delivery_Status</tp:type>)</dt>
            <dd>The status of the message. All delivery reports MUST contain
              this key in the first Message_Part.</dd>

            <dt>delivery-token (s - <tp:type>Protocol_Message_Token</tp:type>)</dt>

            <dd>
              <p>An identifier for the message to which this delivery report
                refers. MUST NOT be an empty string. Omitted if not
                available.</p>

              <p>Clients may match this against the token produced by the
                SendMessage method and MessageSent signal. A status report
                with no token could match any sent message, and a sent
                message with an empty token could match any status report.
                If multiple sent messages match, clients SHOULD use some
                reasonable heuristic.</p>

              <tp:rationale>
                In an ideal world, we could unambiguously match reports
                against messages; however, deployed protocols are not ideal,
                and not all reports and messages can be matched.
              </tp:rationale>
            </dd>

            <dt>delivery-error (u -
              <tp:type>Channel_Text_Send_Error</tp:type>)</dt>
            <dd>
              The reason for the failure. MUST be omitted if this was a
              successful delivery; SHOULD be omitted if it would be
              Channel_Text_Send_Error_Unknown.
            </dd>

            <dt>delivery-dbus-error (s -
              <tp:type>DBus_Error_Name</tp:type>)</dt>
            <dd>
              The reason for the failure, specified as a (possibly
              implementation-specific) D-Bus error. MUST be omitted if this was
              a successful delivery. If set, the 'delivery-error' key SHOULD be
              set to the closest available value.
            </dd>

            <dt>delivery-error-message (s)</dt>
            <dd>
              Debugging information on why the message could not be delivered.
              MUST be omitted if this was a successful delivery; MAY always be
              omitted.
            </dd>

            <dt>delivery-echo (aa{sv} - <tp:type>Message_Part[]</tp:type>)</dt>
            <dd>
              <p>The message content, as defined by the Messages interface.
                Omitted if no content is available. Content MAY have been
                truncated, message parts MAY have been removed, and message
                parts MAY have had their content removed (i.e. the message part
                metadata is present, but the 'content' key is not).</p>

              <tp:rationale>
                Some protocols, like XMPP, echo the failing message back to
                the sender. This is sometimes the only way to match it
                against the sent message, so we include it here.
              </tp:rationale>
            </dd>

          </dl>
      </tp:docstring>
    </tp:simple-type>

    <tp:simple-type type="u" name="Message_Part_Index"
      array-name="Message_Part_Index_List">
      <tp:deprecated version="0.21.5">
        This type is only used by
        <tp:member-ref>GetPendingMessageContent</tp:member-ref>, which is
        unimplemented and deprecated.
      </tp:deprecated>
      <tp:added version="0.17.17"/>
      <tp:docstring>
        The index of a message part within a message.
      </tp:docstring>
    </tp:simple-type>

    <tp:mapping name="Message_Part_Content_Map">
      <tp:added version="0.17.17"/>
      <tp:deprecated version="0.21.5">
        This structure is only used by
        <tp:member-ref>GetPendingMessageContent</tp:member-ref>, which is
        unimplemented and deprecated.
      </tp:deprecated>
      <tp:docstring>
        A mapping from message part indexes to their content, as returned by
        <tp:member-ref>GetPendingMessageContent</tp:member-ref>.
      </tp:docstring>

      <tp:member type="u" tp:type="Message_Part_Index" name="Part">
        <tp:docstring>
          Indexes into the array of <tp:type>Message_Part</tp:type>s that
          represents a message. The "headers" part (which is not a valid
          argument to GetPendingMessageContent) is considered to be part 0,
          so the valid part numbers start at 1 (for the second message part).
        </tp:docstring>
      </tp:member>

      <tp:member type="v" name="Content">
        <tp:docstring>
          The message part's content. The variant MUST contain either type
          's' or 'ay' (UTF-8 text string, or byte array), following the
          same rules as for the value of the 'content' key in
          the <tp:type>Message_Part</tp:type> mappings.
        </tp:docstring>
      </tp:member>
    </tp:mapping>

    <tp:simple-type type="s" name="Protocol_Message_Token"
                    array-name="Protocol_Message_Token_List">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>An opaque token used to identify messages in the underlying.
          protocol. As a special case, the empty string indicates that there
          is no particular identification for a message.</p>

        <p>CM implementations SHOULD use an identifier expected to be unique,
          such as a UUID, for outgoing messages (if possible).</p>

        <p>Some protocols can only track a limited number of messages
          in a small message-ID space (SMS messages are identified by a single
          byte), and some implementations send non-unique identifiers (some
          XMPP clients use very simple message IDs, such as an incrementing
          integer that resets to 1 at the beginning of each connection). As a
          result, clients MUST NOT assume that protocol tokens will not be
          re-used.</p>

        <p>In particular, clients SHOULD use a heuristic to assign delivery
          reports to messages, such as matching on message content or
          timestamp (if available), or assuming that the delivery report
          refers to the most recent message with that ID.</p>
      </tp:docstring>
    </tp:simple-type>

    <tp:simple-type name="Protocol_Content_Identifier" type="s">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>A protocol-specific identifier for a blob of content, as used for
          the <tt>identifier</tt> key in a <tp:type>Message_Part</tp:type>. The
          same identifier MAY be re-used if the same content, byte-for-byte,
          appears as a part of several messages.</p>

        <tp:rationale>
          <p>On XMPP, these identifiers might be Content-IDs for custom
            smileys implemented using <a
              href="http://xmpp.org/extensions/xep-0231.html">XEP-0232 Bits of
            Binary</a>; the same smiley might well appear in multiple
            messages.</p>
        </tp:rationale>
      </tp:docstring>
    </tp:simple-type>

    <method name="SendMessage" tp:name-for-bindings="Send_Message">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Submit a message to the server for sending.
          If this method returns successfully, the message has been submitted
          to the server and the <tp:member-ref>MessageSent</tp:member-ref>
          signal is emitted. A corresponding
          <tp:dbus-ref
            namespace="org.freedesktop.Telepathy.Channel.Type.Text">Sent</tp:dbus-ref>
          signal on the Text interface MUST also be emitted.</p>

        <p>This method MUST return before the MessageSent signal is
          emitted.</p>

        <tp:rationale>
          <p>This means that the process sending the message is the first
            to see the <tp:type>Protocol_Message_Token</tp:type>, and can
            relate the message to the corresponding
            <tp:member-ref>MessageSent</tp:member-ref> signal by comparing
            message tokens (if supported by the protocol).</p>
        </tp:rationale>

        <p>If this method fails, message submission to the server has failed
          and no signal on this interface (or the Text interface) is
          emitted.</p>

        <p>If this method succeeds, message submission to the server has
          succeeded, but the message has not necessarily reached its intended
          recipient. If a delivery failure is detected later, this is
          signalled by receiving a message whose <code>message-type</code>
          header maps to
          <tp:value-ref type="Channel_Text_Message_Type">Delivery_Report</tp:value-ref>.
          Similarly, if delivery is detected to have been successful
          (which is not possible in all protocols), a successful delivery
          report will be signalled.</p>
      </tp:docstring>

      <arg direction="in" type="aa{sv}" tp:type="Message_Part[]"
        name="Message">
        <tp:docstring>
          The message content, including any attachments or alternatives.
          This MUST NOT include the following headers, or any others that
          do not make sense for a client to specify:
          <code>message-sender</code>, <code>message-sender-id</code>,
          <code>message-sent</code>, <code>message-received</code>,
          <code>pending-message-id</code>.
        </tp:docstring>
      </arg>
      <arg direction="in" name="Flags" type="u"
        tp:type="Message_Sending_Flags">
        <tp:docstring>
          Flags affecting how the message is sent. The channel MAY ignore some
          or all flags, depending on
          <tp:member-ref>DeliveryReportingSupport</tp:member-ref>; the flags
          that were handled by the CM are provided in
          <tp:member-ref>MessageSent</tp:member-ref>.
        </tp:docstring>
      </arg>

      <arg direction="out" type="s" tp:type="Protocol_Message_Token"
        name="Token">
        <tp:docstring>
          An opaque token used to match any incoming delivery or failure
          reports against this message, or an empty string if the message
          is not readily identifiable.
        </tp:docstring>
      </arg>

      <tp:possible-errors>
        <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
          <tp:docstring>
            The requested message is malformed and cannot be sent.
          </tp:docstring>
        </tp:error>
        <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
        <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
        <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
      </tp:possible-errors>
    </method>

    <tp:flags name="Message_Sending_Flags" value-prefix="Message_Sending_Flag"
      type="u">
      <tp:docstring>
        Flags altering the way a message is sent. The "most usual" action
        should always be to have these flags unset. Some indication of which
        flags are supported is provided by the
        <tp:member-ref>DeliveryReportingSupport</tp:member-ref> property.
      </tp:docstring>

      <tp:flag suffix="Report_Delivery" value="1">
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>Provide a successful delivery report if possible, even if this is
            not the default for this protocol. Ignored if delivery reports are
            not possible on this protocol.</p>

          <tp:rationale>
            <p>In some protocols, like XMPP, it is not conventional to request
              or send positive delivery notifications.</p>
          </tp:rationale>

          <p>Delivery failure reports SHOULD always be sent, but if this flag
            is present, the connection manager MAY also try harder to obtain
            failed delivery reports or allow them to be matched to outgoing
            messages.</p>
        </tp:docstring>
      </tp:flag>

      <tp:flag suffix="Report_Read" value="2">
        <tp:added version="0.19.9"/>
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>Provide a delivery report when the message is read by the
            recipient, even if this is not the default for this protocol.
            Ignored if read reports are not possible on this protocol.</p>
        </tp:docstring>
      </tp:flag>

      <tp:flag suffix="Report_Deleted" value="4">
        <tp:added version="0.19.9"/>
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>Provide a delivery report when the message is deleted by the
            recipient, even if this is not the default for this protocol.
            Ignored if such reports are not possible on this protocol.</p>
        </tp:docstring>
      </tp:flag>
    </tp:flags>

    <signal name="MessageSent" tp:name-for-bindings="Message_Sent">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Signals that a message has been submitted for sending. This
          MUST be emitted exactly once per emission of the <tp:dbus-ref
            namespace="org.freedesktop.Telepathy.Channel.Type.Text">Sent</tp:dbus-ref>
          signal on the Text interface, for backwards-compatibility; clients
          SHOULD ignore the latter if this interface is present, as mentioned
          in the introduction.</p>

        <p>This SHOULD be emitted as soon as the CM determines it's
          theoretically possible to send the message (e.g. the parameters are
          supported and correct).</p>

        <tp:rationale>
          <p>This signal allows a process that is not the caller of
            SendMessage to log sent messages.</p>
        </tp:rationale>
      </tp:docstring>

      <arg type="aa{sv}" tp:type="Message_Part[]" name="Content">
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>The message content (see <tp:type>Message_Part</tp:type> for full
            details). If the message that was passed to
            <tp:member-ref>SendMessage</tp:member-ref> has a formatted text
            part that the connection manager recognises, but no
            <tt>text/plain</tt> alternative, the CM MUST use the formatted text
            part to generate a <tt>text/plain</tt> alternative which is also
            included in this signal argument.</p>

          <p>The connection manager SHOULD include the
            <code>message-sender</code>, <code>message-sender-id</code> and
            <code>message-sent</code> headers in the representation of the
            message that is signalled here. If the channel has
            channel-specific handles, the <code>message-sender</code> and
            <code>message-sender-id</code> SHOULD reflect the sender that
            other contacts will see.</p>

          <p>If the connection manager can predict that the message will be
            altered during transmission, this argument SHOULD reflect what
            other contacts will receive, rather than being a copy of the
            argument to SendMessage (if the message is truncated,
            formatting or alternatives are dropped, etc., then the edited
            version SHOULD appear in this signal).</p>
        </tp:docstring>
      </arg>

      <arg name="Flags" type="u" tp:type="Message_Sending_Flags">
        <tp:docstring>
          <p>Flags affecting how the message was sent.  The flags might be a
            subset of those passed to SendMessage if the caller requested
            unsupported flags.</p>
        </tp:docstring>
      </arg>

      <arg name="Message_Token" type="s" tp:type="Protocol_Message_Token">
        <tp:docstring>
          An opaque token used to match any incoming delivery or failure
          reports against this message, or an empty string if the message
          is not readily identifiable.
        </tp:docstring>
      </arg>
    </signal>

    <property name="PendingMessages" type="aaa{sv}" access="read"
      tp:type="Message_Part[][]" tp:name-for-bindings="Pending_Messages">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>A list of incoming messages that have neither been acknowledged nor
          rejected. This list is a more detailed version of the one returned
          by <tp:dbus-ref
            namespace="org.freedesktop.Telepathy.Channel.Type">Text.ListPendingMessages</tp:dbus-ref>,
          and contains the same messages, uniquely identified by the same
          pending message IDs. Its items can be removed using
          <tp:dbus-ref
            namespace="org.freedesktop.Telepathy.Channel.Type">Text.AcknowledgePendingMessages</tp:dbus-ref>.</p>

        <p>Change notification is via
          <tp:member-ref>MessageReceived</tp:member-ref> and
          <tp:member-ref>PendingMessagesRemoved</tp:member-ref>.</p>
      </tp:docstring>
    </property>

    <signal name="PendingMessagesRemoved"
      tp:name-for-bindings="Pending_Messages_Removed">
      <tp:docstring>
        The messages with the given IDs have been removed from the
        <tp:member-ref>PendingMessages</tp:member-ref> list. Clients SHOULD NOT
        attempt to acknowledge those messages.

        <tp:rationale>
          This completes change notification for the PendingMessages property
          (previously, there was change notification when pending messages
          were added, but not when they were removed).
        </tp:rationale>
      </tp:docstring>

      <arg name="Message_IDs" type="au" tp:type="Message_ID[]">
        <tp:docstring>
          The messages that have been removed from the pending message list.
        </tp:docstring>
      </arg>
    </signal>

    <method name="GetPendingMessageContent"
      tp:name-for-bindings="Get_Pending_Message_Content">
      <tp:deprecated version='0.21.5'
                     xmlns="http://www.w3.org/1999/xhtml">
        This method has never been implemented, and in any case would have been
        impossible to use correctly when multiple clients (such as a logger and
        the handler) are interested in a text channel. See <a
          href='https://bugs.freedesktop.org/show_bug.cgi?id=26417'>freedesktop.org
        bug #26417</a> for more details.
      </tp:deprecated>
      <tp:docstring>
        Retrieve the content of one or more parts of a pending message.
        Note that this function may take a considerable amount of time
        to return if the part's 'needs-retrieval' flag is true; consider
        extending the default D-Bus method call timeout. Additional API is
        likely to be added in future, to stream large message parts.
      </tp:docstring>

      <arg name="Message_ID" type="u" tp:type="Message_ID" direction="in">
        <tp:docstring>
          The ID of a pending message
        </tp:docstring>
      </arg>

      <arg name="Parts" type="au" direction="in"
        tp:type="Message_Part_Index[]">
        <tp:docstring>
          The desired entries in the array of message parts, identified by
          their position. The "headers" part (which is not a valid argument
          to this method) is considered to be part 0, so the valid part
          numbers start at 1 (for the second Message_Part).
        </tp:docstring>
      </arg>

      <arg name="Content" type="a{uv}" direction="out"
        tp:type="Message_Part_Content_Map">
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>The content of the requested parts. The keys in this mapping
            are positions in the array of message parts; the values are
            either of type 's' or 'ay' (UTF-8 text string, or byte array),
            following the same rules as for the value of the 'content' key in
            the <tp:type>Message_Part</tp:type> mappings.</p>

          <p>If the one of the requested part numbers was greater than zero
            but referred to a part that had no content (i.e. it had no
            'content-type' key or no 'content' key), it is simply omitted from
            this mapping; this is not considered to be an error condition.</p>
        </tp:docstring>
      </arg>

      <tp:possible-errors>
        <tp:error name="org.freedesktop.Telepathy.Error.InvalidArgument">
          <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
            Either there is no pending message with the given message ID,
            or one of the part numbers given was 0 or too large.
          </tp:docstring>
        </tp:error>
        <tp:error name="org.freedesktop.Telepathy.Error.NotAvailable"/>
        <tp:error name="org.freedesktop.Telepathy.Error.PermissionDenied"/>
        <tp:error name="org.freedesktop.Telepathy.Error.NetworkError"/>
      </tp:possible-errors>
    </method>

    <signal name="MessageReceived" tp:name-for-bindings="Message_Received">
      <tp:docstring>
        Signals that a message has been received and added to the pending
        messages queue. This MUST be emitted exactly once per emission of the
        <tp:dbus-ref
          namespace="org.freedesktop.Telepathy.Channel.Type.Text">Received</tp:dbus-ref>
        signal on the Text interface, for backwards-compatibility; clients
        SHOULD ignore the latter in favour of this signal if this interface is
        present, as mentioned in the introduction.
      </tp:docstring>

      <arg type="aa{sv}" tp:type="Message_Part[]" name="Message">
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>The message content, including any attachments or alternatives. If
            the incoming message contains formatted text without a plain text
            alternative, the connection manager MUST generate a
            <tt>text/plain</tt> alternative from the formatted text, and
            include it in this message (both here, and in the
            <tp:member-ref>PendingMessages</tp:member-ref> property).</p>
        </tp:docstring>
      </arg>
    </signal>

    <tp:enum name="Delivery_Status" value-prefix="Delivery_Status"
      plural="Delivery_Statuses" type="u">
      <tp:docstring>
        <p>The status of a message as indicated by a delivery report.</p>

        <p>If this enum is extended in future specifications, this should
          only be to add new, non-overlapping conditions (i.e. all failures
          should still be signalled as either Temporarily_Failed
          or Permanently_Failed). If additional detail is required (e.g.
          distinguishing between the various types of permanent failure) this
          will be done using additional
          <tp:type>Delivery_Report_Header_Key</tp:type>s.</p>
      </tp:docstring>

      <tp:enumvalue suffix="Unknown" value="0">
        <tp:docstring>
          The message's disposition is unknown.
          Clients SHOULD consider all messages to have status
          Delivery_Status_Unknown unless otherwise specified; connection
          managers SHOULD NOT signal this delivery status explicitly.
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Delivered" value="1">
        <tp:docstring>
          The message has been delivered to the intended recipient.
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Temporarily_Failed" value="2">
        <tp:docstring>
          Delivery of the message has failed. Clients SHOULD notify the user,
          but MAY automatically try sending another copy of the message.

          <tp:rationale>
            Similar to errors with type="wait" in XMPP; analogous to
            4xx errors in SMTP.
          </tp:rationale>
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Permanently_Failed" value="3">
        <tp:docstring>
          Delivery of the message has failed. Clients SHOULD NOT try again
          unless by specific user action. If the user does not modify the
          message or alter configuration before re-sending, this error is
          likely to happen again.

          <tp:rationale>
            Similar to errors with type="cancel", type="modify"
            or type="auth" in XMPP; analogous to 5xx errors in SMTP.
          </tp:rationale>
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Accepted" value="4">
        <tp:docstring>
          An intermediate server has accepted the message but the message
          has not been yet delivered to the ultimate recipient. The
          connection manager might send a Failed report or Delivered report
          later.

          <tp:rationale>
            Similar to "202 Accepted" success code in SIP; analogous to
            251 and 252 responses in SMTP.
          </tp:rationale>
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Read" value="5">
        <tp:added version="0.19.9"/>
        <tp:docstring>
          The message has been read by the intended recipient.
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Deleted" value="6">
        <tp:added version="0.19.9"/>
        <tp:docstring>
          The message has been deleted by the intended recipient. This MAY be
          signalled on its own if the message is deleted without being read, or
          after <code>Read</code> if the message was read before being deleted.
        </tp:docstring>
      </tp:enumvalue>
    </tp:enum>

    <tp:flags name="Delivery_Reporting_Support_Flags"
      value-prefix="Delivery_Reporting_Support_Flag" type="u">
      <tp:docstring>
        Flags indicating the level of support for delivery reporting on this
        channel, as found on the
        <tp:member-ref>DeliveryReportingSupport</tp:member-ref> property. Any
        future flags added to this set will conform to the
        convention that the presence of an extra flag implies that
        more operations will succeed. Note that CMs may always provide more
        reports than are requested in the
        <tp:type>Message_Sending_Flags</tp:type> passed to
        <tp:member-ref>SendMessage</tp:member-ref>.

        <tp:rationale>
          If senders want delivery reports, they should ask for them.  If they
          don't want delivery reports, they can just ignore them, so there's no
          need to have capability discovery for what will happen if a delivery
          report isn't requested.
        </tp:rationale>
      </tp:docstring>

      <tp:flag suffix="Receive_Failures" value="1">
        <tp:docstring>
          Clients MAY expect to receive negative delivery reports if
          Message_Sending_Flag_Report_Delivery is specified when sending.
        </tp:docstring>
      </tp:flag>

      <tp:flag suffix="Receive_Successes" value="2">
        <tp:docstring>
          Clients MAY expect to receive positive delivery reports if
          Message_Sending_Flag_Report_Delivery is specified when sending.
        </tp:docstring>
      </tp:flag>

      <tp:flag suffix="Receive_Read" value="4">
        <tp:added version="0.19.9"/>
        <tp:docstring>
          Clients MAY expect to receive <tp:type>Delivery_Status</tp:type>
          <code>Read</code> reports if Message_Sending_Flag_Report_Read
          is specified when sending.
        </tp:docstring>
      </tp:flag>

      <tp:flag suffix="Receive_Deleted" value="8">
        <tp:added version="0.19.9"/>
        <tp:docstring>
          Clients MAY expect to receive <tp:type>Delivery_Status</tp:type>
          <code>Deleted</code> reports if Message_Sending_Flag_Report_Deleted
          is specified when sending.
        </tp:docstring>
      </tp:flag>
    </tp:flags>

    <property name="DeliveryReportingSupport" access="read"
      tp:type="Delivery_Reporting_Support_Flags" type="u"
      tp:name-for-bindings="Delivery_Reporting_Support"
      tp:immutable="yes">
      <tp:docstring>
        A bitfield indicating features supported by this channel.
      </tp:docstring>
    </property>

  </interface>
</node>
<!-- vim:set sw=2 sts=2 et ft=xml: -->
