anchor.diff:      refac_module_graph:module_graph_to_dot(OutFile, Res, false).
   
   
  +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  +%%                                                                     %%
  +%%  Some utility functions.                                            %%
  +%%                                                                     %%
  +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  +
  +
  +
  +
  +list_insection(L1, L2) ->
  +    ordsets:to_list(ordsets:intersection(ordsets:from_list(L1), ordsets:from_list(L2))).
  +
  +list_subtract(L1, L2) ->
  +    ordsets:to_list(ordsets:subtract(ordsets:from_list(L1), ordsets:from_list(L2))).
  +
  +is_sub_list(L1, L2) ->
  +    ordsets:is_subset(ordsets:from_list(L1), ordsets:from_list(L2)).
  +
  +remove_sub_lists(ListOfLists) ->
  +    ListOfLists1 = lists:sort(fun(L1, L2)-> length(L1)>= length(L2) end, ListOfLists),
  +    remove_sub_lists(ListOfLists1,[]).
  +
  +remove_sub_lists([], Acc) ->
  +    lists:reverse(Acc);
  +remove_sub_lists([L|T], Acc) ->
  +    case lists:any(fun(A)->
  +			   is_sub_list(L, A) 
  +		   end, Acc) of 
  +	true ->
  +	    remove_sub_lists(T, Acc);
  +	false ->
  +	    remove_sub_lists(T, [L|Acc])
  +    end.
  +		  
  +
  +
  +is_prop_sub_list(L1, L2) ->
  +    S1 = ordsets:from_list(L1),
  +    S2 = ordsets:from_list(L2),
  +    size(S1) < size(S2) andalso ordsets:is_subset(S1, S2).
  +
   add_edges([], MG) ->
       MG;
   add_edges([{Caller, Callees}|Left], MG) ->
  
positive.code:     digraph:add_edge(MG, From, To),
      MG.
  
  
