anchor.diff:  
   -export([try_eval/2]).
   
  -%% -define(DEBUG, true).
  +-compile(export_all).
  +
  +%%-define(DEBUG, true).
   
   -ifdef(DEBUG).
   -define(debug(__String, __Args), ?wrangler_io(__String, __Args)).
  
positive.code: 	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_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 ->
  	    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;
  		    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
  	    end;
  	_ -> Node
      end.
  
  
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).
  
  