protected void printClass() {
   if (typeElement.getTypeParameters().isEmpty()) {
     iprint("/** */%n");
   } else {
     iprint("/**%n");
     for (TypeParameterElement typeParam : typeElement.getTypeParameters()) {
       iprint(" * @param <%1$s> %1$s%n", typeParam.getSimpleName());
     }
     iprint(" */%n");
   }
   printGenerated();
   iprint(
       "public final class %1$s implements %2$s<%3$s, %4$s> {%n",
       simpleMetaTypeName,
       DomainType.class.getName(),
       TypeMirrorUtil.boxIfPrimitive(domainMeta.getValueType(), env),
       typeName);
   print("%n");
   indent();
   printValidateVersionStaticInitializer();
   printFields();
   printConstructors();
   printMethods();
   unindent();
   unindent();
   iprint("}%n");
 }
 private List<Type> toTypeVariables(List<? extends TypeParameterElement> typeParameters) {
   List<Type> results = new ArrayList<>();
   for (TypeParameterElement typeParameter : typeParameters) {
     SimpleName name = factory.newSimpleName(typeParameter.getSimpleName().toString());
     results.add(factory.newNamedType(name));
   }
   return results;
 }
 private List<TypeParameterDeclaration> toTypeParameters(
     List<? extends TypeParameterElement> typeParameters) {
   assert typeParameters != null;
   List<TypeParameterDeclaration> results = new ArrayList<>();
   for (TypeParameterElement typeParameter : typeParameters) {
     SimpleName name = factory.newSimpleName(typeParameter.getSimpleName().toString());
     List<Type> typeBounds = new ArrayList<>();
     for (TypeMirror typeBound : typeParameter.getBounds()) {
       typeBounds.add(t(typeBound));
     }
     results.add(factory.newTypeParameterDeclaration(name, typeBounds));
   }
   return results;
 }
 /**
  * INTERNAL: Visit a generic type parameter (either to a field or method) e.g Collection&lt;X&gt;,
  * 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;
 }
    private void addFieldFromBeanMethod(JsonObject o, ExecutableElement executableElement) {
      if (!isJsonBeanGetter(executableElement)) {
        return;
      }

      TypeMirror type = executableElement.getReturnType();
      String methodName = executableElement.getSimpleName().toString();
      int trimLength = methodName.startsWith("is") ? 2 : 3;
      String beanName = methodName.substring(trimLength + 1, methodName.length());
      beanName = methodName.substring(trimLength, trimLength + 1).toLowerCase() + beanName;

      // loop over the element's generic types, and build a concrete list from the owning context
      List<DeclaredType> concreteTypes = new ArrayList();

      // replace variables with the current concrete manifestation
      if (type instanceof TypeVariable) {
        type = getDeclaredTypeForTypeVariable((TypeVariable) type);
        if (type == null) {
          return; // couldn't find a replacement -- must be a generics-capable type with no generics
                  // info
        }
      }

      String docComment = processingEnv.getElementUtils().getDocComment(executableElement);
      if (type instanceof DeclaredType) {
        TypeElement element = (TypeElement) ((DeclaredType) type).asElement();
        for (TypeParameterElement generic : element.getTypeParameters()) {
          concreteTypes.add(_typeArguments.get(generic.getSimpleName()));
        }
        Collection<DeclaredType> types = new HashSet<DeclaredType>(_typeRecursionGuard);
        types.add(_type);
        o.addField(beanName, newJsonType((DeclaredType) type, concreteTypes, types))
            .setCommentText(docComment);
      } else {
        o.addField(beanName, newJsonType(type)).setCommentText(docComment);
      }
    }
 /**
  * {@inheritDoc} This implementation scans the enclosed elements.
  *
  * @param e {@inheritDoc}
  * @param p {@inheritDoc}
  * @return the result of scanning
  */
 public R visitTypeParameter(TypeParameterElement e, P p) {
   return scan(e.getEnclosedElements(), p);
 }