negative.code:      wrangler_callgraph_server:fun_callgraph_to_dot(OutFile, FileName).
     
  
  %% Detetect those module dependencies where the dependeny is only caused by those non-API functions.
  %% Use ibrowse (part of couchdb) as an example.
  
  %% Check cases studies: counch db; wrangler; refactorerl; and ibrowse.
  
  
  %% Question: structure it is possible to find a target module, but how about semantically?.
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%                                                                     %%
  %%  Detecte and Remove Improper Inter-module calles.                   %%
  %%                                                                     %%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  
  improper_inter_module_calls(OutFile, SearchPaths, NotCareMods) ->
      ModCallerCallees = refac_module_graph:module_graph_with_funs(SearchPaths),
      FullMG = digraph:new(), 
      refac_module_graph:add_edges(ModCallerCallees,[],FullMG),
      Files = refac_util:expand_files(SearchPaths, ".erl"),
      FunCallees = lists:flatmap(fun non_api_funs/1, Files),
      MG = lists:append([[{CallerMod, [{CalleeMod, CalledFuns}]}|| 
  			   {CalleeMod, CalledFuns} <- CalleeMods,
  			   not lists:member(CalleeMod, NotCareMods),
  			   is_sub_list([{CalleeMod, F, A} || {F, A} <- CalledFuns],FunCallees)]
  		       || {CallerMod, CalleeMods} <- ModCallerCallees,
  			  not lists:member(CallerMod, NotCareMods)]),
      
      Edges = [{CallerMod, CalleeMod, CalleeFun} || 
  		{{CallerMod,_}, CalleeMods}<-MG,
  		{CalleeMod, CalleeFuns}<-CalleeMods, 
  		CalleeFun<-CalleeFuns],
      GroupedEdges=refac_misc:group_by(3, Edges),
      Res =[find_best_target_module(EdgeGroup, FullMG)||EdgeGroup<-GroupedEdges],
      refac_module_graph:module_graph_to_dot(OutFile, MG, true),
      digraph:delete(FullMG),
      Res.
  
  find_best_target_module(EdgeGroup, MG) ->
      {CalledMods, DefMod1, Fun1}=lists:unzip3(EdgeGroup),
      find_best_target_module_1(hd(Fun1), hd(DefMod1), [hd(DefMod1)|CalledMods], MG).
  
  find_best_target_module_1({F, A}, DefMod, UsedMods, MG) ->
      RNB =lists:append([digraph:out_neighbours(MG, Mod)--[DefMod]||Mod<-UsedMods]),
      RNB1 =sort_list_by_freq(RNB),
      case RNB1 of 
  	[] ->
  	    {{DefMod, F, A}, target_module_not_found};
  	_ ->
  	   {{DefMod, F, A}, element(1, hd(RNB1))}
      end.
  
  	
  sort_list_by_freq(L) ->
      L1 = sort_list_by_freq(L, []),
      lists:reverse(lists:keysort(2, L1)).
  		 
  sort_list_by_freq([], Acc) ->
      Acc;
  sort_list_by_freq([H|L], Acc) ->
      case lists:keysearch(H,1, Acc) of
  	{value, {H, F}} ->
  	    sort_list_by_freq(L, lists:keyreplace(H, 1, Acc, {H, F+1}));
  	false ->
  	    sort_list_by_freq(L, lists:keystore(H,1, Acc, {H,1}))
      end.
  %% Not very interesting. (too many false positives).
  improper_located_apis(OutFile, SearchPaths, NotCareMods) ->
      ModCallerCallees = refac_module_graph:module_graph_with_funs(SearchPaths),
      Files = refac_util:expand_files(SearchPaths, ".erl"),
      APIFuns = lists:flatmap(fun api_funs/1, Files),
      LabelFuns = lists:append([[{CalleeMod, F, A} || {F, A} <- CalledFuns]
  			      || {_CallerMod, CalleeMods} <- ModCallerCallees,
  				 {CalleeMod, CalledFuns} <- CalleeMods]),
      FunsUsedByOnlyOneMod = get_uniques(LabelFuns),
      APIFunsUsedByOnlyOneMod = list_insection(APIFuns, FunsUsedByOnlyOneMod),
      Res = [[{CallerMod, [{CalleeMod, [{F, A} || 
  					 {F, A} <- CalledFuns, 
  					 lists:member({CalleeMod, F, A}, APIFunsUsedByOnlyOneMod)]}]}
  	    || {CalleeMod, CalledFuns} <- CalleeMods]
  	   || {CallerMod, CalleeMods} <- ModCallerCallees],
      MG = lists:append(Res),
      MG1 = [{{CallerMod, CallerFile}, [{CalleeMod, CalledFuns} || {CalleeMod, CalledFuns} <- CalleeMods, CalledFuns /= [],
  								 not lists:member(CalleeMod, NotCareMods)]}
  	   || {{CallerMod, CallerFile}, CalleeMods} <- MG, not lists:member(CallerMod, NotCareMods)],
      refac_module_graph:module_graph_to_dot(OutFile, MG1, true).
  
  
  get_uniques(L) ->    
      get_uniques(L, [],[]).
  
  get_uniques([], Acc, _) ->
       Acc;
  get_uniques([H|L], Acc, Acc1) ->
      case lists:member(H, Acc) of 
  	true ->
  	    get_uniques(L, Acc--[H], [H|Acc1]);
  	false ->
  	    case lists:member(H, Acc1) of 
  		true ->
  		    get_uniques(L, Acc, Acc1);
  		false ->
  		    get_uniques(L, [H|Acc], Acc1)
  	    end
      end.
  
  %%TODO: compare the result of using NonAPIs and ClosedNonAPIs.
  non_api_funs(File) -> 
      element(3, api_and_non_api_funs(File)).
  
  
  api_funs(File) ->
      element(1, api_and_non_api_funs(File)).
      
      
  api_and_non_api_funs(File) ->
      ExpFuns = exported_funs(File),
      #callgraph{callercallee = CallerCallees} =
  	wrangler_callgraph_server:get_callgraph([File]),
      CG = digraph:new(),
      add_edges(CallerCallees, CG),
      Vs = digraph:vertices(CG),
      SCCs = [SCC || SCC <- digraph_utils:strong_components(CG), length(SCC) > 1],
      Reaching = [{V, digraph_utils:reaching([V], CG)}
  		|| V <- Vs, lists:member(V, ExpFuns)],
      APIs = [V || {V, Rs} <- Reaching, lists:member(V, ExpFuns), Rs == [V] orelse
  								  lists:any(fun (SCC) -> Rs == SCC
  									    end, SCCs)],
      SemiAPIs = [V || V <- ExpFuns -- APIs, similar_to_some_api(V, APIs, CG)],
      NonAPIs = ExpFuns -- APIs ++ SemiAPIs,
      ClosedNonAPIs = [V || V <- NonAPIs, is_closed(V, CG)],
      digraph:delete(CG),
      {APIs, SemiAPIs, NonAPIs, ClosedNonAPIs}.
  
  
  is_closed(V= {M, _F, _A}, CG) ->
      Rs = [{M1, F1, A1} || {M1, F1, A1} <- digraph_utils:reachable([V], CG),
  			  M == M1],
      InEdges=lists:sort([{V1, V2}|| R<-Rs, R/=V, E<-digraph:in_edges(CG,R), 
  				   {_, V1, V2, _}<-[digraph:edge(CG, E)]]),
      OutEdges=lists:sort([{V1, {M2, F2, A2}}|| R<-Rs, E<-digraph:out_edges(CG,R), 
  					      {_, V1, {M2, F2,A2}, _}<-[digraph:edge(CG, E)], M2==M]),
      InEdges == OutEdges.
  
  
  %% is_closed(V = {M, _F, _A}, File) ->
  %%     #callgraph{callercallee = CallerCallees} =
  %%  	wrangler_callgraph_server:get_callgraph([File]),
  %%     CG = digraph:new(),
  %%     add_edges(CallerCallees, CG),
  %%     Rs = [V|[{M1, F1, A1} || {M1, F1, A1} <- digraph_utils:reachable([V], CG),
  %% 			  M == M1]],
  %%     Rs1 = lists:usort(lists:append([digraph_utils:reaching([R],CG) || R <- Rs]) -- [V]),
  %%     refac_io:format("V:\n~p\n", [V]),
  %%     refac_io:format("Rs:\n~p\n", [Rs]),
  %%     refac_io:format("Rs1:\n~p\n", [Rs1]),
  %%     Res=lists:usort(Rs1)--lists:usort(Rs) ==[],    
  %%     refac_io:format("Closed:\n~p\n", [Res]).
     
  
  %% moveability(V={M,_F, _A}, File) ->
  %%     #callgraph{callercallee = CallerCallees} =
  %% 	wrangler_callgraph_server:get_callgraph([File]),
  %%     CG = digraph:new(),
  %%     add_edges(CallerCallees, CG),
  %%     Rs = [{M1, F1, A1} || {M1, F1, A1} <- digraph_utils:reachable([V], CG),
  %% 			  M == M1],
  %%     Rs1 = lists:append([digraph:in_neighbours(CG, R) || R <- Rs]) -- [V],
  %%     Vs=[{M1, F, A}||{M1, F, A}<-digraph:vertices(CG), M==M1],
  %%     refac_io:format("Rs:\n~p\n", [Rs]),
  %%     refac_io:format("Vs:\n~p\n", [Vs]),
  %%     case lists:usort(Rs1)--lists:usort(Rs)==[] of 
  %% 	true ->
  %% 	    1-length(Rs)/length(Vs);
  %% 	false ->
  %% 	    0
  %%     end.
  	  
  
  unmoveability(V={M,_F, _A}, CG) ->
      Rs = [{M1, F1, A1} || {M1, F1, A1} <- digraph_utils:reachable([V], CG),
  			  M == M1],
      Vs=[{M1, F, A}||{M1, F, A}<-digraph:vertices(CG), M==M1],
      case is_closed(V, CG) of 
  	true ->
  	    length(Rs)/length(Vs);
  	false ->
  	    1
      end.
  	  
  
  
   
  %% What other metrics to use: use of records.
  similar_to_some_api(V, APIs, MG) ->
      VReachable=digraph_utils:reachable([V], MG),
      Reaching =digraph_utils:reaching([V], MG),
      ReachingAPIs = [R||R<-Reaching, lists:member(R, APIs)],
      lists:any(fun(R)->
  		      SimiScore=length(VReachable)/length(digraph_utils:reachable([R], MG)),
  		      SimiScore>=?SimiScore
  	      end, ReachingAPIs).
  
  
  
  exported_funs(File) ->
      {ok, {_, Info}} = refac_util:parse_annotate_file(File, true),
      {value, {module, ModName}} =lists:keysearch(module,1,Info),
      ImpExports = 
  	case lists:keysearch(attributes, 1, Info) of
  	    {value, {attributes, Attrs}} ->
  		case lists:member({compile, export_all}, Attrs) of
  		    true -> 
  			case lists:keysearch(functions, 1, Info) of
  			    {value, {functions, Funs}} ->
  				[{ModName, F, A}||{F, A}<-Funs];
  			    false ->
  				[]
  			end;
  		    false ->
  			[]
  		end;
  	    false -> []
  	end,
      case ImpExports of
  	[] ->
  	    case lists:keysearch(exports, 1, Info) of
  	      {value, {exports, ExpFuns}} ->
  		    [{ModName, F, A}||{F, A}<-ExpFuns];
  		false ->
  		    []
  	    end;
  	_ -> ImpExports
      end.
  
     
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%                                                                     %%
  %%  Detecte and  removed cyclic module dependences.                    %%
  %%                                                                     %%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  
  %% Instead of trying to break a SCC, I should try to break cycles.
  cyclic_dependent_modules(OutFile, SearchPaths, WithLabel) ->
      ?wrangler_io("\nCMD: ~p:cyclic_dependent_modules(~p, ~p, ~p).\n",
  		 [?MODULE, OutFile, SearchPaths, WithLabel]),
      ModCallerCallees = refac_module_graph:module_graph_with_funs(SearchPaths),
      MG = digraph:new(),
      refac_module_graph:add_edges(ModCallerCallees,[],MG),
      SCCs = digraph_utils:cyclic_strong_components(MG),
      Cycles = [digraph:get_short_cycle(MG, V) || SCC<-SCCs, V <-SCC],
      Cycles1 = remove_duplicated_circles(Cycles),
      CycleWeakestLinkPairs=[{C, break_a_circle(C, ModCallerCallees)}|| C<-Cycles1],
      cycles_to_dot(MG, OutFile,CycleWeakestLinkPairs).
  
  
  remove_duplicated_circles(Cs) ->
      remove_duplicated_circles(Cs, []).
  
  remove_duplicated_circles([], Acc) ->
      Acc;
  remove_duplicated_circles([C|Cs], Acc) ->
      case lists:any(fun(C1) ->
  			   lists:usort(C)==lists:usort(C1) 
  		   end, Acc) of 
  	true ->
  	    remove_duplicated_circles(Cs, Acc);
  	false ->
  	    remove_duplicated_circles(Cs, [C|Acc])
      end.
  	
  
  cycles_to_dot(MG, OutFile, CycleWeakestLinkPairs)->
      CycleEdges=[get_cycle_edges(MG, C, WeakestLink)||{C, WeakestLink}<-CycleWeakestLinkPairs],
      NewEdgeList=get_renamed_edge_list(CycleEdges),
      edge_list_to_dot(lists:append(NewEdgeList), OutFile, "ModuleGraph", true).
      
  get_cycle_edges(MG, C, WeakestLink) ->
      get_cycle_edges(MG, C, WeakestLink, []).
  
  get_cycle_edges(MG, T, _WeakestLink={WE, Score}, Edges)  when length(T)=<1->
      Edges1 =lists:reverse(Edges),
      [{X, Y, Label, {X,Y}==WE, Score}|| E<-digraph:edges(MG),
  				       {_, X, Y, Label} <- [digraph:edge(MG, E)],
  				       lists:member({X, Y}, Edges1)];
  get_cycle_edges(MG,[V1, V2|T], WeakestLink,  Edges) ->
      get_cycle_edges(MG, [V2|T], WeakestLink, [{V1,V2}|Edges]).
  
  			
  get_renamed_edge_list(Cycles) ->
      get_renamed_edge_list_1(Cycles, [], []).
  get_renamed_edge_list_1([], _Vs, Acc) ->
      lists:reverse(Acc);
  get_renamed_edge_list_1([C|Cs],Vs,Acc) ->
      {NewVs, NewEdges}=get_renamed_edge_list_2(C, Vs, []),
      get_renamed_edge_list_1(Cs, NewVs, [NewEdges|Acc]).
  
  get_renamed_edge_list_2(C, Vs, Edges) ->
      get_renamed_edge_list_3(C, Vs, [], Edges).
  
  get_renamed_edge_list_3([],Vs, NewVs,  NewEdges) ->
      {Vs++lists:usort(NewVs), lists:reverse(NewEdges)};
  get_renamed_edge_list_3([{X, Y, Label, Weak, Score}|T], Vs, NewVs, NewEdges) ->
      N=length([X||V<-Vs, X==V]),
      X1 = atom_to_list(X)++"("++integer_to_list(N)++")",
      N1 =length([Y||V<-Vs, Y==V]),
      Y1 = atom_to_list(Y)++"("++integer_to_list(N1)++")",
      get_renamed_edge_list_3(T, Vs, [X,Y,X1, Y1|NewVs], [{X1, Y1, Label, Weak, Score}|NewEdges]).    
  	    
  
  break_a_circle(Cycle, ModCallerCallees) ->
      CycleCallerCallees = get_circle_caller_callees(Cycle, ModCallerCallees),
      find_weakest_link(CycleCallerCallees).
     
  
  get_circle_caller_callees(Cycle, ModCallerCallees) ->
      get_circle_caller_callees(Cycle, ModCallerCallees,[]).
  
  get_circle_caller_callees(Vs, _ ,Acc) when length(Vs) =<1 ->
      lists:reverse(Acc);
  get_circle_caller_callees([V1, V2|T], ModCallerCallees, Acc) ->
      CalleeFileName=hd([filename:join([Dir, atom_to_list(V2)++".erl"])||{{CallerMod, Dir}, _}<-ModCallerCallees, CallerMod==V2]),
      CalledFAs = [CalledFuns||{{CallerMod, _}, CalleeMods}<- ModCallerCallees, 
  			      CallerMod==V1, 
  			      {CalleeMod, CalledFuns}<-CalleeMods,
  			      CalleeMod == V2],
      get_circle_caller_callees([V2|T], ModCallerCallees, [{V1,V2, {CalleeFileName, hd(CalledFAs)}}|Acc]).
      
  
  find_weakest_link(CycleCallerCallees) ->    
      Scores =[score_a_link(Link) || Link<-CycleCallerCallees],
      refac_io:format("LinkScores:\n~p\n", [Scores]),
      SortedScores=lists:keysort(2, Scores),
      hd(SortedScores).
  
  score_a_link({M1, M2, {File, FAs}}) ->    
      APIScorePairs= api_score_pairs(File),
      refac_io:format("FA:\n~p\n", [FAs]),
      refac_io:format("APIScorePairs:\n~p\n", [APIScorePairs]),
      Scores=[{{F, A}, APIScore, MoveScore}|| {{_M, F, A}, APIScore, MoveScore}<-APIScorePairs, lists:member({F, A}, FAs)],
      refac_io:format("Scores:\n~p\n", [Scores]),
      {_LinkFuns, APIScores, MoveScores} = lists:unzip3(Scores),
      {{M1, M2}, {lists:sum(APIScores), lists:sum(MoveScores)/length(MoveScores)}}.
  		      
    
  api_score_pairs(File) -> 
      ExpFuns =exported_funs(File),
      #callgraph{callercallee = CallerCallees} =
  	wrangler_callgraph_server:get_callgraph([File]),
      CG = digraph:new(),
      add_edges(CallerCallees, CG),
      Vs=digraph:vertices(CG),
      SCCs = [SCC||SCC<-digraph_utils:strong_components(CG), length(SCC)>1],
      Reaching =[{V, digraph_utils:reaching([V], CG)} ||
  		  V <-Vs, lists:member(V, ExpFuns)],
      APIs = [V|| {V, Rs}<-Reaching, lists:member(V, ExpFuns), Rs==[V] orelse 
  		    lists:any(fun(SCC)->Rs==SCC end, SCCs)],
      [{V, get_api_score(V,APIs,CG), unmoveability(V, CG)}||V<-ExpFuns].
    
  get_api_score(V, APIs, MG) ->
      VReachable=digraph_utils:reachable([V], MG),
      Reaching =digraph_utils:reaching([V], MG),
      ReachingAPIs = [R||R<-Reaching, lists:member(R, APIs)],
      Scores = [case lists:member(V, APIs) of 
  		  true -> 1;
  		  false->
  		      length(VReachable)/length(digraph_utils:reachable([R], MG))
  	      end
  	      ||R<-ReachingAPIs],
      case Scores of 
  	[] -> 1;
  	_ -> lists:last(lists:sort(Scores))
      end.
  
  remove_a_link(File, Funs) ->
      case filelib:is_regular(File) of
        true -> ok;
        false -> throw:error("The file name given does not refer to a file.")
      end,
      #callgraph{callercallee = CallerCallees} =
  	wrangler_callgraph_server:get_callgraph([File]),
      CG = digraph:new(),
      add_edges(CallerCallees, CG),
      Vs = digraph_utils:reaching(Funs, CG),
      case Vs of
        Funs ->
  	  throw({error, "None of the functions given are used by the file specified."});
        _ ->
  	  ModName = element(1, hd(Vs)),
  	  Vs2 = digraph_utils:reachable(Vs, CG),
  	  Vs3 = [{M2, F2, A2} || {M2, F2, A2} <- Vs2, M2 == ModName],
  	  APIs = exported_funs(File),
  	  Vs4 = [V || V <- Vs3, is_sub_list(digraph_utils:reaching([V], CG), Vs2)],
  	  Vs5 = [V || V <- Vs4, lists:member(V, APIs), not lists:member(V, Vs)],
  	  FunsToMove = Vs4 -- Vs5,
  	  refac_io:format("FunsToMove:\n~p\n", [FunsToMove]),
  	  FunsToMove
      end.
  				       
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%                                                                     %%
  %%  Partition a big module into two smaller ones.                      %%
  %%                                                                     %%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  
  %% TODO: Take function names into account.
  
  partition_a_module_into_two(File) ->
      {ok, {_, Info}} = refac_util:parse_annotate_file(File, true),
      {value, {module, ModName}} =lists:keysearch(module,1,Info),
      ExportedFuns = exported_funs(File),
      CallerCalleesWithDef = wrangler_callgraph_server:build_callercallee_callgraph([File]),
      CallerCallees = [{{M,F,A}, [{M, F, A}||[{M1,F1,A1}||{M1,F1,A1}<-Callee, M1==ModName]]}
  		     ||{{{M,F,A}, _}, Callee}<-CallerCalleesWithDef],
      MG = digraph:new(),
      add_edges(CallerCallees,  MG),
      Coms = digraph_utils:components(MG),
      Coms1 =[[MFA||MFA<-C, lists:member(MFA, ExportedFuns)]||C<-Coms],
      refac_io:format("Coms:\n~p\n", [Coms1]).
      
  
  
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%                                                                     %%
  %%  Detect and eliminate modules with very big fanin.                  %%
  %%                                                                     %%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  
  modules_with_big_fanin(DotFile, SearchPaths, MinInDegree, NotCareMods) ->
      ModCallerCallees = refac_module_graph:module_graph_with_funs(SearchPaths),
      CalleeMods1 = lists:append([element(1, lists:unzip(CalleeMods)) || {_CallerMod, CalleeMods} <- ModCallerCallees]),
      Res = [[{CallerMod, [{CalleeMod, CalledFuns}]} || {CalleeMod, CalledFuns} <- CalleeMods,
  						      not lists:member(CalleeMod, NotCareMods),
  						      length([M || M <- CalleeMods1, M == CalleeMod]) >= MinInDegree]
  	   || {CallerMod, CalleeMods} <- ModCallerCallees],
      refac_io:format("Res:\n~p\n", [Res]),
      refac_module_graph:module_graph_to_dot(DotFile, lists:append(Res), true).
  
      
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %%                                                                     %%
  %%  Detect and eliminate modules with very big fanout.                 %%
  %%                                                                     %%
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
  modules_with_big_fanout(OutFile, SearchPaths, MinOutDegree, NotCareMods) ->
      ModCallerCallees = refac_module_graph:module_graph_with_funs(SearchPaths),
      Res = [{CallerMod, CalleeMods} || {CallerMod, CalleeMods} <- ModCallerCallees,
  