private static boolean isGetterInvocation(@NotNull GrMethodCall call) {
    GrExpression expr = call.getInvokedExpression();
    if (!(expr instanceof GrReferenceExpression)) return false;

    PsiMethod method = call.resolveMethod();
    if (!GroovyPropertyUtils.isSimplePropertyGetter(method)) return false;
    LOG.assertTrue(method != null);
    if (!GroovyNamesUtil.isValidReference(
        GroovyPropertyUtils.getPropertyNameByGetterName(method.getName(), true),
        ((GrReferenceExpression) expr).getQualifier() != null,
        call.getProject())) {
      return false;
    }

    GrArgumentList args = call.getArgumentList();
    if (args == null || args.getAllArguments().length != 0) {
      return false;
    }

    GrExpression ref = genRefForGetter(call, ((GrReferenceExpression) expr).getReferenceName());
    if (ref instanceof GrReferenceExpression) {
      PsiElement resolved = ((GrReferenceExpression) ref).resolve();
      PsiManager manager = call.getManager();
      if (manager.areElementsEquivalent(resolved, method)
          || areEquivalentAccessors(method, resolved, manager)) {
        return true;
      }
    }

    return false;
  }
  private static boolean isQualifiedStaticMethodWithUnnecessaryQualifier(
      GrReferenceExpression ref) {
    if (ref.getQualifier() == null) return false;

    final PsiElement resolved = ref.resolve();
    if (!(resolved instanceof PsiMember)) return false;
    if (!((PsiMember) resolved).hasModifierProperty(PsiModifier.STATIC)) return false;

    PsiElement copyResolved;
    final PsiElement parent = ref.getParent();
    if (parent instanceof GrMethodCall) {
      final GrMethodCall copy = (GrMethodCall) parent.copy();
      GrReferenceExpression invoked = (GrReferenceExpression) copy.getInvokedExpression();
      assert invoked != null;

      invoked.setQualifier(null);

      copyResolved = ((GrReferenceExpression) copy.getInvokedExpression()).resolve();
    } else {
      final GrReferenceExpression copy = (GrReferenceExpression) ref.copy();
      copy.setQualifier(null);
      copyResolved = copy.resolve();
    }
    return ref.getManager().areElementsEquivalent(copyResolved, resolved);
  }
  private static GrExpression genRefForGetter(GrMethodCall call, String accessorName) {
    String name = GroovyPropertyUtils.getPropertyNameByGetterName(accessorName, true);
    GrReferenceExpression refExpr = (GrReferenceExpression) call.getInvokedExpression();
    String oldNameStr = refExpr.getReferenceNameElement().getText();
    String newRefExpr = StringUtil.trimEnd(refExpr.getText(), oldNameStr) + name;

    final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(call.getProject());
    return factory.createExpressionFromText(newRefExpr, call);
  }
 public static void fixJavaStyleProperty(GrMethodCall call) {
   GrExpression invoked = call.getInvokedExpression();
   String accessorName = ((GrReferenceExpression) invoked).getReferenceName();
   if (isGetterInvocation(call) && invoked instanceof GrReferenceExpression) {
     final GrExpression newCall = genRefForGetter(call, accessorName);
     call.replaceWithExpression(newCall, true);
   } else if (isSetterInvocation(call) && invoked instanceof GrReferenceExpression) {
     final GrStatement newCall = genRefForSetter(call, accessorName);
     if (newCall != null) {
       call.replaceWithStatement(newCall);
     }
   }
 }
  @Nullable
  private static GrAssignmentExpression genRefForSetter(GrMethodCall call, String accessorName) {
    String name = GroovyPropertyUtils.getPropertyNameBySetterName(accessorName);
    if (name == null) return null;
    GrExpression value = call.getExpressionArguments()[0];
    GrReferenceExpression refExpr = (GrReferenceExpression) call.getInvokedExpression();

    final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(call.getProject());
    final GrAssignmentExpression assignment =
        (GrAssignmentExpression) factory.createStatementFromText("yyy = xxx", call);

    GrReferenceExpression lvalueRef = (GrReferenceExpression) assignment.getLValue();
    lvalueRef.setQualifier(refExpr.getQualifier());
    lvalueRef.handleElementRenameSimple(name);
    assignment.getRValue().replaceWithExpression(value, true);

    return assignment;
  }
  private static boolean isSetterInvocation(GrMethodCall call) {
    GrExpression expr = call.getInvokedExpression();

    if (!(expr instanceof GrReferenceExpression)) return false;
    GrReferenceExpression refExpr = (GrReferenceExpression) expr;

    PsiMethod method;
    if (call instanceof GrApplicationStatement) {
      PsiElement element = refExpr.resolve();
      if (!(element instanceof PsiMethod)
          || !GroovyPropertyUtils.isSimplePropertySetter(((PsiMethod) element))) return false;
      method = (PsiMethod) element;
    } else {
      method = call.resolveMethod();
      if (!GroovyPropertyUtils.isSimplePropertySetter(method)) return false;
      LOG.assertTrue(method != null);
    }

    if (!GroovyNamesUtil.isValidReference(
        GroovyPropertyUtils.getPropertyNameBySetterName(method.getName()),
        ((GrReferenceExpression) expr).getQualifier() != null,
        call.getProject())) {
      return false;
    }

    GrArgumentList args = call.getArgumentList();
    if (args == null
        || args.getExpressionArguments().length != 1
        || PsiImplUtil.hasNamedArguments(args)) {
      return false;
    }

    GrAssignmentExpression assignment = genRefForSetter(call, refExpr.getReferenceName());
    if (assignment != null) {
      GrExpression value = assignment.getLValue();
      if (value instanceof GrReferenceExpression
          && call.getManager()
              .areElementsEquivalent(((GrReferenceExpression) value).resolve(), method)) {
        return true;
      }
    }

    return false;
  }
 private static boolean methodCallExpressionsAreEquivalent(
     @NotNull GrMethodCall methodExp1, @NotNull GrMethodCall methodExp2) {
   final GrExpression methodExpression1 = methodExp1.getInvokedExpression();
   final GrExpression methodExpression2 = methodExp2.getInvokedExpression();
   if (!expressionsAreEquivalent(methodExpression1, methodExpression2)) {
     return false;
   }
   final GrArgumentList argumentList1 = methodExp1.getArgumentList();
   if (argumentList1 == null) {
     return false;
   }
   final GrArgumentList argumentList2 = methodExp2.getArgumentList();
   if (argumentList2 == null) {
     return false;
   }
   final GrExpression[] args1 = argumentList1.getExpressionArguments();
   final GrExpression[] args2 = argumentList2.getExpressionArguments();
   if (!expressionListsAreEquivalent(args1, args2)) {
     return false;
   }
   final GrNamedArgument[] namedArgs1 = argumentList1.getNamedArguments();
   final GrNamedArgument[] namedArgs2 = argumentList2.getNamedArguments();
   if (!namedArgumentListsAreEquivalent(namedArgs1, namedArgs2)) {
     return false;
   }
   final GrClosableBlock[] closures1 = methodExp1.getClosureArguments();
   final GrClosableBlock[] closures2 = methodExp2.getClosureArguments();
   return expressionListsAreEquivalent(closures1, closures2);
 }
  @NotNull
  private Collection<? extends MavenRemoteRepository> findMavenRemoteRepositories(
      @Nullable GrClosableBlock repositoriesBlock) {
    Set<MavenRemoteRepository> myRemoteRepositories = ContainerUtil.newHashSet();
    for (GrMethodCall repo :
        PsiTreeUtil.getChildrenOfTypeAsList(repositoriesBlock, GrMethodCall.class)) {

      final String expressionText = repo.getInvokedExpression().getText();
      if ("mavenCentral".equals(expressionText)) {
        myRemoteRepositories.add(mavenCentralRemoteRepository);
      } else if ("mavenRepo".equals(expressionText)) {
        for (GrNamedArgument namedArgument : repo.getNamedArguments()) {
          if ("url".equals(namedArgument.getLabelName())) {
            URI urlArgumentValue = resolveUriFromSimpleExpression(namedArgument.getExpression());
            if (urlArgumentValue != null) {
              String textUri = urlArgumentValue.toString();
              myRemoteRepositories.add(
                  new MavenRemoteRepository(textUri, null, textUri, null, null, null));
            }
            break;
          }
        }
      } else if ("maven".equals(expressionText) && repo.getClosureArguments().length > 0) {
        List<GrApplicationStatement> applicationStatementList =
            PsiTreeUtil.getChildrenOfTypeAsList(
                repo.getClosureArguments()[0], GrApplicationStatement.class);
        if (!applicationStatementList.isEmpty()) {
          GrApplicationStatement statement = applicationStatementList.get(0);
          if (statement == null) continue;
          GrExpression expression = statement.getInvokedExpression();

          if ("url".equals(expression.getText())) {
            URI urlArgumentValue =
                resolveUriFromSimpleExpression(statement.getExpressionArguments()[0]);
            if (urlArgumentValue != null) {
              String textUri = urlArgumentValue.toString();
              myRemoteRepositories.add(
                  new MavenRemoteRepository(textUri, null, textUri, null, null, null));
            }
          }
        }

        List<GrAssignmentExpression> assignmentExpressionList =
            PsiTreeUtil.getChildrenOfTypeAsList(
                repo.getClosureArguments()[0], GrAssignmentExpression.class);
        if (!assignmentExpressionList.isEmpty()) {
          GrAssignmentExpression statement = assignmentExpressionList.get(0);
          if (statement == null) continue;
          GrExpression expression = statement.getLValue();

          if ("url".equals(expression.getText())) {
            URI urlArgumentValue = resolveUriFromSimpleExpression(statement.getRValue());
            if (urlArgumentValue != null) {
              String textUri = urlArgumentValue.toString();
              myRemoteRepositories.add(
                  new MavenRemoteRepository(textUri, null, textUri, null, null, null));
            }
          }
        }
      }
    }

    return myRemoteRepositories;
  }
  @Nullable
  public static GrExpression replaceExpression(
      GrExpression oldExpr, GrExpression newExpr, boolean removeUnnecessaryParentheses) {
    PsiElement oldParent = oldExpr.getParent();
    if (oldParent == null) throw new PsiInvalidElementAccessException(oldExpr);

    if (!(oldExpr instanceof GrApplicationStatement)) {
      newExpr = ApplicationStatementUtil.convertToMethodCallExpression(newExpr);
    }

    // Remove unnecessary parentheses
    if (removeUnnecessaryParentheses
        && oldParent instanceof GrParenthesizedExpression
        && !(oldParent.getParent() instanceof GrArgumentLabel)) {
      return ((GrExpression) oldParent)
          .replaceWithExpression(newExpr, removeUnnecessaryParentheses);
    }

    // regexes cannot be after identifier , try to replace it with simple string
    if (getRegexAtTheBeginning(newExpr) != null && isAfterIdentifier(oldExpr)) {
      final PsiElement copy = newExpr.copy();
      final GrLiteral regex = getRegexAtTheBeginning(copy);
      LOG.assertTrue(regex != null);
      final GrLiteral stringLiteral = GrStringUtil.createStringFromRegex(regex);
      if (regex == copy) {
        return oldExpr.replaceWithExpression(stringLiteral, removeUnnecessaryParentheses);
      } else {
        regex.replace(stringLiteral);
        return oldExpr.replaceWithExpression((GrExpression) copy, removeUnnecessaryParentheses);
      }
    }

    GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(oldExpr.getProject());
    if (oldParent instanceof GrStringInjection) {
      if (newExpr instanceof GrString
          || newExpr instanceof GrLiteral && ((GrLiteral) newExpr).getValue() instanceof String) {
        return GrStringUtil.replaceStringInjectionByLiteral(
            (GrStringInjection) oldParent, (GrLiteral) newExpr);
      } else {
        newExpr = factory.createExpressionFromText("{" + newExpr.getText() + "}");
        oldParent.getNode().replaceChild(oldExpr.getNode(), newExpr.getNode());
        return newExpr;
      }
    }

    if (PsiTreeUtil.getParentOfType(oldExpr, GrStringInjection.class, false, GrCodeBlock.class)
        != null) {
      final PsiElement replaced = oldExpr.replace(newExpr);
      final GrStringInjection stringInjection =
          PsiTreeUtil.getParentOfType(replaced, GrStringInjection.class);
      GrStringUtil.wrapInjection(stringInjection);
      assert stringInjection != null;
      return stringInjection.getClosableBlock();
    }

    // check priorities
    if (oldParent instanceof GrExpression && !(oldParent instanceof GrParenthesizedExpression)) {
      GrExpression addedParenth =
          addParenthesesIfNeeded(newExpr, oldExpr, (GrExpression) oldParent);
      if (newExpr != addedParenth) {
        return oldExpr.replaceWithExpression(addedParenth, removeUnnecessaryParentheses);
      }
    }

    // if replace closure argument with expression
    // we should add the expression in arg list
    if (oldExpr instanceof GrClosableBlock
        && !(newExpr instanceof GrClosableBlock)
        && oldParent instanceof GrMethodCallExpression
        && ArrayUtil.contains(
            oldExpr, ((GrMethodCallExpression) oldParent).getClosureArguments())) {
      return ((GrMethodCallExpression) oldParent)
          .replaceClosureArgument((GrClosableBlock) oldExpr, newExpr);
    }

    newExpr = (GrExpression) oldExpr.replace(newExpr);

    // if newExpr is the first grand child of command argument list we should replace command arg
    // list with parenthesised arg list.
    // In other case the code will be broken. So we try to find wrapping command arg list counting
    // levels. After arg list replace we go inside it
    // to find target parenthesised expression.
    if (newExpr instanceof GrParenthesizedExpression && isFirstChild(newExpr)) {
      int parentCount = 0;

      PsiElement element = oldParent;
      while (element != null && !(element instanceof GrCommandArgumentList)) {
        if (element instanceof GrCodeBlock || element instanceof GrParenthesizedExpression) break;
        if (element instanceof PsiFile) break;

        final PsiElement parent = element.getParent();
        if (parent == null) break;
        if (!isFirstChild(element)) break;

        element = parent;
        parentCount++;
      }

      if (element instanceof GrCommandArgumentList) {
        final GrCommandArgumentList commandArgList = (GrCommandArgumentList) element;

        final PsiElement parent = commandArgList.getParent();
        LOG.assertTrue(parent instanceof GrApplicationStatement);

        final GrMethodCall methodCall =
            factory.createMethodCallByAppCall((GrApplicationStatement) parent);
        final GrMethodCall newCall = (GrMethodCall) parent.replace(methodCall);

        PsiElement result = newCall.getArgumentList().getAllArguments()[0];

        for (int i = 0; i < parentCount; i++) {
          result = PsiUtil.skipWhitespacesAndComments(result.getFirstChild(), true);
        }

        LOG.assertTrue(result instanceof GrParenthesizedExpression);
        return (GrExpression) result;
      }
    }
    return newExpr;
  }
 private static boolean isInvokedOnMap(GrMethodCall call) {
   GrExpression expr = call.getInvokedExpression();
   return expr instanceof GrReferenceExpression
       && ResolveUtil.isKeyOfMap((GrReferenceExpression) expr);
 }