anchor.diff:       ?_assertEqual(true, is_response(Response)),
        ?_assertEqual(true, is_provisional_response(ProvResponse)),
        ?_assertEqual(false, is_provisional_response(Response)),
  +     ?_assertEqual(true, is_redirect_response(RedResponse)),
  +     ?_assertEqual(false, is_redirect_response(Response)),
        ?_assertEqual(<<"INVITE sip:urn:service:test SIP/2.0\r\nContent-Length: 5\r\nx-custom: Nothing\r\n\r\nHello">>, to_binary(Request)),
        ?_assertEqual(<<"SIP/2.0 200 Ok\r\nContent-Length: 5\r\n\r\nHello">>, to_binary(Response))
       ].
  
positive.code: -spec is_provisional_response(#sip_message{}) -> boolean().
  is_provisional_response(#sip_message{kind = #sip_response{status = Status}}) ->
      Status >= 100 andalso Status =< 199.
  
  %% @doc Retrieve method of SIP message
  %%
  
negative.code: %% RFC3261 7.1: The SIP-Version string is case-insensitive, but implementations MUST send upper-case.
  -spec parse_start_line(binary()) -> #sip_request{} | #sip_response{}.
  parse_start_line(StartLine) when is_binary(StartLine) ->
      % split on three parts
      [First, Rest] = binary:split(StartLine, <<" ">>),
      [Second, Third] = binary:split(Rest, <<" ">>),
      case {First, Second, Third} of
          {Method, RequestURI, <<?SIPVERSION>>} ->
              #sip_request{method = sip_binary:binary_to_existing_atom(sip_binary:to_upper(Method)),
                           uri = RequestURI};
  
          {<<?SIPVERSION>>, <<A,B,C>>, ReasonPhrase} when
            $1 =< A andalso A =< $6 andalso % 1xx - 6xx
            $0 =< B andalso B =< $9 andalso
            $0 =< C andalso C =< $9 ->
              #sip_response{status = list_to_integer([A, B, C]),
                            reason = ReasonPhrase}
      end.
  