anchor.diff:  pack_message(_Message) -> <<>>.
   
   %% if the binary is empty, all messages were parsed successfully
  --spec unpack3(binary(), message() | list(message()), ppspp_options:options()) ->
  -    list(message()) | { message(), binary()}.
  +-spec unpack3(binary(), message() | messages(), ppspp_options:options()) ->
  +    messages() | { message(), binary()}.
   unpack3( <<>>, Parsed_Messages, _) ->
       lists:reverse(Parsed_Messages);
   %% otherwise try to unpack another valid message, peeling off and parsing
  
positive.code:     ?DEBUG("message: parser got valid message type ~p~n", [Message_Type]),
      Message_Type.
  
  %% @doc helper unwrapper to pull out messages from a datagram orddict
  %% @end
  -spec get_messages([any()]) -> any().
  get_messages(Messages) -> orddict:fetch(messages, Messages).
  
  %% @doc dispatch messages to correct handler in received order
  %% @end
  -spec handle(messages() | list(message()),
               ppspp_options:options(),
               ppspp_datagram:endpoint()) -> ok.
  handle({messages, Messages}, Swarm_Options, Endpoint) ->
      handle(Messages, Swarm_Options, Endpoint);
  handle([], _, _ ) -> ok;
  handle([Message | Messages], Swarm_Options, Endpoint) ->
      ok  = handle_message(Message, Swarm_Options, Endpoint),
      handle(Messages, Swarm_Options, Endpoint).
  
  %% @doc does the dirty work of routing each message.
  %% Options and Endpoint are required state for handling many message types.
  %% @end
  -spec handle_message(ppspp_handshake:handshake(),
                       ppspp_options:options(),
                       ppspp_datagram:endpoint()) -> ok | {error, any()}.
  handle_message(Message = {handshake, _Body}, _Swarm_Options, Endpoint) ->
      ppspp_handshake:handle(Message, Endpoint);
  
  handle_message(Message, Swarm_Options, Endpoint) ->
      ?DEBUG("~p: handler not yet implemented ~n~p~n~p~n~p~n",
             [?MODULE, Message, Swarm_Options, Endpoint]),
      {error, ppspp_message_handler_not_yet_implemented}.
  
negative.code: -module(ppspp_message).
  -include("swirl.hrl").
  
  %% api
  -export([unpack/2,
           pack/1,
           get_message_type/1,
           handle/3]).
  
  -opaque messages() :: list(message()).
  %% TODO once all messages are defined then tighten the message() spec
  -opaque message() :: #{message_type() => any()}
  | ppspp_handshake:handshake()
  | ppspp_have:have().
  -opaque message_type() :: handshake
  | data
  | ack
  