@Override
  public String name(Path path) {
    List<String> names = new ArrayList<>();
    Type enclosingType = (Class<?>) path.root().element();
    for (Member member : path.members()) {
      JavaType javaType = mapper.getTypeFactory().constructType(enclosingType);
      if (javaType.isCollectionLikeType() || javaType.isTypeOrSubTypeOf(Optional.class)) {
        // Get element type (T) from Optional<T> or List<T>
        javaType = javaType.getBindings().getTypeParameters().get(0);
      }

      BeanDescription description = mapper.getSerializationConfig().introspect(javaType);
      if (description.findProperties().isEmpty()) {
        description = findImmutableClassDefinition(javaType);
      }
      Optional<BeanPropertyDefinition> def = Stream.of(description)
              .flatMap(x -> x.findProperties().stream())
              .filter(x -> x.getPrimaryMember() != null && member.equals(x.getPrimaryMember().getMember()))
              .findAny();

      String name = def.map(BeanPropertyDefinition::getName).orElse(member.getName());
      names.add(name);
      if (member instanceof Field) {
        enclosingType = ((Field) member).getGenericType();
      } else if (member instanceof Method) {
        enclosingType = ((Method) member).getGenericReturnType();
      } else {
        enclosingType = member.getDeclaringClass();
      }
    }

    return String.join(".", names);
  }
Leverages Jackson Introspection API (like {@link com.fasterxml.jackson.databind.SerializationConfig}) to
derive correct names for each path element be it field or method.

<p>This feature is experimental. The location of this class might change in future.</p>
criteria/mongo/src/org/immutables/criteria/mongo/bson4jackson/JacksonPathNaming.java