private abstract static class BaseInvoker implements Invoker {
    final Function jffiFunction;
    final com.kenai.jffi.Invoker jffiInvoker = com.kenai.jffi.Invoker.getInstance();
    final ParameterMarshaller[] marshallers;
    final int arity;

    public BaseInvoker(Function function, ParameterMarshaller[] marshallers) {
      this.jffiFunction = function;
      this.marshallers = marshallers;
      this.arity = marshallers.length;
    }

    final HeapInvocationBuffer convertArguments(PyObject[] args) {
      checkArity(args);
      HeapInvocationBuffer buffer = new HeapInvocationBuffer(jffiFunction);

      for (int i = 0; i < marshallers.length; ++i) {
        marshallers[i].marshal(buffer, args[i]);
      }

      return buffer;
    }

    public final PyObject invoke() {
      return invoke(new PyObject[0]);
    }

    public final PyObject invoke(PyObject arg0) {
      return invoke(new PyObject[] {arg0});
    }

    public final PyObject invoke(PyObject arg0, PyObject arg1) {
      return invoke(new PyObject[] {arg0, arg1});
    }

    public final PyObject invoke(PyObject arg0, PyObject arg1, PyObject arg2) {
      return invoke(new PyObject[] {arg0, arg1, arg2});
    }

    final void checkArity(PyObject[] args) {
      checkArity(args.length);
    }

    final void checkArity(int got) {
      if (got != arity) {
        throw Py.TypeError(String.format("expected %d args; got %d", arity, got));
      }
    }
  }
 private abstract static class BaseInvoker implements FunctionInvoker {
   static final Invoker invoker = Invoker.getInstance();
 }