anchor.diff:                                  {'max-forwards', 70},
                                   {via, sip_headers:via(udp, "localhost", [])},
                                   {require, <<"foo">>}]},
  -    ValidResponse = create_response(ValidRequest, 200),
  -
  -    % No contact in dialog-establishing request/response
  -    InvalidRequest = replace_top_header(cseq, sip_headers:cseq(1, 'INVITE'), ValidRequest#sip_request{method = 'INVITE'}),
  -    InvalidResponse = create_response(InvalidRequest, 200),
  +    ValidResponse = sip_message:create_response(ValidRequest, 200),
  +
  +    % No contact in dialog-establishing request
  +    InvalidRequest = sip_message:replace_top_header(
  +                       cseq,
  +                       sip_headers:cseq(1, 'INVITE'),
  +                       ValidRequest#sip_request{method = 'INVITE'}),
   
       % with added contact header
  -    ValidRequest2 = append_header(contact, sip_headers:address(<<>>, <<"sip:alice@localhost">>, []), InvalidRequest),
  -    ValidResponse2 = append_header(contact, sip_headers:address(<<>>, <<"sip:alice@localhost">>, []), InvalidResponse),
  -    ValidResponse3 = create_response(InvalidRequest, 300), % not dialog-establishing response
  +    ValidRequest2 = sip_message:append_header(contact, sip_headers:address(<<>>, <<"sip:alice@localhost">>, []), InvalidRequest),
   
       % Contact is not sips URI, but top route is
  -    InvalidRequest2 = append_header(route, sip_headers:address(<<>>, <<"sips:proxy@localhost">>, []), ValidRequest2),
  -    ValidRequest3 = replace_top_header(contact, sip_headers:address(<<>>, <<"sips:alice@localhost">>, []), InvalidRequest2),
  -
  -
  -    [% Header lookup functions
  -     ?_assertEqual(Via1, header_top_value('via', #sip_request{headers = [{'via', [Via1, Via2]}]})),
  -     ?_assertEqual([Via1, Via2, Via1Up], header_values('via', #sip_request{headers = [{'via', Via1}, {'via', [Via2, Via1Up]}]})),
  -
  -     ?_assertEqual(true, has_header(via, #sip_request{headers = [{via, [Via1, Via2]}]})),
  -     ?_assertEqual(false, has_header(via, #sip_request{headers = [{'content-length', 5}]})),
  -
  -     % Fold Via's (extract hostnames in reverse order)
  -     ?_assertEqual(["localhost", "127.0.0.2", "127.0.0.1"],
  -                   foldl_headers(via, fun (#sip_hdr_via{host = Host}, Acc) -> [Host | Acc] end, [],
  -                                 #sip_request{headers = [{'via', Via1}, {'via', [Via2, Via1Up]}]})),
  -
  -     % Validation
  +    InvalidRequest2 = sip_message:append_header(route, sip_headers:address(<<>>, <<"sips:proxy@localhost">>, []), ValidRequest2),
  +    ValidRequest3 = sip_message:replace_top_header(contact, sip_headers:address(<<>>, <<"sips:alice@localhost">>, []), InvalidRequest2),
  +
  +    % Valid response
  +    ValidResponse = sip_message:create_response(ValidRequest, 200),
  +
  +    % Without a Via header
  +    InvalidResponse = ValidResponse#sip_response{headers = [{Name, Value} || {Name, Value} <- ValidResponse#sip_response.headers, Name =/= via]},
  +
  +    [% Request validation
        ?_assertEqual(ok, validate_request(ValidRequest)),
        ?_assertEqual({error, {invalid, contact}}, validate_request(InvalidRequest)),
        ?_assertEqual(ok, validate_request(ValidRequest2)),
  -     ?_assertEqual({error, {invalid, contact}}, validate_request(InvalidRequest2)),
  +     ?_assertEqual({error, {invalid, contact_must_be_sips}}, validate_request(InvalidRequest2)),
        ?_assertEqual(ok, validate_request(ValidRequest3)),
   
   
  -     % Validation
  +     % Response validation
        ?_assertEqual(ok, validate_response(ValidResponse)),
  -     ?_assertEqual({error, {invalid, contact}}, validate_response(InvalidResponse)),
  -     ?_assertEqual(ok, validate_response(ValidResponse2)),
  -     ?_assertEqual(ok, validate_response(ValidResponse3))
  +     ?_assertEqual({error, {invalid, via}}, validate_response(InvalidResponse))
        ].
   
   -spec update_header_test() -> ok.
  
positive.code:         606 -> <<"Not Acceptable">>
      end.
  
  %% @doc Retrieve headers from SIP request/response
  %% @end
  -spec headers(sip_message()) -> sip_headers().
  
negative.code:     Via2 = sip_headers:via(tcp, {"127.0.0.2", 15060}, [{ttl, 4}]),
      Via1Up = sip_headers:via(udp, {"localhost", 5060}, []),
  
      [% Header lookup functions
       ?_assertEqual(Via1, header_top_value('via', #sip_request{headers = [{'via', [Via1, Via2]}]})),
       ?_assertEqual([Via1, Via2, Via1Up], header_values('via', #sip_request{headers = [{'via', Via1}, {'via', [Via2, Via1Up]}]})),
  
       ?_assertEqual(true, has_header(via, #sip_request{headers = [{via, [Via1, Via2]}]})),
       ?_assertEqual(false, has_header(via, #sip_request{headers = [{'content-length', 5}]})),
  
       % Fold Via's (extract hostnames in reverse order)
       ?_assertEqual(["localhost", "127.0.0.2", "127.0.0.1"],
                     foldl_headers(via, fun (#sip_hdr_via{host = Host}, Acc) -> [Host | Acc] end, [],
                                   #sip_request{headers = [{'via', Via1}, {'via', [Via2, Via1Up]}]}))
       ].
  
  -spec validation_test_() -> list().
  validation_test_() ->
      URI = <<"sip@nowhere.invalid">>,
      ValidRequest =
          #sip_request{method = 'OPTIONS',
  