anchor.diff:  -type types() :: erl_types:type_table().
   
   -type typesig_scc()    :: [{mfa(), {cerl:c_var(), cerl:c_fun()}, types()}].
  --type typesig_funmap() :: [{type_var(), type_var()}]. %% Orddict
  +-type typesig_funmap() :: #{type_var() => type_var()}.
   
   -type prop_types() :: dict:dict(label(), types()).
   
  --type dict_or_ets() :: {'d', prop_types()} | {'e', ets:tid()}.
  -
  --record(state, {callgraph                    :: dialyzer_callgraph:callgraph()
  -                                              | 'undefined',
  -		cs          = []                :: [constr()],
  -		cmap        = {'d', dict:new()} :: dict_or_ets(),
  -		fun_map     = []                :: typesig_funmap(),
  -		fun_arities = dict:new()        :: dict:dict(type_var(), arity()),
  -		in_match    = false             :: boolean(),
  -		in_guard    = false             :: boolean(),
  -		module                          :: module(),
  -		name_map    = dict:new()        :: dict:dict(mfa(),
  -                                                             cerl:c_fun()),
  -		next_label  = 0                 :: label(),
  -		self_rec                        :: 'false' | erl_types:erl_type(),
  -		plt                             :: dialyzer_plt:plt()
  -                                                 | 'undefined',
  -		prop_types  = {'d', dict:new()} :: dict_or_ets(),
  -		records     = dict:new()        :: types(),
  -		scc         = []                :: [type_var()],
  -		mfas                            :: [tuple()],
  -                solvers     = []                :: [solver()]
  +-record(state, {callgraph                :: dialyzer_callgraph:callgraph()
  +                                          | 'undefined',
  +		cs          = []         :: [constr()],
  +		cmap        = dict:new() :: dict:dict(), % FIXME
  +		fun_map     = maps:new() :: typesig_funmap(),
  +		fun_arities = dict:new() :: dict:dict(type_var(), arity()),
  +		in_match    = false      :: boolean(),
  +		in_guard    = false      :: boolean(),
  +		module                   :: module(),
  +		name_map    = dict:new() :: dict:dict(mfa(), cerl:c_fun()),
  +		next_label  = 0          :: label(),
  +		self_rec                 :: 'false' | erl_types:erl_type(),
  +		plt                      :: dialyzer_plt:plt()
  +                                          | 'undefined',
  +		prop_types  = dict:new() :: dict:dict(), % FIXME
  +		records     = dict:new() :: types(),
  +		scc         = []         :: ordsets:ordset(type_var()),
  +		mfas                     :: [tuple()], % FIXME?
  +                solvers     = []         :: [solver()]
   	       }).
   
   -type state() :: #state{}.
  
positive.code:   debug_make_name_map(Vars0, Funs0),
    Vars = mk_var_list(Vars0),
    Funs = mk_var_list(Funs0),
    NewMap = lists:foldl(fun({Var, Fun}, MP) -> orddict:store(Var, Fun, MP) end,
  		       Map, lists:zip(Vars, Funs)),
    State#state{fun_map = NewMap}.
  
  state__get_rec_var(Fun, #state{fun_map = Map}) ->
    case [V || {V, FV} <- Map, FV =:= Fun] of
      [Var] -> {ok, Var};
      [] -> error
    end.
  
  state__finalize(State) ->
    State1 = enumerate_constraints(State),
  
negative.code: solve([_|_] = SCC, State) ->
    ?debug("============ Analyzing SCC: ~w ===========\n",
  	 [[debug_lookup_name(F) || F <- SCC]]),
    Users = comp_users(SCC, State),
    solve_scc(SCC, map_new(), State, Users, _ToSolve=SCC, false).
  
  comp_users(SCC, State) ->
    Vars0 = [{Fun, state__get_rec_var(Fun, State)} || Fun <- SCC],
    Vars = lists:sort([t_var_name(Var) || {_, {ok, Var}} <- Vars0]),
    family([{t_var(V), F} ||
             F <- SCC,
             V <- ordsets:intersection(get_deps(state__get_cs(F, State)),
                                       Vars)]).
  
  solve_fun(Fun, FunMap, State) ->
    Cs = state__get_cs(Fun, State),
  