anchor.diff:      print_ast(FileFmt, AST, [], TabWidth).
   
   print_ast(FileFmt, AST, Options, TabWidth) ->
  +    element(1, print_ast_and_get_changes(FileFmt, AST, Options, TabWidth)).
  +
  +print_ast_and_get_changes(FileFmt, AST, TabWidth) ->
  +    print_ast_and_get_changes(FileFmt, AST, [], TabWidth).
  +
  +print_ast_and_get_changes(FileFmt, AST, Options, TabWidth) ->
       Fs = refac_syntax:form_list_elements(AST),
  -    vertical_concat(Fs, FileFmt, Options, TabWidth).
  +    {FmStrs, C} = lists:unzip([print_a_form(F, FileFmt, Options, TabWidth)|| F<-Fs]),
  +    Content = lists:append(FmStrs),
  +    {NoFunsChanged, NoToksRemoved, NoToksAdded} =lists:unzip3(C),
  +    Change={lists:sum(NoFunsChanged), 
  +            lists:sum(NoToksRemoved),
  +            lists:sum(NoToksAdded)},
  +    {Content, Change}.
  +
  +print_a_form(Form, FileFmt, Options, TabWidth) ->
  +    case false of %% form_not_changed(Form) of
  +        true ->
  +            FormStr=refac_util:concat_toks(refac_util:get_toks(Form)),
  +            {FormStr, {0, 0, 0}};
  +        false ->
  +            %% refac_io:format("Form:\n~p\n", [Form]),
  +            print_a_form_and_get_changes(Form, FileFmt, Options, TabWidth)
  +    end.
    
  -print_form(F,Ctxt,Fun) ->
  -    {Paper,Ribbon} = get_paper_ribbon_width(F),
  -    best(Fun(F,Ctxt),Paper,Ribbon).
  -
  -vertical_concat(Forms, FileFmt, Options, TabWidth) ->
  -    vertical_concat(Forms, FileFmt, Options, "", TabWidth).
  -
  -vertical_concat([], _FileFormat, _Options, Acc, _TabWidth) ->
  -    Acc;
  -vertical_concat([Form| T], FileFormat, Options, Acc, TabWidth) ->
  -    UseOriginalCode = form_not_changed(Form),
  -    Delimitor = case FileFormat of
  -		    dos -> "\r\n";
  -		    mac -> "\r";
  -		    _ -> "\n"
  -		end,
  -    Acc1 = case UseOriginalCode orelse Acc=="" of
  -	       true ->
  -		   Acc;
  -	       false ->
  -		   Toks = refac_util:get_toks(Form),
  -		   case Toks of
  -		       [] -> Acc++ Delimitor++Delimitor;
  -		       _ ->OriginalStr=refac_util:concat_toks(Toks),
  -			   NewLns=lists:takewhile(fun(C)->C==$\n end, OriginalStr),
  -			   Acc++NewLns
  -		   end
  -	   end,
  -    Str = case UseOriginalCode of
  -	      true ->
  -		  refac_util:concat_toks(refac_util:get_toks(Form));
  -	      false ->
  -		  print_a_form(Form, FileFormat, Options, TabWidth)
  -	  end,
  -    vertical_concat(T, FileFormat, Options, Acc1++Str, TabWidth).
  -
  -
  -print_a_form(Form, FileFormat, Options) ->
  -    print_a_form(Form, FileFormat, Options, ?TabWidth).
  -
  -print_a_form(Form, FileFormat, Options, TabWidth) ->
  -    Ctxt = #ctxt{hook  = 
  -		     proplists:get_value(hook,Options,?NOHOOK),
  +       
  +print_a_form_and_get_changes(Form, FileFormat, Options, TabWidth) ->
  +    Ctxt = #ctxt{hook  = proplists:get_value(hook,Options,?NOHOOK),
   		 paper = proplists:get_value(paper,Options,?PAPER),
   		 ribbon = proplists:get_value(ribbon,Options,?RIBBON),
   		 user = proplists:get_value(user,Options),
   		 format = FileFormat,
   		 tabwidth = TabWidth,
   		 tokens = refac_util:get_toks(Form)},
  -    E = print_form(Form,reset_prec(Ctxt),fun lay/2),
  -    Str1 = refac_prettypr_0:layout(E,FileFormat,TabWidth),
  -    remove_trailing_whitespace(Str1).
  - 
  +    OrigToks = refac_util:get_toks(Form),
  +    refac_io:format("Form:\n~p\n", [Form]),
  +    refac_io:format("OrigToks:\n~p\n", [OrigToks]),
  +    OrigFormStr=refac_util:concat_toks(OrigToks),
  +    refac_io:format("OrigFormStr:\n~p\n", [OrigFormStr]),
  +    NewFormStr0= print_form(Form,reset_prec(Ctxt),fun lay/2),
  +    refac_io:format("NewFormStr:\n~p\n", [NewFormStr0]),
  +    NewFormStr=repair_new_form_str(OrigFormStr, NewFormStr0, TabWidth,FileFormat),
  +    {ok, NewToks, _} = refac_scan:string(NewFormStr),
  +    Change =get_changes(OrigToks, NewToks),
  +    {NewFormStr, Change}.
  +   
  +
  +get_changes(OrigToks, NewToks) ->
  +    OrigToks1 = remove_locs_whites_and_comments(OrigToks),
  +    NewToks1 = remove_locs(NewToks),
  +    ToksRemoved = OrigToks1 -- NewToks1,
  +    ToksAdded = NewToks1 -- OrigToks1,
  +    {1, length(ToksRemoved), length(ToksAdded)}.
  +
  +
  +print_form(Form,Ctxt,Fun) ->
  +    Paper = Ctxt#ctxt.paper,
  +    Ribbon = Ctxt#ctxt.ribbon,
  +    D=best(Fun(Form,Ctxt),Paper,Ribbon),
  +    FileFormat = Ctxt#ctxt.format,
  +    TabWidth = Ctxt#ctxt.tabwidth,
  +    FStr0=refac_prettypr_0:layout(D,FileFormat,TabWidth),
  +    FStr=remove_trailing_whitespace(FStr0), 
  +    Toks = refac_util:get_toks(Form),
  +    if Toks ==[] ->
  +            Delimitor = get_delimitor(FileFormat),
  +            Delimitor++Delimitor++FStr; 
  +       true ->
  +            FStr
  +    end.
  +
  +
  +get_delimitor(FileFormat) ->        
  +    case FileFormat of
  +        dos -> "\r\n";
  +        mac -> "\r";
  +        _ -> "\n"
  +    end.
  +  
   is_special_form(Form) ->
       case refac_syntax:type(Form) of
  -	error_marker -> true;
  -	comment -> true;
  +	error_marker -> 
  +            true;
  +	comment -> 
  +            true; 
   	attribute ->
  -	    case refac_syntax:atom_value(refac_syntax:attribute_name(Form)) of
  +	    AtrName = refac_syntax:attribute_name(Form),
  +            case refac_syntax:atom_value(AtrName) of
   		type -> true;
   		spec -> true;
  -		record -> [_R, FieldTuple] = refac_syntax:attribute_arguments(Form),
  -			  Fields = refac_syntax:tuple_elements(FieldTuple),
  -			  lists:any(fun (Field) -> case refac_syntax:type(Field) of
  -						       typed_record_field ->
  -							   true;
  -						       _ -> false
  -						   end
  -				    end, Fields);
  +		record -> 
  +                    [_R, FieldTuple] = refac_syntax:attribute_arguments(Form),
  +                    Fields = refac_syntax:tuple_elements(FieldTuple),
  +                    lists:any(fun(F) ->  
  +                                      refac_syntax:type(F)==typed_record_field
  +                              end, Fields);
   		_ -> false
   	    end;
   	_ -> false
  
