Make all subtype constraints atomic by generating new
type variables for all argument/return types of function-types
along with the corresponding subtype constraints.

@return
428619
private ConstraintSet makeAtomic() {
    boolean done = false;
    List<Constraint> current = subConstraints;
    List<Constraint> next = Lists.newArrayList();
    TypeReplacement nextBindings = new TypeReplacement(bindings);
    boolean solvable = this.solvable;
    while (!done) {
      done = true;
      for (Constraint c : current) {
        Constraint substituted = c.substitute(nextBindings.getBindings());
        Type subtype = substituted.subtype;
        Type supertype = substituted.supertype;
        
        if (subtype.isFunctional() && supertype.isFunctional()) {
          next.add(new Constraint(supertype.getArgumentType(), subtype.getArgumentType()));
          next.add(new Constraint(subtype.getReturnType(), supertype.getReturnType()));
          done = false;
        } else if (!subtype.isFunctional() && supertype.isFunctional()) {
          if (subtype.hasTypeVariables()) {
            Type subtypeReplacement = upcast(supertype, next, false);
            nextBindings.add(subtype.getAtomicTypeVar(), subtypeReplacement);
            done = false;
          } else {
            solvable = false;
          }
        } else if (subtype.isFunctional() && !supertype.isFunctional()) {
          if (supertype.hasTypeVariables()) {
            Type supertypeReplacement = upcast(subtype, next, true);
            nextBindings.add(supertype.getAtomicTypeVar(), supertypeReplacement);
            done = false;
          } else {
            solvable = false;
          }
        } else {
          next.add(substituted);
        }
      }

      current = next;
      next = Lists.newArrayList();
    }

    return new ConstraintSet(Lists.newArrayList(), current, nextBindings,
        solvable, typeVarCounter);
  }
140425
public List<UniqueConstraint<CollectionTable<T>>> getAllUniqueConstraint()
   {
      List<UniqueConstraint<CollectionTable<T>>> list = new ArrayList<UniqueConstraint<CollectionTable<T>>>();
      List<Node> nodeList = childNode.get("unique-constraint");
      for(Node node: nodeList)
      {
         UniqueConstraint<CollectionTable<T>>  type = new UniqueConstraintImpl<CollectionTable<T>>(this, "unique-constraint", childNode, node);
         list.add(type);
      }
      return list;
   }
898210
public Datatype.Builder clearGeneratedBuilderAnnotations() {
    if (generatedBuilderAnnotations instanceof ImmutableList) {
      generatedBuilderAnnotations = ImmutableList.of();
    } else {
      generatedBuilderAnnotations.clear();
    }
    return (Datatype.Builder) this;
  }
598073
private ConstraintSet solveEquality() {
    List<Constraint> current = eqConstraints;
    List<Constraint> next = Lists.newArrayList();
    boolean done = false;
    boolean solvable = this.solvable;

    TypeReplacement nextBindings = new TypeReplacement(bindings);
    while (!done) {
      done = true;
      // Iterative constraint solving algorithm with four cases
      for (Constraint c : current) {
        Type subtype = c.subtype.substitute(nextBindings.getBindings());
        Type supertype = c.supertype.substitute(nextBindings.getBindings());
        
        if (subtype.isFunctional() && supertype.isFunctional()) {
          // Case 1: <a,b> = <c,d> => a = c && b = d
          
          // Replace this constraint with the entailed subtype
          // constraints on argument/return types.
          next.add(new Constraint(supertype.getArgumentType(), subtype.getArgumentType()));
          next.add(new Constraint(subtype.getReturnType(), supertype.getReturnType()));
          done = false;
        } else if (!subtype.isFunctional() && supertype.isFunctional()) {
          // Case 2: A = <c,d> => A = <c,d> (if A is a type var, else fail)
          if (subtype.hasTypeVariables()) {
            nextBindings.add(subtype.getAtomicTypeVar(), supertype);
            done = false;
          } else {
            solvable = false;
          }
        } else if (subtype.isFunctional() && !supertype.isFunctional()) {
          // Case 3: <c,d> = A => A = <c,d> (if A is a type var, else fail)
          if (supertype.hasTypeVariables()) {
            nextBindings.add(supertype.getAtomicTypeVar(), subtype);
            done = false;
          } else {
            solvable = false;
          }
        } else {
          // Case 4: A = B => A = B
          if (subtype.hasTypeVariables() && supertype.hasTypeVariables()) {
            if (subtype.getAtomicTypeVar() != supertype.getAtomicTypeVar()) {
              nextBindings.add(subtype.getAtomicTypeVar(), supertype);
            }
          } else if (subtype.hasTypeVariables()) {
            nextBindings.add(subtype.getAtomicTypeVar(), supertype);
            done = false;
          } else if (supertype.hasTypeVariables()) {
            nextBindings.add(supertype.getAtomicTypeVar(), subtype);
            done = false;
          } else {
            if (!subtype.equals(supertype)) {
              solvable = false;
            }
          }
        }
      }

      current = next;
      next = Lists.newArrayList();
    }
    
    List<Constraint> newSubConstraints = Lists.newArrayList();
    for (Constraint c : subConstraints) {
      newSubConstraints.add(c.substitute(nextBindings.getBindings()));
    }
    return new ConstraintSet(Lists.newArrayList(), newSubConstraints, nextBindings,
        solvable, typeVarCounter);
  }
