private void processNestedType(
     String prefix,
     TypeElement element,
     ExecutableElement source,
     String name,
     ExecutableElement getter,
     VariableElement field,
     TypeMirror returnType) {
   Element returnElement = this.processingEnv.getTypeUtils().asElement(returnType);
   boolean isNested = isNested(returnElement, field, element);
   AnnotationMirror annotation = getAnnotation(getter, configurationPropertiesAnnotation());
   if (returnElement != null
       && returnElement instanceof TypeElement
       && annotation == null
       && isNested) {
     String nestedPrefix = ConfigurationMetadata.nestedPrefix(prefix, name);
     this.metadataCollector.add(
         ItemMetadata.newGroup(
             nestedPrefix,
             this.typeUtils.getType(returnElement),
             this.typeUtils.getType(element),
             (getter == null ? null : getter.toString())));
     processTypeElement(nestedPrefix, (TypeElement) returnElement, source);
   }
 }
 private void processExecutableElement(String prefix, ExecutableElement element) {
   if (element.getModifiers().contains(Modifier.PUBLIC)
       && (TypeKind.VOID != element.getReturnType().getKind())) {
     Element returns = this.processingEnv.getTypeUtils().asElement(element.getReturnType());
     if (returns instanceof TypeElement) {
       ItemMetadata group =
           ItemMetadata.newGroup(
               prefix,
               this.typeUtils.getType(returns),
               this.typeUtils.getType(element.getEnclosingElement()),
               element.toString());
       if (this.metadataCollector.hasSimilarGroup(group)) {
         this.processingEnv
             .getMessager()
             .printMessage(
                 Kind.ERROR,
                 "Duplicate `@ConfigurationProperties` definition for prefix '" + prefix + "'",
                 element);
       } else {
         this.metadataCollector.add(group);
         processTypeElement(prefix, (TypeElement) returns, element);
       }
     }
   }
 }
 private void processSimpleTypes(
     String prefix,
     TypeElement element,
     ExecutableElement source,
     TypeElementMembers members,
     Map<String, Object> fieldValues) {
   for (Map.Entry<String, ExecutableElement> entry : members.getPublicGetters().entrySet()) {
     String name = entry.getKey();
     ExecutableElement getter = entry.getValue();
     TypeMirror returnType = getter.getReturnType();
     ExecutableElement setter = members.getPublicSetter(name, returnType);
     VariableElement field = members.getFields().get(name);
     Element returnTypeElement = this.processingEnv.getTypeUtils().asElement(returnType);
     boolean isExcluded = this.typeExcludeFilter.isExcluded(returnType);
     boolean isNested = isNested(returnTypeElement, field, element);
     boolean isCollection = this.typeUtils.isCollectionOrMap(returnType);
     if (!isExcluded && !isNested && (setter != null || isCollection)) {
       String dataType = this.typeUtils.getType(returnType);
       String sourceType = this.typeUtils.getType(element);
       String description = this.typeUtils.getJavaDoc(field);
       Object defaultValue = fieldValues.get(name);
       boolean deprecated = isDeprecated(getter) || isDeprecated(setter) || isDeprecated(source);
       this.metadataCollector.add(
           ItemMetadata.newProperty(
               prefix,
               name,
               dataType,
               sourceType,
               null,
               description,
               defaultValue,
               (deprecated ? getItemDeprecation(getter) : null)));
     }
   }
 }
 private void processAnnotatedTypeElement(String prefix, TypeElement element) {
   String type = this.typeUtils.getType(element);
   this.metadataCollector.add(ItemMetadata.newGroup(prefix, type, type, null));
   processTypeElement(prefix, element, null);
 }