content: -- |
  -- Module:      $Header$
  --
  -- Stability:   unstable
  -- Portability: portable
  --
  -- The Extensible Messaging and Presence Protocol (XMPP) is an open technology
  -- for near-real-time communication, which powers a wide range of applications
  -- including instant messaging, presence, multi-party chat, voice and video
  -- calls, collaboration, lightweight middleware, content syndication, and
  -- generalized routing of XML data. XMPP provides a technology for the
  -- asynchronous, end-to-end exchange of structured data by means of direct,
  -- persistent XML streams among a distributed network of globally addressable,
  -- presence-aware clients and servers.
  --
  -- Pontarius XMPP is an XMPP client library, implementing the core capabilities
  -- of XMPP (RFC 6120): setup and tear-down of XML streams, channel encryption,
  -- authentication, error handling, and communication primitives for messaging.
  --
  -- For low-level access to Pontarius XMPP, see the "Network.Xmpp.Internal"
  -- module.
  --
  -- Getting Started
  --
  -- We use 'session' to create a session object and connect to a server. Here we
  -- use the default 'SessionConfiguration'.
  --
  -- @
  -- sess <- session realm (simpleAuth \"myUsername\" \"mypassword\") def
  -- @
  --
  -- Defining 'AuthData' can be a bit unwieldy, so 'simpleAuth' gives us a
  -- reasonable default. Though, for improved security, we should consider
  -- restricting the mechanisms to 'scramSha1' whenever we can.
  --
  -- Next we have to set the presence to online, otherwise we won't be able to
  -- send or receive stanzas to/from other entities.
  --
  -- @
  -- sendPresence presenceOnline sess
  -- @
  --
  {-# LANGUAGE CPP, NoMonomorphismRestriction, OverloadedStrings #-}
  
  module Network.Xmpp
    ( -- * Session management
      Session
    , session
    , setConnectionClosedHandler
    , reconnect
    , reconnect'
    , reconnectNow
    , StreamConfiguration(..)
    , SessionConfiguration(..)
    , ConnectionDetails(..)
    , ConnectionState(..)
    , closeConnection
    , endSession
    , waitForStream
    , streamState
      -- ** Feature
    , StreamFeatures(..)
    , getFeatures
      -- ** Authentication handlers
      -- | The use of 'scramSha1' is /recommended/, but 'digestMd5' might be
      -- useful for interaction with older implementations.
    , SaslHandler
    , AuthData
    , Username
    , Password
    , AuthZID
    , simpleAuth
    , scramSha1
    , plain
    , digestMd5
    -- * Addressing
    -- | A JID (historically: Jabber ID) is XMPPs native format
    -- for addressing entities in the network. It is somewhat similar to an e-mail
    -- address, but contains three parts instead of two.
    , Jid
  #if WITH_TEMPLATE_HASKELL
    , jid
    , jidQ
  #endif
    , isBare
    , isFull
    , jidFromText
    , jidFromTexts
    , jidToText
    , jidToTexts
    , toBare
    , localpart
    , domainpart
    , resourcepart
    , parseJid
    , getJid
    -- * Stanzas
    -- | The basic protocol data unit in XMPP is the XML stanza. The stanza is
    -- essentially a fragment of XML that is sent over a stream. @Stanzas@ come in
    -- 3 flavors:
    --
    --  * /Message/, for traditional push-style message passing between peers
    --
    --  * /Presence/, for communicating status updates
    --
    --  * /Info/\//Query/ (or /IQ/), for request-response semantics communication
    --
    -- All stanza types have the following attributes in common:
    --
    --  * The /id/ attribute is used by the originating entity to track any
    --    response or error stanza that it might receive in relation to the
    --    generated stanza from another entity (such as an intermediate server or
    --    the intended recipient).  It is up to the originating entity whether the
    --    value of the 'id' attribute is unique only within its current stream or
    --    unique globally.
    --
    --  * The /from/ attribute specifies the JID of the sender.
    --
    --  * The /to/ attribute specifies the JID of the intended recipient for the
    --    stanza.
    --
    --  * The /type/ attribute specifies the purpose or context of the message,
    --    presence, or IQ stanza. The particular allowable values for the 'type'
    --    attribute vary depending on whether the stanza is a message, presence,
    --    or IQ stanza.
    , getStanza
    , getStanzaChan
    , newStanzaID
    -- ** Messages
    -- | The /message/ stanza is a /push/ mechanism whereby one entity
    -- pushes information to another entity, similar to the communications that
    -- occur in a system such as email. It is not to be confused with
    -- an 'InstantMessage'
    , Message(..)
    , message
    , MessageError(..)
    , MessageType(..)
    -- *** Creating
    , answerMessage
    -- *** Sending
    , sendMessage
    -- *** Receiving
    , pullMessage
    , getMessage
    , getMessageA
    , waitForMessage
    , waitForMessageA
    , waitForMessageError
    , waitForMessageErrorA
    , filterMessages
    , filterMessagesA
    -- ** Presence
    -- | XMPP includes the ability for an entity to advertise its network
    -- availability, or "presence", to other entities. In XMPP, this availability
    -- for communication is signaled end-to-end by means of a dedicated
    -- communication primitive: the presence stanza.
    , Presence(..)
    , PresenceType(..)
    , PresenceError(..)
    -- *** Creating
    , presence
    , presenceOffline
    , presenceOnline
    , presenceSubscribe
    , presenceSubscribed
    , presenceUnsubscribe
    , presenceUnsubscribed
    , presTo
    -- *** Sending
    -- | Sends a presence stanza. In general, the presence stanza should have no
    -- 'to' attribute, in which case the server to which the client is connected
    -- will broadcast that stanza to all subscribed entities. However, a
    -- publishing client may also send a presence stanza with a 'to' attribute, in
    -- which case the server will route or deliver that stanza to the intended
    -- recipient.
    , sendPresence
    -- *** Receiving
    , pullPresence
    , waitForPresence
    -- ** IQ
    -- | Info\/Query, or IQ, is a /request-response/ mechanism, similar in some
    -- ways to the Hypertext Transfer Protocol @HTTP@. The semantics of IQ enable
    -- an entity to make a request of, and receive a response from, another
    -- entity. The data content and precise semantics  of the request and response
    -- is defined by the schema or other structural definition associated with the
    -- XML namespace that qualifies the direct child element of the IQ element. IQ
    -- interactions follow a common pattern of structured data exchange such as
    -- get\/result or set\/result (although an error can be returned in reply to a
    -- request if appropriate)
    --
    -- <http://xmpp.org/rfcs/rfc6120.html#stanzas-semantics-iq>
    , IQRequest(..)
    , IQRequestTicket
    , iqRequestBody
    , IQRequestType(..)
    , IQResult(..)
    , IQError(..)
    , IQResponse(..)
    , IQRequestClass(..)
    , IQRequestHandler
    , sendIQ
    , sendIQ'
    , sendIQRequest
    , answerIQ
    , iqResult
    , listenIQ
    , runIQHandler
    , unlistenIQ
    -- * Errors
    , StanzaErrorType(..)
    , StanzaError(..)
    , associatedErrorType
    , mkStanzaError
    , StanzaErrorCondition(..)
    , SaslFailure(..)
    , IQSendError(..)
    , IQRequestError(..)
    -- * Threads
    , dupSession
    -- * Lenses
    -- | Network.Xmpp doesn't re-export the accessors to avoid name
    -- clashes. To use them import Network.Xmpp.Lens
    , module Network.Xmpp.Lens
    -- * Plugins
    -- Plugins modify incoming and outgoing stanzas. They can, for example, handle
    -- encryption, compression or other protocol extensions.
    , Annotated
    , Annotation(..)
    , Plugin
    , Plugin'(..)
    -- * LangTag
    , LangTag
    , langTagFromText
    , langTagToText
    , parseLangTag
    -- * Miscellaneous
    , XmppFailure(..)
    , StreamErrorInfo(..)
    , StreamErrorCondition(..)
    , AuthFailure( AuthNoAcceptableMechanism
                 , AuthSaslFailure
                 , AuthIllegalCredentials
                 , AuthOtherFailure )
    , connectTls
    , def
    ) where
  
  import Network.Xmpp.Concurrent
  import Network.Xmpp.Sasl
  import Network.Xmpp.Sasl.Types
  import Network.Xmpp.Stanza
  import Network.Xmpp.Types
  import Network.Xmpp.Tls
  import Network.Xmpp.Lens hiding (view, set, modify)
  import Data.Default (def)
  