private void generateView(
      Map<String, DesignDocument.View> views, Method me, Class<?> handledType) {
    String name = me.getName();
    if (!name.startsWith("findBy") && !name.equals("getAll")) {
      throw new ViewGenerationException(
          String.format(
              "The method: %s in %s annotated with GenerateView does not conform to the naming convention of 'findByXxxx'",
              name, me.getDeclaringClass()));
    }

    Class<?> type = resolveReturnType(me);
    if (type == null) {
      if (handledType != null) {
        type = handledType;
      } else {
        throw new ViewGenerationException(
            "Could not resolve return type for method: %s in %s",
            me.getName(), me.getDeclaringClass());
      }
    }

    String typeDiscriminator = resolveTypeDiscriminator(type);

    if (name.equals("getAll")) {
      if (typeDiscriminator.length() < 1) {
        throw new ViewGenerationException(
            String.format(
                "Cannot generate 'all' view for %s. No type discriminator could be resolved. Try annotate unique field(s) with @TypeDiscriminator",
                type.getDeclaringClass()));
      }
      views.put("all", generateAllView(typeDiscriminator));
      return;
    }

    String finderName = name.substring(6);
    String fieldName = resolveFieldName(me, finderName);
    Method getter = findMethod(type, "get" + fieldName);
    if (getter == null) {
      // try pluralis
      fieldName += "s";
      getter = findMethod(type, "get" + fieldName);
    }
    if (getter == null) {
      throw new ViewGenerationException(
          "Could not generate view for method %s. No get method found for property %s in %s",
          name, name.substring(6), type);
    }

    fieldName = firstCharToLowerCase(fieldName);

    DesignDocument.View view;
    if (isIterable(getter.getReturnType())) {
      view = generateFindByIterableView(fieldName, typeDiscriminator);
    } else {
      view = generateFindByView(fieldName, typeDiscriminator);
    }

    views.put("by_" + firstCharToLowerCase(finderName), view);
  }
  protected void generateView(
      Map<String, org.ektorp.support.DesignDocument.View> views, Method me) {
    DocumentReferences referenceMetaData = me.getAnnotation(DocumentReferences.class);
    if (referenceMetaData == null) {
      LOG.warn("No DocumentReferences annotation found in method: ", me.getName());
      return;
    }
    if (!me.getName().startsWith("get")) {
      throw new ViewGenerationException(
          String.format(
              "The method: %s in %s annotated with DocumentReferences does not conform to the naming convention of 'getXxxx'",
              me.getName(), me.getDeclaringClass()));
    }

    if (Set.class.isAssignableFrom(me.getReturnType())) {
      generateSetBasedDocRefView(views, me, referenceMetaData);
    } else {
      throw new ViewGenerationException(
          String.format(
              "The return type of: %s in %s annotated with DocumentReferences is not supported. (Must be assignable from java.util.Set)",
              me.getName(), me.getDeclaringClass()));
    }
  }