qbit/core/src/main/java/io/advantageous/qbit/boon/client/BoonClient.java
private <T> Callback createHandler(final Class<T> serviceInterface, final MethodCall call,
                                       final Callback handler) {

        final ClassMeta<T> clsMeta = ClassMeta.classMeta(serviceInterface);
        final MethodAccess method = clsMeta.method(call.name());

        Class<?> returnType = null;
        Class<?> compType = null;

        if (Promise.class.isAssignableFrom(method.returnType()) ) {

            Type t0 = method.method().getGenericReturnType();
            if (t0 instanceof ParameterizedType) {
                ParameterizedType parameterizedType = ((ParameterizedType) t0);
                Type type = ((parameterizedType != null ? parameterizedType.getActualTypeArguments().length : 0) > 0 ? (parameterizedType != null ? parameterizedType.getActualTypeArguments() : new Type[0])[0] : null);

                if (type instanceof ParameterizedType) {
                    returnType = (Class) ((ParameterizedType) type).getRawType();
                    final Type type1 = ((ParameterizedType) type).getActualTypeArguments()[0];

                    if (type1 instanceof Class) {
                        compType = (Class) type1;
                    }
                } else if (type instanceof Class) {
                    returnType = (Class<?>) type;
                }

            }
        } else {
            if (method.parameterTypes().length > 0) {
                Type[] genericParameterTypes = method.getGenericParameterTypes();
                ParameterizedType parameterizedType = genericParameterTypes.length > 0 ? (ParameterizedType) genericParameterTypes[0] : null;

                Type type = ((parameterizedType != null ? parameterizedType.getActualTypeArguments().length : 0) > 0 ? (parameterizedType != null ? parameterizedType.getActualTypeArguments() : new Type[0])[0] : null);

                if (type instanceof ParameterizedType) {
                    returnType = (Class) ((ParameterizedType) type).getRawType();
                    final Type type1 = ((ParameterizedType) type).getActualTypeArguments()[0];

                    if (type1 instanceof Class) {
                        compType = (Class) type1;
                    }
                } else if (type instanceof Class) {
                    returnType = (Class<?>) type;
                }

            }
        }
        final Class<?> actualReturnType = returnType;

        final Class<?> componentClass = compType;

        /** Create the return handler. */
        return new Callback<Object>() {
            @Override
            public void accept(Object event) {

                if (actualReturnType != null) {

                    if (componentClass != null && actualReturnType == List.class) {

                        try {
                            //noinspection unchecked
                            event = MapObjectConversion.convertListOfMapsToObjects(componentClass, (List) event);
                        } catch (Exception ex) {
                            if (event instanceof CharSequence) {
                                String errorMessage = event.toString();
                                if (errorMessage.startsWith("java.lang.IllegalState")) {
                                    handler.onError(new IllegalStateException(errorMessage));
                                    return;
                                } else {
                                    handler.onError(new IllegalStateException("Conversion error"));
                                    return;
                                }
                            } else {
                                handler.onError(new IllegalStateException("Conversion error"));
                                return;
                            }
                        }
                    } else {

                        switch (actualReturnType.getName()) {
                            case "java.lang.Boolean":
                                if (event instanceof Value) {
                                    event = ((Value) event).booleanValue();
                                } else {
                                    event = Conversions.coerce(actualReturnType, event);
                                }
                                break;
                            default:
                                event = Conversions.coerce(actualReturnType, event);
                        }
                    }
                    //noinspection unchecked
                    handler.accept(event);
                }


            }

            @Override
            public void onError(Throwable error) {
                handler.onError(error);
            }

            @Override
            public void onTimeout() {
                handler.onTimeout();
            }
        };


    }
private <T> Callback createHandler(final Class<T> serviceInterface, final MethodCall call,
                                       final Callback handler) {

        final ClassMeta<T> clsMeta = ClassMeta.classMeta(serviceInterface);
        final MethodAccess method = clsMeta.method(call.name());

        Class<?> returnType = null;
        Class<?> compType = null;

        if (Promise.class.isAssignableFrom(method.returnType()) ) {

            Type t0 = method.method().getGenericReturnType();
            if (t0 instanceof ParameterizedType) {
                ParameterizedType parameterizedType = ((ParameterizedType) t0);
                Type type = ((parameterizedType != null ? parameterizedType.getActualTypeArguments().length : 0) > 0 ? (parameterizedType != null ? parameterizedType.getActualTypeArguments() : new Type[0])[0] : null);

                if (type instanceof ParameterizedType) {
                    returnType = (Class) ((ParameterizedType) type).getRawType();
                    final Type type1 = ((ParameterizedType) type).getActualTypeArguments()[0];

                    if (type1 instanceof Class) {
                        compType = (Class) type1;
                    }
                } else if (type instanceof Class) {
                    returnType = (Class<?>) type;
                }

            }
        } else {
            if (method.parameterTypes().length > 0) {
                Type[] genericParameterTypes = method.getGenericParameterTypes();
                ParameterizedType parameterizedType = genericParameterTypes.length > 0 ? (ParameterizedType) genericParameterTypes[0] : null;

                Type type = ((parameterizedType != null ? parameterizedType.getActualTypeArguments().length : 0) > 0 ? (parameterizedType != null ? parameterizedType.getActualTypeArguments() : new Type[0])[0] : null);

                if (type instanceof ParameterizedType) {
                    returnType = (Class) ((ParameterizedType) type).getRawType();
                    final Type type1 = ((ParameterizedType) type).getActualTypeArguments()[0];

                    if (type1 instanceof Class) {
                        compType = (Class) type1;
                    }
                } else if (type instanceof Class) {
                    returnType = (Class<?>) type;
                }

            }
        }
        final Class<?> actualReturnType = returnType;

        final Class<?> componentClass = compType;

        /** Create the return handler. */
        return new Callback<Object>() {
            @Override
            public void accept(Object event) {

                if (actualReturnType != null) {

                    if (componentClass != null && actualReturnType == List.class) {

                        try {
                            //noinspection unchecked
                            event = MapObjectConversion.convertListOfMapsToObjects(componentClass, (List) event);
                        } catch (Exception ex) {
                            if (event instanceof CharSequence) {
                                String errorMessage = event.toString();
                                if (errorMessage.startsWith("java.lang.IllegalState")) {
                                    handler.onError(new IllegalStateException(errorMessage));
                                    return;
                                } else {
                                    handler.onError(new IllegalStateException("Conversion error"));
                                    return;
                                }
                            } else {
                                handler.onError(new IllegalStateException("Conversion error"));
                                return;
                            }
                        }
                    } else {

                        switch (actualReturnType.getName()) {
                            case "java.lang.Boolean":
                                if (event instanceof Value) {
                                    event = ((Value) event).booleanValue();
                                } else {
                                    event = Conversions.coerce(actualReturnType, event);
                                }
                                break;
                            default:
                                event = Conversions.coerce(actualReturnType, event);
                        }
                    }
                    //noinspection unchecked
                    handler.accept(event);
                }


            }

            @Override
            public void onError(Throwable error) {
                handler.onError(error);
            }

            @Override
            public void onTimeout() {
                handler.onTimeout();
            }
        };


    }
Create an async handler. Uses some generics reflection to see what the actual type is

@param serviceInterface client interface
@param call             method call object
@param handler          handler that will handle the message
@param <T>              the class of hte client interface
@return the new handler