anchor.diff:          || F <- Forms]
       , ", ")
       ++ " ";
  -
  +fold({'group by', GroupBy}) ->
  +    Size = length(GroupBy),
  +    if Size > 0 -> "group by " ++ string:join([binary_to_list(F) || F <- GroupBy], ", ") ++ " ";
  +    true -> ""
  +    end;
  +fold({having, _Having}) -> "";
  +fold({'order by', OrderBy}) ->
  +    Size = length(OrderBy),
  +    if Size > 0 ->
  +        "order by " ++
  +        string:join(
  +            [case F of
  +            F when is_binary(F) -> binary_to_list(F);
  +            {O, Op} when is_binary(O), is_binary(Op) -> string:strip(lists:flatten([binary_to_list(O), " ", binary_to_list(Op)]));
  +            {O, Op} when is_binary(Op)               -> string:strip(lists:flatten([fold(O), " ", binary_to_list(Op)]))
  +            end
  +            || F <- OrderBy]
  +        , ", ")
  +        ++ " ";
  +    true -> ""
  +    end;
  +
  +% betwen operator
   fold({'between', A, B, C}) ->
       A1 = if is_binary(A) -> binary_to_list(A); true -> fold(A) end,
       B1 = if is_binary(B) -> binary_to_list(B); true -> fold(B) end,
       C1 = if is_binary(C) -> binary_to_list(C); true -> fold(C) end,
       lists:flatten([A1,  " between ", B1, " and ", C1]);
   
  -fold({Op, A}) when Op =:= '-'; Op =:= 'not' ->
  -    case A of
  -        A when is_binary(A) -> lists:flatten([atom_to_list(Op), " (", binary_to_list(A), ")"]);
  -        A                   -> lists:flatten([atom_to_list(Op)," (", fold(A), ")"])
  -    end;
  -
  +% PL/SQL concatenate operator
   fold({'||', Args}) ->
       string:join(
       [case A of
  
positive.code:         || A <- Args]
      , ", ")
      ++ ")";
  fold({'list', Elms}) ->
      "(" ++
      string:join(
  
negative.code:     end
      || A <- Args], " || ");
  
  % All aliases
  fold({as, A, B}) when is_binary(A), is_binary(B) -> lists:flatten([binary_to_list(A), " ", binary_to_list(B)]);
  fold({as, A, B}) when is_binary(B)               -> lists:flatten([fold(A), " ", binary_to_list(B)]);
  fold({as, A}) when is_binary(A)                  -> lists:flatten(["as ", binary_to_list(A)]);
  
  % Union
  fold({union, A, B})                              -> lists:flatten(["(", fold(A), " union ", fold(B), ")"]);
  
  % All where clauses
  fold({where, []}) -> "";
  fold({where, Where}) -> "where " ++ fold(Where);
  
  % In operator
  % for right hand non list argument extra parenthesis added
  fold({'in', L, {'list', _} = R}) when is_binary(L) ->
      lists:flatten([binary_to_list(L), " in ", fold(R), " "]);
  fold({'in', L, R}) when is_binary(L), is_tuple(R) ->
      lists:flatten([binary_to_list(L), " in (", fold(R), ") "]);
  
  % Boolean and arithmetic binary operators handled with precedence
  % *,/ > +,- > and > or
  fold({Op, L, R}) when is_atom(Op), is_tuple(L), is_tuple(R) ->
      Fl = case {Op, element(1, L)} of
          {'*', Ol} when Ol =:= '-'; Ol =:= '+' -> lists:flatten(["(", fold(L), ")"]);
  