anchor.diff:  -type message_id()      :: any().
   -type message_round()   :: non_neg_integer().
   -type outstanding()     :: {message_id(), module(), message_round(), nodename()}.
  +-type exchange()        :: {module(), node(), reference(), pid()}.
  +-type exchanges()       :: [exchange()].
   
   -record(state, {
             %% Initially trees rooted at each node are the same.
  
positive.code:          broadcast/2,
           ring_update/1,
           broadcast_members/0,
           broadcast_members/1]).
  
  %% Debug API
  -export([debug_get_peers/2,
  
negative.code: broadcast_members(Timeout) ->
      gen_server:call(?SERVER, broadcast_members, Timeout).
  
  %% @doc return a list of exchanges, started by broadcast on thisnode, that are running
  -spec exchanges() -> exchanges().
  exchanges() ->
      exchanges(node()).
  
  %% @doc returns a list of exchanges, started by broadcast on `Node', that are running
  -spec exchanges(node()) -> exchanges().
  exchanges(Node) ->
      gen_server:call({?SERVER, Node}, exchanges, infinity).
  
  %% @doc cancel exchanges started by this node.
  -spec cancel_exchanges(all              |
                         {peer, node()}   |
                         {mod, module()}  |
                         reference()      |
                         pid()) -> exchanges().
  cancel_exchanges(WhichExchanges) ->
      gen_server:call(?SERVER, {cancel_exchanges, WhichExchanges}, infinity).
  
  %%%===================================================================
  %%% Debug API
  %%%===================================================================
  