anchor.diff:  check_var_val(_Function, _Arity, Fun) ->
     Fun.
   
  -%% @doc Processes a function's ast and modifies all calls to functions
  -%%      in the function's own module for a call to the fun returned by
  -%%      clj_module:fake_fun/3.
  -%%
  -%% If the call is a recursive call to the top function then it changes
  -%% the call to a variable built using the value of TopFunction.
  -%% @end
  --spec replace_calls(erl_parse:abstract_form(), module(), atom()) ->
  -  erl_parse:abstract_form().
  -replace_calls( { call, Line
  -               , { remote, _
  -                 , {atom, _, Module}
  -                 , {atom, _, Function}
  -                 } = RemoteOriginal
  -               , Args
  -               }
  -             , CurrentModule
  -             , TopFunction) when CurrentModule =:= Module;
  -                                 CurrentModule =:= '_' ->
  -
  -  Args1 = replace_calls(Args, CurrentModule, TopFunction),
  -  Arity = length(Args),
  -  %% Only replace the call if the module is loaded. If it is not, then the
  -  %% replacement is happening for the evaluation of an expression where the
  -  %% called function hasn't been declared in the same evaluation.
  -  case is_loaded(Module) of
  -    true  ->
  -      Remote = {remote, Line,
  -                {atom, Line, ?MODULE},
  -                {atom, Line, fake_fun}
  -               },
  -
  -      FunCall = { call, Line, Remote
  -                , [ {atom, Line, Module}
  -                  , {atom, Line, Function}
  -                  , {integer, Line, Arity}
  -                  ]
  -                },
  -      {call, Line, FunCall, Args1};
  -    false ->
  -      {call, Line, RemoteOriginal, Args1}
  -  end;
  -%% Detect non-remote calls done to other functions in the module, so we
  -%% can replace them with fake_funs when necessary.
  -replace_calls( {call, Line, {atom, Line2, Function}, Args}
  -             , ModuleName
  -             , TopFunction) ->
  -  Arity = length(Args),
  -  Args1 = replace_calls(Args, ModuleName, TopFunction),
  -  Remote = {remote, Line,
  -            {atom, Line, ?MODULE},
  -            {atom, Line, fake_fun}
  -           },
  -  FunCall = { call, Line, Remote
  -            , [ {atom, Line2, ModuleName}
  -              , {atom, Line2, Function}
  -              , {integer, Line2, Arity}
  -              ]
  -            },
  -  {call, Line, FunCall, Args1};
  -replace_calls(Ast, Module, TopFunction) when is_tuple(Ast) ->
  -  list_to_tuple(replace_calls(tuple_to_list(Ast), Module, TopFunction));
  -replace_calls(Ast, Module, TopFunction) when is_list(Ast) ->
  -  [replace_calls(Item, Module, TopFunction) || Item <- Ast];
  -replace_calls(Ast, _, _) ->
  -  Ast.
  -
  -%% @doc Makes sure the clj_module is loaded.
  --spec ensure_loaded(atom(), string()) -> ok.
  -ensure_loaded(Name, Source) ->
  -  case is_loaded(Name) of
  -    true  -> ok;
  -    false -> load(Name, Source), ok
  -  end.
  -
   %% @private
  --spec load(atom(), string()) -> ok | {error, term()}.
  -load(Name, Source) ->
  -  Module = case code:ensure_loaded(Name) of
  -             {module, Name} ->
  -               new(clj_utils:code_from_binary(Name));
  -             {error, _} ->
  -               new(Name, Source)
  -           end,
  -  ok = gen_server:call(?MODULE, {load, Module}),
  -  Module.
  -
  --spec is_loaded(module()) -> boolean().
  -is_loaded(Name) ->
  -  ets:member(?MODULE, Name).
  -
  -%% @doc Returns a list with all modules that where loaded by the
  -%%      current process.
  -%% @private
  --spec all() -> [clj_module()].
  -all() ->
  -  gen_server:call(?MODULE, all).
  -
  -%% @doc Returns a list where each element is a list with the abstract
  -%%      forms of all stored modules.
  -%% @end
  --spec all_forms() -> [[erl_parse:abstract_form()]].
  -all_forms() ->
  -  lists:map(fun to_forms/1, all()).
  +-spec delete_fake_modules(clj_module()) -> ok.
  +delete_fake_modules(Module) ->
  +  FakeModulesId = Module#module.fake_modules,
  +  [code:delete(Name) || {Name} <- ets:tab2list(FakeModulesId)],
  +  ok.
   
   %% @private
   -spec to_forms(clj_module()) -> [erl_parse:abstract_form()].
  
