anchor.diff:  
   %% ============================================================================================
  -%% Refactoring: Instrument the program to trace process communication information.
  +%% Refactoring: Add a tag to all the messages received by a process.
   %%
   %% Copyright (C) 2006-2008  Huiqing Li, Simon Thompson
   
  
positive.code: %% Author contact: hl@kent.ac.uk, sjt@kent.ac.uk
  %% 
  %% =============================================================================================
  %% Qn: is it possible to get more static infomration? How to balance the usages of staic and dynamic info?
  %% How do we know the existing trace info is uptodate?
  %% what about the spawn expression has receive expressions?
  
  %% Is theory, it is possible that a  receiver function is shared by different processes (processse with different 
  %% entries); it practice, this rarely happen. We ignore this case for now.
  
  %% special functions involving Pids:
  %% spawn, link, register, send, !, exit ...
  %% =============================================================================================
  -module(refac_add_a_tag).
  
  -export([add_a_tag/5, add_a_tag/6,send_expr_to_region/5]).
  
  -export([counter/0, collector/0,process_trace_info/1, start_collector_process/0]).
  
  -export([trim_callgraph/1]).
  
  -compile(export_all).
  
  -include("../hrl/wrangler.hrl").
  
  
  %% =============================================================================================
  add_a_tag(FileName, Line, Col, Tag, SearchPaths) ->
      io:format("\n[CMD: add_a_tag, ~p, ~p, ~p, ~p,~p]\n", [FileName, Line, Col, Tag, SearchPaths]),
      case refac_util:is_fun_name(Tag) of 
  	true -> case refac_util:parse_annotate_file(FileName, true, SearchPaths) of 
  		    {ok, {AnnAST, Info}} ->
  			 case pos_to_receive_fun(AnnAST, {Line, Col}) of 
  			     {ok, FunDef} ->
  				 {value, {module, ModName}} = lists:keysearch(module, 1, Info),
  				 FunName = refac_syntax:data(refac_syntax:function_name(FunDef)),
  				 FunArity = refac_syntax:function_arity(FunDef),
  				 CallGraph = callgraph(AnnAST, Info, FileName),
  				 ReceiveFuns = collect_receive_funs(AnnAST, Info),
  				 InitialFuns = collect_process_initial_funs(AnnAST, Info),
  				 ReachedReceiveFuns = reached_receive_funs(InitialFuns, CallGraph, ReceiveFuns, Info),
  				 %% get the affected initials by analysing the receiving side.
  				 AffectedInitials = get_affected_initials(ReachedReceiveFuns, {ModName, FunName, FunArity}) ,
  				 %%io:format("AffectInitials (initial result):\n~p\n", [AffectedInitials]),
  				 ProcessedTraceRes =process_trace_info("c:/cygwin/home/hl/distel-wrangler-0.2/test/wrangler_trace_cache"),
  				 FinalAffectedInitials = get_affected_funs_from_send(ProcessedTraceRes, AffectedInitials, ReceiveFuns),
  				 %% io:format("Affected initial functions:\n~p\n", [FinalAffectedInitials]),
  				 ReachedReceiveFuns1 = get_reached_receive_funs_1(FinalAffectedInitials, ReachedReceiveFuns),
  				 %% io:format("Affected receive functions:\n~p\n", [ReachedReceiveFuns1]),
  				 start_collector_process(),
  				 {AnnAST1, Modified} = do_add_a_tag(AnnAST, Tag,ModName, FinalAffectedInitials, ReachedReceiveFuns1, ProcessedTraceRes),
  				 send_collector ! {get, self()},
  			         receive
  				     {collector, S} -> S
  				 end,
  				 send_collector!stop,
  				 if Modified ->
  					 refac_util:write_refactored_files([{{FileName, FileName}, AnnAST1}]),
  					{ok, S};
  				    true ->{ok, []}
  				 end;
  			     _ -> {error, "You have not selected a function containing receive expressions!"}
  			 end;
  		    {error, Reason} -> {error, Reason}
  		end;
  	false  -> {error, "The tag to add should be an atom!"}
      end.
  
  add_a_tag(FileName, TagName, Line1, Col1, Line2, Col2) ->
      F = fun(Node, {Tag, Range}) ->
  		case refac_syntax:type(Node) of 
  		    infix_expr ->
  			case is_send_expr(Node) of 
  			    true ->
  				case refac_util:get_range(Node) of 
  				    Range ->
  					ReceiverPid = refac_syntax:infix_expr_left(Node),
  					Msg = refac_syntax:infix_expr_right(Node),
  					Op  = refac_syntax:infix_expr_operator(Node),
  					Msg1 = case refac_syntax:type(Msg) of 
  						   tuple ->
  						       refac_syntax:tuple([Tag | refac_syntax:tuple_elements(Msg)]);
  						   _ -> refac_syntax:tuple([Tag, Msg])
  					       end,
  					{refac_syntax:infix_expr(ReceiverPid, Op, Msg1), true};
  				    _ ->
  					{Node, false}
  				end;
  			    _ -> {Node, false}
  			end;
  		    _ -> {Node, false}
  		end
  	end,
      case refac_util:parse_annotate_file(FileName, true, []) of  %% Need to fill in the searchpaths.
  	{ok, {AnnAST, _Info}} ->
  	    {AnnAST1, _Modified} = refac_util:stop_tdTP(F, AnnAST, {refac_syntax:atom(TagName), {{Line1, Col1}, {Line2, Col2}}}),
  	    refac_util:write_refactored_files([{{FileName, FileName}, AnnAST1}]),
  	    {ok, []};
  	{error, Reason} ->
  	    {error, Reason}
      end.
      
  test(AnnAST) ->
      F = fun(Node, _Others) ->
  		case refac_syntax:type(Node) of 
  		    function ->
  			io:format("is_process_related_fun:\n~p\n", [is_process_related_fun(Node)]),
  			{Node, true};
  		    _ ->
  			{Node, false}
  		end
  	end,
      refac_util:stop_tdTP(F, AnnAST, []).
  
  annotate_pids(DirList) ->
      Files = refac_util:expand_files(DirList, ".erl"),
      Sccs= trim_callgraph(DirList),
      Sccs2 = lists:concat(Sccs),
      Funs = lists:map(fun({Fun, _FunDef}) -> Fun end, Sccs2),
      Pid = start_fun_typesig_process(Funs),
      Sccs3 = lists:map(fun(S) -> annotate_a_fun(S, Pid) end, Sccs2),
      ASTs=lists:map(fun(F) -> update_function(F, Sccs3) end,  Files),
      _Res = refac_util:full_buTP(fun add_a_tag_to_send_exprs/2, hd(ASTs), []),   
      _Sccs4 = fixpoint(lists:reverse(Sccs3), Pid),
     %% io:format("callgraph:\n~p\n", [lists:map(fun({Fun, _FunDef})-> Fun end, lists:reverse(Sccs4))]),
      Pid ! stop,
      ok.
  	
  
  add_a_tag_to_send_exprs(Node, _TagName) ->
       case refac_syntax:type(Node) of 
   	infix_expr ->
   	    case is_send_expr(Node) of 
   		true ->
   		    _ReceiverPid = refac_syntax:infix_expr_left(Node),
   		    %% io:format("Node:\n~p\n", [ReceiverPid]),
   		    Node;
   		_ -> Node
   	    end;
   	_ -> Node
       end.
  
  fixpoint(Sccs, Pid) ->
      Pid ! {self(), getenv},
      receive 
  	{Pid, Env} ->
  	    Env
      end,
      Sccs4 = lists:map(fun(S) -> topdown_propagate(S, Pid) end, Sccs),
      Pid ! {self(), getenv},
      receive 
  	{Pid, Env1} ->
  	    Env1
      end,
      io:format("Env0:\n~p\n",[Env]),
      io:format("Env1:\n~p\n",[Env1]),
      case Env==Env1 of 
  	true -> 
  	    Pid!stop,
  	    Sccs4;
  	_ ->
  	    fixpoint(Sccs4, Pid)
      end.
  
     
  
  annotate_a_fun({{ModName, FunName, Arity}, FunDef}, TypeSigPid) ->
      EnvPid = start_env_process(),
      FunDef1 = annotate_special_fun_apps({{ModName, FunName, Arity}, EnvPid, FunDef}),
      %% Note
      FunDef2 = refac_util:full_buTP(fun annotate_within_fun/2, FunDef1, {ModName, FunName, Arity, EnvPid, TypeSigPid}), 
      FunDef3 = refac_util:full_buTP(fun annotate_within_fun/2, FunDef2, {ModName, FunName, Arity, EnvPid, TypeSigPid}),
      EnvPid ! stop,
      {{ModName, FunName, Arity}, FunDef3}.
  
  update_function(File, FunList) ->
      {ok, {AnnAST, Info}} = refac_util:parse_annotate_file(File, true, []),
      {value, {module, ModName}} = lists:keysearch(module, 1, Info),
      F = fun(Node, []) ->
  		case refac_syntax:type(Node) of 
  		    function -> FunName = refac_syntax:data(refac_syntax:function_name(Node)),
  				Arity = refac_syntax:function_arity(Node),
  				case lists:keysearch({ModName, FunName, Arity}, 1, FunList) of 
  				    {value, {{ModName, FunName, Arity}, FunDef}} -> {FunDef, true};
  				    _ -> {Node, false}
  				end;				    
  		    _ -> {Node, false}
  		end
  	end,
      {AnnAST1, _} = refac_util:stop_tdTP(F, AnnAST, []),
      AnnAST1.
       
  
  %% annotate_sccs([], Acc, Env) ->
  %%      {Acc, Env};
  %% annotate_sccs([Scc|Sccs], Acc, Env) ->
  %%      {Scc1, Env1}= annotate_a_scc(Scc,[],Env),
  %%      annotate_sccs(Sccs, [Scc1|Acc], Env1).
  
  %% annotate_a_scc([],  Acc, Env) ->
  %%     {lists:reverse(Acc), Env};
  %% annotate_a_scc([{Fun, FunDef}|Fs], Acc, Env) ->
  %%     {FunDef1, Env1} = annotate_a_fun({Fun, FunDef}), 
  %%     annotate_a_scc(Fs, [{Fun, FunDef1}|Acc], Env1).
  
  
  
  
  annotate_within_fun(Node, {_ModName, FunName, Arity, Pid, TypeSigPid}) ->
      case refac_syntax:type(Node) of 
  	variable -> 
  	    Ann = refac_syntax:get_ann(Node),
  	    case lists:keysearch(def, 1, Ann) of
  		{value, {def, DefinePos}} ->
  		    Pid ! {self(), get, {def,DefinePos}},
  		    receive
  			{Pid, value, Value} -> 
  			    refac_util:update_ann(Node, Value);
  			{Pid, false} ->    
  			    Node
  		    end;
  		_ -> Node
  	    end;
  	 match_expr->
  	    P = refac_syntax:match_expr_pattern(Node),
  	    B = refac_syntax:match_expr_body(Node),
  	    Ann = refac_syntax:get_ann(B),
  	    case lists:keysearch(process, 1, Ann) of 
  		{value, {process, Value}} ->
  		    P1 = refac_util:update_ann(P, {process, Value}),
  		    case refac_syntax:type(P) of 
  			variable -> Ann1 = refac_syntax:get_ann(P),
  				    {value, {def, DefinePos}} = lists:keysearch(def, 1, Ann1),
  				    Pid ! {add,{{def, DefinePos}, {process, Value}}};
  			_ -> ok                %%% What about the complex pattern matches?
  		    end,
  		    refac_syntax:match_expr(P1, B);
  		_ -> Node
  	    end;
  	application ->
  	    Operator = refac_syntax:application_operator(Node),
  	    Ann = refac_syntax:get_ann(Operator),
  	    case lists:keysearch(fun_def,1, Ann) of 
  		{value, {fun_def, {Mod, F, A, _, _}}}  -> 
  		    Args = refac_syntax:application_arguments(Node),
  		    TypeSigPid!{self(), get, {Mod,F, A}},
  		    Args1 = receive 
  				{TypeSigPid, value, {ParSig, _RtnSig}} ->
  				    lists:map(fun({Arg, T}) ->
  						      case T of 
  							  {process, Value} ->
  							      case refac_syntax:type(Arg) of 
  								  variable ->
  								      Ann1 = refac_syntax:get_ann(Arg),
  								      case lists:keysearch(process, 1, Ann1) of
  									  {value, {process, _Value1}} ->
  									      Node;
  									  false ->
  									      {value, {def, DefinePos}} = lists:keysearch(def,1, Ann1),
  									      Pid ! {add, {{def, DefinePos}, {process, Value}}},
  									      refac_util:update_ann(Arg, {process, Value})
  								      end;
  								  _ ->Ann1 = refac_syntax:get_ann(Arg),  
  								      case lists:keysearch(process, 1, Ann1) of 
  									  {value, {process, _Value}} ->
  									      Node;
  									  false ->
  									      refac_util:update_ann(Arg, {process, Value})
  								      end
  							      end;
  							  _ -> Arg						      
  						      end
  					      end, lists:zip(Args, ParSig));
  				{TypeSigPid, false} -> Args
  			    end,
  		    refac_syntax:copy_attrs(Node, refac_syntax:application(Operator, Args1));		    		    
  		_ ->
  		    Node
  	    end;
  	function ->
  	    Ann = refac_syntax:get_ann(Node),
  	    {value, {fun_def, {Mod, FunName, Arity, _, _}}} = lists:keysearch(fun_def, 1, Ann),
  	    Cs = refac_syntax:function_clauses(Node),
  	    lists:map(fun(C) ->
  			      Ps = refac_syntax:clause_patterns(C),
  			      ArgsInfo = lists:map(fun(P) ->
  							   Ann1 = refac_syntax:get_ann(P),
  							   case lists:keysearch(process,1, Ann1) of 
  							       {value, {process, Value}} ->
  								   {process, Value};
  							       _  -> any
  							   end
  						   end, Ps),
  			      Info = {{Mod, FunName, Arity}, {ArgsInfo, any}},
  			      TypeSigPid ! {add, Info}
  		      end, Cs),
  	    Node;
  	_ -> Node
      end.
  
  topdown_propagate({{ModName, FunName, Arity}, FunDef}, TypeSigPid) ->
      EnvPid = start_env_process(),
      FunDef2 = do_topdown_propagate(FunDef, {ModName, FunName, Arity, EnvPid, TypeSigPid}),
      FunDef3 = refac_util:full_buTP(fun annotate_within_fun_1/2, FunDef2, {ModName, FunName, Arity, EnvPid, TypeSigPid}),
      EnvPid ! stop,
      {{ModName, FunName, Arity}, FunDef3}.
  
  do_topdown_propagate(FunDef, {_ModName, FunName, Arity, EnvPid, TypeSigPid}) ->
      F = fun(Pat, Typ) ->
  	       Ann = refac_syntax:get_ann(Pat),
  	       case lists:keysearch(process,1, Ann) of 
  		   {value, {process, Value}} ->
  		       case Typ of 
  			   any -> {process, Value};
  			   {process, []} -> {process, Value};
  			   {process, Value1} -> {process, lists:usort(Value++Value1)}
  		       end;
  		   false ->
  		       Typ
  	       end
  	end,
      F2 = fun(Node, _Others) ->
  		 case refac_syntax:type(Node) of 
  		     application ->
  			 Operator = refac_syntax:application_operator(Node),
  			 Ann = refac_syntax:get_ann(Operator),
  			 case lists:keysearch(fun_def,1, Ann) of 
  			     {value, {fun_def, {M1, F1, A1, _P1, _P2}}}  -> 
  				 Args = refac_syntax:application_arguments(Node),
  				 TypeSigPid ! {self(), get, {M1, F1, A1}},
  				 receive
  				     {TypeSigPid, value, {ParSig, _RtnSig}} ->
  					 ArgsInfo = lists:map(fun({A, P}) -> F(A,P) end, lists:zip(Args, ParSig)),
  					 Info = {{M1, F1, A1}, {ArgsInfo, any}}, %% any is for the return type of the function.
  					 
  					 TypeSigPid!{add, Info};
  				     {TypeSigPid, false} ->
  					 ok
  				 end,
  				 Node;
  			     _ ->
  				 Node
  			 end;
  		     variable ->
  			 Ann = refac_syntax:get_ann(Node),
  			 case lists:keysearch(def, 1, Ann) of
  			     {value, {def, DefinePos}} ->
  				 EnvPid ! {self(), get, {def,DefinePos}},
  				 receive
  				     {EnvPid, value, Value} -> 
  					 refac_util:update_ann(Node, Value);
  				     {EnvPid, false} ->    
  					 Node
  				 end;
  			     _ -> Node
  			 end;
  		     _  -> 
  			 Node
  		 end
  	 end,
      Ann = refac_syntax:get_ann(FunDef),
      {value, {fun_def, {Mod, FunName, Arity, _, _}}} = lists:keysearch(fun_def,1, Ann),
      TypeSigPid ! {self(), get, {Mod, FunName, Arity}},
      receive
  	{TypeSigPid, value, {ParsSig, _RtnSig}} -> 
  	    FunName1 = refac_syntax:function_name(FunDef),
  	    Cs = refac_syntax:function_clauses(FunDef),
  	    Cs1 = lists:map(fun(C) -> Ps = refac_syntax:clause_patterns(C),
  				      B = refac_syntax:clause_body(C),
  				      G = refac_syntax:clause_guard(C),
  				      Ps1 = lists:map(fun({P,T}) ->  %% what about complex parameters.
  							      case refac_syntax:type(P) of 
  								  variable ->
  								      case T of 
  									  {process, Value} -> 
  									      Ann1 = refac_syntax:get_ann(P),
  									      {value, {def, DefinePos}} = lists:keysearch(def, 1,Ann1),
  									      EnvPid ! {add, {{def, DefinePos}, {process, Value}}},
  									      refac_util:update_ann(P, {process, Value});
  									  _ -> P
  								      end;
  								  _  -> P
  							      end
  						      end, lists:zip(Ps, ParsSig)),
  				      C1 = refac_syntax:copy_attrs(C, refac_syntax:clause(Ps1, G, B)),
  				      refac_util:full_buTP(F2, C1, [])
  			    end, Cs),
    		    refac_syntax:copy_attrs(FunDef, refac_syntax:function(FunName1, Cs1));
  	{TypeSigPid, false} -> FunDef
      end.
  
  
  annotate_within_fun_1(Node, {_ModName, _FunName, _Arity, Pid, _TypeSigPid}) ->
      case refac_syntax:type(Node) of 
  	variable -> 
  	    Ann = refac_syntax:get_ann(Node),
  	    case lists:keysearch(def, 1, Ann) of
  		{value, {def, DefinePos}} ->
  		    Pid ! {self(), get, {def,DefinePos}},
  		    receive
  			{Pid, value, Value} -> 
  			    refac_util:update_ann(Node, Value);
  			{Pid, false} ->    
  			    Node
  		    end;
  		_ -> Node
  	    end;
  	 match_expr->
  	    P = refac_syntax:match_expr_pattern(Node),
  	    B = refac_syntax:match_expr_body(Node),
  	    Ann = refac_syntax:get_ann(B),
  	    case lists:keysearch(process, 1, Ann) of 
  		{value, {process, Value}} ->
  		    P1 = refac_util:update_ann(P, {process, Value}),
  		    case refac_syntax:type(P) of 
  			variable -> Ann1 = refac_syntax:get_ann(P),
  				    {value, {def, DefinePos}} = lists:keysearch(def, 1, Ann1),
  				    Pid ! {add,{{def, DefinePos}, {process, Value}}};
  			_ -> ok                %%% What about the complex pattern matches?
  		    end,
  		    refac_syntax:match_expr(P1, B);
  		_ -> Node
  	    end;
  %% 	application ->
  %% 	    Operator = refac_syntax:application_operator(Node),
  %% 	    Ann = refac_syntax:get_ann(Operator),
  %% 	    case lists:keysearch(fun_def,1, Ann) of 
  %% 		{value, {fun_def, {Mod, F, A, _, _}}}  -> 
  %% 		    Args = refac_syntax:application_arguments(Node),
  %% 		    TypeSigPid!{self(), get, {Mod,F, A}},
  %% 		    Args1 = receive 
  %% 				{TypeSigPid, value, {ParSig, _RtnSig}} ->
  %% 				    lists:map(fun({Arg, T}) ->
  %% 						      case T of 
  %% 							  {process, Value} ->
  %% 							      case refac_syntax:type(Arg) of 
  %% 								  variable ->
  %% 								      Ann1 = refac_syntax:get_ann(Arg),
  %% 								      case lists:keysearch(process, 1, Ann1) of
  %% 									  {value, {process, _Value1}} ->
  %% 									      Node;
  %% 									  false ->
  %% 									      {value, {def, DefinePos}} = lists:keysearch(def,1, Ann1),
  %% 									      Pid ! {add, {{def, DefinePos}, {process, Value}}},
  %% 									      refac_util:update_ann(Arg, {process, Value})
  %% 								      end;
  %% 								  _ ->Ann1 = refac_syntax:get_ann(Arg),  
  %% 								      case lists:keysearch(process, 1, Ann1) of 
  %% 									  {value, {process, _Value}} ->
  %% 									      Node;
  %% 									  false ->
  %% 									      refac_util:update_ann(Arg, {process, Value})
  %% 								      end
  %% 							      end;
  %% 							  _ -> Arg						      
  %% 						      end
  %% 					      end, lists:zip(Args, ParSig));
  %% 				{TypeSigPid, false} -> Args
  %% 			    end,
  %% 		    refac_syntax:copy_attrs(Node, refac_syntax:application(Operator, Args1));	
  		
  %% 		_ ->
  %% 		    Node
  %% 	    end;
  %% 	function ->
  %% 	    Ann = refac_syntax:get_ann(Node),
  %% 	    {value, {fun_def, {Mod, FunName, Arity, _, _}}} = lists:keysearch(fun_def, 1, Ann),
  %% 	    Cs = refac_syntax:function_clauses(Node),
  %% 	    lists:map(fun(C) ->
  %% 			      Ps = refac_syntax:clause_patterns(C),
  %% 			      ArgsInfo = lists:map(fun(P) ->
  %% 							   Ann1 = refac_syntax:get_ann(P),
  %% 							   case lists:keysearch(process,1, Ann1) of 
  %% 							       {value, {process, Value}} ->
  %% 								   {process, Value};
  %% 							       _  -> any
  %% 							   end
  %% 						   end, Ps),
  %% 			      Info = {{Mod, FunName, Arity}, {ArgsInfo, any}},
  %% 			      TypeSigPid ! {add, Info}
  %% 		      end, Cs),
  %% 	    Node;
  	_ -> Node
      end.
  
  annotate_special_fun_apps({{ModName, FunName, Arity}, EnvPid, FunDef}) ->
      refac_util:full_buTP(fun do_annotate_special_fun_apps/2,FunDef, {ModName, FunName, Arity, EnvPid}).
  
  do_annotate_special_fun_apps(Node, {ModName, FunName, Arity, EnvPid}) ->
      F = fun(Args) ->
  		case Args of 
  		     [M, F, A] ->
  			ModName = refac_syntax:atom_value(M),
  			FunName = refac_syntax:atom_value(F),
  			Arity = refac_syntax:list_length(A),
  			{ModName, FunName, Arity};
  		    [_N, M, F, A] ->
  			ModName = refac_syntax:atom_value(M),
  			FunName = refac_syntax:atom_value(F),
  			Arity = refac_syntax:list_length(A),
  			{ModName, FunName, Arity};
  		    [Fun] -> refac_prettypr:format(Fun);
  		    [_N, Fun] -> refac_prettypr:format(Fun)
  		end
  	end,
      case refac_syntax:type(Node) of 
  	application ->
  	    case is_spawn_app(Node) of 
  		true ->
  		    Arguments = refac_syntax:application_arguments(Node),
  		    InitialFun = F(Arguments),
  		    Node1 = refac_util:update_ann(Node, {process, [{pid,InitialFun}]}),
  		    Node1;
  		_ ->case is_self_app(Node) of
  			true ->
  			    CurrentFun = {ModName, FunName, Arity},
  			    %% TODO: NEED TO FIND OUT THE REAL INITIAL FUN.
  			    Node1 = refac_util:update_ann(Node, {process, [{pid, CurrentFun}]}),  
  			    Node1;
  			_ -> case is_register_app(Node) of 
  				 true -> 
  				     Operator = refac_syntax:application_operator(Node),
  				     [RegName, Pid]= refac_syntax:application_arguments(Node),
  				     case lists:keysearch(process, 1, refac_syntax:get_ann(Pid)) of 
  					 {value, {process, [{pid, Value}]}} ->
  					     RegName1 = refac_util:update_ann(RegName,{process, [{pname, Value}]}),
  					     Node1 =refac_syntax:application(Operator, [RegName1, Pid]),
  					     case refac_syntax:type(RegName) of 
  						 variable -> 
  						     Ann1 = refac_syntax:get_ann(RegName), 
  						     {value, {def, DefinePos}} = lists:keysearch(def, 1, Ann1),
  						     EnvPid ! {add, {{def, DefinePos}, {process, [{pname, Value}]}}},
  						     refac_syntax:copy_attrs(Node, Node1);
  						 atom -> 
  						     EnvPid ! {add, {refac_syntax:atom_value(RegName), {process, [{pname, Value}]}}},
  						     refac_syntax:copy_attrs(Node, Node1)
  					     end;
  					 _ ->  Node
  				     end;
  				 _ -> Node
  			     end
  		    end
  	    end;
  	infix_expr ->
   	    case is_send_expr(Node) of 
  		true -> Dest = refac_syntax:infix_expr_left(Node),
  			Ann = refac_syntax:get_ann(Dest),
  			case lists:keysearch(process, 1, Ann) of 
  			    false ->
  				case refac_syntax:type(Dest) of 
  				    variable ->
  					{value, {def, DefinePos}} = lists:keysearch(def, 1, Ann),
  					EnvPid ! {add, {{def, DefinePos}, {process, []}}},
  					refac_util:update_ann(Node,{process, []});
  				    atom ->
  					PName = refac_syntax:atom_value(Dest),
  					EnvPid ! {add, PName, {process, [{pname, any}]}},
  					refac_util:update_ann(Node, {process, [{pname, any}]});
  				    _ -> Node			
  				end;
  			    _ -> Node
  			end
  	    end;
  	_  -> Node
      end.
  
  
  is_register_app(T) ->
      case refac_syntax:type(T) of 
  	application ->
  	    Operator = refac_syntax:application_operator(T),
  	    Ann = refac_syntax:get_ann(Operator),
  	    case lists:keysearch(fun_def, 1, Ann) of 
  		{value, {fun_def, {erlang, register,2, _, _}}} ->
  		    true;
  		_  ->
  		    false
  	    end;
  	_ -> false
      end.
      
  
  is_self_app(T) ->
      case refac_syntax:type(T) of 
  	application ->
  	    Operator = refac_syntax:application_operator(T),
  	    Ann = refac_syntax:get_ann(Operator),
  	    case lists:keysearch(fun_def, 1, Ann) of 
  		{value, {fun_def, {erlang, self, 0, _, _}}} ->
  		    true;
  		_  ->
  		    false
  	    end;
  	_ -> false
      end.
  
  is_spawn_app(T) ->
      SpawnFuns = [{erlang, spawn, 1}, {erlang, spawn,2}, {erlang, spawn, 3},
  		 {erlang, spawn, 4}, {erlang, spawn_link, 1}, {erlang, spawn_link, 2}, {erlang, spawn_link, 3},
  		 {erlang, spawn_link, 4}],
      case refac_syntax:type(T) of 
  	application ->
  	    Operator = refac_syntax:application_operator(T),
  	    Ann = refac_syntax:get_ann(Operator),
  	    case lists:keysearch(fun_def,1,Ann) of 
  		{value, {fun_def, {Mod, Fun, Arity, _, _}}} ->
  		    lists:member({Mod, Fun, Arity}, SpawnFuns);
  		_ -> false
  	    end;
  	_ -> false
      end.
  
  
  is_send_expr(Tree) ->
      case refac_syntax:type(Tree) of 
  	infix_expr ->
  
