anchor.diff:  %%           ViaList = list() of string(), string() = the contents of
   %%                     Via: header. Usually the result of
   %%                     keylist:fetch('via', Header)
  -%%           Header = keylist record()
  +%%           Header  = keylist record()
   %% Descrip.: parse header data
   %% Returns : list() of via record() | throw()
   %%--------------------------------------------------------------------
   via(Header) when is_record(Header, keylist) ->
  -    via(keylist:fetch('via', Header));
  -
  -via([]) ->
  -    [];
  -via([String | Rest]) ->
  -    Headers = comma(String),
  -    lists:append(lists:map(fun(H) ->
  -				   [Protocol, Sentby] = string:tokens(H, " "),
  -				   [Hostport | Parameters ] = string:tokens(Sentby, ";"),
  -				   case sipparse_util:parse_hostport(Hostport) of
  -				       {Host, Port} when is_list(Host),
  -							 is_integer(Port); Port == none ->
  -					   #via{proto=Protocol, host=Host, port=Port, param=Parameters};
  -				       _ ->
  -					   throw({error, unparseable_via})
  -				   end
  -			   end, Headers),
  -		 via(Rest)).
  -
  +    via2(keylist:fetch('via', Header), []);
  +
  +via(Vias) when is_list(Vias) ->
  +    via2(Vias, []).
  +
  +via2([H | T], Res) when is_list(H) ->
  +    %% Parse SIP version and protocol ("SIP/2.0/FOO" part)
  +    {SIP1, Rest1} = sipparse_util:split_fields(H, $/),
  +    SIP = sipparse_util:strip(SIP1, both, [?SP, ?HTAB]),
  +    {Ver1, Rest2} = sipparse_util:split_fields(Rest1, $/),
  +    Ver = sipparse_util:strip(Ver1, both, [?SP, ?HTAB]),
  +    {ProtoHostport1, Parameters} = case catch sipparse_util:split_fields(Rest2, $;) of
  +				       {error, no_second_part} ->
  +					   [Rest2_1] = string:tokens(Rest2, ";"),
  +					   {Rest2_1, ""};
  +				       {Rest2_1, Rest2_2} ->
  +					   %% XXX strip the tokenized values?
  +					   {Rest2_1, string:tokens(Rest2_2, ";")};
  +				       {Rest2_1} ->
  +					   {Rest2_1, ""}
  +				   end,
  +    %% Strip horizontal whitespace from ProtoHostport
  +    ProtoHostport = sipparse_util:strip(ProtoHostport1, both, [?SP, ?HTAB]),
  +
  +    {ok, Proto, Hostport} = via_proto_hostport(ProtoHostport),
  +
  +    %% Handle sent-by (Hostport)
  +    case sipparse_util:parse_hostport(Hostport) of
  +	{Host, Port} when is_list(Host),
  +			  is_integer(Port); Port == none ->
  +	    Protocol = lists:concat([SIP, "/", Ver, "/", Proto]),
  +	    This = #via{proto=Protocol, host=Host, port=Port, param=Parameters},
  +	    via2(T, [This | Res]);
  +	_ ->
  +	    throw({error, unparseable_via})
  +    end;
  +via2([], Res) ->
  +    lists:reverse(Res).
  +
  +%% via_proto_hostport/1 - part of via/1. Returns : {ok, Proto, Hostport} | throw()
  +via_proto_hostport(ProtoHostport) ->
  +    %% Split ProtoHostport - can result in either two, three or four elements
  +    case string:tokens(ProtoHostport, [?SP, ?HTAB]) of
  +	[Proto1, Hostport1] ->
  +	    {ok, Proto1, Hostport1};
  +	[Proto1, Host1, Port1] ->
  +	    %% Check if last character in Host1 is a colon
  +	    case lists:reverse(Host1) of
  +		":" ++ RHost2 ->
  +		    %% Vias can have whitespace between host and colon and
  +		    %% colon and port - crazy
  +		    Host2 = lists:reverse(
  +			      sipparse_util:strip(RHost2, left, [?SP, ?HTAB])
  +			     ),
  +		    {ok, Proto1, Host2 ++ ":" ++ Port1};
  +		_ ->
  +		    %% check if first character in port is a colon
  +		    case hd(Port1) == $: of
  +			true ->
  +			    {ok, Proto1, Host1 ++ Port1};
  +			false ->
  +			    throw({error, {invalid_proto_host_port_in_via, ProtoHostport}})
  +		    end
  +	    end;
  +	[Proto, Host, ":", Port] ->
  +	    %% Vias can have whitespace both between host and colon, and colon and port - crazy
  +	    {ok, Proto, Host ++ ":" ++ Port}
  +    end.
  +    
   %%--------------------------------------------------------------------
   %% Function: topvia(Header)
   %%           Header = keylist record()
  
positive.code:     io:format("test: name_header/1 - 6 (disabled)~n"),
      %% test with quoted quotes in the display name
      %%{"Quoted \\\" here", NameHeaderURI1} = name_header("\"Quoted \\\" here\" <sip:ft@example.org>"),
          
  
      %% test via_is_equal(A, B)
      %%--------------------------------------------------------------------
  
negative.code:     io:format("test: get_tag/1 - 3~n"),
      none = get_tag(["\"Fredrik\" <sip:ft@example.org>;test=auto"]),
  
      io:format("test: get_tag/1 - 4~n"),
      %% >;tag= appearing more than once
      "foo" = get_tag(["\"Evil <evil>;tag=bar displayname\" <sip:ft@example.org>;tag=foo"]),
  
      io:format("test: get_tag/1 - 5~n"),
      %% token names (tag=) should be case-insensitive
      "foo" = get_tag(["<sip:ft@example.org>;Tag=foo"]),
  
  
      %% test dialogid(Header)
      %%--------------------------------------------------------------------
  