sig
  module Down :
    sig
      type t = { tick : unit Join.chan; wait : unit -> unit; }
      val create : int -> JoinCount.Down.t
    end
  module Collector :
    sig
      type ('a, 'b) t = { collect : 'Join.chan; wait : unit -> 'b; }
      val create :
        ('-> '-> 'b) -> '-> int -> ('a, 'b) JoinCount.Collector.t
    end
  module Dynamic :
    sig
      type ('a, 'b) t = {
        enter : unit -> unit;
        leave : 'Join.chan;
        wait : unit -> 'b;
        finished : unit Join.chan;
      }
      val create : ('-> '-> 'b) -> '-> ('a, 'b) JoinCount.Dynamic.t
    end
  module Monitor :
    sig
      type key
      type ('a, 'b, 'c) t = {
        enter : '-> JoinCount.Monitor.key;
        leave : JoinCount.Monitor.key * '-> unit;
        is_pending : JoinCount.Monitor.key -> bool;
        get_pendings : unit -> (JoinCount.Monitor.key * 'a) list;
        wait : unit -> 'c;
        finished : unit Join.chan;
      }
      val create : ('-> '-> 'c) -> '-> ('a, 'b, 'c) JoinCount.Monitor.t
    end
end