docs: @SuppressWarnings("unchecked")
    public <T> T api(Class<T> serviceInterface) {
  
      final ServiceCall serviceCall = this;
      final Map<Method, MethodInfo> genericReturnTypes = Reflect.methodsInfo(serviceInterface);
  
      // noinspection unchecked
      return (T)
          Proxy.newProxyInstance(
              getClass().getClassLoader(),
              new Class[] {serviceInterface},
              (proxy, method, params) -> {
                final MethodInfo methodInfo = genericReturnTypes.get(method);
                final Class<?> returnType = methodInfo.parameterizedReturnType();
                final boolean isServiceMessage = methodInfo.isRequestTypeServiceMessage();
  
                Optional<Object> check =
                    toStringOrEqualsOrHashCode(method.getName(), serviceInterface, params);
                if (check.isPresent()) {
                  return check.get(); // toString, hashCode was invoked.
                }
  
                switch (methodInfo.communicationMode()) {
                  case FIRE_AND_FORGET:
                    return serviceCall.oneWay(toServiceMessage(methodInfo, params));
  
                  case REQUEST_RESPONSE:
                    return serviceCall
                        .requestOne(toServiceMessage(methodInfo, params), returnType)
                        .transform(asMono(isServiceMessage));
  
                  case REQUEST_STREAM:
                    return serviceCall
                        .requestMany(toServiceMessage(methodInfo, params), returnType)
                        .transform(asFlux(isServiceMessage));
  
                  case REQUEST_CHANNEL:
                    // this is REQUEST_CHANNEL so it means params[0] must be a publisher - its safe to
                    // cast.
                    return serviceCall
                        .requestBidirectional(
                            Flux.from((Publisher) params[0])
                                .map(data -> toServiceMessage(methodInfo, data)),
                            returnType)
                        .transform(asFlux(isServiceMessage));
  
                  default:
                    throw new IllegalArgumentException(
                        "Communication mode is not supported: " + method);
                }
              });
    }