anchor.diff:      end,
       {Params, Rest} = parse_params(ParamsBin, fun parse_q_param/2),
       {TokenBin, Params, Rest}.
  -
  -%% @doc Format header value into the binary.
  -%% @end
  --spec format(atom() | binary(), binary() | term()) -> binary().
  -format(_Name, Value) when is_binary(Value) ->
  -    % already formatted to binary
  -    Value;
  -% generalized multi-value headers handling
  -format(Name, [Value]) -> format(Name, Value);
  -format(Name, [Top | Rest]) ->
  -    Joiner = fun (Elem, Bin) ->
  -                      ElemBin = format(Name, Elem),
  -                      <<Bin/binary, ?COMMA, ?SP, ElemBin/binary>>
  -             end,
  -    TopBin = format(Name, Top),
  -    lists:foldl(Joiner, TopBin, Rest);
  -
  -%% ```
  -%% Accept         =  "Accept" HCOLON
  -%%                    [ accept-range *(COMMA accept-range) ]
  -%% accept-range   =  media-range *(SEMI accept-param)
  -%% media-range    =  ( "*/*"
  -%%                   / ( m-type SLASH "*" )
  -%%                   / ( m-type SLASH m-subtype )
  -%%                   ) *( SEMI m-parameter )
  -%% accept-param   =  ("q" EQUAL qvalue) / generic-param
  -%% qvalue         =  ( "0" [ "." 0*3DIGIT ] )
  -%%                   / ( "1" [ "." 0*3("0") ] )
  -%% generic-param  =  token [ EQUAL gen-value ]
  -%% gen-value      =  token / host / quoted-string
  -%% media-type       =  m-type SLASH m-subtype *(SEMI m-parameter)
  -%% m-type           =  discrete-type / composite-type
  -%% discrete-type    =  "text" / "image" / "audio" / "video"
  -%%                     / "application" / extension-token
  -%% composite-type   =  "message" / "multipart" / extension-token
  -%% extension-token  =  ietf-token / x-token
  -%% ietf-token       =  token
  -%% x-token          =  "x-" token
  -%% m-subtype        =  extension-token / iana-token
  -%% m-parameter      =  m-attribute EQUAL m-value
  -%% m-attribute      =  token
  -%% m-value          =  token / quoted-string
  -%% '''
  -format('accept', Accept) when is_record(Accept, sip_hdr_mediatype) ->
  -    Type = sip_binary:any_to_binary(Accept#sip_hdr_mediatype.type),
  -    SubType = sip_binary:any_to_binary(Accept#sip_hdr_mediatype.subtype),
  -    append_params(<<Type/binary, ?SLASH, SubType/binary>>, Accept#sip_hdr_mediatype.params);
  -
  -%% ```
  -%% Accept-Encoding  =  "Accept-Encoding" HCOLON
  -%%                      [ encoding *(COMMA encoding) ]
  -%% encoding         =  codings *(SEMI accept-param)
  -%% codings          =  content-coding / "*"
  -%% content-coding   =  token
  -%% '''
  -format('accept-encoding', Accept) when is_record(Accept, sip_hdr_encoding) ->
  -    Encoding = sip_binary:any_to_binary(Accept#sip_hdr_encoding.encoding),
  -    append_params(Encoding, Accept#sip_hdr_encoding.params);
  -
  -%% ```
  -%% Accept-Language  =  "Accept-Language" HCOLON
  -%%                      [ language *(COMMA language) ]
  -%% language         =  language-range *(SEMI accept-param)
  -%% language-range   =  ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) / "*" )
  -%% '''
  -format('accept-language', Accept) when is_record(Accept, sip_hdr_language) ->
  -    LangBin = sip_binary:any_to_binary(Accept#sip_hdr_language.lang),
  -    Bin =
  -        case Accept#sip_hdr_language.sublang of
  -            undefined ->
  -                LangBin;
  -            SubLang ->
  -                SublangBin = sip_binary:any_to_binary(SubLang),
  -                <<LangBin/binary, $-, SublangBin/binary>>
  -        end,
  -    append_params(Bin, Accept#sip_hdr_language.params);
  -
  -%% ```
  -%% Alert-Info   =  "Alert-Info" HCOLON alert-param *(COMMA alert-param)
  -%% alert-param  =  LAQUOT absoluteURI RAQUOT *( SEMI generic-param )
  -%%
  -%% Call-Info   =  "Call-Info" HCOLON info *(COMMA info)
  -%% info        =  LAQUOT absoluteURI RAQUOT *( SEMI info-param)
  -%% info-param  =  ( "purpose" EQUAL ( "icon" / "info"
  -%%                / "card" / token ) ) / generic-param
  -%% '''
  -format(Name, Info) when (Name =:= 'alert-info' orelse Name =:= 'call-info'),
  -  is_record(Info, sip_hdr_info) ->
  -    URI = sip_uri:format(Info#sip_hdr_info.uri),
  -    Bin = <<?LAQUOT, URI/binary, ?RAQUOT>>,
  -    append_params(Bin, Info#sip_hdr_info.params);
  -
  -%% ```
  -%% Authentication-Info  =  "Authentication-Info" HCOLON ainfo
  -%%                         *(COMMA ainfo)
  -%% ainfo                =  nextnonce / message-qop
  -%%                          / response-auth / cnonce
  -%%                          / nonce-count
  -%% nextnonce            =  "nextnonce" EQUAL nonce-value
  -%% nonce-value          =  quoted-string
  -%% response-auth        =  "rspauth" EQUAL response-digest
  -%% response-digest      =  LDQUOT *LHEX RDQUOT
  -%% message-qop          =  "qop" EQUAL qop-value
  -%% qop-value            =  "auth" / "auth-int" / token
  -%% nonce-count          =  "nc" EQUAL nc-value
  -%% nc-value             =  8LHEX
  -%% cnonce               =  "cnonce" EQUAL cnonce-value
  -%% cnonce-value         =  nonce-value
  -%% '''
  -format('authentication-info', Pair) ->
  -    format_auth(Pair);
  -
  -%% ```
  -%% Authorization     =  "Authorization" HCOLON credentials
  -%% credentials       =  ("Digest" LWS digest-response)
  -%%                     / other-response
  -%% digest-response   =  dig-resp *(COMMA dig-resp)
  -%% dig-resp          =  username / realm / nonce / digest-uri
  -%%                       / dresponse / algorithm / cnonce
  -%%                       / opaque / message-qop
  -%%                       / nonce-count / auth-param
  -%% username          =  "username" EQUAL username-value
  -%% username-value    =  quoted-string
  -%% digest-uri        =  "uri" EQUAL LDQUOT digest-uri-value RDQUOT
  -%% digest-uri-value  =  rquest-uri ; Equal to request-uri as specified by HTTP/1.1
  -%% other-response    =  auth-scheme LWS auth-param
  -%%                     *(COMMA auth-param)
  -%% auth-scheme       =  token
  -%% auth-param        =  auth-param-name EQUAL
  -%%                      ( token / quoted-string )
  -%% auth-param-name   =  token
  -%% '''
  -format('authorization', Auth) when is_record(Auth, sip_hdr_auth) ->
  -    SchemeBin = sip_binary:any_to_binary(Auth#sip_hdr_auth.scheme),
  -    [First | Rest] = Auth#sip_hdr_auth.params,
  -    FirstBin = format_auth(First),
  -    Fun = fun (Val, Acc) -> <<Acc/binary, ?COMMA, ?SP, (format_auth(Val))/binary>> end,
  -    lists:foldl(Fun, <<SchemeBin/binary, ?SP, FirstBin/binary>>, Rest);
  -
  -%% Via               =  ( "Via" / "v" ) HCOLON via-parm *(COMMA via-parm)
  -%% via-parm          =  sent-protocol LWS sent-by *( SEMI via-params )
  -%% via-params        =  via-ttl / via-maddr
  -%%                      / via-received / via-branch
  -%%                      / via-extension
  -%% sent-protocol     =  protocol-name SLASH protocol-version
  -%%                      SLASH transport
  -format('via', Via) when is_record(Via, sip_hdr_via) ->
  -    Version = Via#sip_hdr_via.version,
  -    Transport = sip_binary:to_upper(atom_to_binary(Via#sip_hdr_via.transport, latin1)),
  -    Bin = <<"SIP/", Version/binary, $/, Transport/binary>>,
  -    Host = sip_binary:addr_to_binary(Via#sip_hdr_via.host),
  -    Bin2 = case Via#sip_hdr_via.port of
  -        undefined ->
  -            <<Bin/binary, ?SP, Host/binary>>;
  -        Port ->
  -            <<Bin/binary, ?SP, Host/binary, ?HCOLON, (sip_binary:integer_to_binary(Port))/binary>>
  -    end,
  -    append_params(Bin2, Via#sip_hdr_via.params);
  -
  -%% Content-Length  =  ( "Content-Length" / "l" ) HCOLON 1*DIGIT
  -format('content-length', Length) when is_integer(Length) ->
  -    sip_binary:integer_to_binary(Length);
  -
  -%% CSeq  =  "CSeq" HCOLON 1*DIGIT LWS Method
  -format('cseq', CSeq) when is_record(CSeq, sip_hdr_cseq) ->
  -    SequenceBin = sip_binary:integer_to_binary(CSeq#sip_hdr_cseq.sequence),
  -    MethodBin = sip_binary:any_to_binary(CSeq#sip_hdr_cseq.method),
  -    <<SequenceBin/binary, " ", MethodBin/binary>>;
  -
  -%% Max-Forwards  =  "Max-Forwards" HCOLON 1*DIGIT
  -format('max-forwards', Hops) when is_integer(Hops) ->
  -    sip_binary:integer_to_binary(Hops);
  -
  -%% Call-ID  =  ( "Call-ID" / "i" ) HCOLON callid
  -%% Call id is always a binary, so handled by first case
  -
  -%% ```
  -%% To             =  ( "To" / "t" ) HCOLON ( name-addr / addr-spec ) *( SEMI to-param )
  -%% to-param       =  tag-param / generic-param
  -%%
  -%% From           =  ( "From" / "f" ) HCOLON from-spec
  -%% from-spec      =  ( name-addr / addr-spec ) *( SEMI from-param )
  -%% from-param     =  tag-param / generic-param
  -%%
  -%% Contact        =  ("Contact" / "m" ) HCOLON
  -%%                  ( STAR / (contact-param *(COMMA contact-param)))
  -%% contact-param  =  (name-addr / addr-spec) *(SEMI contact-params)
  -%% contact-params     =  c-p-q / c-p-expires
  -%%                      / contact-extension
  -%% c-p-q              =  "q" EQUAL qvalue
  -%% c-p-expires        =  "expires" EQUAL delta-seconds
  -%% contact-extension  =  generic-param
  -%% delta-seconds      =  1*DIGIT
  -%%
  -%% Route              =  "Route" HCOLON route-param *(COMMA route-param)
  -%% route-param        =  name-addr *( SEMI rr-param )
  -%% rr-param           =  generic-param
  -%%
  -%% Record-Route       =  "Record-Route" HCOLON rec-route *(COMMA rec-route)
  -%% rec-route          =  name-addr *( SEMI rr-param )
  -%%
  -%% name-addr      =  [ display-name ] LAQUOT addr-spec RAQUOT
  -%% addr-spec      =  SIP-URI / SIPS-URI / absoluteURI
  -%% display-name   =  *(token LWS)/ quoted-string
  -%% '''
  -format('contact', '*') -> <<"*">>;
  -format(Name, #sip_hdr_address{} = Addr) when
  -  Name =:= 'from';
  -  Name =:= 'to';
  -  Name =:= 'contact';
  -  Name =:= 'route';
  -  Name =:= 'record-route' ->
  -
  -    URIBin = sip_uri:format(Addr#sip_hdr_address.uri),
  -    Bin = case Addr#sip_hdr_address.display_name of
  -              <<>> -> <<?LAQUOT, URIBin/binary, ?RAQUOT>>;
  -              DisplayName ->
  -                  Quoted = sip_binary:quote_string(DisplayName),
  -                  <<Quoted/binary, " ", ?LAQUOT, URIBin/binary, ?RAQUOT>>
  -          end,
  -    append_params(Bin, Addr#sip_hdr_address.params);
  -
  -%% Any other header
  -format(_Name, Value) ->
  -    sip_binary:any_to_binary(Value).
   
   %% @doc Append parameters to the binary
   %% @end
  
positive.code: %% Header parsing/format functions
  %%-----------------------------------------------------------------
  
  %% @doc Parse header binary value into term representation
  %% @end
  -spec parse(Name :: atom() | binary(), Value :: any()) -> term().
  parse(_Name, Header) when not is_binary(Header) ->
      % Already parsed
      Header;
  
  %% ```
  %% Accept         =  "Accept" HCOLON
  %%                    [ accept-range *(COMMA accept-range) ]
  %% accept-range   =  media-range *(SEMI accept-param)
  %% media-range    =  ( "*/*"
  %%                   / ( m-type SLASH "*" )
  %%                   / ( m-type SLASH m-subtype )
  %%                   ) *( SEMI m-parameter )
  %% accept-param   =  ("q" EQUAL qvalue) / generic-param
  %% qvalue         =  ( "0" [ "." 0*3DIGIT ] )
  %%                   / ( "1" [ "." 0*3("0") ] )
  %% generic-param  =  token [ EQUAL gen-value ]
  %% gen-value      =  token / host / quoted-string
  %% media-type       =  m-type SLASH m-subtype *(SEMI m-parameter)
  %% m-type           =  discrete-type / composite-type
  %% discrete-type    =  "text" / "image" / "audio" / "video"
  %%                     / "application" / extension-token
  %% composite-type   =  "message" / "multipart" / extension-token
  %% extension-token  =  ietf-token / x-token
  %% ietf-token       =  token
  %% x-token          =  "x-" token
  %% m-subtype        =  extension-token / iana-token
  %% m-parameter      =  m-attribute EQUAL m-value
  %% m-attribute      =  token
  %% m-value          =  token / quoted-string
  %% '''
  parse('accept', Bin) ->
      {Media, Rest} = parse_media_range(Bin, fun parse_q_param/2),
      parse_list('accept', Media, Rest);
  
  %% ```
  %% Accept-Encoding  =  "Accept-Encoding" HCOLON
  %%                      [ encoding *(COMMA encoding) ]
  %% encoding         =  codings *(SEMI accept-param)
  %% codings          =  content-coding / "*"
  %% accept-param     =  ("q" EQUAL qvalue) / generic-param
  %% content-coding   =  token
  %% '''
  parse('accept-encoding', Bin) ->
      {EncodingBin, Params, Rest} = parse_accept(Bin),
      Encoding = encoding(sip_binary:binary_to_existing_atom(EncodingBin), Params),
      parse_list('accept-encoding', Encoding, Rest);
  
  %% ```
  %% Accept-Language  =  "Accept-Language" HCOLON
  %%                      [ language *(COMMA language) ]
  %% language         =  language-range *(SEMI accept-param)
  %% language-range   =  ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) / "*" )
  %% '''
  parse('accept-language', Bin) ->
      {LanguageBin, Params, Rest} = parse_accept(Bin),
      Language = language(parse_language(LanguageBin), Params),
      parse_list('accept-language', Language, Rest);
  
  %% ```
  %% Alert-Info  =  "Alert-Info" HCOLON alert-param *(COMMA alert-param)
  %% alert-param =  LAQUOT absoluteURI RAQUOT *( SEMI generic-param )
  %% '''
  parse('alert-info', Bin) ->
      parse_info('alert-info', Bin, fun parse_generic_param/2);
  
  %% ```
  %% Authentication-Info  =  "Authentication-Info" HCOLON ainfo
  %%                         *(COMMA ainfo)
  %% ainfo                =  nextnonce / message-qop
  %%                          / response-auth / cnonce
  %%                          / nonce-count
  %% nextnonce            =  "nextnonce" EQUAL nonce-value
  %% response-auth        =  "rspauth" EQUAL response-digest
  %% response-digest      =  LDQUOT *LHEX RDQUOT
  %% message-qop          =  "qop" EQUAL qop-value
  %% qop-value           =  "auth" / "auth-int" / token
  %% nonce-count          =  "nc" EQUAL nc-value
  %% nc-value             =  8LHEX
  %% cnonce               =  "cnonce" EQUAL cnonce-value
  %% cnonce-value         =  nonce-value
  %% '''
  parse('authentication-info', Bin) ->
      parse_auths(Bin);
  
  %% ```
  %% Authorization     =  "Authorization" HCOLON credentials
  %% credentials       =  ("Digest" LWS digest-response)
  %%                     / other-response
  %% digest-response   =  dig-resp *(COMMA dig-resp)
  %% dig-resp          =  username / realm / nonce / digest-uri
  %%                       / dresponse / algorithm / cnonce
  %%                       / opaque / message-qop
  %%                       / nonce-count / auth-param
  %% username          =  "username" EQUAL username-value
  %% username-value    =  quoted-string
  %% digest-uri        =  "uri" EQUAL LDQUOT digest-uri-value RDQUOT
  %% digest-uri-value  =  rquest-uri ; Equal to request-uri as specified by HTTP/1.1
  %% other-response    =  auth-scheme LWS auth-param
  %%                     *(COMMA auth-param)
  %% auth-scheme       =  token
  %% auth-param        =  auth-param-name EQUAL
  %%                      ( token / quoted-string )
  %% auth-param-name   =  token
  %% '''
  parse('authorization', Bin) ->
      {SchemeBin, Bin2} = sip_binary:parse_token(Bin),
      Scheme = sip_binary:binary_to_existing_atom(SchemeBin),
      auth(Scheme, parse_auths(Bin2));
  
  
  %% ```
  %% Call-ID  =  ( "Call-ID" / "i" ) HCOLON callid
  %% callid   =  word [ "@" word ]
  %% word     =  1*(alphanum / "-" / "." / "!" / "%" / "*" /
  %%             "_" / "+" / "`" / "'" / "~" /
  %%             "(" / ")" / "<" / ">" /
  %%             ":" / "\" / DQUOTE /
  %%             "/" / "[" / "]" / "?" /
  %%             "{" / "}" )
  %% '''
  parse('call-id', Bin) -> Bin;
  
  %% ```
  %% Call-Info   =  "Call-Info" HCOLON info *(COMMA info)
  %% info        =  LAQUOT absoluteURI RAQUOT *( SEMI info-param)
  %% info-param  =  ( "purpose" EQUAL ( "icon" / "info"
  %%                / "card" / token ) ) / generic-param
  %% '''
  parse('call-info', Bin) ->
      ParamFun =
          fun(purpose, Value) -> sip_binary:binary_to_existing_atom(Value);
             (_Name, Value) -> Value
          end,
      parse_info('call-info', Bin, ParamFun);
  
  %% Via               =  ( "Via" / "v" ) HCOLON via-parm *(COMMA via-parm)
  %% via-parm          =  sent-protocol LWS sent-by *( SEMI via-params )
  %% via-params        =  via-ttl / via-maddr
  %%                      / via-received / via-branch
  %%                      / via-extension
  parse('via', Bin) ->
      {{<<"SIP">>, Version, Transport}, Bin2} = parse_sent_protocol(Bin),
      % Parse parameters (which should start with semicolon)
      {Host, Port, Bin3} = sip_binary:parse_host_port(Bin2),
  
negative.code:     {media(Type2, SubType2, Params), Rest}.
  
  
  %% Parse `Alert-Info' or `Call-Info' like headers
  parse_info(Name, Bin, ParamFun) ->
      <<?LAQUOT, Bin2/binary>> = sip_binary:trim_leading(Bin),
      {URI, <<?RAQUOT, Bin3/binary>>} = sip_binary:parse_until(Bin2, ?RAQUOT),
  