// Path: qbit/core/src/main/java/io/advantageous/qbit/reactive/Callback.java
// public interface Callback<T> extends io.advantageous.reakt.CallbackHandler<T> {
// 
// 
//     /**
//      * Client View (client of the service)
//      * Called when there is an error
//      *
//      * @param error error
//      */
//     default void onError(final Throwable error) {
// 
//         LoggerFactory.getLogger(Callback.class)
//                 .error(error.getMessage(), error);
// 
//     }
// 
//     /**
//      * Performs this operation on the given argument.
//      *
//      * @param t the input argument
//      */
//     void accept(T t);
// 
// 
//     @Override
//     default void onResult(Result<T> result) {
//         if (result.failure()) {
//             onError(result.cause());
//         } else {
//             accept(result.get());
//         }
//     }
// 
// 
//     /**
//      * Called if there is a timeout.
//      * <p>
//      * This will be taken out in Reakt 3.0 (and QBit 2.0).
//      * Use reject instead.
//      */
//     default void onTimeout() {
//     }
// 
// 
//     /**
//      * Service View (service)
//      * Return an error message
//      * alias for reject.
//      * <p>
//      * This will be taken out in Reakt 3.0 (and QBit 2.0).
//      * Use reject instead.
//      *
//      * @param error error
//      */
//     @Deprecated
//     @SuppressWarnings("deprecated")
//     default void returnError(final String error) {
//         reject(error);
//     }
// 
// 
//     /**
//      * Service View (service)
//      * alias for reply
//      * <p>
//      * This will be taken out in Reakt 3.0 (and QBit 2.0).
//      * Use resolve or reply instead.
//      *
//      * @param thisReturn the value to return.
//      */
//     @Deprecated
//     @SuppressWarnings("deprecated")
//     default void returnThis(T thisReturn) {
//         resolve(thisReturn);
//     }
// 
// 
// }


import io.advantageous.boon.core.reflection.MethodAccess;
import io.advantageous.qbit.message.MethodCall;
import io.advantageous.qbit.message.Response;
import io.advantageous.qbit.message.impl.ResponseImpl;
import io.advantageous.qbit.reactive.Callback;
import io.advantageous.qbit.service.impl.ServiceConstants;
import io.advantageous.reakt.promise.Promise;
import java.util.List;
package io.advantageous.qbit.boon.service.impl;



/**
 * Created by rick on 4/20/16.
 */
class MapAndInvokeDynamic implements MapAndInvoke {
    private BoonServiceMethodCallHandler boonServiceMethodCallHandler;

    public MapAndInvokeDynamic(BoonServiceMethodCallHandler boonServiceMethodCallHandler) {
        this.boonServiceMethodCallHandler = boonServiceMethodCallHandler;
    }