1310339
def reconcile(constraint):
    '''
    
    '''
    
    if isinstance(constraint.subtype, NamedType):
        if isinstance(constraint.supertype, NamedType):
            if constraint.subtype.name == constraint.supertype.name:
                return {}
            else:
                return Refutation('Cannot reconcile different atomic types: %s' % constraint)
        elif isinstance(constraint.supertype, Variable):
            return {constraint.supertype.name: constraint.subtype}
        else:
            return Refutation('Cannot reconcile atomic type with non-atomic type: %s' % constraint)

    elif isinstance(constraint.supertype, NamedType):
        if isinstance(constraint.subtype, NamedType):
            if constraint.subtype.name == constraint.supertype.name:
                return {}
            else:
                return Refutation('Cannot reconcile different atomic types: %s' % constraint)
        elif isinstance(constraint.subtype, Variable):
            return {constraint.subtype.name: constraint.supertype}
        else:
            return Refutation('Cannot reconcile non-atomic type with atomic type: %s' % constraint)

    elif isinstance(constraint.supertype, Union):
        # Lots of stuff could happen here; unsure if there's research to bring to bear
        if constraint.subtype in constraint.supertype.types:
            return {}

    return Stumper(constraint)
607561
@Override
    public ImmutableSubstitution<ImmutableTerm> composeWith(ImmutableSubstitution<? extends ImmutableTerm> f) {
        if (isEmpty()) {
            return (ImmutableSubstitution<ImmutableTerm>)f;
        }
        if (f.isEmpty()) {
            return (ImmutableSubstitution<ImmutableTerm>)this;
        }

        Map<Variable, ImmutableTerm> substitutionMap = new HashMap<>();

        /**
         * For all variables in the domain of f
         */

        for (Map.Entry<Variable, ? extends ImmutableTerm> gEntry :  f.getImmutableMap().entrySet()) {
            substitutionMap.put(gEntry.getKey(), apply(gEntry.getValue()));
        }

        /**
         * For the other variables (in the local domain but not in f)
         */
        for (Map.Entry<Variable, ? extends ImmutableTerm> localEntry :  getImmutableMap().entrySet()) {
            Variable localVariable = localEntry.getKey();

            if (substitutionMap.containsKey(localVariable))
                continue;

            substitutionMap.put(localVariable, localEntry.getValue());
        }

        return substitutionFactory.getSubstitution(
                substitutionMap.entrySet().stream()
                        // Clean out entries like t/t
                        .filter(entry -> !entry.getKey().equals(entry.getValue()))
                        .collect(ImmutableCollectors.toMap()));
    }
480051
public JSType build() {
    if (result == null) {
      result = reduceAlternatesWithoutUnion();
      if (result == null) {
        result = new UnionType(registry, ImmutableList.copyOf(getAlternates()));
      }
    }
    return result;
  }
581798
private final Type getGenericType() {
        final Class<?> raw = getClass();
        final TypeVariable<?>[] typeParameters = raw.getTypeParameters();
        if (ArrayUtils.isEmpty(typeParameters)) {
            return raw;
        }
        final Type[] parameters = new Type[typeParameters.length];

        // use empty type variable map because we're relying on @BindTypeVariable functionality:
        final Map<TypeVariable<?>, Type> typeVariableMap = Collections.emptyMap();
        for (int i = 0; i < parameters.length; i++) {
            parameters[i] = Types.resolveAt(this, typeParameters[i], typeVariableMap);
        }
        return TypeUtils.parameterize(raw, parameters);
    }
