static PsiElement[] getOccurrences(GrIntroduceParameterSettings settings) {
    final GrParametersOwner scope = settings.getToReplaceIn();

    final GrExpression expression = settings.getExpression();
    if (expression != null) {
      final PsiElement expr = PsiUtil.skipParentheses(expression, false);
      if (expr == null) return PsiElement.EMPTY_ARRAY;

      final PsiElement[] occurrences = GroovyRefactoringUtil.getExpressionOccurrences(expr, scope);
      if (occurrences == null || occurrences.length == 0) {
        throw new GrRefactoringError(GroovyRefactoringBundle.message("no.occurrences.found"));
      }
      return occurrences;
    } else {
      final GrVariable var = settings.getVar();
      LOG.assertTrue(var != null);
      final List<PsiElement> list = Collections.synchronizedList(new ArrayList<PsiElement>());
      ReferencesSearch.search(var, new LocalSearchScope(scope))
          .forEach(
              new Processor<PsiReference>() {
                @Override
                public boolean process(PsiReference psiReference) {
                  final PsiElement element = psiReference.getElement();
                  if (element != null) {
                    list.add(element);
                  }
                  return true;
                }
              });
      return list.toArray(new PsiElement[list.size()]);
    }
  }
  @Nullable
  public static PsiType inferExpectedTypeForDiamond(GrExpression diamondNew) {
    PsiElement skipped = PsiUtil.skipParentheses(diamondNew, true);
    assert skipped != null;
    PsiElement pparent = skipped.getParent();
    if (pparent instanceof GrAssignmentExpression
        && PsiTreeUtil.isAncestor(
            ((GrAssignmentExpression) pparent).getRValue(), diamondNew, false)) {
      GrExpression lValue = ((GrAssignmentExpression) pparent).getLValue();
      if (PsiUtil.mightBeLValue(lValue)) {
        return lValue.getNominalType();
      }
    } else if (pparent instanceof GrVariable
        && ((GrVariable) pparent).getInitializerGroovy() == diamondNew) {
      return ((GrVariable) pparent).getDeclaredType();
    } else if (pparent instanceof GrListOrMap) {
      PsiElement ppparent = PsiUtil.skipParentheses(pparent.getParent(), true);

      if (ppparent instanceof GrAssignmentExpression
          && PsiTreeUtil.isAncestor(
              ((GrAssignmentExpression) ppparent).getRValue(), pparent, false)) {

        PsiElement lValue =
            PsiUtil.skipParentheses(((GrAssignmentExpression) ppparent).getLValue(), false);
        if (lValue instanceof GrTupleExpression) {
          GrExpression[] initializers = ((GrListOrMap) pparent).getInitializers();
          int index = ArrayUtil.find(initializers, diamondNew);
          GrExpression[] expressions = ((GrTupleExpression) lValue).getExpressions();
          if (index < expressions.length) {
            return expressions[index].getNominalType();
          }
        }
      }
    }

    return null;
  }
  public static void generateBody(
      ExtractInfoHelper helper, boolean isVoid, StringBuilder buffer, boolean forceReturn) {
    VariableInfo[] outputInfos = helper.getOutputVariableInfos();

    ParameterInfo[] infos = helper.getParameterInfos();

    Set<String> declaredVars = new HashSet<String>();
    for (ParameterInfo info : infos) {
      declaredVars.add(info.getName());
    }

    for (VariableInfo info : mustAddVariableDeclaration(helper.getStatements(), outputInfos)) {
      declaredVars.add(info.getName());
    }

    List<VariableInfo> genDecl = new ArrayList<VariableInfo>();
    final Collection<GrVariable> outside =
        collectUsedLocalVarsOrParamsDeclaredOutside(helper.getStatements());

    for (final GrVariable variable : outside) {
      if (!declaredVars.contains(variable.getName())) {
        genDecl.add(
            new VariableInfo() {
              @NotNull
              @Override
              public String getName() {
                return variable.getName();
              }

              @Override
              public PsiType getType() {
                return variable.getDeclaredType();
              }
            });
      }
    }
    final List<GrStatement> statements =
        generateVarDeclarations(genDecl, helper.getProject(), null);
    for (GrStatement statement : statements) {
      buffer.append(statement.getText()).append('\n');
    }

    if (!isSingleExpression(helper.getStatements()) || statements.size() > 0) {
      for (PsiElement element : helper.getInnerElements()) {
        buffer.append(element.getText());
      }
      // append return statement
      if (!isVoid && outputInfos.length > 0) {
        buffer.append('\n');
        if (forceReturn) {
          buffer.append("return ");
        }
        if (outputInfos.length > 1) buffer.append('[');
        for (VariableInfo info : outputInfos) {
          buffer.append(info.getName()).append(", ");
        }
        buffer.delete(buffer.length() - 2, buffer.length());
        if (outputInfos.length > 1) buffer.append(']');
      }
    } else {
      GrExpression expr = (GrExpression) PsiUtil.skipParentheses(helper.getStatements()[0], false);
      boolean addReturn = !isVoid && forceReturn;
      if (addReturn) {
        buffer.append("return ");
        expr = ApplicationStatementUtil.convertToMethodCallExpression(expr);
        buffer.append(expr.getText());
      } else {
        buffer.append(expr != null ? expr.getText() : "");
      }
    }
  }
 @SuppressWarnings({"ConstantConditions"})
 public static boolean expressionsAreEquivalent(
     @Nullable GrExpression exp1, @Nullable GrExpression exp2) {
   if (exp1 == null && exp2 == null) {
     return true;
   }
   if (exp1 == null || exp2 == null) {
     return false;
   }
   GrExpression expToCompare1 = (GrExpression) PsiUtil.skipParentheses(exp1, false);
   GrExpression expToCompare2 = (GrExpression) PsiUtil.skipParentheses(exp2, false);
   final int type1 = getExpressionType(expToCompare1);
   final int type2 = getExpressionType(expToCompare2);
   if (type1 != type2) {
     return false;
   }
   switch (type1) {
     case THIS_EXPRESSION:
     case SUPER_EXPRESSION:
       return true;
     case LITERAL_EXPRESSION:
     case REFERENCE_EXPRESSION:
       final String text1 = expToCompare1.getText();
       final String text2 = expToCompare2.getText();
       return text1.equals(text2);
     case CALL_EXPRESSION:
       return methodCallExpressionsAreEquivalent(
           (GrMethodCall) expToCompare1, (GrMethodCall) expToCompare2);
     case NEW_EXPRESSION:
       return newExpressionsAreEquivalent(
           (GrNewExpression) expToCompare1, (GrNewExpression) expToCompare2);
     case ARRAY_LITERAL_EXPRESSION:
       return arrayDeclarationsAreEquivalent(
           (GrArrayDeclaration) expToCompare1, (GrArrayDeclaration) expToCompare2);
     case PREFIX_EXPRESSION:
       return prefixExpressionsAreEquivalent(
           (GrUnaryExpression) expToCompare1, (GrUnaryExpression) expToCompare2);
     case POSTFIX_EXPRESSION:
       return postfixExpressionsAreEquivalent(
           (GrUnaryExpression) expToCompare1, (GrUnaryExpression) expToCompare2);
     case BINARY_EXPRESSION:
       return binaryExpressionsAreEquivalent(
           (GrBinaryExpression) expToCompare1, (GrBinaryExpression) expToCompare2);
     case ASSIGNMENT_EXPRESSION:
       return assignmentExpressionsAreEquivalent(
           (GrAssignmentExpression) expToCompare1, (GrAssignmentExpression) expToCompare2);
     case CONDITIONAL_EXPRESSION:
       return conditionalExpressionsAreEquivalent(
           (GrConditionalExpression) expToCompare1, (GrConditionalExpression) expToCompare2);
     case ELVIS_EXPRESSION:
       return elvisExpressionsAreEquivalent(
           (GrElvisExpression) expToCompare1, (GrElvisExpression) expToCompare2);
     case RANGE_EXPRESSION:
       return rangeExpressionsAreEquivalent(
           (GrRangeExpression) expToCompare1, (GrRangeExpression) expToCompare2);
     case TYPE_CAST_EXPRESSION:
       return typecastExpressionsAreEquivalent(
           (GrTypeCastExpression) expToCompare1, (GrTypeCastExpression) expToCompare2);
     case SAFE_CAST_EXPRESSION:
       return safecastExpressionsAreEquivalent(
           (GrSafeCastExpression) expToCompare1, (GrSafeCastExpression) expToCompare2);
     case INSTANCEOF_EXPRESSION:
       return instanceofExpressionsAreEquivalent(
           (GrInstanceOfExpression) expToCompare1, (GrInstanceOfExpression) expToCompare2);
     case INDEX_EXPRESSION:
       return indexExpressionsAreEquivalent(
           (GrIndexProperty) expToCompare1, (GrIndexProperty) expToCompare2);
     case LIST_OR_MAP_EXPRESSION:
       return listOrMapExpressionsAreEquivalent(
           (GrListOrMap) expToCompare1, (GrListOrMap) expToCompare2);
     case CLOSABLE_BLOCK_EXPRESSION:
       return closableBlockExpressionsAreEquivalent(
           (GrClosableBlock) expToCompare1, (GrClosableBlock) expToCompare2);
     case PROPERTY_SELECTION_EXPRESSION:
       return textOfExpressionsIsEquivalent(expToCompare1, expToCompare2); // todo
     default:
       return false;
   }
 }
 public MyCalculator(GrExpression expression) {
   myExpression = (GrExpression) PsiUtil.skipParentheses(expression, true);
   myResult = TypeConstraint.EMPTY_ARRAY;
 }