    public Response<Object> mapArgsAsyncHandlersAndInvoke(MethodCall<Object> serviceMethodCall, MethodAccess serviceMethod) {


        if (serviceMethod.parameterTypes().length == 0 && !(Promise.class.isAssignableFrom(serviceMethod.returnType()))) {

            Object returnValue = serviceMethod.invokeDynamicObject(boonServiceMethodCallHandler.service, null);
            return boonServiceMethodCallHandler.response(serviceMethod, serviceMethodCall, returnValue);

        }


        boolean hasHandlers = boonServiceMethodCallHandler.hasHandlers(serviceMethodCall, serviceMethod);

        Object returnValue;

        if (hasHandlers) {
            Object body = serviceMethodCall.body();
            List<Object> argsList = boonServiceMethodCallHandler.prepareArgumentList(serviceMethodCall, serviceMethod.parameterTypes());
            if (body instanceof List || body instanceof Object[]) {
                boonServiceMethodCallHandler.extractHandlersFromArgumentList(serviceMethodCall.callback(), serviceMethod, body, argsList);
            } else {
// Path: qbit/core/src/main/java/io/advantageous/qbit/reactive/Callback.java
// public interface Callback<T> extends io.advantageous.reakt.CallbackHandler<T> {
// 
// 
//     /**
//      * Client View (client of the service)
//      * Called when there is an error
//      *
//      * @param error error
//      */
//     default void onError(final Throwable error) {
// 
//         LoggerFactory.getLogger(Callback.class)
//                 .error(error.getMessage(), error);
// 
//     }
// 
//     /**
//      * Performs this operation on the given argument.
//      *
//      * @param t the input argument
//      */
//     void accept(T t);
// 
// 
//     @Override
//     default void onResult(Result<T> result) {
//         if (result.failure()) {
//             onError(result.cause());
//         } else {
//             accept(result.get());
//         }
//     }
// 
// 
//     /**
//      * Called if there is a timeout.
//      * <p>
//      * This will be taken out in Reakt 3.0 (and QBit 2.0).
//      * Use reject instead.
//      */
//     default void onTimeout() {
//     }
// 
// 
//     /**
//      * Service View (service)
//      * Return an error message
//      * alias for reject.
//      * <p>
//      * This will be taken out in Reakt 3.0 (and QBit 2.0).
//      * Use reject instead.
//      *
//      * @param error error
//      */
//     @Deprecated
//     @SuppressWarnings("deprecated")
//     default void returnError(final String error) {
//         reject(error);
//     }
// 
// 
//     /**
//      * Service View (service)
//      * alias for reply
//      * <p>
//      * This will be taken out in Reakt 3.0 (and QBit 2.0).
//      * Use resolve or reply instead.
//      *
//      * @param thisReturn the value to return.
//      */
//     @Deprecated
//     @SuppressWarnings("deprecated")
//     default void returnThis(T thisReturn) {
//         resolve(thisReturn);
//     }
// 
// 
// }


// Path: qbit/core/src/main/java/io/advantageous/qbit/boon/service/impl/MapAndInvokeDynamic.java
import io.advantageous.boon.core.reflection.MethodAccess;
import io.advantageous.qbit.message.MethodCall;
import io.advantageous.qbit.message.Response;
import io.advantageous.qbit.message.impl.ResponseImpl;
import io.advantageous.qbit.reactive.Callback;
import io.advantageous.qbit.service.impl.ServiceConstants;
import io.advantageous.reakt.promise.Promise;
import java.util.List;

package io.advantageous.qbit.boon.service.impl;



/**
 * Created by rick on 4/20/16.
 */
class MapAndInvokeDynamic implements MapAndInvoke {
    private BoonServiceMethodCallHandler boonServiceMethodCallHandler;

    public MapAndInvokeDynamic(BoonServiceMethodCallHandler boonServiceMethodCallHandler) {
        this.boonServiceMethodCallHandler = boonServiceMethodCallHandler;
    }

    public Response<Object> mapArgsAsyncHandlersAndInvoke(MethodCall<Object> serviceMethodCall, MethodAccess serviceMethod) {


        if (serviceMethod.parameterTypes().length == 0 && !(Promise.class.isAssignableFrom(serviceMethod.returnType()))) {

            Object returnValue = serviceMethod.invokeDynamicObject(boonServiceMethodCallHandler.service, null);
            return boonServiceMethodCallHandler.response(serviceMethod, serviceMethodCall, returnValue);

        }


        boolean hasHandlers = boonServiceMethodCallHandler.hasHandlers(serviceMethodCall, serviceMethod);

        Object returnValue;

        if (hasHandlers) {
            Object body = serviceMethodCall.body();
            List<Object> argsList = boonServiceMethodCallHandler.prepareArgumentList(serviceMethodCall, serviceMethod.parameterTypes());
            if (body instanceof List || body instanceof Object[]) {
                boonServiceMethodCallHandler.extractHandlersFromArgumentList(serviceMethodCall.callback(), serviceMethod, body, argsList);
            } else {
                if (argsList.size() == 1 && !(argsList.get(0) instanceof Callback)) {