public void invoke(MethodInvocation invocation) throws Throwable {
      next.invoke(invocation);
      if (invocation.found() || invocation.getParameterTypes().length != 1) {
        return;
      }

      if (!invocation.isIsOrGet()) {
        return;
      }

      MethodInvocation getterInvocation =
          new MethodInvocation(
              invocation.getName(),
              invocation.getReturnType(),
              invocation.getGenericReturnType(),
              EMPTY_CLASS_ARRAY,
              invocation.getDelegate(),
              EMPTY);
      next.invoke(getterInvocation);
      if (getterInvocation.found() && getterInvocation.getResult() != null) {
        invocation.setResult(getterInvocation.getResult());
      } else {
        invocation.setResult(invocation.getParameters()[0]);
      }
    }
  public MethodInvoker getMethod(Class<?> clazz, String name, Class<?>[] parameters) {
    MethodDescriptor mDescriptor = new MethodDescriptor(name, clazz, parameters);
    MethodInvoker mInvoker = null;
    List<Method> acceptableMethods = null;
    LRUCache<MethodDescriptor, MethodInvoker> cache = cacheHolder.get();

    mInvoker = cache.get(mDescriptor);

    if (mInvoker == null) {
      acceptableMethods = getMethodsByNameAndLength(clazz, name, parameters.length);

      if (acceptableMethods.size() == 1) {
        mInvoker = MethodInvoker.buildInvoker(acceptableMethods.get(0), parameters);
      } else {
        mInvoker = getBestMethod(acceptableMethods, parameters);
      }

      if (mInvoker != null && mInvoker.getCost() != -1) {
        cache.put(mDescriptor, mInvoker);
      } else {
        String errorMessage =
            "Method " + name + "(" + Arrays.toString(parameters) + ") does not exist";
        logger.log(Level.WARNING, errorMessage);
        throw new Py4JException(errorMessage);
      }
    }

    return mInvoker;
  }
  public Object invoke(Object object, MethodInvoker invoker, Object[] parameters) {
    Object returnObject = null;

    returnObject = invoker.invoke(object, parameters);
    if (invoker.isVoid()) {
      returnObject = RETURN_VOID;
    }

    return returnObject;
  }
    public void invoke(MethodInvocation invocation) throws Throwable {
      if (current.get() != null) {
        // Already invoking a method on the mix-in
        return;
      }

      if (instance == null) {
        instance = DirectInstantiator.INSTANCE.newInstance(mixInClass, proxy);
      }
      MethodInvocation beanInvocation =
          new MethodInvocation(
              invocation.getName(),
              invocation.getReturnType(),
              invocation.getGenericReturnType(),
              invocation.getParameterTypes(),
              instance,
              invocation.getParameters());
      current.set(beanInvocation);
      try {
        next.invoke(beanInvocation);
      } finally {
        current.set(null);
      }
      if (beanInvocation.found()) {
        invocation.setResult(beanInvocation.getResult());
      }
    }
    public Object invoke(Object target, Method method, Object[] params) throws Throwable {
      if (EQUALS_METHOD.equals(method)) {
        Object param = params[0];
        if (param == null || !Proxy.isProxyClass(param.getClass())) {
          return false;
        }
        InvocationHandler other = Proxy.getInvocationHandler(param);
        return equals(other);
      } else if (HASHCODE_METHOD.equals(method)) {
        return hashCode();
      }

      MethodInvocation invocation =
          new MethodInvocation(
              method.getName(),
              method.getReturnType(),
              method.getGenericReturnType(),
              method.getParameterTypes(),
              delegate,
              params);
      invoker.invoke(invocation);
      if (!invocation.found()) {
        String methodName =
            method.getDeclaringClass().getSimpleName() + "." + method.getName() + "()";
        throw Exceptions.unsupportedMethod(methodName);
      }
      return invocation.getResult();
    }
 public void invoke(MethodInvocation invocation) throws Throwable {
   next.invoke(invocation);
   if (invocation.found() && invocation.getResult() != null) {
     invocation.setResult(
         convert(invocation.getGenericReturnType(), invocation.getResult(), mapping));
   }
 }
  private MethodInvoker getBestMethod(List<Method> acceptableMethods, Class<?>[] parameters) {
    MethodInvoker lowestCost = null;

    for (Method method : acceptableMethods) {
      MethodInvoker temp = MethodInvoker.buildInvoker(method, parameters);
      int cost = temp.getCost();
      if (cost == -1) {
        continue;
      } else if (cost == 0) {
        lowestCost = temp;
        break;
      } else if (lowestCost == null || cost < lowestCost.getCost()) {
        lowestCost = temp;
      }
    }

    return lowestCost;
  }
  private MethodInvoker getBestConstructor(
      List<Constructor<?>> acceptableConstructors, Class<?>[] parameters) {
    MethodInvoker lowestCost = null;

    for (Constructor<?> constructor : acceptableConstructors) {
      MethodInvoker temp = MethodInvoker.buildInvoker(constructor, parameters);
      int cost = temp.getCost();
      if (cost == -1) {
        continue;
      } else if (cost == 0) {
        lowestCost = temp;
        break;
      } else if (lowestCost == null || cost < lowestCost.getCost()) {
        lowestCost = temp;
      }
    }

    return lowestCost;
  }
    public void invoke(MethodInvocation invocation) throws Throwable {
      Matcher matcher = IS_SUPPORT_METHOD.matcher(invocation.getName());
      if (!matcher.matches()) {
        next.invoke(invocation);
        return;
      }

      String getterName = String.format("get%s", matcher.group(1));
      MethodInvocation getterInvocation =
          new MethodInvocation(
              getterName,
              invocation.getReturnType(),
              invocation.getGenericReturnType(),
              new Class[0],
              invocation.getDelegate(),
              EMPTY);
      next.invoke(getterInvocation);
      invocation.setResult(getterInvocation.found());
    }
  public Channel getChannel(Player player) {
    Channel channel = channelLookup.get(player.getName());

    if (channel == null) {
      Object connection = getConnection.get(getPlayerHandle.invoke(player));
      Object manager = getManager.get(connection);

      channelLookup.put(player.getName(), channel = getChannel.get(manager));
    }

    return channel;
  }
    public void invoke(MethodInvocation method) throws Throwable {
      if (method.isGetter()) {
        if (properties.containsKey(method.getName())) {
          method.setResult(properties.get(method.getName()));
          return;
        }
        if (unknown.contains(method.getName())) {
          return;
        }

        Object value;
        next.invoke(method);
        if (!method.found()) {
          unknown.add(method.getName());
          return;
        }
        value = method.getResult();
        properties.put(method.getName(), value);
        return;
      }

      next.invoke(method);
    }
  @SuppressWarnings("unchecked")
  private void registerChannelHandler() {
    Object mcServer = getMinecraftServer.get(Bukkit.getServer());
    Object serverConnection = getServerConnection.get(mcServer);
    boolean looking = true;

    networkManagers = (List<Object>) getNetworkMarkers.invoke(null, serverConnection);
    createServerChannelHandler();

    for (int i = 0; looking; i++) {
      List<Object> list =
          Reflection.getField(serverConnection.getClass(), List.class, i).get(serverConnection);

      for (Object item : list) {
        if (!ChannelFuture.class.isInstance(item)) break;

        Channel serverChannel = ((ChannelFuture) item).channel();

        serverChannels.add(serverChannel);
        serverChannel.pipeline().addFirst(serverChannelHandler);
        looking = false;
      }
    }
  }
 public void invoke(MethodInvocation method) throws Throwable {
   for (int i = 0; !method.found() && i < invokers.length; i++) {
     MethodInvoker invoker = invokers[i];
     invoker.invoke(method);
   }
 }
 ReflectMethodSetter(final MethodInvoker invoker) {
   super(invoker.getMethod());
 }
 @Override
 public void set(final Object src, final Object obj) {
   super.invoke(src, obj);
 }