@Override
    public void visitMethodCallExpression(GrMethodCallExpression grMethodCallExpression) {
      super.visitMethodCallExpression(grMethodCallExpression);
      final GrArgumentList args = grMethodCallExpression.getArgumentList();
      if (args.getExpressionArguments().length != 1) {
        return;
      }
      if (PsiImplUtil.hasNamedArguments(args)) {
        return;
      }
      final GrExpression methodExpression = grMethodCallExpression.getInvokedExpression();
      if (!(methodExpression instanceof GrReferenceExpression)) {
        return;
      }
      final GrReferenceExpression referenceExpression = (GrReferenceExpression) methodExpression;
      final String name = referenceExpression.getReferenceName();
      if (!"get".equals(name)) {
        return;
      }
      final GrExpression qualifier = referenceExpression.getQualifierExpression();

      if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) {
        return;
      }

      if (referenceExpression.getDotTokenType() == GroovyTokenTypes.mOPTIONAL_DOT) return;
      final PsiType type = qualifier.getType();
      if (!InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) {
        return;
      }
      registerMethodCallError(grMethodCallExpression);
    }
    public boolean satisfiedBy(PsiElement element) {
      if (element instanceof GrMethodCallExpression) {
        final GrMethodCallExpression expression = (GrMethodCallExpression) element;
        //        final PsiElement parent = expression.getParent();
        //        if (parent instanceof GrAssignmentExpression) return false;
        //        if (parent instanceof GrArgumentList) return false;
        //        if (parent instanceof GrReturnStatement) return false;
        //        if (!(parent instanceof GrCodeBlock || parent instanceof GrIfStatement|| parent
        // instanceof GrCaseSection)) return false;

        final GrExpression invokedExpression = expression.getInvokedExpression();
        if (invokedExpression instanceof GrReferenceExpression) {
          GrReferenceExpression referenceExpression = (GrReferenceExpression) invokedExpression;
          if ("each".equals(referenceExpression.getReferenceName())) {
            final GrArgumentList argumentList = expression.getArgumentList();
            if (argumentList != null) {
              if (PsiImplUtil.hasExpressionArguments(argumentList)) return false;
              if (PsiImplUtil.hasNamedArguments(argumentList)) return false;
            }
            final GrClosableBlock[] closureArguments = expression.getClosureArguments();
            if (closureArguments.length != 1) return false;
            final GrParameter[] parameters = closureArguments[0].getParameterList().getParameters();
            if (parameters.length > 1) return false;
            return true;
          }
        }
      }
      return false;
    }
  @Override
  protected void processIntention(@NotNull PsiElement element, Project project, Editor editor)
      throws IncorrectOperationException {
    final GrMethodCallExpression expression = (GrMethodCallExpression) element;
    final GrClosableBlock block = expression.getClosureArguments()[0];
    final GrParameterList parameterList = block.getParameterList();
    final GrParameter[] parameters = parameterList.getParameters();

    String var;
    if (parameters.length == 1) {
      var = parameters[0].getText();
      var = StringUtil.replace(var, GrModifier.DEF, "");
    } else {
      var = "it";
    }

    final GrExpression invokedExpression = expression.getInvokedExpression();
    GrExpression qualifier = ((GrReferenceExpression) invokedExpression).getQualifierExpression();
    final GroovyPsiElementFactory elementFactory =
        GroovyPsiElementFactory.getInstance(element.getProject());
    if (qualifier == null) {
      qualifier = elementFactory.createExpressionFromText("this");
    }

    StringBuilder builder = new StringBuilder();
    builder.append("for (").append(var).append(" in ").append(qualifier.getText()).append(") {\n");
    String text = block.getText();
    final PsiElement blockArrow = block.getArrow();
    int index;
    if (blockArrow != null) {
      index = blockArrow.getStartOffsetInParent() + blockArrow.getTextLength();
    } else {
      index = 1;
    }
    while (index < text.length() && Character.isWhitespace(text.charAt(index))) index++;
    text = text.substring(index, text.length() - 1);
    builder.append(text);
    builder.append("}");

    final GrStatement statement = elementFactory.createStatementFromText(builder.toString());
    GrForStatement forStatement = (GrForStatement) expression.replaceWithStatement(statement);
    final GrForClause clause = forStatement.getClause();
    GrVariable variable = clause.getDeclaredVariable();

    forStatement = updateReturnStatements(forStatement);

    if (variable == null) return;

    if (ApplicationManager.getApplication().isUnitTestMode()) return;

    final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
    final Document doc = documentManager.getDocument(element.getContainingFile());
    if (doc == null) return;

    documentManager.doPostponedOperationsAndUnblockDocument(doc);
    editor.getCaretModel().moveToOffset(variable.getTextOffset());
    new VariableInplaceRenamer(variable, editor).performInplaceRename();
  }
 @Override
 public void doFix(Project project, ProblemDescriptor descriptor)
     throws IncorrectOperationException {
   final PsiElement referenceName = descriptor.getPsiElement();
   final GrReferenceExpression invokedExpression =
       (GrReferenceExpression) referenceName.getParent();
   final GrMethodCallExpression callExpression =
       (GrMethodCallExpression) invokedExpression.getParent();
   final GrArgumentList args = callExpression.getArgumentList();
   final GrExpression arg = args.getExpressionArguments()[0];
   replaceExpression(
       callExpression,
       invokedExpression.getQualifierExpression().getText() + '[' + arg.getText() + ']');
 }
 private static void removeParametersFromCall(
     GrMethodCallExpression methodCall, GrIntroduceParameterSettings settings) {
   final GroovyResolveResult resolveResult = methodCall.advancedResolve();
   final PsiElement resolved = resolveResult.getElement();
   LOG.assertTrue(resolved instanceof PsiMethod);
   final GrClosureSignature signature =
       GrClosureSignatureUtil.createSignature(
           (PsiMethod) resolved, resolveResult.getSubstitutor());
   final GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos =
       GrClosureSignatureUtil.mapParametersToArguments(signature, methodCall);
   LOG.assertTrue(argInfos != null);
   settings
       .parametersToRemove()
       .forEach(
           new TIntProcedure() {
             @Override
             public boolean execute(int value) {
               final List<PsiElement> args = argInfos[value].args;
               for (PsiElement arg : args) {
                 arg.delete();
               }
               return true;
             }
           });
 }
 @Override
 public boolean satisfiedBy(PsiElement element) {
   if (!(element instanceof GrMethodCallExpression)) {
     return false;
   }
   final GrMethodCallExpression call = (GrMethodCallExpression) element;
   final GrExpression invokedExpression = call.getInvokedExpression();
   if (invokedExpression == null) {
     return false;
   }
   final PsiType type = invokedExpression.getType();
   if (type == null) {
     return false;
   }
   if (!type.equalsToText(GroovyCommonClassNames.GROOVY_LANG_CLOSURE)) {
     return false;
   }
   return !ErrorUtil.containsError(element);
 }
  @NotNull
  private static GrStatement[] createResultStatement(ExtractInfoHelper helper) {
    VariableInfo[] outputVars = helper.getOutputVariableInfos();

    PsiType type = helper.getOutputType();
    GrStatement[] statements = helper.getStatements();
    GrMethodCallExpression callExpression = createMethodCall(helper);

    if ((outputVars.length == 0 || PsiType.VOID.equals(type)) && !helper.hasReturnValue())
      return new GrStatement[] {callExpression};
    GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(helper.getProject());
    if (helper.hasReturnValue()) {
      return new GrStatement[] {
        factory.createStatementFromText("return " + callExpression.getText())
      };
    }

    LOG.assertTrue(outputVars.length > 0);

    final List<VariableInfo> mustAdd = mustAddVariableDeclaration(statements, outputVars);
    if (mustAdd.size() == 0) {
      return new GrStatement[] {createAssignment(outputVars, callExpression, helper.getProject())};
    } else if (mustAdd.size() == outputVars.length && outputVars.length == 1) {
      return new GrVariableDeclaration[] {
        factory.createVariableDeclaration(
            ArrayUtil.EMPTY_STRING_ARRAY,
            callExpression,
            outputVars[0].getType(),
            outputVars[0].getName())
      };
    } else if (varsAreEqual(mustAdd, outputVars)) {
      return createTupleDeclaration(outputVars, callExpression, helper.getProject());
    } else {
      final List<GrStatement> result = generateVarDeclarations(mustAdd, helper.getProject(), null);
      result.add(createAssignment(outputVars, callExpression, helper.getProject()));
      return result.toArray(new GrStatement[result.size()]);
    }
  }
    public void visitMethodCallExpression(GrMethodCallExpression methodCall) {
      final GrExpression invokedExpression = methodCall.getInvokedExpression();
      if (myExpression.equals(invokedExpression)) {
        myResult =
            new TypeConstraint[] {
              SubtypeConstraint.create(GroovyCommonClassNames.GROOVY_LANG_CLOSURE, methodCall)
            };
        return;
      }

      final GrClosableBlock[] closureArgs = methodCall.getClosureArguments();
      //noinspection SuspiciousMethodCalls
      final int closureIndex = Arrays.asList(closureArgs).indexOf(myExpression);
      if (closureIndex >= 0) {
        List<TypeConstraint> constraints = new ArrayList<TypeConstraint>();
        for (GroovyResolveResult variant : ResolveUtil.getCallVariants(myExpression)) {
          final GrArgumentList argumentList = methodCall.getArgumentList();
          final GrNamedArgument[] namedArgs =
              argumentList == null ? GrNamedArgument.EMPTY_ARRAY : argumentList.getNamedArguments();
          final GrExpression[] expressionArgs =
              argumentList == null
                  ? GrExpression.EMPTY_ARRAY
                  : argumentList.getExpressionArguments();
          try {
            final Map<GrExpression, Pair<PsiParameter, PsiType>> map =
                GrClosureSignatureUtil.mapArgumentsToParameters(
                    variant, methodCall, true, true, namedArgs, expressionArgs, closureArgs);
            addConstraintsFromMap(constraints, map);
          } catch (RuntimeException e) {
            LOG.error(
                "call: " + methodCall.getText() + "\nsymbol: " + variant.getElement().getText(), e);
          }
        }
        if (!constraints.isEmpty()) {
          myResult = constraints.toArray(new TypeConstraint[constraints.size()]);
        }
      }
    }
  public static void processChangedMethodCall(
      PsiElement element, GrIntroduceParameterSettings settings, Project project) {
    if (!(element.getParent() instanceof GrMethodCallExpression)) {
      LOG.error(element.getParent());
      return;
    }

    GrMethodCallExpression methodCall = (GrMethodCallExpression) element.getParent();

    GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project);
    final String name = settings.getName();
    LOG.assertTrue(name != null);
    GrExpression expression = factory.createExpressionFromText(name, null);
    final GrArgumentList argList = methodCall.getArgumentList();
    final PsiElement[] exprs = argList.getAllArguments();

    if (exprs.length > 0) {
      argList.addAfter(expression, exprs[exprs.length - 1]);
    } else {
      argList.add(expression);
    }

    removeParametersFromCall(methodCall, settings);
  }
 private static GrStatement createAssignment(
     VariableInfo[] infos, GrMethodCallExpression callExpression, final Project project) {
   StringBuilder text = new StringBuilder();
   if (infos.length > 1) text.append('(');
   for (VariableInfo info : infos) {
     text.append(info.getName()).append(", ");
   }
   if (infos.length > 1) {
     text.replace(text.length() - 2, text.length(), ") =");
   } else {
     text.replace(text.length() - 2, text.length(), " = ");
   }
   text.append(callExpression.getText());
   return GroovyPsiElementFactory.getInstance(project).createExpressionFromText(text.toString());
 }
  private static GrStatement[] createTupleDeclaration(
      final VariableInfo[] infos, GrMethodCallExpression callExpression, final Project project) {
    GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project);

    StringBuilder tuple = new StringBuilder();
    tuple.append("def (");
    for (VariableInfo info : infos) {
      final PsiType type = info.getType();
      if (type != null) {
        final PsiType unboxed = TypesUtil.unboxPrimitiveTypeWrapper(type);
        tuple.append(unboxed.getCanonicalText());
        tuple.append(' ');
      }
      tuple.append(info.getName());
      tuple.append(",");
    }
    StringUtil.trimEnd(tuple, ",");
    tuple.append(")=");
    tuple.append(callExpression.getText());

    return new GrStatement[] {factory.createStatementFromText(tuple)};
  }