anchor.diff:  -export_type([endpoint/0,
                 endpoint_option/0,
                 datagram/0]).
  -
  -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  -%% @doc receives datagram from peer_worker, parses & delivers to matching channel
  -%% @spec handle_datagram() -> ok
  -%% @end
  --spec handle({udp, inet:socket(), inet:ip_address(), inet:port_number(),
  -              binary()}, any()) -> ok.
  -
  -handle({udp, Socket, Peer_IP_Address, Peer_Port, Maybe_Datagram}, State) ->
  -    Channel = ppspp_channel:get_channel(Maybe_Datagram),
  -    Endpoint = build_endpoint(udp, Socket, Peer_IP_Address, Peer_Port, Channel),
  -    {ok, Parsed_Datagram} = unpack(Maybe_Datagram, Endpoint, State),
  -    % NB usually called from spawned process, so return values are ignored
  -    handle(Parsed_Datagram).
   
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   %% @doc translates raw udp packet into a tidy structure for later use
  
positive.code:     Endpoint.
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %% @doc Extract PPSPP channel ID from header of datagram
  %% <p>  Each PPSPP datagram contains as the first 4 byes the inbount channel ID.
  %% </p>
  %% @end
  
  -spec handle(datagram()) -> ok.
  handle(_Datagram = {datagram, Datagram}) ->
      %% handle/1 needs to become handle/2 as the swarm state and inbound channel
      %% are needed to process the messages correctly.
      %% This also needs to be moved into ppspp_message module wrt opaque typing.
  
negative.code: -endif.
  
  %% api
  -export([handle/1,
           unpack/2,
           pack/1]).
  
  -opaque endpoint() :: {endpoint, list( endpoint_option())}.
  