// Path: stubs-shared/src/main/java/org/freedesktop/wayland/util/jaccall/wl_argument.java
// @Struct(union = true,
//         value = {
//                 @Field(name = "i",
//                        type = CType.INT),
//                 @Field(name = "u",
//                        type = CType.INT),
//                 @Field(name = "f",
//                        type = CType.INT),
//                 @Field(name = "s",
//                        type = CType.POINTER,
//                        dataType = String.class),
//                 @Field(name = "o",
//                        type = CType.POINTER),
//                 @Field(name = "n",
//                        type = CType.INT),
//                 @Field(name = "a",
//                        type = CType.POINTER,
//                        dataType = wl_array.class),
//                 @Field(name = "h",
//                        type = CType.INT)
//         })
// public final class wl_argument extends wl_argument_Jaccall_StructType {
// }
// 
// Path: stubs-shared/src/main/java/org/freedesktop/wayland/util/jaccall/wl_array.java
// @Struct({
//                 @Field(name = "size",
//                        type = CType.LONG_LONG),
//                 @Field(name = "alloc",
//                        type = CType.LONG_LONG),
//                 @Field(name = "data",
//                        type = CType.POINTER)
//         })
// public final class wl_array extends wl_array_Jaccall_StructType {
// 
// }
// 
// Path: stubs-shared/src/main/java/org/freedesktop/wayland/util/jaccall/wl_dispatcher_func_t.java
// @Functor
// public interface wl_dispatcher_func_t {
//     int invoke(@Ptr(Object.class) long implementation,
//                @Ptr long wlObject,
//                int opcode,
//                @Ptr(wl_message.class) long wlMessage,
//                @Ptr(wl_argument.class) long wl_arguments);
// }
// 
// Path: stubs-shared/src/main/java/org/freedesktop/wayland/util/jaccall/wl_message.java
// @Struct({
//                 @Field(name = "name",
//                        type = CType.POINTER,
//                        dataType = String.class),
//                 @Field(name = "signature",
//                        type = CType.POINTER,
//                        dataType = String.class),
//                 @Field(name = "types",
//                        type = CType.POINTER,
//                        pointerDepth = 1,
//                        dataType = wl_interface.class)
//         })
// public final class wl_message extends wl_message_Jaccall_StructType {
// 
// }


import static org.freedesktop.wayland.util.jaccall.Pointerwl_dispatcher_func_t.nref;
import org.freedesktop.jaccall.JNI;
import org.freedesktop.jaccall.Pointer;
import org.freedesktop.jaccall.Ptr;
import org.freedesktop.wayland.util.jaccall.wl_argument;
import org.freedesktop.wayland.util.jaccall.wl_array;
import org.freedesktop.wayland.util.jaccall.wl_dispatcher_func_t;
import org.freedesktop.wayland.util.jaccall.wl_message;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import static org.freedesktop.jaccall.Pointer.wrap;
                                             method,
                                             waylandObject.getImplementation(),
                                             Arrays.toString(jargs),
                                             message));
            e.printStackTrace();
        }

        return 0;
    }

    private static Method get(final Class<? extends WaylandObject> waylandObjectType,
                              final Class<?> implementationType,
                              final Message message) throws NoSuchMethodException {

        Map<Integer, Method> methodMap = METHOD_CACHE.get(implementationType);
        if (methodMap == null) {
            methodMap = new HashMap<>();
            METHOD_CACHE.put(implementationType,
                             methodMap);
        }

        final int methodHash = Objects.hash(waylandObjectType,
                                            message);
        Method method = methodMap.get(methodHash);
        if (method == null) {
            final Class<?>[] types    = message.types();
            final Class<?>[] argTypes = new Class<?>[types.length + 1];
            //copy to new array and shift by 1
            System.arraycopy(types,
                             0,
// Path: stubs-shared/src/main/java/org/freedesktop/wayland/util/jaccall/wl_argument.java
// @Struct(union = true,
//         value = {
//                 @Field(name = "i",
//                        type = CType.INT),
//                 @Field(name = "u",
//                        type = CType.INT),
//                 @Field(name = "f",
//                        type = CType.INT),
//                 @Field(name = "s",
//                        type = CType.POINTER,
//                        dataType = String.class),
//                 @Field(name = "o",
//                        type = CType.POINTER),
//                 @Field(name = "n",
//                        type = CType.INT),
//                 @Field(name = "a",
//                        type = CType.POINTER,
//                        dataType = wl_array.class),
//                 @Field(name = "h",
//                        type = CType.INT)
//         })
// public final class wl_argument extends wl_argument_Jaccall_StructType {
// }
// 
// Path: stubs-shared/src/main/java/org/freedesktop/wayland/util/jaccall/wl_array.java
// @Struct({
//                 @Field(name = "size",
//                        type = CType.LONG_LONG),
//                 @Field(name = "alloc",
//                        type = CType.LONG_LONG),
//                 @Field(name = "data",
//                        type = CType.POINTER)
//         })
// public final class wl_array extends wl_array_Jaccall_StructType {
// 
// }
// 
// Path: stubs-shared/src/main/java/org/freedesktop/wayland/util/jaccall/wl_dispatcher_func_t.java
// @Functor
// public interface wl_dispatcher_func_t {
//     int invoke(@Ptr(Object.class) long implementation,
//                @Ptr long wlObject,
//                int opcode,
//                @Ptr(wl_message.class) long wlMessage,
//                @Ptr(wl_argument.class) long wl_arguments);
// }
// 
// Path: stubs-shared/src/main/java/org/freedesktop/wayland/util/jaccall/wl_message.java
// @Struct({
//                 @Field(name = "name",
//                        type = CType.POINTER,
//                        dataType = String.class),
//                 @Field(name = "signature",
//                        type = CType.POINTER,
//                        dataType = String.class),
//                 @Field(name = "types",
//                        type = CType.POINTER,
//                        pointerDepth = 1,
//                        dataType = wl_interface.class)
//         })
// public final class wl_message extends wl_message_Jaccall_StructType {
// 
// }


// Path: stubs-shared/src/main/java/org/freedesktop/wayland/util/Dispatcher.java
import static org.freedesktop.wayland.util.jaccall.Pointerwl_dispatcher_func_t.nref;
import org.freedesktop.jaccall.JNI;
import org.freedesktop.jaccall.Pointer;
import org.freedesktop.jaccall.Ptr;
import org.freedesktop.wayland.util.jaccall.wl_argument;
import org.freedesktop.wayland.util.jaccall.wl_array;
import org.freedesktop.wayland.util.jaccall.wl_dispatcher_func_t;
import org.freedesktop.wayland.util.jaccall.wl_message;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import static org.freedesktop.jaccall.Pointer.wrap;

                                             method,
                                             waylandObject.getImplementation(),
                                             Arrays.toString(jargs),
                                             message));
            e.printStackTrace();
        }

        return 0;
    }

    private static Method get(final Class<? extends WaylandObject> waylandObjectType,
                              final Class<?> implementationType,
                              final Message message) throws NoSuchMethodException {

        Map<Integer, Method> methodMap = METHOD_CACHE.get(implementationType);
        if (methodMap == null) {
            methodMap = new HashMap<>();
            METHOD_CACHE.put(implementationType,
                             methodMap);
        }

        final int methodHash = Objects.hash(waylandObjectType,
                                            message);
        Method method = methodMap.get(methodHash);
        if (method == null) {
            final Class<?>[] types    = message.types();
            final Class<?>[] argTypes = new Class<?>[types.length + 1];
            //copy to new array and shift by 1
            System.arraycopy(types,
                             0,
                             argTypes,