positive.code:           end,
    Clause = {clause, 0, [], [], Exprs},
    {function, 0, ?ON_LOAD_FUNCTION, 0, [Clause]}.
  
  -spec add_vars(module() | clj_module(), ['clojerl.Var':type()]) -> clj_module().
  add_vars(ModuleName, Vars) when is_atom(ModuleName)  ->
    add_vars(get(?MODULE, ModuleName), Vars);
  add_vars(Module, Vars) ->
    AddFun = fun(V) ->
                 K = clj_core:name(V),
                 save(Module#module.vars, {K, V})
             end,
    lists:foreach(AddFun, Vars),
    Module.
  
  -spec add_attributes(clj_module(), [erl_parse:abstract_form()]) -> clj_module().
  add_attributes(ModuleName, Attrs) when is_atom(ModuleName)  ->
    add_attributes(get(?MODULE, ModuleName), Attrs);
  add_attributes(Module, []) ->
    Module;
  add_attributes(Module, Attrs) ->
    Module1 = Module#module{attrs = Attrs ++ Module#module.attrs},
    save(?MODULE, Module1).
  
  -spec add_exports(clj_module(), [{atom(), non_neg_integer()}]) ->
    clj_module().
  add_exports(ModuleName, Exports) when is_atom(ModuleName)  ->
    add_exports(get(?MODULE, ModuleName), Exports);
  add_exports(Module, Exports) ->
    AddExport = fun(E) ->
                    save(Module#module.exports, {E})
                end,
    ok = lists:foreach(AddExport, Exports),
    Module.
  
  -spec add_functions(module() | clj_module(), [erl_parse:abstract_form()]) ->
    clj_module().
  add_functions(ModuleName, Funs) when is_atom(ModuleName)  ->
    add_functions(get(?MODULE, ModuleName), Funs);
  add_functions(Module, Funs) ->
    SaveFun = fun(F) ->
                  FunctionId  = function_id(F),
                  ok          = delete_fake_fun(Module, FunctionId),
                  save(Module#module.funs, {FunctionId, F})
              end,
    lists:foreach(SaveFun, Funs),
    Module.
  
  -spec add_on_load(module() | clj_module(), erl_parse:abstract_expr()) ->
    clj_module().
  add_on_load(ModuleName, Expr) when is_atom(ModuleName) ->
    add_on_load(get(?MODULE, ModuleName), Expr);
  add_on_load(Module, Expr) ->
    save(Module#module.on_load, {Expr, Expr}),
    Module.
  
  -spec is_clojure(module()) -> boolean().
  is_clojure(Name) ->
    Key = {?MODULE, is_clojure, Name},
    case clj_cache:get(Key) of
      undefined ->
        Attrs = Name:module_info(attributes),
        IsClojure = lists:keymember(clojure, 1, Attrs),
        clj_cache:put(Key, IsClojure),
        IsClojure;
      {ok, Value} ->
        Value
    end.
  
  %%------------------------------------------------------------------------------
  %% gen_server callbacks
  %%------------------------------------------------------------------------------
  
  start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
  
  init([]) ->
    ets:new(?MODULE, [named_table, set, protected, {keypos, 2}]),
    TabId = ets:new(loaded_modules, [set, protected, {keypos, 1}]),
    {ok, #{loaded_modules => TabId}}.
  
  handle_call({load, Module}, {Pid, _}, #{loaded_modules := TabId} = State) ->
    Module = save(?MODULE, Module),
    case get(TabId, Pid) of
      undefined ->
        save(TabId, {Pid, [Module]});
      {Pid, Modules}  ->
        save(TabId, {Pid, [Module | Modules]})
    end,
  
    {reply, ok, State};
  handle_call(cleanup, {Pid, _}, #{loaded_modules := TabId} = State) ->
    Modules = case get(TabId, Pid) of
                undefined   -> [];
                {Pid, Mods} -> Mods
              end,
  
    true = ets:delete(TabId, Pid),
    ok = lists:foreach(fun(M) -> ets:delete(?MODULE, M#module.name) end, Modules),
  
    {reply, Modules, State};
  handle_call(all, {Pid, _}, #{loaded_modules := TabId} = State) ->
    Modules = case get(TabId, Pid) of
                undefined   -> [];
                {Pid, Mods} -> Mods
              end,
  
    {reply, Modules, State}.
  
  handle_cast(_Msg, State) ->
    {ok, State}.
  
  handle_info(_Msg, State) ->
    {ok, State}.
  
  terminate(_Msg, State) ->
    {ok, State}.
  
  code_change(_Msg, _From, State) ->
    {ok, State}.
  
  %%------------------------------------------------------------------------------
  %% Helper Functions
  %%------------------------------------------------------------------------------
  
  %% @private
  -spec delete_fake_modules(clj_module()) -> ok.
  delete_fake_modules(Module) ->
    FakeModulesId = Module#module.fake_modules,
    [code:delete(Name) || {Name} <- ets:tab2list(FakeModulesId)],
    ok.
  
  -spec get(atom(), module()) -> any().
  get(Table, Id) ->
  
negative.code:       end
    end.
  
  %% @doc Processes a function's ast and modifies all calls to functions
  %%      in the function's own module for a call to the fun returned by
  %%      clj_module:fake_fun/3.
  %% @end
  -spec replace_calls(erl_parse:abstract_form(), module()) ->
    erl_parse:abstract_form().
  replace_calls( { call, Line
                 , { remote, _
                   , {atom, _, Module}
                   , {atom, _, Function}
                   } = RemoteOriginal
                 , Args
                 }
               , CurrentModule) ->
    Args1 = replace_calls(Args, CurrentModule),
    Arity = length(Args),
    %% Only replace the call if the module is loaded. If it is not, then the
    %% replacement is happening for the evaluation of an expression where the
    %% called function hasn't been declared in the same evaluation.
    case is_loaded(Module) of
      true  ->
        Remote = {remote, Line,
                  {atom, Line, ?MODULE},
                  {atom, Line, fake_fun}
                 },
  
        FunCall = { call, Line, Remote
                  , [ {atom, Line, Module}
                    , {atom, Line, Function}
                    , {integer, Line, Arity}
                    ]
                  },
        {call, Line, FunCall, Args1};
      false ->
        {call, Line, RemoteOriginal, Args1}
    end;
  %% Detect non-remote calls done to other functions in the module, so we
  %% can replace them with fake_funs when necessary.
  replace_calls({call, Line, {atom, Line2, Function}, Args}, ModuleName) ->
    Arity = length(Args),
    Args1 = replace_calls(Args, ModuleName),
    Remote = {remote, Line,
              {atom, Line, ?MODULE},
              {atom, Line, fake_fun}
             },
    FunCall = { call, Line, Remote
              , [ {atom, Line2, ModuleName}
                , {atom, Line2, Function}
                , {integer, Line2, Arity}
                ]
              },
    {call, Line, FunCall, Args1};
  replace_calls(Ast, Module) when is_tuple(Ast) ->
    list_to_tuple(replace_calls(tuple_to_list(Ast), Module));
  replace_calls(Ast, Module) when is_list(Ast) ->
    [replace_calls(Item, Module) || Item <- Ast];
  replace_calls(Ast, _) ->
    Ast.
  
  -spec add_vars(module() | clj_module(), ['clojerl.Var':type()]) -> clj_module().
  add_vars(ModuleName, Vars) when is_atom(ModuleName)  ->
    add_vars(get(?MODULE, ModuleName), Vars);
  add_vars(Module, Vars) ->
    AddFun = fun(V) ->
                 K = clj_core:name(V),
                 save(Module#module.vars, {K, V})
             end,
    lists:foreach(AddFun, Vars),
    Module.
  
  -spec add_attributes(clj_module(), [erl_parse:abstract_form()]) -> clj_module().
  add_attributes(ModuleName, Attrs) when is_atom(ModuleName)  ->
    add_attributes(get(?MODULE, ModuleName), Attrs);
  add_attributes(Module, []) ->
    Module;
  add_attributes(Module, Attrs) ->
    Module1 = Module#module{attrs = Attrs ++ Module#module.attrs},
    save(?MODULE, Module1).
  
  -spec add_exports(clj_module(), [{atom(), non_neg_integer()}]) ->
    clj_module().
  add_exports(ModuleName, Exports) when is_atom(ModuleName)  ->
    add_exports(get(?MODULE, ModuleName), Exports);
  add_exports(Module, Exports) ->
    AddExport = fun(E) ->
                    save(Module#module.exports, {E})
                end,
    ok = lists:foreach(AddExport, Exports),
    Module.
  
  -spec add_functions(module() | clj_module(), [erl_parse:abstract_form()]) ->
    clj_module().
  add_functions(ModuleName, Funs) when is_atom(ModuleName)  ->
    add_functions(get(?MODULE, ModuleName), Funs);
  add_functions(Module, Funs) ->
    SaveFun = fun(F) ->
                  FunctionId  = function_id(F),
                  ok          = delete_fake_fun(Module, FunctionId),
                  save(Module#module.funs, {FunctionId, F})
              end,
    lists:foreach(SaveFun, Funs),
    Module.
  
  -spec add_on_load(module() | clj_module(), erl_parse:abstract_expr()) ->
    clj_module().
  add_on_load(ModuleName, Expr) when is_atom(ModuleName) ->
    add_on_load(get(?MODULE, ModuleName), Expr);
  add_on_load(Module, Expr) ->
    save(Module#module.on_load, {Expr, Expr}),
    Module.
  
  -spec is_clojure(module()) -> boolean().
  is_clojure(Name) ->
    Key = {?MODULE, is_clojure, Name},
    case clj_cache:get(Key) of
      undefined ->
        Attrs = Name:module_info(attributes),
        IsClojure = lists:keymember(clojure, 1, Attrs),
        clj_cache:put(Key, IsClojure),
        IsClojure;
      {ok, Value} ->
        Value
    end.
  
  %%------------------------------------------------------------------------------
  %% gen_server callbacks
  %%------------------------------------------------------------------------------
  
  start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
  
  init([]) ->
    ets:new(?MODULE, [named_table, set, protected, {keypos, 2}]),
    TabId = ets:new(loaded_modules, [set, protected, {keypos, 1}]),
    {ok, #{loaded_modules => TabId}}.
  
  handle_call({load, Module}, {Pid, _}, #{loaded_modules := TabId} = State) ->
    Module = save(?MODULE, Module),
    case get(TabId, Pid) of
      undefined ->
        save(TabId, {Pid, [Module]});
      {Pid, Modules}  ->
        save(TabId, {Pid, [Module | Modules]})
    end,
  
    {reply, ok, State};
  handle_call(cleanup, {Pid, _}, #{loaded_modules := TabId} = State) ->
    Modules = case get(TabId, Pid) of
                undefined   -> [];
                {Pid, Mods} -> Mods
              end,
  
    true = ets:delete(TabId, Pid),
    ok   = lists:foreach(fun(M) -> ets:delete(?MODULE, M#module.name) end, Modules),
  
    {reply, Modules, State};
  handle_call(all, {Pid, _}, #{loaded_modules := TabId} = State) ->
    Modules = case get(TabId, Pid) of
                undefined   -> [];
                {Pid, Mods} -> Mods
              end,
  
    {reply, Modules, State}.
  
  handle_cast(_Msg, State) ->
    {ok, State}.
  
  handle_info(_Msg, State) ->
    {ok, State}.
  
  terminate(_Msg, State) ->
    {ok, State}.
  
  code_change(_Msg, _From, State) ->
    {ok, State}.
  
  %%------------------------------------------------------------------------------
  %% Helper Functions
  %%------------------------------------------------------------------------------
  
  %% @private
  -spec cleanup() -> ok.
  cleanup() ->
    Modules = gen_server:call(?MODULE, cleanup),
    lists:foreach(fun delete_fake_modules/1, Modules).
  
  %% @private
  %% @doc
  %% Loads the module `Name' into memory. This function assumes it is not
  %% loaded already, so this check should be done before calling it.
  %% The value of `Source' is used to set the `file' attribute of the module
  %% if the module's binary is not found, which is interpreted as if the
  %% module is new.
  %% @end
  -spec load(atom(), string()) -> ok | {error, term()}.
  load(Name, Source) ->
    Module = case code:ensure_loaded(Name) of
               {module, Name} ->
                 new(clj_utils:code_from_binary(Name));
               {error, _} ->
                 new(Name, Source)
             end,
    ok = gen_server:call(?MODULE, {load, Module}),
    Module.
  
  -spec is_loaded(module()) -> boolean().
  is_loaded(Name) ->
    ets:member(?MODULE, Name).
  
  %% @private
  -spec build_fake_fun(clj_module(), atom(), integer()) -> function().
  build_fake_fun(Module, Function, Arity) ->
    {_, FunctionAst} = get(Module#module.funs, {Function, Arity}),
  
    {function, _, _, _, Clauses} =
      replace_calls(FunctionAst, Module#module.name),
    Int = erlang:unique_integer([positive]),
    FakeModuleName = list_to_atom("fake_module_" ++ integer_to_list(Int)),
  
  