/**
  * INTERNAL: Visit a generic type parameter (either to a field or method) e.g Collection<X>,
  * the type parameter being X.
  */
 @Override
 public MetadataClass visitTypeParameter(
     TypeParameterElement typeParameterElement, MetadataClass metadataClass) {
   metadataClass.setName(typeParameterElement.getSimpleName().toString());
   metadataClass.setType(TypeVisitor.GENERIC_TYPE);
   return metadataClass;
 }
  /** INTERNAL: */
  @Override
  public MetadataClass visitType(TypeElement typeElement, MetadataClass metadataClass) {
    // processingEnv.getMessager().printMessage(Kind.NOTE, "Visiting class: " + typeElement);
    MetadataMirrorFactory factory = ((MetadataMirrorFactory) metadataClass.getMetadataFactory());

    // Set the qualified name.
    metadataClass.setName(typeElement.getQualifiedName().toString());

    // By default, set the type to be the same as the name, which in most
    // cases is correct. For non JDK elements we'll visit the typeElement
    // further (see below). This will further process any generic types,
    // e.g. Employee<Integer>. For the most part I don't think we need to
    // care, certainly not with JDK classes but for round elements we'll
    // set them anyway.
    metadataClass.setType(metadataClass.getName());

    // Add the interfaces.
    for (TypeMirror interfaceCls : typeElement.getInterfaces()) {
      metadataClass.addInterface(factory.getMetadataClass(interfaceCls).getName());
    }

    // Set the superclass name (if there is one)
    TypeMirror superclass = typeElement.getSuperclass();
    if (superclass != null) {
      metadataClass.setSuperclassName(factory.getMetadataClass(superclass).getName());
    }

    // As a performance gain, limit what is visited by JDK elements.
    if (!metadataClass.isJDK()) {
      // Set the modifiers.
      metadataClass.setModifiers(getModifiers(typeElement.getModifiers()));

      // Visit the type element for type and generic type.
      typeElement.asType().accept(typeVisitor, metadataClass);

      // Visit the enclosed elements.
      for (Element enclosedElement : typeElement.getEnclosedElements()) {
        if (enclosedElement.getKind().isClass()) {
          metadataClass.addEnclosedClass(factory.getMetadataClass(enclosedElement));
        } else {
          enclosedElement.accept(this, metadataClass);
        }
      }

      // Visit the annotations only if it is a round element.
      buildMetadataAnnotations(metadataClass, typeElement.getAnnotationMirrors());
    }

    return metadataClass;
  }