docs: def exchange_declare(self, exchange, type, passive=False, durable=False,
          auto_delete=True, internal=False, nowait=False,
          arguments=None, ticket=None):
          """
          declare exchange, create if needed
  
          This method creates an exchange if it does not already exist,
          and if the exchange exists, verifies that it is of the correct
          and expected class.
  
          RULE:
  
              The server SHOULD support a minimum of 16 exchanges per
              virtual host and ideally, impose no limit except as
              defined by available resources.
  
          PARAMETERS:
              exchange: shortstr
  
                  RULE:
  
                      Exchange names starting with "amq." are reserved
                      for predeclared and standardised exchanges.  If
                      the client attempts to create an exchange starting
                      with "amq.", the server MUST raise a channel
                      exception with reply code 403 (access refused).
  
              type: shortstr
  
                  exchange type
  
                  Each exchange belongs to one of a set of exchange
                  types implemented by the server.  The exchange types
                  define the functionality of the exchange - i.e. how
                  messages are routed through it.  It is not valid or
                  meaningful to attempt to change the type of an
                  existing exchange.
  
                  RULE:
  
                      If the exchange already exists with a different
                      type, the server MUST raise a connection exception
                      with a reply code 507 (not allowed).
  
                  RULE:
  
                      If the server does not support the requested
                      exchange type it MUST raise a connection exception
                      with a reply code 503 (command invalid).
  
              passive: boolean
  
                  do not create exchange
  
                  If set, the server will not create the exchange.  The
                  client can use this to check whether an exchange
                  exists without modifying the server state.
  
                  RULE:
  
                      If set, and the exchange does not already exist,
                      the server MUST raise a channel exception with
                      reply code 404 (not found).
  
              durable: boolean
  
                  request a durable exchange
  
                  If set when creating a new exchange, the exchange will
                  be marked as durable.  Durable exchanges remain active
                  when a server restarts. Non-durable exchanges
                  (transient exchanges) are purged if/when a server
                  restarts.
  
                  RULE:
  
                      The server MUST support both durable and transient
                      exchanges.
  
                  RULE:
  
                      The server MUST ignore the durable field if the
                      exchange already exists.
  
              auto_delete: boolean
  
                  auto-delete when unused
  
                  If set, the exchange is deleted when all queues have
                  finished using it.
  
                  RULE:
  
                      The server SHOULD allow for a reasonable delay
                      between the point when it determines that an
                      exchange is not being used (or no longer used),
                      and the point when it deletes the exchange.  At
                      the least it must allow a client to create an
                      exchange and then bind a queue to it, with a small
                      but non-zero delay between these two actions.
  
                  RULE:
  
                      The server MUST ignore the auto-delete field if
                      the exchange already exists.
  
              internal: boolean
  
                  create internal exchange
  
                  If set, the exchange may not be used directly by
                  publishers, but only when bound to other exchanges.
                  Internal exchanges are used to construct wiring that
                  is not visible to applications.
  
              nowait: boolean
  
                  do not send a reply method
  
                  If set, the server will not respond to the method. The
                  client should not wait for a reply method.  If the
                  server could not complete the method it will raise a
                  channel or connection exception.
  
              arguments: table
  
                  arguments for declaration
  
                  A set of arguments for the declaration. The syntax and
                  semantics of these arguments depends on the server
                  implementation.  This field is ignored if passive is
                  True.
  
              ticket: short
  
                  When a client defines a new exchange, this belongs to
                  the access realm of the ticket used.  All further work
                  done with that exchange must be done with an access
                  ticket for the same realm.
  
                  RULE:
  
                      The client MUST provide a valid access ticket
                      giving "active" access to the realm in which the
                      exchange exists or will be created, or "passive"
                      access if the if-exists flag is set.
  
          """
          if arguments is None:
              arguments = {}
  
          args = AMQPWriter()
          if ticket is not None:
              args.write_short(ticket)
          else:
              args.write_short(self.default_ticket)
          args.write_shortstr(exchange)
          args.write_shortstr(type)
          args.write_bit(passive)
          args.write_bit(durable)
          args.write_bit(auto_delete)
          args.write_bit(internal)
          args.write_bit(nowait)
          args.write_table(arguments)
          self._send_method((40, 10), args)
  
          if not nowait:
              return self.wait(allowed_methods=[
                                (40, 11),    # Channel.exchange_declare_ok
                              ])