@Override
    public @Nullable Object invoke(Object proxy, final Method method, final Object[] args) {
      ClassLoader initialClassLoader = Thread.currentThread().getContextClassLoader();
      try {
        Thread.currentThread().setContextClassLoader(myTargetClassLoader);

        Class<?>[] parameterTypes = method.getParameterTypes();
        Class<?>[] delegateParameterTypes = new Class<?>[parameterTypes.length];

        Object[] delegateArgs = new Object[parameterTypes.length];
        for (int i = 0; i < parameterTypes.length; i++) {
          Mirror parameterMirror = new Mirror(parameterTypes[i], args[i], mySourceClassLoader, myTargetClassLoader);
          delegateParameterTypes[i] = parameterMirror.getMirrorType();
          delegateArgs[i] = parameterMirror.getMirrorValue();
        }

        Method delegateMethod = myTarget.getClass().getMethod(method.getName(), delegateParameterTypes);
        delegateMethod.setAccessible(true);

        Object result = delegateMethod.invoke(myTarget, delegateArgs);
        Mirror resultMirror = new Mirror(delegateMethod.getReturnType(), result, myTargetClassLoader, mySourceClassLoader);
        return resultMirror.getMirrorValue();
      }
      catch (IllegalAccessException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException e) {
        LOG.error(e);
        return null;
      }
      finally {
        Thread.currentThread().setContextClassLoader(initialClassLoader);
      }
    }
@Override
    public @Nullable Object invoke(Object proxy, final Method method, final Object[] args)