anchor.diff:  to_lower(Key) ->
       Key.
   
  +%%--------------------------------------------------------------------
  +%% Function: to_lower_list(Keys)
  +%%           Keys = list() of string(), the name of a field in a sip 
  +%%           message 
  +%% Descrip.: convert header key, to a standard format - lowercase and
  +%%           verbose string() 
  +%% Returns : list() of string()
  +%%--------------------------------------------------------------------
   to_lower_list(Keys) ->
       lists:map(fun(Key) ->
   		      to_lower(Key)
   	      end, Keys).
   
  -fetch(Key, List) when record(List, keylist) ->
  -    fetchcase(to_lower(Key), List#keylist.list);
  -fetch(Key, List) ->
  -    erlang:fault("Keylist not wellformed", [Key, List]).
  -
  -fetchcase(Key, []) ->
  -    [];
  -fetchcase(Key, [Elem | List]) when record(Elem, keyelem), Elem#keyelem.casekey == Key ->
  -    Elem#keyelem.item;
  -fetchcase(Key, [Elem | List]) when record(Elem, keyelem) ->
  -    fetchcase(Key, List);
  -fetchcase(Key, [Elem | List]) ->
  -    erlang:fault("Keylist element not wellformed", [Key, [Elem | List]]).
  -
  -empty() ->
  -    #keylist{list=[]}.
  -
  -appendlist(Keylist, List) when record(Keylist, keylist) ->
  -    Func = fun ({Key, Item}, KeylistAcc) ->
  -		   append({Key, Item}, KeylistAcc)
  -	   end,
  -    lists:foldl(Func, Keylist, List).
  -
  -from_list(List) ->
  -    appendlist(empty(), List).
  -
  -append({Key, NewValueList}, List) when record(List, keylist) ->
  -    mod(Key, fun (Valuelist) ->
  -			 lists:append(Valuelist, NewValueList)
  -		 end, List).
  -
  -prepend({Key, NewValueList}, List) when record(List, keylist) ->
  -    mod(Key, fun (Valuelist) ->
  -			 lists:append(NewValueList, Valuelist)
  -		 end, List).
  -
  -delete(Key, List) when record(List, keylist) ->
  -    Casekey = to_lower(Key),
  -    #keylist{list=del(Casekey, List#keylist.list)}.
  -
  -deletefirstvalue(Key, List) when record(List, keylist) ->
  -    mod(Key, fun (Valuelist) ->
  -			 case Valuelist of
  -			     [Item | Rest] ->
  -				 Rest;
  -			     [] ->
  -				 []
  -			 end
  -		 end, List).
  -
  -set(Key, Valuelist, List) when record(List, keylist) ->
  -    mod(Key, fun (_) ->
  -			 Valuelist
  -		 end, List).
  -
  +%%--------------------------------------------------------------------
  +%% Function: mod(Key, Func, List)
  +%%           Key = string(), the name of a field in a sip message 
  +%%           Func = fun()
  +%%           List = keylist record()
  +%% Descrip.: apply Func to all elements E; 
  +%%           E#keyelem{item = F(E#keyelem.item)} - in List, where
  +%%           E#keyelem.casekey == to_lower(Key)
  +%%           A new #keyelem{key=Key, 
  +%%                          casekey=to_lower(CaseKey), 
  +%%                          item=Func([])} 
  +%%           is added if Key isn't found
  +%% Returns : keylist record()
  +%%--------------------------------------------------------------------
   mod(Key, Func, List) when record(List, keylist) ->
       Casekey = to_lower(Key),
       #keylist{list=modcase(Key, Casekey, Func, List#keylist.list)}.
  
positive.code: -module(keylist).
  -export([fetch/2, from_list/1, append/2, prepend/2,
  	 delete/2, deletefirstvalue/2, set/3, copy/2, appendlist/2, map/2]).
  
  -record(keylist, {list}).
  -record(keyelem, {key, casekey, item}).
  
  % This is to support the compact headers we are required to support
  % by RFC3261 7.3.3.
  
negative.code:     [#keyelem{key=Key,
  	      casekey=Casekey,
  	      item=Func([])}];
  %% stop after first addition
  modcase(Key, Casekey, Func, [Elem | List]) when record(Elem, keyelem), Elem#keyelem.casekey == Casekey ->
      [Elem#keyelem{item=Func(Elem#keyelem.item)} | List];
  modcase(Key, Casekey, Func, [Elem | List]) when record(Elem, keyelem) ->
      [Elem | modcase(Key, Casekey, Func, List)].
  
  
  %%--------------------------------------------------------------------
  %% Note: It may be preferable to store the #keyelem.casekey field as 
  %% a atom() rather than a string() - this should speed up 
  %% patternmatching, but don't store random strings as atom(), as 
  %% atoms are not GCed. It may be possible to convert the headers tags
  %% to atom() when parsed initialy so that yxa can treat them as atom()
  %% internaly and only output them as string().
  %% 
  %% Note: this module does some costly list operations, appendning
  %% elements to the end of lists.
  %% There may be datastructure better suited for this need, of adding
  %% elements to both front and end of lists, but note that most 
  %% #keyelem.item are probably short, so that the overhead of smarter 
  %% datastructures may still be more costly.
  %% It may also be benificial, when several elements are added to the 
  %% end of a list - to reverse it, append the new elements in revese
  %% order and then reverse the new list back to it's proper order. 
  %% This results in O(3N+2M) rather than O(N * M) (aproximate - M 
  %% grows for each element in N) list hd/1 calls 
  %% (N = new list of elements to add, M = the orginal list). If N is 
  %% small compared to M this results in roughly a O(2M) vs a O(N*M) 
  %% algorithm.
  %%--------------------------------------------------------------------
  