anchor.diff:    erlang:put(gensym_env, #{}),
     %% TODO: change syntax_quote/2 so that if it changes the env
     %%       (because of find var) we keep the changes.
  -  NewFormWithMeta = add_meta(Form, Env, syntax_quote(Form, Env)),
  +  {QuotedForm, Env1}      = syntax_quote(Form, Env),
  +  {NewFormWithMeta, Env2} = add_meta(Form, Env1, QuotedForm),
     erlang:erase(gensym_env),
  -  push_form(NewFormWithMeta, NewState).
  +  push_form(NewFormWithMeta, NewState#{env => Env2}).
   
   syntax_quote(Form, Env) ->
     IsSpecial    = clj_analyzer:is_special(Form),
  
positive.code:       GenSym = clj_core:symbol(erlang:iolist_to_binary(PartsStr)),
        SymbolName = clj_core:name(Symbol),
        erlang:put(gensym_env, GensymEnv#{SymbolName => GenSym}),
        GenSym;
      GenSym ->
        GenSym
    end.
  
  resolve_symbol(Symbol, Env) ->
  
negative.code:   case clj_core:namespace(Symbol) of
      undefined ->
        case clj_env:find_var(Env, Symbol) of
          {undefined, Env1} ->
            CurrentNsName = clj_core:name(CurrentNsSym),
            NameStr = clj_core:name(Symbol),
            Sym = clj_core:symbol(CurrentNsName, NameStr),
            {Sym, Env1};
          {Var, Env1} ->
            Sym = clj_core:symbol(clj_core:namespace(Var), clj_core:name(Var)),
            {Sym, Env1}
        end;
      NamespaceStr ->
        case clj_env:resolve_ns(Env, clj_core:symbol(NamespaceStr)) of
          undefined ->
            {Symbol, Env};
          Ns ->
            NsNameSym = clj_namespace:name(Ns),
            NsNameStr = clj_core:name(NsNameSym),
            NameStr = clj_core:name(Symbol),
            {clj_core:symbol(NsNameStr, NameStr), Env}
        end
    end.
  
  -spec syntax_quote_coll(any(), 'clojerl.Symbol':type(), clj_env:env()) ->
    {any(), clj_env:env()}.
  syntax_quote_coll(List, undefined, Env) ->
    syntax_quote_coll(List, Env);
  syntax_quote_coll(List, FunSymbol, Env) ->
    {ExpandedList, Env1} = syntax_quote_coll(List, Env),
    ApplySymbol = clj_core:symbol(<<"clojure.core">>, <<"apply">>),
    {clj_core:list([ApplySymbol, FunSymbol, ExpandedList]), Env1}.
  
  -spec syntax_quote_coll(any(), clj_env:env()) -> {any(), clj_env:env()}.
  syntax_quote_coll(List, Env) ->
    case clj_core:'empty?'(List) of
      true ->
        ListSymbol = clj_core:symbol(<<"clojure.core">>, <<"list">>),
        {clj_core:list([ListSymbol]), Env};
      false ->
        {ReversedExpandedItems, Env1} = expand_list(List, Env, []),
        ExpandedItems = lists:reverse(ReversedExpandedItems),
        ConcatSymbol = clj_core:symbol(<<"clojure.core">>, <<"concat">>),
        {clj_core:list([ConcatSymbol | ExpandedItems]), Env1}
    end.
  
  -spec expand_list(any(), clj_env:env(), any()) -> {any(), clj_env:env()}.
  expand_list(undefined, Env, Result) ->
    {Result, Env};
  expand_list(List, Env, Result) ->
    Item = clj_core:first(List),
    ListSymbol = clj_core:symbol(<<"clojure.core">>, <<"list">>),
    {NewItem, Env2} =
      case {is_unquote(Item), is_unquote_splicing(Item)} of
        {true, _} ->
          {clj_core:list([ListSymbol, clj_core:second(Item)]), Env};
        {_, true} ->
          {clj_core:second(Item), Env};
        _ ->
          {QuotedForm, Env1} = syntax_quote(Item, Env),
          {clj_core:list([ListSymbol, QuotedForm]), Env1}
        end,
    expand_list(clj_core:next(List), Env2, [NewItem | Result]).
  
  -spec add_meta(any(), clj_env:env(), any()) -> {any(), clj_env:env()}.
  add_meta(Form, Env, Result) ->
    case clj_core:'meta?'(Form) of
      true ->
        WithMetaSym = clj_core:symbol(<<"clojure.core">>, <<"with-meta">>),
        {Meta, Env1} = syntax_quote(clj_core:meta(Form), Env),
        {clj_core:list([WithMetaSym, Result, Meta]), Env1};
      _ ->
        {Result, Env}
    end.
  
  is_unquote(Form) ->
  