sig
  module type CLIENT =
    sig
      module Io : sig type 'a t type inet_addr type config end
      type connection_t
      val send :
        connection:Irc_client.CLIENT.connection_t ->
        Irc_message.t -> unit Irc_client.CLIENT.Io.t
      val send_join :
        connection:Irc_client.CLIENT.connection_t ->
        channel:string -> unit Irc_client.CLIENT.Io.t
      val send_nick :
        connection:Irc_client.CLIENT.connection_t ->
        nick:string -> unit Irc_client.CLIENT.Io.t
      val send_pass :
        connection:Irc_client.CLIENT.connection_t ->
        password:string -> unit Irc_client.CLIENT.Io.t
      val send_pong :
        connection:Irc_client.CLIENT.connection_t ->
        message:string -> unit Irc_client.CLIENT.Io.t
      val send_privmsg :
        connection:Irc_client.CLIENT.connection_t ->
        target:string -> message:string -> unit Irc_client.CLIENT.Io.t
      val send_notice :
        connection:Irc_client.CLIENT.connection_t ->
        target:string -> message:string -> unit Irc_client.CLIENT.Io.t
      val send_quit :
        connection:Irc_client.CLIENT.connection_t ->
        unit Irc_client.CLIENT.Io.t
      val send_user :
        connection:Irc_client.CLIENT.connection_t ->
        username:string ->
        mode:int -> realname:string -> unit Irc_client.CLIENT.Io.t
      val connect :
        ?username:string ->
        ?mode:int ->
        ?realname:string ->
        ?password:string ->
        ?config:Irc_client.CLIENT.Io.config ->
        addr:Irc_client.CLIENT.Io.inet_addr ->
        port:int ->
        nick:string ->
        unit -> Irc_client.CLIENT.connection_t Irc_client.CLIENT.Io.t
      val connect_by_name :
        ?username:string ->
        ?mode:int ->
        ?realname:string ->
        ?password:string ->
        ?config:Irc_client.CLIENT.Io.config ->
        server:string ->
        port:int ->
        nick:string ->
        unit -> Irc_client.CLIENT.connection_t option Irc_client.CLIENT.Io.t
      type keepalive = { mode : [ `Active | `Passive ]; timeout : int; }
      val default_keepalive : Irc_client.CLIENT.keepalive
      val listen :
        ?keepalive:Irc_client.CLIENT.keepalive ->
        connection:Irc_client.CLIENT.connection_t ->
        callback:(Irc_client.CLIENT.connection_t ->
                  Irc_message.parse_result -> unit Irc_client.CLIENT.Io.t) ->
        unit -> unit Irc_client.CLIENT.Io.t
      val reconnect_loop :
        ?keepalive:Irc_client.CLIENT.keepalive ->
        after:int ->
        connect:(unit ->
                 Irc_client.CLIENT.connection_t option Irc_client.CLIENT.Io.t) ->
        f:(Irc_client.CLIENT.connection_t -> unit Irc_client.CLIENT.Io.t) ->
        callback:(Irc_client.CLIENT.connection_t ->
                  Irc_message.parse_result -> unit Irc_client.CLIENT.Io.t) ->
        unit -> unit Irc_client.CLIENT.Io.t
      val set_log : (string -> unit Irc_client.CLIENT.Io.t) -> unit
    end
  module Make :
    functor (Io : Irc_transport.IO->
      sig
        module Io :
          sig
            type 'a t = 'Io.t
            type inet_addr = Io.inet_addr
            type config = Io.config
          end
        type connection_t
        val send : connection:connection_t -> Irc_message.t -> unit Io.t
        val send_join :
          connection:connection_t -> channel:string -> unit Io.t
        val send_nick : connection:connection_t -> nick:string -> unit Io.t
        val send_pass :
          connection:connection_t -> password:string -> unit Io.t
        val send_pong :
          connection:connection_t -> message:string -> unit Io.t
        val send_privmsg :
          connection:connection_t ->
          target:string -> message:string -> unit Io.t
        val send_notice :
          connection:connection_t ->
          target:string -> message:string -> unit Io.t
        val send_quit : connection:connection_t -> unit Io.t
        val send_user :
          connection:connection_t ->
          username:string -> mode:int -> realname:string -> unit Io.t
        val connect :
          ?username:string ->
          ?mode:int ->
          ?realname:string ->
          ?password:string ->
          ?config:Io.config ->
          addr:Io.inet_addr ->
          port:int -> nick:string -> unit -> connection_t Io.t
        val connect_by_name :
          ?username:string ->
          ?mode:int ->
          ?realname:string ->
          ?password:string ->
          ?config:Io.config ->
          server:string ->
          port:int -> nick:string -> unit -> connection_t option Io.t
        type keepalive = { mode : [ `Active | `Passive ]; timeout : int; }
        val default_keepalive : keepalive
        val listen :
          ?keepalive:keepalive ->
          connection:connection_t ->
          callback:(connection_t -> Irc_message.parse_result -> unit Io.t) ->
          unit -> unit Io.t
        val reconnect_loop :
          ?keepalive:keepalive ->
          after:int ->
          connect:(unit -> connection_t option Io.t) ->
          f:(connection_t -> unit Io.t) ->
          callback:(connection_t -> Irc_message.parse_result -> unit Io.t) ->
          unit -> unit Io.t
        val set_log : (string -> unit Io.t) -> unit
      end
end