private static void performRefactoring(final PsiElement element,
                                         final GrParameterListOwner owner,
                                         final Collection<PsiElement> occurrences,
                                         final boolean createNewFirstParam,
                                         @Nullable final String mapParamName,
                                         final boolean specifyMapType) {
    final GrParameter param = getAppropriateParameter(element);
    assert param != null;
    final String paramName = param.getName();
    final String mapName = createNewFirstParam ? mapParamName : getFirstParameter(owner).getName();


    final Project project = element.getProject();
    final Runnable runnable = () -> {
      final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project);

      final GrParameterList list = owner.getParameterList();
      final int index = list.getParameterNumber(param);
      if (!createNewFirstParam && index <= 0) { // bad undo
        return;
      }

      //Remove old arguments from occurrences
      //final List<GrCall> calls = getCallOccurrences(occurrences);
      try {
        for (PsiElement occurrence : occurrences) {
          GrReferenceExpression refExpr = null;
          GroovyResolveResult resolveResult = null;
          boolean isExplicitGetterCall = false;
          if (occurrence instanceof GrReferenceExpression) {
            final PsiElement parent = occurrence.getParent();
            if (parent instanceof GrCall) {
              refExpr = (GrReferenceExpression)occurrence;
              resolveResult = refExpr.advancedResolve();
              final PsiElement resolved = resolveResult.getElement();
              if (resolved instanceof PsiMethod &&
                  GroovyPropertyUtils.isSimplePropertyGetter(((PsiMethod)resolved)) &&
                  //check for explicit getter call
                  ((PsiMethod)resolved).getName().equals(refExpr.getReferenceName())) {
                isExplicitGetterCall = true;
              }
            }
            else if (parent instanceof GrReferenceExpression) {
              resolveResult = ((GrReferenceExpression)parent).advancedResolve();
              final PsiElement resolved = resolveResult.getElement();
              if (resolved instanceof PsiMethod && "call".equals(((PsiMethod)resolved).getName())) {
                refExpr = (GrReferenceExpression)parent;
              }
            }
          }
          if (refExpr == null) continue;
          final GrSignature signature = generateSignature(owner, refExpr);
          if (signature == null) continue;
          GrCall call;
          if (isExplicitGetterCall) {
            PsiElement parent = refExpr.getParent();
            LOG.assertTrue(parent instanceof GrCall);
            parent = parent.getParent();
            if (parent instanceof GrReferenceExpression && "call".equals(((GrReferenceExpression)parent).getReferenceName())) {
              parent = parent.getParent();
            }
            if (parent instanceof GrCall) {
              call = (GrCall)parent;
            }
            else {
              continue;
            }
          }
          else {
            call = (GrCall)refExpr.getParent();
          }

          if (resolveResult.isInvokedOnProperty()) {
            final PsiElement parent = call.getParent();
            if (parent instanceof GrCall) {
              call = (GrCall)parent;
            }
            else if (parent instanceof GrReferenceExpression && parent.getParent() instanceof GrCall) {
              final PsiElement resolved = ((GrReferenceExpression)parent).resolve();
              if (resolved instanceof PsiMethod && "call".equals(((PsiMethod)resolved).getName())) {
                call = (GrCall)parent.getParent();
              }
              else {
                continue;
              }
            }
          }

          final GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos = GrClosureSignatureUtil.mapParametersToArguments(signature, call);
          if (argInfos == null) continue;
          final GrClosureSignatureUtil.ArgInfo<PsiElement> argInfo = argInfos[index];

          final GrNamedArgument namedArg;
          if (argInfo.isMultiArg) {
            if (argInfo.args.isEmpty()) continue;
            String arg = "[" + StringUtil.join(ContainerUtil.map(argInfo.args, element1 -> element1.getText()), ", ") + "]";
            for (PsiElement psiElement : argInfo.args) {
              psiElement.delete();
            }
            namedArg = factory.createNamedArgument(paramName, factory.createExpressionFromText(arg));
          }
          else {
            if (argInfo.args.isEmpty()) continue;
            final PsiElement argument = argInfo.args.iterator().next();
            assert argument instanceof GrExpression;
            namedArg = factory.createNamedArgument(paramName, (GrExpression)argument);
            argument.delete();
          }
          call.addNamedArgument(namedArg);
        }
      }
      catch (IncorrectOperationException e) {
        LOG.error(e);
      }

      //Replace of occurrences of old parameter in closure/method
      final Collection<PsiReference> references = ReferencesSearch.search(param).findAll();
      for (PsiReference ref : references) {
        final PsiElement elt = ref.getElement();
        if (elt instanceof GrReferenceExpression expr) {
          final GrExpression newExpr = factory.createExpressionFromText(mapName + "." + paramName);
          expr.replaceWithExpression(newExpr, true);
        }
      }

      //Add new map parameter to closure/method if it's necessary
      if (createNewFirstParam) {
        try {
          final GrParameter newParam = factory.createParameter(mapName, specifyMapType ? MAP_TYPE_TEXT : "", null);
          list.addAfter(newParam, null);
        }
        catch (IncorrectOperationException e) {
          LOG.error(e);
        }
      }

      //Eliminate obsolete parameter from parameter list
      param.delete();
    };

    CommandProcessor.getInstance().executeCommand(project, () -> ApplicationManager.getApplication().runWriteAction(runnable),
                                                  GroovyBundle.message("convert.parameter.to.map.entry.title"), null);
  }
private static void performRefactoring(final PsiElement element,
                                         final GrParameterListOwner owner,
                                         final Collection<PsiElement> occurrences,
                                         final boolean createNewFirstParam,
                                         @Nullable final String mapParamName,
                                         final boolean specifyMapType)