public static PsiExpression findDefinition(
     @NotNull PsiReferenceExpression referenceExpression, @Nullable PsiVariable variable) {
   if (variable == null) {
     final PsiElement target = referenceExpression.resolve();
     if (!(target instanceof PsiVariable)) {
       return null;
     }
     variable = (PsiVariable) target;
   }
   final PsiCodeBlock block = PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class);
   if (block == null) {
     return null;
   }
   final PsiElement[] defs = DefUseUtil.getDefs(block, variable, referenceExpression);
   if (defs.length != 1) {
     return null;
   }
   final PsiElement def = defs[0];
   if (def instanceof PsiVariable) {
     final PsiVariable target = (PsiVariable) def;
     final PsiExpression initializer = target.getInitializer();
     return ParenthesesUtils.stripParentheses(initializer);
   } else if (def instanceof PsiReferenceExpression) {
     final PsiElement parent = def.getParent();
     if (!(parent instanceof PsiAssignmentExpression)) {
       return null;
     }
     final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression) parent;
     if (assignmentExpression.getOperationTokenType() != JavaTokenType.EQ) {
       return null;
     }
     return ParenthesesUtils.stripParentheses(assignmentExpression.getRExpression());
   }
   return null;
 }
    private boolean isListGetLookup(PsiElement element,
                                    String indexName,
                                    PsiVariable listVariable) {
      if (!(element instanceof PsiExpression)) {
        return false;
      }
      final PsiExpression expression = (PsiExpression)element;
      if (!expressionIsListGetLookup(expression)) {
        return false;
      }
      final PsiMethodCallExpression methodCallExpression =
        (PsiMethodCallExpression)
          ParenthesesUtils.stripParentheses(expression);
      if (methodCallExpression == null) {
        return false;
      }
      final PsiReferenceExpression methodExpression =
        methodCallExpression.getMethodExpression();
      final PsiExpression qualifierExpression =
        methodExpression.getQualifierExpression();

      final PsiExpressionList argumentList =
        methodCallExpression.getArgumentList();
      final PsiExpression[] expressions = argumentList.getExpressions();
      if (expressions.length != 1) {
        return false;
      }
      if (!indexName.equals(expressions[0].getText())) {
        return false;
      }
      if (qualifierExpression == null ||
          qualifierExpression instanceof PsiThisExpression ||
          qualifierExpression instanceof PsiSuperExpression) {
        return listVariable == null;
      }
      if (!(qualifierExpression instanceof PsiReferenceExpression)) {
        return false;
      }
      final PsiReferenceExpression referenceExpression =
        (PsiReferenceExpression)qualifierExpression;
      final PsiExpression qualifier =
        referenceExpression.getQualifierExpression();
      if (qualifier != null && !(qualifier instanceof PsiThisExpression) &&
          !(qualifier instanceof PsiSuperExpression)) {
        return false;
      }
      final PsiElement target = referenceExpression.resolve();
      return listVariable.equals(target);
    }
 @Override
 public void doFix(Project project, ProblemDescriptor descriptor) {
   final PsiExpression expression = (PsiExpression) descriptor.getPsiElement();
   final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, false);
   if (expectedType == null) {
     return;
   }
   final String expectedTypeText = expectedType.getCanonicalText();
   final String classToConstruct;
   if (s_boxingClasses.containsValue(expectedTypeText)) {
     classToConstruct = expectedTypeText;
   } else {
     final PsiType type = expression.getType();
     if (type == null) {
       return;
     }
     final String expressionTypeText = type.getCanonicalText();
     classToConstruct = s_boxingClasses.get(expressionTypeText);
   }
   if (shortcutReplace(expression, classToConstruct)) {
     return;
   }
   final PsiExpression strippedExpression = ParenthesesUtils.stripParentheses(expression);
   if (strippedExpression == null) {
     return;
   }
   @NonNls final String expressionText = strippedExpression.getText();
   @NonNls final String newExpression;
   if ("true".equals(expressionText)) {
     newExpression = "java.lang.Boolean.TRUE";
   } else if ("false".equals(expressionText)) {
     newExpression = "java.lang.Boolean.FALSE";
   } else {
     newExpression = classToConstruct + ".valueOf(" + expressionText + ')';
   }
   replaceExpression(expression, newExpression);
 }
 public static boolean expressionsAreEquivalent(
     @Nullable PsiExpression expression1, @Nullable PsiExpression expression2) {
   expression1 = ParenthesesUtils.stripParentheses(expression1);
   expression2 = ParenthesesUtils.stripParentheses(expression2);
   if (expression1 == null) {
     return expression2 == null;
   } else if (expression2 == null) {
     return false;
   }
   if (expression1.getClass() != expression2.getClass()) {
     return false;
   }
   if (expression1 instanceof PsiThisExpression) {
     return true;
   } else if (expression1 instanceof PsiSuperExpression) {
     return true;
   } else if (expression1 instanceof PsiLiteralExpression) {
     return literalExpressionsAreEquivalent(
         (PsiLiteralExpression) expression1, (PsiLiteralExpression) expression2);
   } else if (expression1 instanceof PsiClassObjectAccessExpression) {
     return classObjectAccessExpressionsAreEquivalent(
         (PsiClassObjectAccessExpression) expression1,
         (PsiClassObjectAccessExpression) expression2);
   } else if (expression1 instanceof PsiReferenceExpression) {
     return referenceExpressionsAreEquivalent(
         (PsiReferenceExpression) expression1, (PsiReferenceExpression) expression2);
   } else if (expression1 instanceof PsiMethodCallExpression) {
     return methodCallExpressionsAreEquivalent(
         (PsiMethodCallExpression) expression1, (PsiMethodCallExpression) expression2);
   } else if (expression1 instanceof PsiNewExpression) {
     return newExpressionsAreEquivalent(
         (PsiNewExpression) expression1, (PsiNewExpression) expression2);
   } else if (expression1 instanceof PsiArrayInitializerExpression) {
     return arrayInitializerExpressionsAreEquivalent(
         (PsiArrayInitializerExpression) expression1, (PsiArrayInitializerExpression) expression2);
   } else if (expression1 instanceof PsiTypeCastExpression) {
     return typeCastExpressionsAreEquivalent(
         (PsiTypeCastExpression) expression1, (PsiTypeCastExpression) expression2);
   } else if (expression1 instanceof PsiArrayAccessExpression) {
     return arrayAccessExpressionsAreEquivalent(
         (PsiArrayAccessExpression) expression2, (PsiArrayAccessExpression) expression1);
   } else if (expression1 instanceof PsiPrefixExpression) {
     return prefixExpressionsAreEquivalent(
         (PsiPrefixExpression) expression1, (PsiPrefixExpression) expression2);
   } else if (expression1 instanceof PsiPostfixExpression) {
     return postfixExpressionsAreEquivalent(
         (PsiPostfixExpression) expression1, (PsiPostfixExpression) expression2);
   } else if (expression1 instanceof PsiPolyadicExpression) {
     return polyadicExpressionsAreEquivalent(
         (PsiPolyadicExpression) expression1, (PsiPolyadicExpression) expression2);
   } else if (expression1 instanceof PsiAssignmentExpression) {
     return assignmentExpressionsAreEquivalent(
         (PsiAssignmentExpression) expression1, (PsiAssignmentExpression) expression2);
   } else if (expression1 instanceof PsiConditionalExpression) {
     return conditionalExpressionsAreEquivalent(
         (PsiConditionalExpression) expression1, (PsiConditionalExpression) expression2);
   } else if (expression1 instanceof PsiInstanceOfExpression) {
     return instanceofExpressionsAreEquivalent(
         (PsiInstanceOfExpression) expression1, (PsiInstanceOfExpression) expression2);
   }
   return false;
 }
 @Nullable
 private String createArrayIterationText(@NotNull PsiForStatement forStatement) {
   final PsiExpression condition = forStatement.getCondition();
   final PsiBinaryExpression strippedCondition = (PsiBinaryExpression)ParenthesesUtils.stripParentheses(condition);
   if (strippedCondition == null) {
     return null;
   }
   final PsiExpression lhs = ParenthesesUtils.stripParentheses(strippedCondition.getLOperand());
   if (lhs == null) {
     return null;
   }
   final PsiExpression rhs = ParenthesesUtils.stripParentheses(strippedCondition.getROperand());
   if (rhs == null) {
     return null;
   }
   final IElementType tokenType = strippedCondition.getOperationTokenType();
   final PsiReferenceExpression arrayLengthExpression;
   final String indexName;
   if (tokenType.equals(JavaTokenType.LT)) {
     arrayLengthExpression = (PsiReferenceExpression)ParenthesesUtils.stripParentheses(rhs);
     indexName = lhs.getText();
   }
   else if (tokenType.equals(JavaTokenType.GT)) {
     arrayLengthExpression = (PsiReferenceExpression)ParenthesesUtils.stripParentheses(lhs);
     indexName = rhs.getText();
   }
   else {
     return null;
   }
   if (arrayLengthExpression == null) {
     return null;
   }
   PsiReferenceExpression arrayReference = (PsiReferenceExpression)arrayLengthExpression.getQualifierExpression();
   if (arrayReference == null) {
     final PsiElement target = arrayLengthExpression.resolve();
     if (!(target instanceof PsiVariable)) {
       return null;
     }
     final PsiVariable variable = (PsiVariable)target;
     final PsiExpression initializer = variable.getInitializer();
     if (!(initializer instanceof PsiReferenceExpression)) {
       return null;
     }
     final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)initializer;
     arrayReference = (PsiReferenceExpression)referenceExpression.getQualifierExpression();
     if (arrayReference == null) {
       return null;
     }
   }
   final PsiArrayType arrayType = (PsiArrayType)arrayReference.getType();
   if (arrayType == null) {
     return null;
   }
   final PsiType componentType = arrayType.getComponentType();
   final String typeText = componentType.getCanonicalText();
   final PsiElement target = arrayReference.resolve();
   if (!(target instanceof PsiVariable)) {
     return null;
   }
   final PsiVariable arrayVariable = (PsiVariable)target;
   final PsiStatement body = forStatement.getBody();
   final PsiStatement firstStatement = getFirstStatement(body);
   final boolean isDeclaration = isArrayElementDeclaration(firstStatement, arrayVariable, indexName);
   final String contentVariableName;
   @NonNls final String finalString;
   final PsiStatement statementToSkip;
   if (isDeclaration) {
     final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)firstStatement;
     assert declarationStatement != null;
     final PsiElement[] declaredElements = declarationStatement.getDeclaredElements();
     final PsiElement declaredElement = declaredElements[0];
     if (!(declaredElement instanceof PsiVariable)) {
       return null;
     }
     final PsiVariable variable = (PsiVariable)declaredElement;
     if (VariableAccessUtils.variableIsAssigned(variable, forStatement)) {
       final String collectionName = arrayReference.getReferenceName();
       contentVariableName = createNewVariableName(forStatement, componentType, collectionName);
       final Project project = forStatement.getProject();
       final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
       if (codeStyleSettings.GENERATE_FINAL_LOCALS) {
         finalString = "final ";
       }
       else {
         finalString = "";
       }
       statementToSkip = null;
     }
     else {
       contentVariableName = variable.getName();
       statementToSkip = declarationStatement;
       if (variable.hasModifierProperty(PsiModifier.FINAL)) {
         finalString = "final ";
       }
       else {
         finalString = "";
       }
     }
   }
   else {
     final String collectionName = arrayReference.getReferenceName();
     contentVariableName = createNewVariableName(forStatement, componentType, collectionName);
     final Project project = forStatement.getProject();
     final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
     if (codeStyleSettings.GENERATE_FINAL_LOCALS) {
       finalString = "final ";
     }
     else {
       finalString = "";
     }
     statementToSkip = null;
   }
   @NonNls final StringBuilder out = new StringBuilder();
   out.append("for(");
   out.append(finalString);
   out.append(typeText);
   out.append(' ');
   out.append(contentVariableName);
   out.append(": ");
   final String arrayName = arrayReference.getText();
   out.append(arrayName);
   out.append(')');
   if (body != null) {
     replaceArrayAccess(body, contentVariableName, arrayVariable, indexName, statementToSkip, out);
   }
   return out.toString();
 }
 @Nullable
 private String createListIterationText(
   @NotNull PsiForStatement forStatement) {
   final PsiBinaryExpression condition =
     (PsiBinaryExpression)ParenthesesUtils.stripParentheses(
       forStatement.getCondition());
   if (condition == null) {
     return null;
   }
   final PsiExpression lhs = ParenthesesUtils.stripParentheses(condition.getLOperand());
   if (lhs == null) {
     return null;
   }
   final PsiExpression rhs = ParenthesesUtils.stripParentheses(condition.getROperand());
   if (rhs == null) {
     return null;
   }
   final IElementType tokenType = condition.getOperationTokenType();
   final String indexName;
   PsiExpression collectionSize;
   if (JavaTokenType.LT.equals(tokenType)) {
     indexName = lhs.getText();
     collectionSize = rhs;
   }
   else if (JavaTokenType.GT.equals(tokenType)) {
     indexName = rhs.getText();
     collectionSize = lhs;
   }
   else {
     return null;
   }
   if (collectionSize instanceof PsiReferenceExpression) {
     final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)collectionSize;
     final PsiElement target = referenceExpression.resolve();
     if (target instanceof PsiVariable) {
       final PsiVariable variable = (PsiVariable)target;
       collectionSize = ParenthesesUtils.stripParentheses(variable.getInitializer());
     }
   }
   if (!(collectionSize instanceof PsiMethodCallExpression)) {
     return null;
   }
   final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)ParenthesesUtils.stripParentheses(collectionSize);
   if (methodCallExpression == null) {
     return null;
   }
   final PsiReferenceExpression listLengthExpression = methodCallExpression.getMethodExpression();
   final PsiExpression qualifier = listLengthExpression.getQualifierExpression();
   final PsiReferenceExpression listReference;
   if (qualifier instanceof PsiReferenceExpression) {
     listReference = (PsiReferenceExpression)qualifier;
   }
   else {
     listReference = null;
   }
   PsiType parameterType;
   if (listReference == null) {
     parameterType = extractListTypeFromContainingClass(forStatement);
   }
   else {
     final PsiType type = listReference.getType();
     if (type == null) {
       return null;
     }
     parameterType = extractContentTypeFromType(type);
   }
   if (parameterType == null) {
     parameterType = TypeUtils.getObjectType(forStatement);
   }
   final String typeString = parameterType.getCanonicalText();
   final PsiVariable listVariable;
   if (listReference == null) {
     listVariable = null;
   }
   else {
     final PsiElement target = listReference.resolve();
     if (!(target instanceof PsiVariable)) {
       return null;
     }
     listVariable = (PsiVariable)target;
   }
   final PsiStatement body = forStatement.getBody();
   final PsiStatement firstStatement = getFirstStatement(body);
   final boolean isDeclaration = isListElementDeclaration(firstStatement, listVariable, indexName, parameterType);
   final String contentVariableName;
   @NonNls final String finalString;
   final PsiStatement statementToSkip;
   if (isDeclaration) {
     final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)firstStatement;
     assert declarationStatement != null;
     final PsiElement[] declaredElements = declarationStatement.getDeclaredElements();
     final PsiElement declaredElement = declaredElements[0];
     if (!(declaredElement instanceof PsiVariable)) {
       return null;
     }
     final PsiVariable variable = (PsiVariable)declaredElement;
     contentVariableName = variable.getName();
     statementToSkip = declarationStatement;
     if (variable.hasModifierProperty(PsiModifier.FINAL)) {
       finalString = "final ";
     }
     else {
       finalString = "";
     }
   }
   else {
     final String collectionName;
     if (listReference == null) {
       collectionName = null;
     }
     else {
       collectionName = listReference.getReferenceName();
     }
     contentVariableName = createNewVariableName(forStatement, parameterType, collectionName);
     finalString = "";
     statementToSkip = null;
   }
   @NonNls final StringBuilder out = new StringBuilder();
   out.append("for(");
   out.append(finalString);
   out.append(typeString);
   out.append(' ');
   out.append(contentVariableName);
   out.append(": ");
   @NonNls final String listName;
   if (listReference == null) {
     listName = "this";
   }
   else {
     listName = listReference.getText();
   }
   out.append(listName);
   out.append(')');
   if (body != null) {
     replaceCollectionGetAccess(body, contentVariableName, listVariable, indexName, statementToSkip, out);
   }
   return out.toString();
 }
 public static boolean expressionsAreEquivalent(
     @Nullable PsiExpression exp1, @Nullable PsiExpression exp2) {
   if (exp1 == null && exp2 == null) {
     return true;
   }
   if (exp1 == null || exp2 == null) {
     return false;
   }
   final PsiExpression expToCompare1 = ParenthesesUtils.stripParentheses(exp1);
   final PsiExpression expToCompare2 = ParenthesesUtils.stripParentheses(exp2);
   if (expToCompare1 == null && expToCompare2 == null) {
     return true;
   }
   if (expToCompare1 == null || expToCompare2 == null) {
     return false;
   }
   if (expToCompare1.getClass() != expToCompare2.getClass()) {
     return false;
   }
   if (expToCompare1 instanceof PsiThisExpression) {
     return true;
   } else if (expToCompare1 instanceof PsiSuperExpression) {
     return true;
   } else if (expToCompare1 instanceof PsiLiteralExpression) {
     final String text1 = expToCompare1.getText();
     final String text2 = expToCompare2.getText();
     return text1.equals(text2);
   } else if (expToCompare1 instanceof PsiClassObjectAccessExpression) {
     final String text1 = expToCompare1.getText();
     final String text2 = expToCompare2.getText();
     return text1.equals(text2);
   } else if (expToCompare1 instanceof PsiReferenceExpression) {
     return referenceExpressionsAreEquivalent(
         (PsiReferenceExpression) expToCompare1, (PsiReferenceExpression) expToCompare2);
   } else if (expToCompare1 instanceof PsiMethodCallExpression) {
     return methodCallExpressionsAreEquivalent(
         (PsiMethodCallExpression) expToCompare1, (PsiMethodCallExpression) expToCompare2);
   } else if (expToCompare1 instanceof PsiNewExpression) {
     return newExpressionsAreEquivalent(
         (PsiNewExpression) expToCompare1, (PsiNewExpression) expToCompare2);
   } else if (expToCompare1 instanceof PsiArrayInitializerExpression) {
     return arrayInitializerExpressionsAreEquivalent(
         (PsiArrayInitializerExpression) expToCompare1,
         (PsiArrayInitializerExpression) expToCompare2);
   } else if (expToCompare1 instanceof PsiTypeCastExpression) {
     return typecastExpressionsAreEquivalent(
         (PsiTypeCastExpression) expToCompare1, (PsiTypeCastExpression) expToCompare2);
   } else if (expToCompare1 instanceof PsiArrayAccessExpression) {
     return arrayAccessExpressionsAreEquivalent(
         (PsiArrayAccessExpression) expToCompare2, (PsiArrayAccessExpression) expToCompare1);
   } else if (expToCompare1 instanceof PsiPrefixExpression) {
     return prefixExpressionsAreEquivalent(
         (PsiPrefixExpression) expToCompare1, (PsiPrefixExpression) expToCompare2);
   } else if (expToCompare1 instanceof PsiPostfixExpression) {
     return postfixExpressionsAreEquivalent(
         (PsiPostfixExpression) expToCompare1, (PsiPostfixExpression) expToCompare2);
   } else if (expToCompare1 instanceof PsiBinaryExpression) {
     return binaryExpressionsAreEquivalent(
         (PsiBinaryExpression) expToCompare1, (PsiBinaryExpression) expToCompare2);
   } else if (expToCompare1 instanceof PsiAssignmentExpression) {
     return assignmentExpressionsAreEquivalent(
         (PsiAssignmentExpression) expToCompare1, (PsiAssignmentExpression) expToCompare2);
   } else if (expToCompare1 instanceof PsiConditionalExpression) {
     return conditionalExpressionsAreEquivalent(
         (PsiConditionalExpression) expToCompare1, (PsiConditionalExpression) expToCompare2);
   } else if (expToCompare1 instanceof PsiInstanceOfExpression) {
     return instanceofExpressionsAreEquivalent(
         (PsiInstanceOfExpression) expToCompare1, (PsiInstanceOfExpression) expToCompare2);
   }
   return false;
 }