public static <T> void verify(Target<T> target) {
      Class<T> type = target.type();
      if (!type.isInterface()) {
        throw new IllegalArgumentException("Type must be an interface: " + type);
      }

      for (final Method m : type.getMethods()) {
        final Class<?> retType = m.getReturnType();

        if (!CompletableFuture.class.isAssignableFrom(retType)) {
          continue; // synchronous case
        }

        if (retType != CompletableFuture.class) {
          throw new IllegalArgumentException(
              "Method return type is not CompleteableFuture: "
                  + getFullMethodName(type, retType, m));
        }

        final Type genRetType = m.getGenericReturnType();

        if (!(genRetType instanceof ParameterizedType)) {
          throw new IllegalArgumentException(
              "Method return type is not parameterized: " + getFullMethodName(type, genRetType, m));
        }

        if (((ParameterizedType) genRetType).getActualTypeArguments()[0] instanceof WildcardType) {
          throw new IllegalArgumentException(
              "Wildcards are not supported for return-type parameters: "
                  + getFullMethodName(type, genRetType, m));
        }
      }
    }
creates an api binding to the {@code target}. As this invokes reflection, care should be taken
to cache the result.
core/src/main/java/feign/ReflectiveFeign.java