anchor.diff:  	TypeInfo ->
   	    ?debug("Typeinfo:\n~p\n", [TypeInfo]),
   	    stop_type_env_process(),
  -	    %% propagate type info form variables to atoms 
  -	    %% to which the variables are bound to.
   	    prop_type_info(AnnAST1, TypeInfo)
       end.
   
   
  -%% Annotate a function.
  -%%NOTE:LIMITATION HERE: How to handle functions with multiple clauses?
  -do_type_ann(F) ->
  -    case refac_syntax:type(F) of
  -	function->   
  -	    Name = refac_syntax:function_name(F),
  -	    Cs = [do_type_ann_clause(C,refac_syntax:clause_patterns(C)) ||
  -		     C <- refac_syntax:function_clauses(F)],
  -	    refac_syntax:function(Name, Cs);	    
  -	_ ->
  -	    F
  -    end.
  -
  -%% Annotate a function clause.
  -%% LIMITATION HERE: does not handle complex patterns yet.
  +do_type_ann(Form) ->
  +    case refac_syntax:type(Form) of
  +      function ->
  +	  Ann = refac_syntax:get_ann(Form),
  +	  {value, {fun_def, {M, F, A, _, _}}}=lists:keysearch(fun_def,1,Ann),
  +	  Name = refac_syntax:function_name(Form),
  +	  Cs = [refac_util:full_buTP(fun do_type_ann_clause/2, C, refac_syntax:clause_patterns(C))
  +		|| C <- refac_syntax:function_clauses(Form)],
  +	  CsPats = [refac_syntax:clause_patterns(C) || C <- refac_syntax:function_clauses(Form)],
  +	  TypeInfo = get_all_type_info(),
  +	  CsPatsTypes = [[get_pat_type(P, TypeInfo)|| P <- CPats] || CPats <- CsPats],
  +	  ZippedCsPatsTypes = zip_list(CsPatsTypes),
  +	  PatTypes = [lists:usort(Ts) || Ts <- ZippedCsPatsTypes],
  +	  ?debug("MFA:\n~p\n", [{M,F,A}]),
  +	  ?debug("ParTypes:\n~p\n", [[hd(PT)||PT<-PatTypes]]),
  +	  case lists:all(fun (T) -> length(T) == 1 end, PatTypes) andalso 
  +	       lists:any(fun(T) -> T/=[any] end, PatTypes) of
  +	    true ->
  +		Ts = {{M, F, A}, {[hd(PT)||PT<-PatTypes], any}},
  +		refac_io:format("Ts:\n~p\n", [Ts]),
  +		add_to_type_env([Ts]);
  +	      _ -> ok
  +	  end,
  +	  refac_syntax:function(Name, Cs);
  +      _ ->
  +	  Form
  +    end.
  + 
   do_type_ann_clause(Node, Pats) ->
  -    Ann = refac_syntax:get_ann(Node),
  -    {value, {fun_def, {M, F, A, _, _}}}=lists:keysearch(fun_def,1,Ann),
  -    C =refac_util:full_buTP(fun do_type_ann_clause_1/2, Node, Pats),
  -    TypeInfo = get_all_type_info(),
  -    Fun= fun(P) ->
  -		 case refac_syntax:type(P) of
  -		     variable ->
  -			 As = refac_syntax:get_ann(P),
  -			 case lists:keysearch(def,1,As) of
  -			     {value, {def, [DefinePos]}} ->
  -				 case lists:keysearch(DefinePos,1, TypeInfo) of
  -				     {value, {DefinePos, {type, T}}} ->
  -					 T;
  -				     _ -> any
  -				 end;
  -			     _ -> any
  -			 end;
  -		     _ -> any
  -		 end
  -	 end,
  -    Ts = {{M, F, A}, {lists:map(Fun, Pats),any}},
  -    add_to_type_env([Ts]),
  -    ?debug("Ts:\n~p\n", [Ts]),
  -    C.
  -
  -do_type_ann_clause_1(Node, Pats) ->
  -    Fun=fun(N, Type) ->
  -		case refac_syntax:type(N) of
  -		    variable ->
  -			?debug("Type:\n~p\n", [Type]),
  -			add_type_info({type, Type}, N);
  -		    _ ->
  -			N
  -		end
  -	end,
       case refac_syntax:type(Node) of
  -	application ->
  +      application ->
   	    Op = refac_syntax:application_operator(Node),
   	    Args = refac_syntax:application_arguments(Node),
  -	    Arity = length(Args),
  -	    case lists:keysearch(fun_def, 1, refac_syntax:get_ann(Op)) of 
  -		{value, {fun_def, {M, F, A, _, _}}} 
  -		when M=/='_' andalso F=/='_'  -> %% both module name and function name are known;
  +	    case lists:keysearch(fun_def, 1, refac_syntax:get_ann(Op)) of
  +	    {value, {fun_def, {M, F, A, _, _}}}
  +		  when
  +		      M =/= '_' andalso F =/= '_' -> 
   		    Args1 = do_type_ann_args({M, F, A}, map_args(Pats, Args), Args),
   		    refac_util:rewrite(Node, refac_syntax:application(Op, Args1));
   		_ -> %% Either module name or function name is not an atom;
  -		    case refac_syntax:type(Op) of
  -			variable ->
  -			    Op1 = add_type_info({type, {f_atom, ['_', try_eval(Op, fun is_atom/1), Arity]}}, Op),
  -			    refac_util:rewrite(Node, refac_syntax:application(Op1, Args));
  -			module_qualifier ->
  -			    M = refac_syntax:module_qualifier_argument(Op),
  -			    F = refac_syntax:module_qualifier_body(Op),
  -			    M1 = Fun(M, m_atom),
  -			    F1 = Fun(F, {f_atom, [try_eval(M, fun is_atom/1),try_eval(F, fun is_atom/1), Arity]}),
  -			    Op1 = refac_util:rewrite(Op, refac_syntax:module_qualifier(M1, F1)),
  -			    refac_util:rewrite(Node, refac_syntax:application(Op1, Args));
  -			tuple -> 
  -			    case refac_syntax:tuple_elements(Op) of
  -				[M, F] ->
  -				    M1 = Fun(M, m_atom),
  -				    F1 = Fun(F, {f_atom, [try_eval(M, fun is_atom/1), try_eval(M, fun is_atom/1), Arity]}),
  -				    Op1 = refac_util:rewrite(Op, refac_syntax:tuple([M1, F1])),
  -				    refac_util:rewrite(Node, refac_syntax:application(Op1, Args));
  -				_ ->
  -				    Node
  -			    end;
  -			_ -> Node
  -		    end
  +		    do_type_ann_op(Node)
   	    end;
  +	_ -> Node
  +    end.
  +
  +do_type_ann_op(Node) ->
  +    Fun = fun (N, Type) -> 
  +		  case refac_syntax:type(N) of
  +		      variable ->
  +			  ?debug("Type:\n~p\n", [Type]),
  +			  add_type_info({type, Type}, N);
  +		      _ -> N
  +		  end
  +	  end,
  +    Op = refac_syntax:application_operator(Node),
  +    Args = refac_syntax:application_arguments(Node),
  +    Arity = length(Args),
  +    case refac_syntax:type(Op) of
  +	variable ->
  +	    Op1 = add_type_info({type, {f_atom, ['_', try_eval(Op, fun is_atom/1), Arity]}}, Op),
  +	    refac_util:rewrite(Node, refac_syntax:application(Op1, Args));
  +	module_qualifier ->
  +	    M = refac_syntax:module_qualifier_argument(Op),
  +	    F = refac_syntax:module_qualifier_body(Op),
  +	    M1 = Fun(M, m_atom),
  +	    F1 = Fun(F, {f_atom, [try_eval(M, fun is_atom/1), try_eval(F, fun is_atom/1), Arity]}),
  +	    Op1 = refac_util:rewrite(Op, refac_syntax:module_qualifier(M1, F1)),
  +	    refac_util:rewrite(Node, refac_syntax:application(Op1, Args));
  +	tuple ->
  +	    case refac_syntax:tuple_elements(Op) of
  +	      [M, F] ->
  +		  M1 = Fun(M, m_atom),
  +		  F1 = Fun(F, {f_atom, [try_eval(M, fun is_atom/1), try_eval(M, fun is_atom/1), Arity]}),
  +		  Op1 = refac_util:rewrite(Op, refac_syntax:tuple([M1, F1])),
  +		  refac_util:rewrite(Node, refac_syntax:application(Op1, Args));
  +	      _ ->
  +		  Node
  +	  end;
   	_ -> Node
       end.
   
  
