anchor.diff:  % Function declarations create a new scope
   transform(State, {function, Line, Name, Arguments, Expressions}) ->
     % Create a new scope with dict:new()
  -  {ok, {_, Dict}, Arguments2} = reia_visitor:transform(Arguments, {argument, dict:new()}, fun transform/2),
  -  {ok, _, Expressions2} = reia_visitor:transform(Expressions, {normal, Dict}, fun transform/2),
  +  {ok, #state{bindings=Dict}, Arguments2} = reia_visitor:transform(
  +    Arguments, 
  +    #state{mode=argument, bindings=dict:new()}, 
  +    fun transform/2
  +  ),
  +  {ok, _, Expressions2} = reia_visitor:transform(Expressions, #state{bindings=Dict}, fun transform/2),
       
     % Return to the original scope
     {stop, State, {function, Line, Name, Arguments2, Expressions2}};
   
   % Lambdas close over the outer scope, bind arguments, but don't affect the outer scope
  -transform({_, Dict} = State, {lambda, Line, Arguments, Expressions}) ->
  -  {ok, {_, Dict2}, Arguments2} = reia_visitor:transform(Arguments, {argument, Dict}, fun transform/2),
  -  {ok, _, Expressions2} = reia_visitor:transform(Expressions, {normal, Dict2}, fun transform/2),
  +transform(#state{bindings=Dict} = State, {lambda, Line, Arguments, Expressions}) ->
  +  {ok, #state{bindings=Dict2}, Arguments2} = reia_visitor:transform(
  +    Arguments, 
  +    #state{mode=argument, bindings=Dict}, 
  +    fun transform/2
  +  ),
  +  {ok, _, Expressions2} = reia_visitor:transform(Expressions, #state{bindings=Dict2}, fun transform/2),
     {stop, State, {lambda, Line, Arguments2, Expressions2}};
     
   % Function names are identifiers and should remain undisturbed unless they are bound variables
  -transform({Mode, Dict} = State, {funcall, Line, {identifier, _Line, Name} = Identifier, Arguments}) ->
  -  {ok, {_, Dict2}, Arguments2} = reia_visitor:transform(Arguments, State, fun transform/2),
  +transform(#state{mode=Mode, bindings=Dict} = State, {funcall, Line, {identifier, _Line, Name} = Identifier, Arguments}) ->
  +  {ok, #state{bindings=Dict2}, Arguments2} = reia_visitor:transform(Arguments, State, fun transform/2),
     Identifier2 = case dict:find(Name, Dict) of
       {ok, Version} ->
         {var, Line, ssa_name(Name, Version)};
  
positive.code:     error ->
        build_method_call(Line, Identifier, Arguments2, Mode, Dict2)
    end,
    {stop, {Mode, Dict3}, Node};
  
  transform({Mode, _Dict} = State, {erl_funcall, Line, Module, Function, Arguments}) ->
    {ok, {_, Dict2}, Arguments2} = reia_visitor:transform(Arguments, State, fun transform/2),
    Node = {erl_funcall, Line, Module, Function, Arguments2},
    {stop, {Mode, Dict2}, Node};
    
  % Arguments should initialize new entries in the SSA dict
  transform({argument, Dict}, {identifier, Line, Name}) ->
    case dict:find(Name, Dict) of
      {ok, _} ->
        throw({error, {Line, lists:flatten(io_lib:format("argument already bound: '~s'", [Name]))}});
      error ->
        Dict2 = dict:store(Name, 0, Dict),
        Node = {identifier, Line, ssa_name(Name, 0)},
        {stop, {argument, Dict2}, Node}
    end;
  
  % Match expressions mutate variables on the LHS
  transform({Mode, Dict}, {match, Line, In1, In2}) ->
    {ok, {_, Dict2}, Out2} = reia_visitor:transform(In2, {Mode, Dict}, fun transform/2),
    {ok, {_, Dict3}, Out1} = reia_visitor:transform(In1, {match, Dict2}, fun transform/2),
    {stop, {Mode, Dict3}, {match, Line, Out1, Out2}};
    
  % Case expressions bind variables in clauses
  transform({Mode, Dict}, {'case', Line, Expression, Clauses}) ->
    {ok, {_, Dict2}, Expression2} = reia_visitor:transform(Expression, {Mode, Dict}, fun transform/2),
    {Dict3, Clauses2} = process_clauses('case', Dict2, Clauses),
    {stop, {Mode, Dict3}, {'case', Line, Expression2, Clauses2}};
  
  % Case clauses match against patterns
  transform({'case', Dict}, {clause, Line, Pattern, Expressions}) ->
    {ok, {_, Dict2}, Pattern2} = reia_visitor:transform(Pattern, {match, Dict}, fun transform/2),
    {ok, {_, Dict3}, Expressions2} = reia_visitor:transform(Expressions, {normal, Dict2}, fun transform/2),
    {stop, {'case', Dict3}, {clause, Line, Pattern2, Expressions2}};
      
  % Catch clauses match against patterns
  transform({Mode, Dict}, {'catch', Line, Pattern, Expressions}) ->
    {ok, {_, Dict2}, Pattern2} = reia_visitor:transform(Pattern, {match, Dict}, fun transform/2),
    {ok, {_, Dict3}, Expressions2} = reia_visitor:transform(Expressions, {normal, Dict2}, fun transform/2),
    {stop, {Mode, Dict3}, {'catch', Line, Pattern2, Expressions2}};
      
  % List comprehensions can access the outer scope but have a scope of their own
  transform({_, Dict} = State, {'lc', Line, Transform, Expressions}) ->
    {ok, {_, Dict2}, Expressions2} = reia_visitor:transform(Expressions, {normal, Dict}, fun transform/2),
    {ok, _, Transform2} = reia_visitor:transform(Transform, {normal, Dict2}, fun transform/2),
    {stop, State, {'lc', Line, Transform2, Expressions2}};
  
  % Generate expressions match a pattern
  transform({Mode, Dict}, {'generate', Line, Pattern, List}) ->
    {ok, {_, Dict2}, Pattern2} = reia_visitor:transform(Pattern, {match, Dict}, fun transform/2),
    {ok, {_, Dict3}, List2} = reia_visitor:transform(List, {Mode, Dict2}, fun transform/2),
    {stop, {Mode, Dict3}, {'generate', Line, Pattern2, List2}};
  
  % Normally identifiers are mapped to their latest version
  transform({normal, Dict} = State, {identifier, Line, Name} = Node) ->
    case dict:find(Name, Dict) of
      {ok, Version} ->
        Node2 = {identifier, Line, ssa_name(Name, Version)},
  
negative.code: process_clauses(Type, Vars, Clauses) ->
    % Proceed with the normal SSA transformation on each clause
    Clauses2 = lists:map(fun(Clause) ->
      {ok, #state{bindings=Binding}, Clause2} = reia_visitor:transform(
        Clause, 
        #state{mode=Type, bindings=Vars}, 
        fun transform/2
      ),
      {Binding, Clause2}
    end, Clauses),
    
  