negative.code: 		    refac_syntax:operator_name(Op) == '!';
  		_ -> false
  	    end;
  	application -> Op = refac_syntax:application_operator(Tree),
  		       Ann = refac_syntax:get_ann(Op),
  		       case lists:keysearch(fun_def,1, Ann) of 
  			   {value, {fun_def, {erlang, send, 2, _Pos1, _Pos2}}} -> true;
  			   _ -> false
  		       end;
   	_ ->false
      
      end.
  
  
  is_spawn_expr(Tree) ->
      SpawnFuns1 = [{erlang, spawn, 1}, {erlang, spawn, 2}, {erlang, spawn, 3}, {erlang, spawn, 4},
  		  {erlang, spawn_link, 1}, {erlang, spawn_link, 2}, {erlang, spawn_link, 3}, {erlang, spawn_link, 4},
  		  {erlang, spawn_opt, 3}, {erlang, spawn_opt, 5}],
      SpawnFuns2 = [{erlang, spawn_monitor, 1}, {erlang, spawn_monitor, 3}, {erlang, spawn_opt, 2},
   		  {erlang, spawn_opt, 4}],  %% These funs return more than a single Pid.
      case refac_syntax:type(Tree) of
        application ->
  	  Operator = refac_syntax:application_operator(Tree),
  	  Ann = refac_syntax:get_ann(Operator),
  	  case lists:keysearch(fun_def, 1, Ann) of
  	    {value, {fun_def, {Mod, Fun, Arity, _, _}}} 
  	      -> lists:member({Mod, Fun, Arity}, SpawnFuns1) orelse 
  		     lists:member({Mod, Fun, Arity}, SpawnFuns2);
  	      _ -> false
  	  end;
        _ -> false
      end.
  
  
  
  %% Qn: is it possible to get more static infomration? How to balance the usages of staic and dynamic info?
  %% How do we know the existing trace info is uptodate?
  %% what about the spawn expression has receive expressions?
  
  %% Is theory, it is possible that a  receiver function is shared by different processes (processse with different 
  %% entries); it practice, this rarely happen. We ignore this case for now.
  
  