private static void processMethodUsage(PsiElement element,
                                         JavaChangeInfo changeInfo,
                                         boolean toChangeArguments,
                                         boolean toCatchExceptions,
                                         GrClosureSignatureUtil.ArgInfo<PsiElement>[] map,
                                         PsiSubstitutor substitutor) {
    if (map == null) return;
    if (changeInfo.isNameChanged()) {
      if (element instanceof GrReferenceElement) {
        element = ((GrReferenceElement<?>)element).handleElementRename(changeInfo.getNewName());
      }
    }
    if (toChangeArguments) {
      JavaParameterInfo[] parameters = changeInfo.getNewParameters();
      GrArgumentList argumentList = PsiUtil.getArgumentsList(element);
      GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(element.getProject());
      if (argumentList == null) {
        if (element instanceof GrEnumConstant) {
          argumentList = factory.createArgumentList();
          argumentList = (GrArgumentList)element.add(argumentList);
        }
        else {
          return;
        }
      }
      Set<PsiElement> argsToDelete = new HashSet<>(map.length * 2);
      for (GrClosureSignatureUtil.ArgInfo<PsiElement> argInfo : map) {
        argsToDelete.addAll(argInfo.args);
      }

      GrExpression[] values = new GrExpression[parameters.length];
      for (int i = 0; i < parameters.length; i++) {
        JavaParameterInfo parameter = parameters[i];
        int index = parameter.getOldIndex();
        if (index >= 0) {
          argsToDelete.removeAll(map[index].args);
        }
        else {
          values[i] = createDefaultValue(factory, changeInfo, parameter, argumentList, substitutor);
        }
      }

      for (PsiElement arg : argsToDelete) {
        arg.delete();
      }


      boolean skipOptionals = false;
      PsiElement anchor = null; //PsiTreeUtil.getChildOfAnyType(argumentList, GrExpression.class, GrNamedArgument.class);
      for (int i = 0; i < parameters.length; i++) {
        JavaParameterInfo parameter = parameters[i];
        int index = parameter.getOldIndex();
        if (index >= 0) {
          GrClosureSignatureUtil.ArgInfo<PsiElement> argInfo = map[index];
          List<PsiElement> arguments = argInfo.args;
          if (argInfo.isMultiArg) { //arguments for Map and varArg
            if ((i != 0 || !(!arguments.isEmpty() && arguments.iterator().next() instanceof GrNamedArgument)) &&
                (i != parameters.length - 1 || !parameter.isVarargType())) {
              final PsiType type = parameter.createType(changeInfo.getMethod().getParameterList(), argumentList.getManager());
              final GrExpression arg = GroovyRefactoringUtil.generateArgFromMultiArg(substitutor, arguments, type, element.getProject());
              for (PsiElement argument : arguments) {
                argument.delete();
              }
              anchor = argumentList.addAfter(arg, anchor);
              JavaCodeStyleManager.getInstance(anchor.getProject()).shortenClassReferences(anchor);
            }
          }
          else {  //arguments for simple parameters
            if (arguments.size() == 1) { //arg exists
              PsiElement arg = arguments.iterator().next();
              if (i == parameters.length - 1 && parameter.isVarargType()) {
                if (arg instanceof GrSafeCastExpression) {
                  PsiElement expr = ((GrSafeCastExpression)arg).getOperand();
                  if (expr instanceof GrListOrMap && !((GrListOrMap)expr).isMap()) {
                    final PsiElement copy = expr.copy();
                    PsiElement[] newVarargs = ((GrListOrMap)copy).getInitializers();
                    for (PsiElement vararg : newVarargs) {
                      anchor = argumentList.addAfter(vararg, anchor);
                    }
                    arg.delete();
                    continue;
                  }
                }
              }

              PsiElement curArg = getNextOfType(argumentList, anchor, GrExpression.class);
              if (curArg == arg) {
                anchor = arg;
              }
              else {
                final PsiElement copy = arg.copy();
                anchor = argumentList.addAfter(copy, anchor);
                arg.delete();
              }
            }
            else { //arg is skipped. Parameter is optional
              skipOptionals = true;
            }
          }
        }
        else {
          if (skipOptionals && isParameterOptional(parameter)) continue;

          if (forceOptional(parameter)) {
            skipOptionals = true;
            continue;
          }
          try {
            final GrExpression value = values[i];
            if (i > 0 && (value == null || anchor == null)) {
              PsiElement comma = Factory.createSingleLeafElement(GroovyTokenTypes.mCOMMA, ",", 0, 1,
                                                                 SharedImplUtil.findCharTableByTree(argumentList.getNode()),
                                                                 argumentList.getManager()).getPsi();
              if (anchor == null) anchor = argumentList.getLeftParen();

              anchor = argumentList.addAfter(comma, anchor);
            }
            if (value != null) {
              anchor = argumentList.addAfter(value, anchor);
            }
          }
          catch (IncorrectOperationException e) {
            LOG.error(e.getMessage());
          }
        }
      }

      for (PsiElement arg : argsToDelete) {
        arg.delete();
      }

      GrCall call = GroovyRefactoringUtil.getCallExpressionByMethodReference(element);
      if (argumentList.getText().trim().isEmpty() && (call == null || !call.hasClosureArguments())) {
        argumentList = argumentList.replaceWithArgumentList(factory.createArgumentList());
      }
      CodeStyleManager.getInstance(argumentList.getProject()).reformat(argumentList);
    }

    if (toCatchExceptions) {
      final ThrownExceptionInfo[] exceptionInfos = changeInfo.getNewExceptions();
      PsiClassType[] exceptions = getExceptions(exceptionInfos, element, element.getManager());
      fixExceptions(element, exceptions);
    }
  }
private static void processMethodUsage(PsiElement element,
                                         JavaChangeInfo changeInfo,
                                         boolean toChangeArguments,
                                         boolean toCatchExceptions,
                                         GrClosureSignatureUtil.ArgInfo<PsiElement>[] map,
                                         PsiSubstitutor substitutor)