positive.code: 					_ -> {{0, 0}, any}
  				    end,
  	    D1 = lay(Operator, reset_prec(Ctxt)),
  	    D2 = lay(PrefixArg, set_prec(Ctxt, PrecR)),
  	    D3 = case Name of
  		     '+' -> beside(D1, D2);
  		     '-' -> beside(D1, D2);
  		     _ ->
  			 OpEndLn = get_end_line(Operator),
  			 ArgStartLn = get_start_line(PrefixArg),
  			 case (OpEndLn == 0) or (ArgStartLn == 0) of
  			     true -> par([D1, D2], Ctxt#ctxt.sub_indent);
  			     _ ->
  				 case ArgStartLn - OpEndLn of
  				     0 -> beside(beside(D1, text(" ")), D2);
  				     1 -> above(D1, nest(Ctxt#ctxt.sub_indent, D2));
  				     _ -> par([D1, D2], Ctxt#ctxt.sub_indent)
  				 end
  			 end
  		 end,
  	    maybe_parentheses(D3, Prec, Ctxt);
  	application ->  %% done.
  	    {PrecL, Prec} = func_prec(),
  	    D = lay(refac_syntax:application_operator(Node), set_prec(Ctxt, PrecL)),
  	    Args = refac_syntax:application_arguments(Node),
  	    Sep = get_separator(Args, Ctxt#ctxt.tokens, ","),
  	    As = seq(Args, floating(text(Sep)), reset_prec(Ctxt), fun lay/2),
  	    Op = refac_syntax:application_operator(Node),
  	    D1 = case Args of
  		     [] ->
  			 beside(D, beside(text("("), text(")")));
  		     [H| _] ->
  			 EndLn = get_end_line(Op),
  			 StartLn = get_start_line(H),
  			 case StartLn - EndLn == 1 of
  			     true ->
  				 above(beside(D, text("(")),
  				       nest(Ctxt#ctxt.sub_indent, beside(lay_elems(fun refac_prettypr_0:par/1,
  										   As, Args), floating(text(")")))));
  			     false ->
  				 beside(D, beside(text("("), beside(lay_elems(fun refac_prettypr_0:par/1,
  									      As, Args), floating(text(")")))))
  			 end
  		 end,
  	    maybe_parentheses(D1, Prec, Ctxt);
  	match_expr ->         %% done;
  	    {PrecL, Prec, PrecR} = inop_prec('='),
  	    Left = refac_syntax:match_expr_pattern(Node),
  	    Right = refac_syntax:match_expr_body(Node),
  	    EndLn = get_end_line(Left),
  	    StartLn = get_start_line(Right),
  	    D1 = lay(refac_syntax:match_expr_pattern(Node), set_prec(Ctxt, PrecL)),
  	    D2 = lay(refac_syntax:match_expr_body(Node), set_prec(Ctxt, PrecR)),
  	    D3 = case (EndLn == 0) or (StartLn == 0) of
  		     true ->
  			 follow(beside(D1, floating(text(" ="))), D2, Ctxt#ctxt.break_indent);
  		     false ->
  			 case EndLn == StartLn of
  			     true -> beside(beside(D1, text(" = ")), D2);
  			     _ ->
  				 above(beside(D1, text(" =")), nest(Ctxt#ctxt.break_indent, D2))
  			 end
  		 end,
  	    maybe_parentheses(D3, Prec, Ctxt);
  	underscore -> text("_");
  	clause ->  %% done;
  	    %% The style used for a clause depends on its context
  	    Ctxt1 = (reset_prec(Ctxt))#ctxt{clause = undefined},
  	    Pats = refac_syntax:clause_patterns(Node),
  	    Body = refac_syntax:clause_body(Node),
  	    Sep = get_separator(Pats, Ctxt#ctxt.tokens, ","),
  	    PatDocs = seq(Pats, floating(text(Sep)), Ctxt1, fun lay/2),
  	    D1 = lay_elems(fun refac_prettypr_0:par/1, PatDocs, Pats),
  	    D2 = case refac_syntax:clause_guard(Node) of
  		     none -> none;
  		     G -> lay(G, Ctxt1)
  		 end,
  	    BodyDocs = seq(Body, floating(text(",")), Ctxt1, fun lay/2),
  	    D3 = lay_body_elems(fun refac_prettypr_0:sep/1, BodyDocs, Body),
  	    HeadLastLn = case refac_syntax:clause_guard(Node) of
  			     none -> case Pats of
  					 [] -> get_start_line(Node);
  					 _ -> case get_end_line(Pats) of
  						  0 -> get_start_line(Node);
  						  L -> L
  					      end
  				     end;
  			     _ -> get_end_line(refac_syntax:clause_guard(Node))
  			 end,
  	    BodyStartLn = get_start_line(hd(Body)),
  	    SameLine = {BodyStartLn, HeadLastLn},
  	    case Ctxt#ctxt.clause of
  		fun_expr -> make_fun_clause(D1, D2, D3, Ctxt, SameLine);
  		{function, N} -> make_fun_clause(N, D1, D2, D3, Ctxt, SameLine);
  		if_expr -> make_if_clause(D1, D2, D3, Ctxt, SameLine);
  		cond_expr -> make_if_clause(D1, D2, D3, Ctxt, SameLine);
  		case_expr ->
  		    make_case_clause(D1, D2, D3, Ctxt, SameLine);
  		receive_expr -> make_case_clause(D1, D2, D3, Ctxt, SameLine);
  		try_expr -> make_case_clause(D1, D2, D3, Ctxt, SameLine);
  		{rule, N} -> make_rule_clause(N, D1, D2, D3, Ctxt, SameLine);
  		undefined ->
  		    %% If a clause is formatted out of context, we
  		    %% use a "fun-expression" clause style.
  		    make_fun_clause(D1, D2, D3, Ctxt, SameLine)
  	    end;
  	function ->  %% done;
  	    %% Comments on the name itself will be repeated for each
  	    %% clause, but that seems to be the best way to handle it.
  	    Ctxt1 = reset_prec(Ctxt),
  	    D1 = lay(refac_syntax:function_name(Node), Ctxt1),
  	    D2 = lay_clauses(refac_syntax:function_clauses(Node), {function, D1}, Ctxt1),
  	    beside(D2, floating(text(".")));
  	case_expr ->  %% done;
  	    Ctxt1 = reset_prec(Ctxt),
  	    D1 = lay(refac_syntax:case_expr_argument(Node), Ctxt1),
  	    D2 = lay_clauses(refac_syntax:case_expr_clauses(Node), case_expr, Ctxt1),
  	    sep([par([follow(text("case"), D1, Ctxt1#ctxt.break_indent), text("of")], Ctxt1#ctxt.break_indent),
  		 nest(Ctxt1#ctxt.break_indent, D2), text("end")]);
  	if_expr ->  %% done;
  	    Ctxt1 = reset_prec(Ctxt),
  	    D = lay_clauses(refac_syntax:if_expr_clauses(Node), if_expr, Ctxt1),
  	    sep([follow(text("if"), D, Ctxt1#ctxt.break_indent), text("end")]);
  	cond_expr ->  %% done;
  	    Ctxt1 = reset_prec(Ctxt),
  	    D = lay_clauses(refac_syntax:cond_expr_clauses(Node), cond_expr, Ctxt1),
  	    sep([text("cond"), nest(Ctxt1#ctxt.break_indent, D), text("end")]);
  	fun_expr ->  %% done;
  	    Ctxt1 = reset_prec(Ctxt),
  	    D = lay_clauses(refac_syntax:fun_expr_clauses(Node), fun_expr, Ctxt1),
  	    sep([follow(text("fun"), D, Ctxt1#ctxt.break_indent), text("end")]);
  	module_qualifier ->  %% done;
  	    {PrecL, _Prec, PrecR} = inop_prec(':'),
  	    D1 = lay(refac_syntax:module_qualifier_argument(Node), set_prec(Ctxt, PrecL)),
  	    D2 = lay(refac_syntax:module_qualifier_body(Node), set_prec(Ctxt, PrecR)),
  	    beside(D1, beside(text(":"), D2));
  	qualified_name ->  %% done;
  	    Ss = refac_syntax:qualified_name_segments(Node),
  	    lay_qualified_name(Ss, Ctxt);
  	%%
  	%% The rest is in alphabetical order
  	%%
  	arity_qualifier ->  %% done;
  	    Ctxt1 = reset_prec(Ctxt),
  	    D1 = lay(refac_syntax:arity_qualifier_body(Node), Ctxt1),
  	    D2 = lay(refac_syntax:arity_qualifier_argument(Node), Ctxt1),
  	    beside(D1, beside(text("/"), D2));
  	attribute ->  %% done;
  	    %% The attribute name and arguments are formatted similar to
  	    %% a function call, but prefixed with a "-" and followed by
  	    %% a period. If the arguments is `none', we only output the
  	    %% attribute name, without following parentheses.
  	    Ctxt1 = reset_prec(Ctxt),
  	    N = refac_syntax:attribute_name(Node),
  	    D = case refac_syntax:attribute_arguments(Node) of
  		    none -> lay(N, Ctxt1);
  		    Args ->
  			Sep = get_separator(Args, Ctxt1#ctxt.tokens, ","),
  			As = seq(Args, floating(text(Sep)), Ctxt1, fun lay/2),
  			Elems = lay_elems(fun refac_prettypr_0:par/1, As, Args),
  			beside(lay(N, Ctxt1), beside(text("("), beside(Elems, floating(text(")")))))
  		end,
  	    beside(floating(text("-")), beside(D, floating(text("."))));
  	binary ->   %% done
  	    Ctxt1 = reset_prec(Ctxt),
  	    Fields = refac_syntax:binary_fields(Node),
  	    Sep = get_separator(Fields, Ctxt#ctxt.tokens, ","),
  	    Es = seq(Fields, floating(text(Sep)), Ctxt1, fun lay/2),
  	    beside(floating(text("<<")), beside(lay_elems(fun refac_prettypr_0:par/1, Es, Fields), floating(text(">>"))));
  	binary_field ->
  	    Ctxt1 = reset_prec(Ctxt),
  	    D = lay(refac_syntax:binary_field_body(Node), Ctxt1),
  	    %% Begin of modification of HL
  	    Body = refac_syntax:binary_field_body(Node),
  	    D1 = case refac_syntax:type(Body) of
  		     size_qualifier -> D;
  		     _ ->
  			 case refac_syntax:type(Body) == variable orelse 
  				refac_syntax:type(Body) == underscore orelse refac_syntax:is_literal(Body) == true
  			     of
  			     true -> D;
  			     false ->
  				 case refac_syntax:type(Body) of
  				     macro -> case lists:keysearch(with_bracket, 1, refac_syntax:get_ann(Body)) of
  						  {value, {with_bracket, true}} ->
  						      beside(floating(text("(")), beside(D, floating(text(")"))));
  						  _ -> D
  					      end;
  				     _ -> beside(floating(text("(")), beside(D, floating(text(")"))))
  				 end
  			 end
  		 end,
  	    %% End of modification by HL
  	    D2 = case refac_syntax:binary_field_types(Node) of
  		     [] -> empty();
  		     Ts ->
  			 beside(floating(text("/")), lay_bit_types(Ts, Ctxt1))
  		 end,
  	    beside(D1, D2);
  	block_expr -> %% done;
  	    Ctxt1 = reset_prec(Ctxt),
  	    Body = refac_syntax:block_expr_body(Node),
  	    Es = seq(Body, floating(text(", ")), Ctxt1, fun lay/2),
  	    sep([text("begin"), nest(Ctxt1#ctxt.break_indent, lay_body_elems(fun refac_prettypr_0:sep/1, Es, Body)), text("end")]);
  	catch_expr ->  %% done;
  	    {Prec, PrecR} = preop_prec('catch'),
  	    D = lay(refac_syntax:catch_expr_body(Node), set_prec(Ctxt, PrecR)),
  	    D1 = follow(text("catch"), D, Ctxt#ctxt.break_indent),
  	    maybe_parentheses(D1, Prec, Ctxt);
  	class_qualifier ->  %% done;
  	    Ctxt1 = set_prec(Ctxt, max_prec()),
  	    D1 = lay(refac_syntax:class_qualifier_argument(Node), Ctxt1),
  	    D2 = lay(refac_syntax:class_qualifier_body(Node), Ctxt1),
  	    beside(D1, beside(text(":"), D2));
  	comment ->
  	    D = stack_comment_lines(refac_syntax:comment_text(Node)),
  	    %% Default padding for standalone comments is empty.
  	    case refac_syntax:comment_padding(Node) of
  		none -> floating(break(D));
  		P -> floating(break(beside(text(spaces(P)), D)))
  	    end;
  	conjunction -> %% done;
  	    Body = refac_syntax:conjunction_body(Node),
  	    Sep = get_separator(Body, Ctxt#ctxt.tokens, ","),
  	    Es = seq(Body, floating(text(Sep)), reset_prec(Ctxt), fun lay/2),
  	    lay_elems(fun refac_prettypr_0:par/1, Es, refac_syntax:conjunction_body(Node));
  	disjunction -> %% done;
  	    %% For clarity, we don't paragraph-format
  	    %% disjunctions; only conjunctions (see above).
  	    Es = seq(refac_syntax:disjunction_body(Node), floating(text(";")), reset_prec(Ctxt), fun lay/2),
  	    lay_elems(fun refac_prettypr_0:sep/1, Es, refac_syntax:disjunction_body(Node));
  	error_marker ->  %% done;
  	    E = refac_syntax:error_marker_info(Node),
  	    beside(text("** "), beside(lay_error_info(E, reset_prec(Ctxt)), text(" **")));
  	eof_marker -> empty();
  	form_list ->
  	    Es = seq(refac_syntax:form_list_elements(Node), none, reset_prec(Ctxt), fun lay/2),
  	    %% I leave this as it is. (HL).
  	    vertical_sep(text(""), Es);
  	generator -> %% done;
  	    Pat = refac_syntax:generator_pattern(Node),
  	    Body = refac_syntax:generator_body(Node),
  	    lay_generator(Ctxt, Pat, Body);
  	binary_generator ->
  	    Pat = refac_syntax:binary_generator_pattern(Node),
  	    Body = efac_syntax:binary_generator_body(Node),
  	    lay_generator(Ctxt, Pat, Body);
  	implicit_fun -> %%done;
  	    D = lay(refac_syntax:implicit_fun_name(Node), reset_prec(Ctxt)),
  	    beside(floating(text("fun ")), D);
  	list_comp ->  %% done;
  	    Ctxt1 = reset_prec(Ctxt),
  	    D1 = lay(refac_syntax:list_comp_template(Node), Ctxt1),
  	    Es0 = refac_syntax:list_comp_body(Node),
  	    Sep = get_separator(Es0, Ctxt#ctxt.tokens, ","),
  	    Es = seq(Es0, floating(text(Sep)), Ctxt1, fun lay/2),
  	    D2 = lay_elems(fun refac_prettypr_0:par/1, Es, refac_syntax:list_comp_body(Node)),
  	    D1EndLn = get_end_line(refac_syntax:list_comp_template(Node)),
  	    D2StartLn = get_start_line(hd(refac_syntax:list_comp_body(Node))),
  	    D3 = case (D2StartLn - D1EndLn == 0) and (D1EndLn =/= 0) of
  		     true -> beside(D1, beside(floating(text(" || ")), beside(D2, floating(text("]")))));
  		     _ -> par([D1, beside(floating(text("|| ")), beside(D2, floating(text("]"))))])
  		 end,
  	    beside(floating(text("[")), D3);
  	binary_comp ->
  	    Ctxt1 = reset_prec(Ctxt),
  	    D1 = lay(erl_syntax:binary_comp_template(Node), Ctxt1),
  	    D2 = par(seq(erl_syntax:binary_comp_body(Node),
  			 floating(text(",")), Ctxt1,
  			 fun lay/2)),
  	    beside(floating(text("<< ")),
  		   par([D1, beside(floating(text(" || ")),
  				   beside(D2, floating(text(" >>"))))]));
  	macro ->  %%done;
  	    %% This is formatted similar to a normal function call, but
  	    %% prefixed with a "?".
  	    Ctxt1 = reset_prec(Ctxt),
  	    N = refac_syntax:macro_name(Node),
  	    Args = refac_syntax:macro_arguments(Node),
  	    D = case Args of
  		    [H| _] ->
  			EndLn = get_end_line(N),
  			StartLn = get_start_line(H),
  			Sep = get_separator(Args, Ctxt#ctxt.tokens, ","),
  			As = seq(Args, floating(text(Sep)), reset_prec(Ctxt), fun lay/2),
  			case StartLn > EndLn of
  			    true ->
  				above(beside(lay(N, Ctxt1), text("(")),
  				      nest(Ctxt1#ctxt.sub_indent,
  					   beside(lay_elems(fun refac_prettypr_0:par/1, As, Args), floating(text(")")))));
  			    false ->
  				beside(lay(N, Ctxt1), beside(text("("),
  							     beside(lay_elems(fun refac_prettypr_0:par/1, As, Args), floating(text(")")))))
  			end;
  		    [] -> beside(lay(N, Ctxt1), text("()"));
  		    none -> lay(N, Ctxt1)
  		end,
  	    D1 = beside(floating(text("?")), D),
  	    case Ctxt#ctxt.prec of
  		P when P > 0 ->
  		    case lists:keysearch(with_bracket, 1, refac_syntax:get_ann(Node)) of
  			{value, {with_bracket, true}} ->
  			    lay_parentheses(D1, Ctxt);
  			_ -> D1
  		    end;
  		_ -> D1
  	    end;
  	parentheses ->  %% done;
  	    D = lay(refac_syntax:parentheses_body(Node), reset_prec(Ctxt)),
  	    lay_parentheses(D, Ctxt);
  	query_expr ->  %% done;
  	    Ctxt1 = reset_prec(Ctxt),
  	    D = lay(refac_syntax:query_expr_body(Node), Ctxt1),
  	    sep([text("query"), nest(Ctxt1#ctxt.break_indent, D), text("end")]);
  	receive_expr ->  %% done;
  	    Ctxt1 = reset_prec(Ctxt),
  	    D1 = lay_clauses(refac_syntax:receive_expr_clauses(Node), receive_expr, Ctxt1),
  	    D2 = case refac_syntax:receive_expr_timeout(Node) of
  		     none -> D1;
  		     T ->
  			 D3 = lay(T, Ctxt1),
  			 A = refac_syntax:receive_expr_action(Node),
  			 D4 = lay_elems(fun refac_prettypr_0:sep/1, seq(A, floating(text(", ")), Ctxt1, fun lay/2), A),
  			 sep([D1, follow(floating(text("after")), append_clause_body(D4, D3, Ctxt1, {1, 1}), Ctxt1#ctxt.break_indent)])
  		 end,
  	    sep([text("receive"), nest(Ctxt1#ctxt.break_indent, D2), text("end")]);
  	record_access ->
  	    {PrecL, Prec, PrecR} = inop_prec('#'),
  	    D1 = lay(refac_syntax:record_access_argument(Node), set_prec(Ctxt, PrecL)),
  	    D2 = beside(floating(text(".")), lay(refac_syntax:record_access_field(Node), set_prec(Ctxt, PrecR))),
  	    D3 = case refac_syntax:record_access_type(Node) of
  		     none -> D2;
  		     T ->
  			 beside(beside(floating(text("#")), lay(T, reset_prec(Ctxt))), D2)
  		 end,
  	    maybe_parentheses(beside(D1, D3), Prec, Ctxt);
  	record_expr ->  %% done;
  	    {PrecL, Prec, _} = inop_prec('#'),
  	    Ctxt1 = reset_prec(Ctxt),
  	    D1 = lay(refac_syntax:record_expr_type(Node), Ctxt1),
  	    Fields = refac_syntax:record_expr_fields(Node),
  	    Sep = get_separator(Fields, Ctxt#ctxt.tokens, ","),
  	    D2 = lay_elems(fun refac_prettypr_0:par/1, seq(refac_syntax:record_expr_fields(Node), floating(text(Sep)), Ctxt1, fun lay/2), Fields),
  	    D3 = beside(beside(floating(text("#")), D1), beside(text("{"), beside(D2, floating(text("}"))))),
  	    D4 = case refac_syntax:record_expr_argument(Node) of
  		     none -> D3;
  		     A -> beside(lay(A, set_prec(Ctxt, PrecL)), D3)
  		 end,
  	    maybe_parentheses(D4, Prec, Ctxt);
  	record_field ->  %% done;
  	    Ctxt1 = reset_prec(Ctxt),
  	    D1 = lay(refac_syntax:record_field_name(Node), Ctxt1),
  	    case refac_syntax:record_field_value(Node) of
  		none -> D1;
  		V -> D2 = lay(V, Ctxt1),
  		     D1EndLn = get_end_line(refac_syntax:record_field_name(Node)),
  		     D2StartLn = get_start_line(V),
  		     case (D2StartLn - D1EndLn == 0) and (D1EndLn =/= 0) of
  			 true -> beside(D1, beside(text(" = "), D2));
  			 _ -> par([D1, floating(text(" = ")), D2], Ctxt1#ctxt.break_indent)
  		     end
  	    end;
  	record_index_expr ->  %% done
  	    {Prec, PrecR} = preop_prec('#'),
  	    D1 = lay(refac_syntax:record_index_expr_type(Node), reset_prec(Ctxt)),
  	    D2 = lay(refac_syntax:record_index_expr_field(Node), set_prec(Ctxt, PrecR)),
  	    D3 = beside(beside(floating(text("#")), D1), beside(floating(text(".")), D2)),
  	    maybe_parentheses(D3, Prec, Ctxt);
  	rule -> %% done.
  	    %% Comments on the name will be repeated; cf.
  	    %% `function'.
  	    Ctxt1 = reset_prec(Ctxt),
  	    D1 = lay(refac_syntax:rule_name(Node), Ctxt1),
  	    D2 = lay_clauses(refac_syntax:rule_clauses(Node), {rule, D1}, Ctxt1),
  	    beside(D2, floating(text(".")));
  	size_qualifier -> %%done;
  	    Ctxt1 = set_prec(Ctxt, max_prec()),
  	    Body = refac_syntax:size_qualifier_body(Node),
  	    D1 = case refac_syntax:type(Body) == variable orelse refac_syntax:type(Body) == underscore orelse refac_syntax:is_literal(Body) == true of
  		     true -> lay(Body, Ctxt1);
  		     false ->
  			 case refac_syntax:type(Body) of
  			     macro -> case lists:keysearch(with_bracket, 1, refac_syntax:get_ann(Body)) of
  					  {value, {with_bracket, true}} ->
  					      beside(floating(text("(")), beside(lay(Body, Ctxt1), floating(text(")"))));
  					  _ -> lay(Body, Ctxt1)
  				      end;
  			     _ -> beside(floating(text("(")), beside(lay(Body, Ctxt1), floating(text(")"))))
  			 end
  		 end,
  	    D2 = lay(refac_syntax:size_qualifier_argument(Node), Ctxt1),
  	    beside(D1, beside(text(":"), D2));
  	try_expr ->
  	    Ctxt1 = reset_prec(Ctxt),
  	    Body = refac_syntax:try_expr_body(Node),
  	    D1 = lay_body_elems(fun refac_prettypr_0:sep/1, seq(Body,floating(text(", ")),Ctxt1,fun lay/2), Body),
  	    Es0 = [text("end")],
  	    Es1 = case refac_syntax:try_expr_after(Node) of
  		      [] -> Es0;
  		      As ->
  			  D2 = lay_elems(fun refac_prettypr_0:sep/1, seq(As,floating(text(", ")),Ctxt1,fun lay/2), As),
  			  [text("after"),nest(Ctxt1#ctxt.break_indent,D2)| Es0]
  		  end,
  	    Es2 = case refac_syntax:try_expr_handlers(Node) of
  		      [] -> Es1;
  		      Hs ->
  			  D3 = lay_clauses(Hs,try_expr,Ctxt1),
  			  [text("catch"),nest(Ctxt1#ctxt.break_indent,D3)| Es1]
  		  end,
  	    {L,C} = refac_syntax:get_pos(hd(Body)),
  	    TryLineNum = get_prev_keyword_line_num(Ctxt1#ctxt.tokens, {L,C}, 'try'),
  	    case refac_syntax:try_expr_clauses(Node) of
  		[] ->
  		    case TryLineNum==L andalso TryLineNum/=0 of
  			true ->
  			    sep([beside(text("try "),nest(Ctxt1#ctxt.break_indent, D1))| Es2]);
  			false ->
  			    sep([text("try"),nest(Ctxt1#ctxt.break_indent, D1)| Es2])
  		    end;
  		Cs ->
  		    {_, {L0,C0}} = refac_util:get_start_end_loc(lists:last(Body)),
  		    OfLineNum = get_post_keyword_line_num(Ctxt1#ctxt.tokens, {L0,C0}, 'of'),
  		    D4 = lay_clauses(Cs, try_expr, Ctxt1),
  		    Es3 = [nest(Ctxt1#ctxt.break_indent, D4)| Es2],
  		    case TryLineNum==L andalso TryLineNum/=0 of
  			true ->
  			    case OfLineNum==L0 andalso L0/=0 of
  				true ->
  				    sep([beside(text("try "), beside(nest(Ctxt1#ctxt.break_indent, D1), text(" of")))| Es3]);
  				false ->
  				    sep([beside(text("try "),nest(Ctxt1#ctxt.break_indent, D1)), text("of")| Es3])
  			    end;
  			false ->
  			    case OfLineNum==L0 andalso L0/=0 of
  				true ->
  				    sep([text("try"), nest(Ctxt1#ctxt.break_indent, D1)| Es3]);
  				false ->
  				    sep([text("try"), nest(Ctxt1#ctxt.break_indent, D1), text("of")| Es3])
  			    end
  		    end
  	    end;
  	warning_marker ->
  	    E = refac_syntax:warning_marker_info(Node),
  	    beside(text("%% WARNING: "), lay_error_info(E, reset_prec(Ctxt)));
  	type -> empty();  %% tempory fix!!
  	typed_record_field -> empty() %% tempory fix!!!
      end.
  
  lay_generator(Ctxt, Pat, Body) ->
      Ctxt1 = reset_prec(Ctxt),
      D1 = lay(Pat,Ctxt1),
      D2 = lay(Body,Ctxt1),
      D1EndLn = get_end_line(Pat),
      D2StartLn = get_start_line(Body),
      case (D1EndLn==0) or (D2StartLn==0) of
  	true ->
  	    par([D1,beside(text("<- "),D2)],Ctxt1#ctxt.break_indent);
  
negative.code:     remove_trailing_whitespace(S, [C| Acc]).
  
  
  remove_trailing_whites(Str) ->
      Str1=lists:dropwhile(fun(S)->
                                   lists:member(S, [$\n, $\r, $\t, $\s])
                           end, lists:reverse(Str)),
      lists:reverse(Str1).
      
  get_leading_whites(OriginalToks) ->
      Ts1=lists:takewhile(fun(Ts) ->
                                  all_whites(Ts)
                          end, OriginalToks),
      refac_util:concat_toks(lists:append(Ts1)).
  
  get_trailing_whites(Str) ->   
      lists:reverse(lists:takewhile(fun(S) ->
                                            lists:member(S, [$\n, $\r, $\t, $\s])
                                    end, lists:reverse(Str))).
      
  
  %% =====================================================================
  
  get_start_loc(Node) ->
      {L, _} = get_start_end_loc(Node),
      L.
  
  get_start_end_loc(Node)->
      refac_util:get_start_end_loc(Node).
  
  get_start_line_with_comment(Node) ->
      {{L, _}, _} = get_start_end_loc_with_comment(Node),
      L.
     
  get_end_line_with_comment(Node) ->
      {_, {L, _}} = get_start_end_loc_with_comment(Node),
      L.
  
  get_start_loc_with_comment(Node) ->
      {Start, _}= get_start_end_loc_with_comment(Node),
      Start.
  
  get_end_loc_with_comment(Node) ->
      {_, End}=get_start_end_loc_with_comment(Node),
      End.
  
  get_start_end_loc_with_comment(Node) ->
      {Start, End} = get_start_end_loc(Node),
      PreCs = refac_syntax:get_precomments(Node),
      PostCs = refac_syntax:get_postcomments(Node),
      Start1 = case PreCs of
                   [] ->
                       Start;
                   _ ->
                       refac_syntax:get_pos(hd(PreCs))
               end,
      End1 = case PostCs of
                 [] ->
                     End;
                 _ ->
                     LastC = refac_syntax:comment_text(lists:last(PostCs)),
                     {L, C}=refac_syntax:get_pos(lists:last(PostCs)),
                     {L, C+length(LastC)-1}
             end,
      {Start1, End1}.
  
   
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  
  repair_new_form_str("", NewFormStr, _TabWidth, _FileFormat) -> NewFormStr;
  repair_new_form_str(OldFormStr, NewFormStr, TabWidth, FileFormat)->
      {ok, OldToks0, _} = refac_scan_with_layout:string(OldFormStr,{1,1}, TabWidth, FileFormat),
      OldToksByLine =group_toks_by_line(OldToks0),
      Str1 = get_leading_whites(OldToksByLine),
      Str2 = get_trailing_whites(OldFormStr),
      NewFormStr1=Str1++remove_trailing_whites(NewFormStr)++Str2,
      {ok, NewToks0, _} = refac_scan_with_layout:string(NewFormStr1, {1,1}, TabWidth, FileFormat),
      NewToksByLine = group_toks_by_line(NewToks0),
      DiffByLine = levenshtein_dist(OldToksByLine, NewToksByLine, TabWidth),
      %% refac_io:format("DiffByLine:\n~p\n", [DiffByLine]),
      repair_form_layout(DiffByLine, TabWidth).
      
  
  repair_form_layout(DiffByLine, TabWidth) ->
      repair_form_layout(DiffByLine, none, TabWidth, []).
  repair_form_layout([], _, _TabWidth, Acc) ->
      refac_util:concat_toks(lists:append(lists:reverse(Acc)));
  repair_form_layout([{'*', LineToks}|Lines], PrevDiff, TabWidth, Acc) ->
      case all_whites(LineToks) of
          true ->
              repair_form_layout(Lines, PrevDiff, TabWidth,[LineToks|Acc]);
          false ->
              repair_form_layout(Lines, '*', TabWidth,[LineToks|Acc])
      end;
  repair_form_layout([{'d', _LineToks}|Lines], _PrevDiff, TabWidth, Acc) ->
      repair_form_layout(Lines, 'd', TabWidth, Acc);
  repair_form_layout([{'i', LineToks}|Lines], _PrevDiff, TabWidth, Acc) ->
      repair_form_layout(Lines, 'i', TabWidth, [LineToks|Acc]);
  repair_form_layout([{'s', OldLineToks, NewLineToks}|Lines], PrevDiff, TabWidth, Acc) ->
      case is_editing_change(OldLineToks, NewLineToks) of
          true ->
              NewLineToks1 = recover_tab_keys(OldLineToks, NewLineToks, TabWidth),
              repair_form_layout(Lines, 's', TabWidth, [NewLineToks1|Acc]);
          false ->
              %% layout change.
              case PrevDiff of 
                  '*' ->
                      repair_form_layout(Lines, '*', TabWidth, [OldLineToks|Acc]);
                  _ -> %% rather conservertive.
                      case all_whites_or_comments(OldLineToks) of 
                          true ->
                              Lines1 = lists:dropwhile(
                                         fun(L) ->
                                                 all_whites_or_comments(element(2,L))
                                         end, Lines),
                              case Lines1 of
                                  [{'s', Toks1, Toks2}|_] ->
                                      case has_layout_change(Toks1, Toks2, TabWidth) of 
                                          true ->
                                              NewLineToks1 = recover_tab_keys(OldLineToks, NewLineToks, TabWidth),
                                              repair_form_layout(Lines, 's', TabWidth, [NewLineToks1|Acc]);
                                          false ->
                                              repair_form_layout(Lines, '*', TabWidth, [OldLineToks|Acc])
                                      end;
                                  _ ->
                                      repair_form_layout(Lines, '*', TabWidth, [OldLineToks|Acc])
                              end;                                
                          false ->
                              NewLineToks1 = recover_tab_keys(OldLineToks, NewLineToks, TabWidth),
                              repair_form_layout(Lines, 's', TabWidth, [NewLineToks1|Acc])
                      end
              end
      end.
  
  is_editing_change(Toks1, Toks2) ->
      remove_loc_and_whites(Toks1) =/=
          remove_loc_and_whites(Toks2).
  
  has_layout_change(Toks1, Toks2, TabWidth) ->
      Toks11 = expand_tab_keys(Toks1, TabWidth),
      Toks21 = expand_tab_keys(Toks2, TabWidth),
      Whites1 = lists:takewhile(fun(T) -> is_whitespace(T) end, Toks11),
      Whites2 = lists:takewhile(fun(T) -> is_whitespace(T) end, Toks21),
      length(Whites1)/=length(Whites2).
                                        
                                      
      
  recover_tab_keys(OldToks, NewToks, TabWidth)->
      TabToks =lists:takewhile(fun(T)-> is_tab_token(T) end, OldToks),
      {WhiteToks, Toks1}=lists:splitwith(fun(T) -> 
                                                 case T of
                                                     {whitespace, _L, ' '} ->
                                                         true;
                                                     _ -> false
                                                 end
                                         end, NewToks),
      recover_tab_keys(TabToks, WhiteToks, TabWidth, [])++Toks1.
  
  recover_tab_keys([], WhiteSpaces, _TabWidth, Acc) ->
      lists:reverse(Acc)++WhiteSpaces;
  recover_tab_keys([T={whitespace, _, '\t'}], WhiteSpaces, TabWidth, Acc) ->
      case length(WhiteSpaces)>=TabWidth of
          true ->
              recover_tab_keys([], lists:nthtail(TabWidth, WhiteSpaces), TabWidth, [T|Acc]);
          false ->
              lists:reverse(Acc)++WhiteSpaces
      end;
  recover_tab_keys([T={whitespace, _, '\t'}|Ts], WhiteSpaces, TabWidth, Acc) ->
      case length(WhiteSpaces)>=TabWidth of
          true ->
              recover_tab_keys(Ts, lists:nthtail(TabWidth, WhiteSpaces), TabWidth, [T|Acc]);
          false ->
             lists:reverse(Acc)++WhiteSpaces
      end.
  
  group_toks_by_line(Toks) ->
      Toks1 =[case T  of 
  		{K, {L,_C}, V} -> {K, L, V};
  		{K, {L,_C}} -> {K, L}
  	    end || T <-Toks],
      group_toks_by_line_1(Toks1,[]).
  
  group_toks_by_line_1([],Acc) -> lists:reverse(Acc);
  group_toks_by_line_1(Toks = [T| _Ts],Acc) ->
      L = element(2,T),
      {Toks1, Toks2} = 
  	lists:partition(fun (T1) ->
  				element(2,T1) == L
  			end,
  			Toks),
      group_toks_by_line_1(Toks2,[Toks1|Acc]).
  
  
                          
  is_tab_token({whitespace, _, '\t'}) ->
      true;
  is_tab_token(_) ->
      false.
  
                                      
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  
  levenshtein_dist(OldToks, NewToks, TabWidth) ->
      OldLen = length(OldToks),
      NewLen = length(NewToks),
      Is =lists:seq(0, OldLen),
      Js= lists:seq(1, NewLen),
      InitAcc=[{{I,0},I}||I<-Is] ++ [{{0, J}, J}||J<-Js],
      Matrix=levenshtein_dist(OldToks, NewToks, OldLen, NewLen, TabWidth, {1, 1}, InitAcc),
      get_edit_ops(Matrix, OldToks, NewToks, OldLen, NewLen, TabWidth, []). 
      
  
  
  levenshtein_dist(_OldToks, _NewToks, _OldLen, NewLen, _TabWidth, {_I, J}, Acc)
    when J>NewLen ->  Acc;
  levenshtein_dist(OldToks, NewToks, OldLen, NewLen, TabWidth, {I, J}, Acc)
    when I>OldLen ->
      levenshtein_dist(OldToks, NewToks, OldLen, NewLen, TabWidth, {1, J+1}, Acc);
  levenshtein_dist(OldToks, NewToks, OldLen, NewLen, TabWidth, {I, J}, Acc) ->
      case same(lists:nth(I, OldToks), lists:nth(J, NewToks), TabWidth) of
          true ->
              {value, {_, V}}=lists:keysearch({I-1, J-1}, 1, Acc),
              levenshtein_dist(OldToks, NewToks, OldLen, NewLen, TabWidth, {I+1, J}, 
                               [{{I,J},V}|Acc]);
          false ->
              {value, {_, Del}} = lists:keysearch({I-1, J}, 1,Acc),
              {value, {_, Ins}} = lists:keysearch({I, J-1}, 1,Acc),
              {value, {_, Sub}} = lists:keysearch({I-1, J-1},1, Acc),
              Min = lists:min([Del, Ins, Sub]),
              levenshtein_dist(OldToks, NewToks, OldLen, NewLen, TabWidth, {I+1, J}, 
                               [{{I,J},Min+1}|Acc])
      end.
  
  
  get_edit_ops(_Matrix, _OldToks, _NewToks, I, J, _TabWidth, Acc) 
    when I=<0 andalso J=<0 ->
      Acc;
  get_edit_ops(Matrix, OldToks, NewToks, I, J, TabWidth,Acc) ->
      Ith = lists:nth(I, OldToks),
      Jth = lists:nth(J, NewToks),
      case same(Ith, Jth, TabWidth) of
          true ->
              get_edit_ops(Matrix, OldToks, NewToks, I-1, J-1, TabWidth, [{'*', Ith}|Acc]);
          false ->
              {value, {_, Del}} = lists:keysearch({I-1, J}, 1,Matrix),
              {value, {_, Ins}} = lists:keysearch({I, J-1}, 1,Matrix),
              {value, {_, Sub}} = lists:keysearch({I-1, J-1},1, Matrix),
              case lists:min([Del, Ins, Sub]) of
                  Ins ->
                      get_edit_ops(Matrix, OldToks, NewToks, I, J-1, TabWidth, [{'i', Jth}|Acc]);
                  Del ->
                      get_edit_ops(Matrix, OldToks, NewToks, I-1, J, TabWidth, [{'d', Ith}|Acc]);
                  Sub ->
                      get_edit_ops(Matrix, OldToks, NewToks, I-1, J-1, TabWidth, [{'s', Ith, Jth}|Acc])
              end
      end.
  
  
  same(Toks1, Toks2, TabWidth) ->
      case all_whites(Toks1) andalso all_whites(Toks2) of 
  	true ->
  	    true;
  	false ->
  	    same_toks_1(Toks1, Toks2, TabWidth)
      end.
  same_toks_1(Toks1, Toks2, TabWidth) ->
      Toks11=expand_tab_keys(Toks1, TabWidth),
      Toks21=expand_tab_keys(Toks2, TabWidth),
      Toks12=remove_whites_after_first_non_white_token(remove_locs(Toks11)),
      Toks22=remove_whites_after_first_non_white_token(remove_locs(Toks21)),
      Toks12==Toks22.
  
  
  all_whites_or_comments(Toks) ->
       lists:all(fun(T) ->
                         is_whitespace_or_comment(T) 
                 end, Toks).
      
  all_whites(Toks) ->
      lists:all(fun(T) ->
  		      is_whitespace(T) 
  	      end, Toks).
  
  expand_tab_keys(Toks, TabWidth) ->
      lists:append([case T of 
  		      {whitespace, L, '\t'} ->
  			  lists:duplicate(TabWidth, {whitespace, L, ' '});
  		      _ -> [T]
  		  end || T<-Toks]).
  
  
  remove_whites_after_first_non_white_token(Toks) ->
      {Toks1, Toks2}=lists:splitwith(fun(T) ->
  					   is_whitespace_or_comment(T)
  				   end, Toks),
      Toks1++[T||T<-Toks2, not is_whitespace(T)].
  
  remove_loc(T) ->
      case T of
          {K, _L, V} -> {K, 0, V};
          {K, _L} -> {K, 0};
  	 _ -> T
      end.
  
  remove_locs(Toks) when is_list(Toks) ->
      [remove_loc(T)|| T<-Toks];
  remove_locs(Others) ->
      Others.
  
  remove_loc_and_whites(Toks) ->
      [remove_loc(T)||T<-Toks,
           not is_whitespace(T)].
  
  
  remove_locs_whites_and_comments(Toks) ->
      [remove_loc(T)||T<-Toks,
           not is_whitespace_or_comment(T)].
  