anchor.diff:  	  ?list(NewContents, NewTermination, Size)
         end
     end;
  -t_subst_aux(?function(Domain, Range), Dict) ->
  -  ?function(t_subst_aux(Domain, Dict), t_subst_aux(Range, Dict));
  -t_subst_aux(?product(Types), Dict) ->
  -  ?product([t_subst_aux(T, Dict) || T <- Types]);
  -t_subst_aux(?tuple(?any, ?any, ?any) = T, _Dict) ->
  +t_subst_dict(?function(Domain, Range), Dict) ->
  +  ?function(t_subst_dict(Domain, Dict), t_subst_dict(Range, Dict));
  +t_subst_dict(?product(Types), Dict) ->
  +  ?product([t_subst_dict(T, Dict) || T <- Types]);
  +t_subst_dict(?tuple(?any, ?any, ?any) = T, _Dict) ->
     T;
  -t_subst_aux(?tuple(Elements, _Arity, _Tag), Dict) ->
  -  t_tuple([t_subst_aux(E, Dict) || E <- Elements]);
  -t_subst_aux(?tuple_set(_) = TS, Dict) ->
  -  t_sup([t_subst_aux(T, Dict) || T <- t_tuple_subtypes(TS)]);
  -t_subst_aux(T, _Dict) ->
  +t_subst_dict(?tuple(Elements, _Arity, _Tag), Dict) ->
  +  t_tuple([t_subst_dict(E, Dict) || E <- Elements]);
  +t_subst_dict(?tuple_set(_) = TS, Dict) ->
  +  t_sup([t_subst_dict(T, Dict) || T <- t_tuple_subtypes(TS)]);
  +t_subst_dict(T, _Dict) ->
  +  T.
  +
  +-spec subst_all_vars_to_any(erl_type()) -> erl_type().
  +
  +subst_all_vars_to_any(T) ->
  +  t_subst_kv(T, []).
  +
  +t_subst_kv(T, KVMap) ->
  +  case t_has_var(T) of
  +    true -> t_subst_aux(T, KVMap);
  +    false -> T
  +  end.
  +
  +t_subst_aux(?var(Id), VarMap) ->
  +  case lists:keyfind(Id, 1, VarMap) of
  +    false -> ?any;
  +    {Id, Type} -> Type
  +  end;
  +t_subst_aux(?list(Contents, Termination, Size), VarMap) ->
  +  case t_subst_aux(Contents, VarMap) of
  +    ?none -> ?none;
  +    NewContents ->
  +      %% Be careful here to make the termination collapse if necessary.
  +      case t_subst_aux(Termination, VarMap) of
  +	?nil -> ?list(NewContents, ?nil, Size);
  +	?any -> ?list(NewContents, ?any, Size);
  +	Other ->
  +	  ?list(NewContents, NewTermination, _) = t_cons(NewContents, Other),
  +	  ?list(NewContents, NewTermination, Size)
  +      end
  +  end;
  +t_subst_aux(?function(Domain, Range), VarMap) ->
  +  ?function(t_subst_aux(Domain, VarMap), t_subst_aux(Range, VarMap));
  +t_subst_aux(?product(Types), VarMap) ->
  +  ?product([t_subst_aux(T, VarMap) || T <- Types]);
  +t_subst_aux(?tuple(?any, ?any, ?any) = T, _VarMap) ->
  +  T;
  +t_subst_aux(?tuple(Elements, _Arity, _Tag), VarMap) ->
  +  t_tuple([t_subst_aux(E, VarMap) || E <- Elements]);
  +t_subst_aux(?tuple_set(_) = TS, VarMap) ->
  +  t_sup([t_subst_aux(T, VarMap) || T <- t_tuple_subtypes(TS)]);
  +t_subst_aux(T, _VarMap) ->
     T.
   	      
   %%-----------------------------------------------------------------------------
  
positive.code: %%-----------------------------------------------------------------------------
  %% Substitution of variables
  %%
  
  -spec t_subst(erl_type(), dict()) -> erl_type().
  
  t_subst(T, Dict) ->
    case t_has_var(T) of
      true -> t_subst_aux(T, Dict);
      false -> T
    end.
  
  -spec subst_all_vars_to_any(erl_type()) -> erl_type().
  
  subst_all_vars_to_any(T) ->
    t_subst(T, dict:new()).
  
  t_subst_aux(?var(Id), Dict) ->
    case dict:find(Id, Dict) of
      error -> ?any;
      {ok, Type} -> Type
    end;
  t_subst_aux(?list(Contents, Termination, Size), Dict) ->
    case t_subst_aux(Contents, Dict) of
      ?none -> ?none;
      NewContents ->
        %% Be careful here to make the termination collapse if necessary.
        case t_subst_aux(Termination, Dict) of
  	?nil -> ?list(NewContents, ?nil, Size);
  	?any -> ?list(NewContents, ?any, Size);
  	Other ->
  
negative.code:   end.
  
  unify_tuple_set_and_tuple(?tuple_set([{Arity, List}]), 
  			  ?tuple(Elements2, Arity, _), VarMap, Opaques) ->
    %% Can only work if the single tuple has variables at correct places.
    %% Collapse the tuple set.
    {NewElements, VarMap1} = unify_lists(sup_tuple_elements(List), Elements2, VarMap, Opaques),
    {t_tuple(NewElements), VarMap1}.
  
  unify_lists(L1, L2, VarMap, Opaques) ->
    unify_lists(L1, L2, VarMap, [], Opaques).
  
  unify_lists([T1|Left1], [T2|Left2], VarMap, Acc, Opaques) ->
    {NewT, NewVarMap} = t_unify(T1, T2, VarMap, Opaques),
    unify_lists(Left1, Left2, NewVarMap, [NewT|Acc], Opaques);
  unify_lists([], [], VarMap, Acc, _Opaques) ->
    {lists:reverse(Acc), VarMap}.
  
  %%t_assign_variables_to_subtype(T1, T2) ->
  %%  try 
  