positive.code: 	    case get_type_info({M, F, A}) of 
  		none -> Args;
  		{ParTypes, _RtnTypes} ->
  		    ?debug("ParTypes:\n~p\n", [ParTypes]),
  		    do_type_ann_args_1(ParTypes, MappedArgs, Args)
  	    end;
  	{ParTypes, _RtnType} ->
  
negative.code: 	{From, get_all} ->
  	    From ! {type_env, Env},
  	    type_env_loop(Env);
  	stop ->
  	    ok
      end.
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%                                                                       %%
  %%                 Utility Functions                                     %%
  %%                                                                       %%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  
  try_eval(Expr, Cond) when is_function(Expr) ->
      fun (X) -> try_eval(Expr(X), Cond) end;
  try_eval(Expr, Cond) ->
      E = refac_syntax:revert(Expr),
      try
        erl_eval:expr(E, [])
      of
        {value, V, _} ->
  	    ?debug("V:\n~p\n", [V]),
  	    case Cond(V) of
  		true -> V;
  		_ -> '_'
  	    end
      catch
  	_E1:_E2 ->
  	    ?debug("Expr:\n~p\n", [Expr]),
  	    As = refac_syntax:get_ann(Expr),
  	    case lists:keysearch(value, 1, As) of
  		{value, {value, {{_, V}, _DefPos}}} ->
  		    case Cond(V) of
  			true ->
  			    ?debug("V:\n~p\n", [V]),
  			    V;
  			_ -> '_'
  		    end;
  		_ -> '_'
  	    end
      end.
  
  try_eval_length(Expr) when is_function(Expr) ->
      fun (X) -> try_eval_length(Expr(X)) end;
  try_eval_length(Expr) ->
      E = refac_syntax:revert(mk_length_app(Expr)),
      try
        erl_eval:expr(E, [])
      of
        {value, V, _} ->
  	  V
      catch
        _E1:_E2 ->
  	  As = refac_syntax:get_ann(Expr),
  	  ?debug("As:\n~p\n", [As]),
  	  case lists:keysearch(value, 1, As) of
  	    {value, {value, {{list, V}, _DefPos}}} ->
  		V;
  	    _ ->
  		?debug("Expr:\n~p\n", [Expr]),
  		case refac_syntax:type(Expr) of
  		  list -> refac_syntax:list_length(Expr);
  		  _ -> '_'
  		end
  	  end
      end.
  
  mk_length_app(Expr) ->
      refac_syntax:set_pos(refac_syntax:application(
  			   refac_syntax:set_pos(
  			     refac_syntax:atom(length), {1, 1}), [Expr]), {1, 1}).
  
  
  zip_list(ListOfLists) ->    
      zip_list_1(ListOfLists, []).
  		      
  zip_list_1([[]|_T], Acc)  ->
      Acc;
  zip_list_1(ListOfLists, Acc)->      
      zip_list_1([tl(L) || L <-ListOfLists], Acc ++ [[hd(L)|| L  <- ListOfLists]]).
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%                                                                       %%
  %%                 Hard Coded Type Info                                  %%
  %%                                                                       %%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  type(erlang, apply, 3) ->
      {[m_atom, fun(Args)->
  		      [A1, A2, A3] = Args, 
  		      {f_atom, [try_eval(A1, fun is_atom/1), try_eval(A2, fun is_atom/1),
  				try_eval_length(A3)]}
  	      end, any], any};
  type(_, _, _) -> 
      none.
  
      
  sorted_funs(File) ->
     CallGraph = wrangler_callgraph_server:get_callgraph([File]),
     lists:append(CallGraph#callgraph.scc_order).
  
  