1055810
public JvmTypeReference inferredType() {
		XComputedTypeReference result = xtypesFactory.createXComputedTypeReference();
		result.setTypeProvider(new InferredTypeIndicator(null));
		return result;
	}
140368
private ImmutableList<UTypeVar> freeTypeVars(Unifier unifier) {
    ImmutableList.Builder<UTypeVar> builder = ImmutableList.builder();
    for (UTypeVar var : typeVariables(unifier.getContext())) {
      if (unifier.getBinding(var.key()) == null) {
        builder.add(var);
      }
    }
    return builder.build();
  }
313982
public com.sun.javadoc.Type[] bounds() {
        return TypeMaker.getTypes(env, getBounds((TypeVar)type, env));
    }
221165
private Map<String, TypeVariableDefinition> getEnclosingTypeVars()
  {
    ICompilableType gsClass = getGosuClass();
    if( gsClass == null )
    {
      return Collections.emptyMap();
    }
    Map<String, TypeVariableDefinition> mapTypeVarDefByName = new HashMap<>( 2 );
    while( !gsClass.isStatic() && gsClass.getEnclosingType() != null )
    {
      // Note we don't resolve type vars defined in outer for static inner classes.
      // This is because we do not maintain separate inner classes for each
      // parameterization of a generic outer class

      ICompilableType enclosingType = gsClass.getEnclosingType();
      for( IGenericTypeVariable gtv : enclosingType.getGenericTypeVariables() )
      {
        Map<String, ITypeVariableDefinition> typeVarMap = getTypeVariables();
        if( !typeVarMap.containsKey( gtv.getTypeVariableDefinition().getName() ) )
        {
          getTypeVariables().put( gtv.getName(), gtv.getTypeVariableDefinition() );
        }
      }
      gsClass = enclosingType;
    }
    return mapTypeVarDefByName;
  }
795141
public List<ConstraintDefinitionType<ValidationMappingDescriptor>> getAllConstraintDefinition()
   {
      List<ConstraintDefinitionType<ValidationMappingDescriptor>> list = new ArrayList<ConstraintDefinitionType<ValidationMappingDescriptor>>();
      List<Node> nodeList = model.get("constraint-definition");
      for(Node node: nodeList)
      {
         ConstraintDefinitionType<ValidationMappingDescriptor>  type = new ConstraintDefinitionTypeImpl<ValidationMappingDescriptor>(this, "constraint-definition", model, node);
         list.add(type);
      }
      return list;
   }
630225
public TypeBindings withUnboundVariable(String name)
    {
        int len = (_unboundVariables == null) ? 0 : _unboundVariables.length;
        String[] names =  (len == 0)
                ? new String[1] : Arrays.copyOf(_unboundVariables, len+1);
        names[len] = name;
        return new TypeBindings(_names, _types, names);
    }
88093
@SuppressWarnings("unchecked")
    public Constraint getConstraint(String ... typeInfo) {
        if( typeInfo == null || typeInfo.length < 1 ) {
            return getConstraints().iterator().next();
        }
        else if( typeInfo.length == 1 ) {
            Constraint c = getConstraint(new String[0]);
            DataType<?> attr = c.getType();
            Boolean b;
            
            b = (Boolean)attr.getValue(typeInfo[0]);
            if( b == null || !b ) {
                return constraints.get(1);
            }
            else {
                return constraints.get(2);
            }
        }
        else {
            return super.getConstraint(typeInfo);
        }
    }
1267307
private static Set<TypeMirror> nonPrivateDeclaredTypes(Types typeUtils, TypeMirror type) {
    if (type == null) {
      return new TypeMirrorSet();
    } else {
      Set<TypeMirror> declared = new TypeMirrorSet();
      declared.add(type);
      List<TypeElement> nestedTypes =
          ElementFilter.typesIn(typeUtils.asElement(type).getEnclosedElements());
      for (TypeElement nestedType : nestedTypes) {
        if (!nestedType.getModifiers().contains(PRIVATE)) {
          declared.add(nestedType.asType());
        }
      }
      for (TypeMirror supertype : typeUtils.directSupertypes(type)) {
        declared.addAll(nonPrivateDeclaredTypes(typeUtils, supertype));
      }
      return declared;
    }
  }
777514
public static SymbolType typeVariableOf(final String typeVariable, List<SymbolType> upperBounds) {
        return new SymbolType(upperBounds, typeVariable);
    }