public void test_isMoreSpecificThan_typeArguments_upperBound() {
    ClassElementImpl classS = classElement("A");

    TypeParameterElementImpl typeParameterT = new TypeParameterElementImpl(identifier("T"));
    typeParameterT.setBound(classS.getType());
    TypeParameterTypeImpl typeParameterTypeT = new TypeParameterTypeImpl(typeParameterT);

    // <T extends S>
    // T << S
    assertTrue(typeParameterTypeT.isMoreSpecificThan(classS.getType()));
  }
 /**
  * Create the types associated with the given type parameters, setting the type of each type
  * parameter, and return an array of types corresponding to the given parameters.
  *
  * @param typeParameters the type parameters for which types are to be created
  * @return an array of types corresponding to the given parameters
  */
 private Type[] createTypeParameterTypes(TypeParameterElement[] typeParameters) {
   int typeParameterCount = typeParameters.length;
   Type[] typeArguments = new Type[typeParameterCount];
   for (int i = 0; i < typeParameterCount; i++) {
     TypeParameterElementImpl typeParameter = (TypeParameterElementImpl) typeParameters[i];
     TypeParameterTypeImpl typeParameterType = new TypeParameterTypeImpl(typeParameter);
     typeParameter.setType(typeParameterType);
     typeArguments[i] = typeParameterType;
   }
   return typeArguments;
 }
  @Override
  public Void visitTypeParameter(TypeParameter node) {
    SimpleIdentifier parameterName = node.getName();
    TypeParameterElementImpl typeParameter = new TypeParameterElementImpl(parameterName);

    TypeParameterTypeImpl typeParameterType = new TypeParameterTypeImpl(typeParameter);
    typeParameter.setType(typeParameterType);

    currentHolder.addTypeParameter(typeParameter);
    parameterName.setStaticElement(typeParameter);
    return super.visitTypeParameter(node);
  }
  public void test_isMoreSpecificThan_typeArguments_transitivity_typeParameters() {
    ClassElementImpl classS = classElement("A");

    TypeParameterElementImpl typeParameterU = new TypeParameterElementImpl(identifier("U"));
    typeParameterU.setBound(classS.getType());
    TypeParameterTypeImpl typeParameterTypeU = new TypeParameterTypeImpl(typeParameterU);

    TypeParameterElementImpl typeParameterT = new TypeParameterElementImpl(identifier("T"));
    typeParameterT.setBound(typeParameterTypeU);
    TypeParameterTypeImpl typeParameterTypeT = new TypeParameterTypeImpl(typeParameterT);

    // <T extends U> and <U extends S>
    // T << S
    assertTrue(typeParameterTypeT.isMoreSpecificThan(classS.getType()));
  }
  public void test_isMoreSpecificThan_typeArguments_transitivity_interfaceTypes() {
    //  class A {}
    //  class B extends A {}
    //
    ClassElement classA = classElement("A");
    ClassElement classB = classElement("B", classA.getType());
    InterfaceType typeA = classA.getType();
    InterfaceType typeB = classB.getType();

    TypeParameterElementImpl typeParameterT = new TypeParameterElementImpl(identifier("T"));
    typeParameterT.setBound(typeB);
    TypeParameterTypeImpl typeParameterTypeT = new TypeParameterTypeImpl(typeParameterT);

    // <T extends B>
    // T << A
    assertTrue(typeParameterTypeT.isMoreSpecificThan(typeA));
  }