public Set<JavaType> getPersistentFieldTypes(
      final JavaType thisType, final PersistenceMemberLocator persistenceMemberLocator) {
    final MethodMetadata identifierAccessor =
        persistenceMemberLocator.getIdentifierAccessor(thisType);
    final MethodMetadata versionAccessor = persistenceMemberLocator.getVersionAccessor(thisType);

    final Set<JavaType> fieldTypes = new LinkedHashSet<JavaType>();
    for (final MethodMetadata method : getMethods()) {
      // Not interested in non-accessor methods or persistence identifiers
      // and version fields
      if (!BeanInfoUtils.isAccessorMethod(method)
          || method.hasSameName(identifierAccessor, versionAccessor)) {
        continue;
      }

      // Not interested in fields that are JPA transient fields or
      // immutable fields
      final FieldMetadata field = BeanInfoUtils.getFieldForJavaBeanMethod(this, method);
      if (field == null
          || field.getCustomData().keySet().contains(CustomDataKeys.TRANSIENT_FIELD)
          || !BeanInfoUtils.hasAccessorAndMutator(field, this)) {
        continue;
      }
      final JavaType returnType = method.getReturnType();
      if (returnType.isCommonCollectionType()) {
        for (final JavaType genericType : returnType.getParameters()) {
          fieldTypes.add(genericType);
        }
      } else {
        if (!field.getCustomData().keySet().contains(EMBEDDED_FIELD)) {
          fieldTypes.add(returnType);
        }
      }
    }
    return fieldTypes;
  }
  private MethodMetadataBuilder getFinderFormMethod(final FinderMetadataDetails finder) {
    Validate.notNull(finder, "Method metadata required for finder");
    final JavaSymbolName finderFormMethodName =
        new JavaSymbolName(
            finder.getFinderMethodMetadata().getMethodName().getSymbolName() + "Form");

    final List<JavaType> methodParameterTypes = new ArrayList<JavaType>();
    final List<JavaSymbolName> methodParameterNames = new ArrayList<JavaSymbolName>();
    final List<JavaType> finderParameterTypes =
        AnnotatedJavaType.convertFromAnnotatedJavaTypes(
            finder.getFinderMethodMetadata().getParameterTypes());

    final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();

    boolean needModel = false;
    for (final JavaType finderParameterType : finderParameterTypes) {
      JavaTypeMetadataDetails typeMd = specialDomainTypes.get(finderParameterType);
      JavaTypePersistenceMetadataDetails javaTypePersistenceMetadataHolder = null;
      if (finderParameterType.isCommonCollectionType()) {
        typeMd = specialDomainTypes.get(finderParameterType.getParameters().get(0));
        if (typeMd != null && typeMd.isApplicationType()) {
          javaTypePersistenceMetadataHolder = typeMd.getPersistenceDetails();
        }
      } else if (typeMd != null && typeMd.isEnumType()) {
        bodyBuilder.appendFormalLine(
            "uiModel.addAttribute(\""
                + typeMd.getPlural().toLowerCase()
                + "\", java.util.Arrays.asList("
                + getShortName(finderParameterType)
                + ".class.getEnumConstants()));");
      } else if (typeMd != null && typeMd.isApplicationType()) {
        javaTypePersistenceMetadataHolder = typeMd.getPersistenceDetails();
      }
      if (typeMd != null
          && javaTypePersistenceMetadataHolder != null
          && javaTypePersistenceMetadataHolder.getFindAllMethod() != null) {
        bodyBuilder.appendFormalLine(
            "uiModel.addAttribute(\""
                + typeMd.getPlural().toLowerCase()
                + "\", "
                + javaTypePersistenceMetadataHolder.getFindAllMethod().getMethodCall()
                + ");");
      }
      needModel = true;
    }
    if (finderParameterTypes.contains(DATE) || finderParameterTypes.contains(CALENDAR)) {
      bodyBuilder.appendFormalLine("addDateTimeFormatPatterns(uiModel);");
    }
    bodyBuilder.appendFormalLine(
        "return \""
            + controllerPath
            + "/"
            + finder.getFinderMethodMetadata().getMethodName().getSymbolName()
            + "\";");

    if (needModel) {
      methodParameterTypes.add(MODEL);
      methodParameterNames.add(new JavaSymbolName("uiModel"));
    }

    if (governorHasMethod(finderFormMethodName, methodParameterTypes)) {
      return null;
    }

    final List<AnnotationAttributeValue<?>> requestMappingAttributes =
        new ArrayList<AnnotationAttributeValue<?>>();
    final List<StringAttributeValue> arrayValues = new ArrayList<StringAttributeValue>();
    arrayValues.add(
        new StringAttributeValue(
            new JavaSymbolName("value"),
            "find="
                + finder
                    .getFinderMethodMetadata()
                    .getMethodName()
                    .getSymbolName()
                    .replaceFirst("find" + javaTypeMetadataHolder.getPlural(), "")));
    arrayValues.add(new StringAttributeValue(new JavaSymbolName("value"), "form"));
    requestMappingAttributes.add(
        new ArrayAttributeValue<StringAttributeValue>(new JavaSymbolName("params"), arrayValues));
    requestMappingAttributes.add(
        new EnumAttributeValue(
            new JavaSymbolName("method"),
            new EnumDetails(REQUEST_METHOD, new JavaSymbolName("GET"))));
    final AnnotationMetadataBuilder requestMapping =
        new AnnotationMetadataBuilder(REQUEST_MAPPING, requestMappingAttributes);
    final List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>();
    annotations.add(requestMapping);

    final MethodMetadataBuilder methodBuilder =
        new MethodMetadataBuilder(
            getId(),
            Modifier.PUBLIC,
            finderFormMethodName,
            JavaType.STRING,
            AnnotatedJavaType.convertFromJavaTypes(methodParameterTypes),
            methodParameterNames,
            bodyBuilder);
    methodBuilder.setAnnotations(annotations);
    return methodBuilder;
  }