@Override
  public IRubyObject call(
      ThreadContext context,
      IRubyObject self,
      RubyModule clazz,
      String name,
      IRubyObject[] args,
      Block block) {
    if (block.isGiven()) {
      JavaProxy proxy = castJavaProxy(self);
      final int len = args.length;
      // these extra arrays are really unfortunate; split some of these paths out to eliminate?
      Object[] convertedArgs = new Object[len + 1];
      IRubyObject[] intermediate = new IRubyObject[len + 1];
      System.arraycopy(args, 0, intermediate, 0, len);
      intermediate[len] = RubyProc.newProc(context.runtime, block, block.type);

      JavaMethod method = (JavaMethod) findCallable(self, name, intermediate, len + 1);
      final Class<?>[] paramTypes = method.getParameterTypes();
      for (int i = 0; i < len + 1; i++) {
        convertedArgs[i] = intermediate[i].toJava(paramTypes[i]);
      }

      return method.invokeDirect(proxy.getObject(), convertedArgs);
    }
    return call(context, self, clazz, name, args);
  }
 @Override
 public IRubyObject call(
     ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args) {
   JavaProxy proxy = castJavaProxy(self);
   JavaMethod method = (JavaMethod) findCallable(self, name, args, args.length);
   return method.invokeDirect(proxy.getObject(), convertArguments(method, args));
 }
 @Override
 public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name) {
   if (javaVarargsCallables != null)
     return call(context, self, clazz, name, IRubyObject.NULL_ARRAY);
   JavaProxy proxy = castJavaProxy(self);
   JavaMethod method = (JavaMethod) findCallableArityZero(self, name);
   return method.invokeDirect(proxy.getObject());
 }
 @Override
 public IRubyObject call(
     ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject arg0) {
   if (javaVarargsCallables != null)
     return call(context, self, clazz, name, new IRubyObject[] {arg0});
   JavaProxy proxy = castJavaProxy(self);
   JavaMethod method = (JavaMethod) findCallableArityOne(self, name, arg0);
   final Class<?>[] paramTypes = method.getParameterTypes();
   Object cArg0 = arg0.toJava(paramTypes[0]);
   return method.invokeDirect(proxy.getObject(), cArg0);
 }
 @Override
 public IRubyObject call(
     ThreadContext context, IRubyObject self, RubyModule clazz, String name, Block block) {
   if (block.isGiven()) {
     JavaProxy proxy = castJavaProxy(self);
     RubyProc proc = RubyProc.newProc(context.runtime, block, block.type);
     JavaMethod method = (JavaMethod) findCallableArityOne(self, name, proc);
     final Class<?>[] paramTypes = method.getParameterTypes();
     Object cArg0 = proc.toJava(paramTypes[0]);
     return method.invokeDirect(proxy.getObject(), cArg0);
   }
   return call(context, self, clazz, name);
 }