anchor.diff:  
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   %% @doc Unpack PPPSPP options as encoded in wire format into erlang terms.
  --spec unpack(binary()) -> {binary(), options()} | {error, atom()}.
  +-spec unpack(binary()) -> {binary(), options()} | {error, any()}.
   unpack(Maybe_Options) ->
  -    {Maybe_Messages, Options} = unpack(Maybe_Options, orddict:new()),
  -    {Maybe_Messages, {options, Options}}.
  --spec unpack(binary(), options_dict()) -> { binary(), options_dict()}.
  +    {Maybe_Messages, Options} = unpack(Maybe_Options, #{}),
  +    {Maybe_Messages, Options}.
  +-spec unpack(binary(), options()) -> { binary(), options()}.
   unpack( <<?PPSPP_SUPPORTED_VERSION,
             Version:?BYTE,
  -          Maybe_Options/binary >>, Options0) ->
  -    Options = orddict:store(supported_version, Version, Options0),
  -    unpack(Maybe_Options, Options);
  +          Maybe_Options/binary >>, Options) ->
  +    unpack(Maybe_Options, Options#{supported_version => Version});
   unpack( <<?PPSPP_MINIMUM_VERSION,
             Version:?BYTE,
  -          Maybe_Options/binary >>, Options0) ->
  -    Options = orddict:store(minimum_version, Version, Options0),
  -    unpack(Maybe_Options, Options);
  +          Maybe_Options/binary >>, Options) ->
  +    unpack(Maybe_Options, Options#{minimum_version => Version});
   unpack( <<?PPSPP_SWARM_ID_LENGTH,
             Length:?WORD,
             Swarm_ID:Length/binary,
  -          Maybe_Options/binary >>, Options0) ->
  -    Options = orddict:store(swarm_id, Swarm_ID, Options0),
  -    unpack(Maybe_Options, Options);
  +          Maybe_Options/binary >>, Options) ->
  +    unpack(Maybe_Options, Options#{swarm_id => Swarm_ID});
   unpack( <<?PPSPP_INTEGRITY_CHECK_METHOD,
             Maybe_Method:?BYTE,
  -          Maybe_Options/binary >>, Options0) ->
  +          Maybe_Options/binary >>, Options) ->
       Method = case Maybe_Method of
                    0 -> no_integrity_protection;
                    1 -> merkle_hash_tree;
                    2 -> sign_all;
                    3 -> unified_merkle_hash_tree
                end,
  -    Options = orddict:store(content_integrity_check_method, Method, Options0),
  -    unpack(Maybe_Options, Options);
  +    unpack(Maybe_Options, Options#{content_integrity_check_method => Method});
   unpack( <<?PPSPP_MERKLE_HASH_FUNCTION,
             Maybe_Hash_Function:?BYTE,
  -          Maybe_Options/binary >>, Options0) ->
  +          Maybe_Options/binary >>, Options) ->
       Hash_Function = case Maybe_Hash_Function of
                           0 -> sha;
                           1 -> sha224;
  
positive.code:                  16#ffffffffffffffff -> ppspp_live_discard_window_keep_all_chunks;
                   _ -> Window0
               end,
      Options = orddict:store(ppspp_live_discard_window, Window, Options0),
      unpack(Maybe_Options, Options);
  unpack( <<?PPSPP_SUPPORTED_MESSAGES,
            Length:?BYTE,
            Maybe_Supported_Message_Types:Length/big,
            Maybe_Options/binary >>, Options0) ->
      Supported_Message_Types = case Maybe_Supported_Message_Types of
                                    %% TODO probably needs a custom bitmatching parser
                                    _ -> ppspp_supported_messages_not_yet_implemented
                                end,
      Options = orddict:store(ppspp_supported_message_types,
                              Supported_Message_Types, Options0),
      unpack(Maybe_Options, Options);
  unpack( <<?PPSPP_END_OPTION, Maybe_Messages/binary>>, Options) ->
      {Maybe_Messages, Options};
  %% if PPPSPP_END_OPTION is not present in the binary, bad things** happen
  unpack( <<>>, _Options) -> {error, ppspp_invalid_options}.
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %% @doc Provides a clean interfaces to retrieve a given option from the
  %% opaque store.
  %% @end
  -spec get(option(), options()) -> any().
  get(Option, {options, Options_Dict}) ->
      orddict:fetch(Option, Options_Dict).
  
  %% @doc Returns chunking method for the swarm
  get_chunk_addressing_method(Options) ->
      get(chunk_addressing_method, Options).
  
  %% @doc Returns CIPM for the provided swarm
  -spec get_content_integrity_check_method(options()) -> any().
  
  get_content_integrity_check_method(Options) ->
      get(content_integrity_check_method, Options).
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %% @doc Returns the hash function for the provided swarm
  -spec get_merkle_hash_tree_function(options()) -> any().
  
  get_merkle_hash_tree_function(Options) ->
      get(merkle_hash_tree_function, Options).
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %% @doc Returns the lowest accepted PPSP version for the swarm.
  -spec get_minimum_version(options()) -> any().
  
  get_minimum_version(Options) ->
      get(minimum_version, Options).
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %% @doc Returns the embedded swarm_id.
  -spec get_swarm_id(options()) -> swarm_id().
  
  get_swarm_id(Options) ->
      get(swarm_id, Options).
  
  %% @doc Returns the swarm chunk size
  -spec get_chunk_size(options()) -> pos_integer().
  get_chunk_size(Options) ->
      get(chunk_size, Options).
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %% @doc Returns the highest accepted PPSP version for the swarm.
  -spec get_maximum_supported_version(options()) -> any().
  
  get_maximum_supported_version(Options) ->
      get(supported_version, Options).
  
  %% @doc helper unwrapper to pull out components from a datagram orddict
  %% @end
  -spec get_options(orddict:orddict()) -> options().
  get_options(Dict) -> {options, orddict:fetch(options, Dict)}.
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %% @doc Provides standard options from the PPSPP RFC as erlang terms.
  
negative.code: %% | supported_messages
  %% | end_option
  %% | default_chunk_size
  %% | chunk_addressing_method.
  -opaque option() :: supported_version
  | minimum_version
  | swarm_id
  | content_integrity_check_method
  | merkle_hash_tree_function
  | live_signature_algorithm
  | chunk_addressing_method
  | live_discard_window
  | supported_messages
  | end_option
  | default_chunk_size
  | chunk_addressing_method.
  
  %% Matches a subset of types from http://erlang.org/doc/man/crypto.html
  %%  digest_type() =  md5 | sha | sha224 | sha256 | sha384 | sha512, and
  