@Override
  public Object evaluate(EvaluationContextImpl context) throws EvaluateException {
    if (!context.getDebugProcess().isAttached()) {
      return null;
    }
    DebugProcessImpl debugProcess = context.getDebugProcess();

    final boolean requiresSuperObject = DisableGC.unwrap(myObjectEvaluator) instanceof SuperEvaluator;
    final Object object = myObjectEvaluator.evaluate(context);
    if (LOG.isDebugEnabled()) {
      LOG.debug("MethodEvaluator: object = " + object);
    }
    if (object == null) {
      throw EvaluateExceptionUtil.createEvaluateException(new NullPointerException());
    }
    if (!(object instanceof ObjectReference || isInvokableType(object))) {
      throw EvaluateExceptionUtil.createEvaluateException(JavaDebuggerBundle.message("evaluation.error.evaluating.method", myMethodName));
    }
    List<Value> args = new ArrayList<>(myArgumentEvaluators.length);
    for (Evaluator evaluator : myArgumentEvaluators) {
      args.add((Value)evaluator.evaluate(context));
    }
    try {
      ReferenceType referenceType = null;

      if (object instanceof ObjectReference) {
        // it seems that if we have an object of the class, the class must be ready, so no need to use findClass here
        referenceType = ((ObjectReference)object).referenceType();
      }
      else if (isInvokableType(object)) {
        referenceType = (ReferenceType)object;
      }

      if (referenceType == null) {
        throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(
          JavaDebuggerBundle.message("evaluation.error.cannot.evaluate.qualifier", myMethodName))
        );
      }
      final String signature = myMethodSignature != null ? myMethodSignature.getName(debugProcess) : null;

      if (requiresSuperObject && (referenceType instanceof ClassType)) {
        referenceType = ((ClassType)referenceType).superclass();
        String className = myClassName != null ? myClassName.getName(debugProcess) : null;
        if (referenceType == null || (className != null && !className.equals(referenceType.name()))) {
          referenceType = debugProcess.findClass(context, className, context.getClassLoader());
        }
      }

      Method jdiMethod = null;
      if (signature == null) {
        // we know nothing about expected method's signature, so trying to match my method name and parameter count
        // dummy matching, may be improved with types matching later
        // IMPORTANT! using argumentTypeNames() instead of argumentTypes() to avoid type resolution inside JDI, which may be time-consuming
        List<Method> matchingMethods =
          StreamEx.of(referenceType.methodsByName(myMethodName)).filter(m -> m.argumentTypeNames().size() == args.size()).toList();
        if (matchingMethods.size() == 1) {
          jdiMethod = matchingMethods.get(0);
        }
        else if (matchingMethods.size() > 1) {
          jdiMethod = ContainerUtil.find(matchingMethods, m -> matchArgs(m, args));
        }
      }
      if (jdiMethod == null) {
        jdiMethod = DebuggerUtils.findMethod(referenceType, myMethodName, signature);
      }
      if (jdiMethod == null) {
        throw EvaluateExceptionUtil.createEvaluateException(JavaDebuggerBundle.message("evaluation.error.no.instance.method", myMethodName));
      }
      if (myMustBeVararg && !jdiMethod.isVarArgs()) {
        // this is a workaround for jdk bugs when bridge or proxy methods do not have ACC_VARARGS flags
        // see IDEA-129869 and IDEA-202380
        wrapVarargParams(jdiMethod, args);
      }
      if (signature == null) { // runtime conversions
        argsConversions(jdiMethod, args, context);
      }

      // Static methods
      if (isInvokableType(object)) {
        if (isInvokableType(referenceType)) {
          if (jdiMethod.isStatic()) {
            if (referenceType instanceof ClassType) {
              return debugProcess.invokeMethod(context, (ClassType)referenceType, jdiMethod, args);
            }
            else {
              return debugProcess.invokeMethod(context, (InterfaceType)referenceType, jdiMethod, args);
            }
          }
        }
        throw EvaluateExceptionUtil.createEvaluateException(JavaDebuggerBundle.message(
          "evaluation.error.no.static.method", DebuggerUtilsEx.methodName(referenceType.name(), myMethodName, signature)));
      }

      // object should be an ObjectReference
      final ObjectReference objRef = (ObjectReference)object;

      if (requiresSuperObject) {
        return debugProcess.invokeInstanceMethod(context, objRef, jdiMethod, args, ObjectReference.INVOKE_NONVIRTUAL);
      }
      return debugProcess.invokeMethod(context, objRef, jdiMethod, args);
    }
    catch (Exception e) {
      LOG.debug(e);
      throw EvaluateExceptionUtil.createEvaluateException(e);
    }
  }
@Override
  public Object evaluate(EvaluationContextImpl context)