private boolean isArrayLookup(PsiElement element, String indexName, PsiVariable arrayVariable) {
   if (element == null) {
     return false;
   }
   if (!(element instanceof PsiArrayAccessExpression)) {
     return false;
   }
   final PsiArrayAccessExpression arrayAccess = (PsiArrayAccessExpression) element;
   final PsiExpression indexExpression = arrayAccess.getIndexExpression();
   if (indexExpression == null) {
     return false;
   }
   if (!indexName.equals(indexExpression.getText())) {
     return false;
   }
   final PsiExpression arrayExpression = arrayAccess.getArrayExpression();
   if (!(arrayExpression instanceof PsiReferenceExpression)) {
     return false;
   }
   final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) arrayExpression;
   final PsiExpression qualifier = referenceExpression.getQualifierExpression();
   if (qualifier != null
       && !(qualifier instanceof PsiThisExpression)
       && !(qualifier instanceof PsiSuperExpression)) {
     return false;
   }
   final PsiElement target = referenceExpression.resolve();
   return arrayVariable.equals(target);
 }
  private static boolean isCollectCall(PsiStatement body, final PsiParameter parameter) {
    PsiIfStatement ifStatement = extractIfStatement(body);
    final PsiMethodCallExpression methodCallExpression = extractAddCall(body, ifStatement);
    if (methodCallExpression != null) {
      final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
      final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
      PsiClass qualifierClass = null;
      if (qualifierExpression instanceof PsiReferenceExpression) {
        if (ReferencesSearch.search(parameter, new LocalSearchScope(qualifierExpression))
                .findFirst()
            != null) {
          return false;
        }
        final PsiElement resolve = ((PsiReferenceExpression) qualifierExpression).resolve();
        if (resolve instanceof PsiVariable) {
          if (ReferencesSearch.search(
                      resolve, new LocalSearchScope(methodCallExpression.getArgumentList()))
                  .findFirst()
              != null) {
            return false;
          }
        }
        qualifierClass = PsiUtil.resolveClassInType(qualifierExpression.getType());
      } else if (qualifierExpression == null) {
        final PsiClass enclosingClass = PsiTreeUtil.getParentOfType(body, PsiClass.class);
        if (PsiUtil.getEnclosingStaticElement(body, enclosingClass) == null) {
          qualifierClass = enclosingClass;
        }
      }

      if (qualifierClass != null
          && InheritanceUtil.isInheritor(
              qualifierClass, false, CommonClassNames.JAVA_UTIL_COLLECTION)) {

        while (ifStatement != null && PsiTreeUtil.isAncestor(body, ifStatement, false)) {
          final PsiExpression condition = ifStatement.getCondition();
          if (condition != null
              && isConditionDependsOnUpdatedCollections(condition, qualifierExpression))
            return false;
          ifStatement = PsiTreeUtil.getParentOfType(ifStatement, PsiIfStatement.class);
        }

        final PsiElement resolve = methodExpression.resolve();
        if (resolve instanceof PsiMethod
            && "add".equals(((PsiMethod) resolve).getName())
            && ((PsiMethod) resolve).getParameterList().getParametersCount() == 1) {
          final PsiExpression[] args = methodCallExpression.getArgumentList().getExpressions();
          if (args.length == 1) {
            if (args[0] instanceof PsiCallExpression) {
              final PsiMethod method = ((PsiCallExpression) args[0]).resolveMethod();
              return method != null && !method.hasTypeParameters() && !isThrowsCompatible(method);
            }
            return true;
          }
        }
      }
    }
    return false;
  }
 @Override
 public void visitReferenceExpression(PsiReferenceExpression expression) {
   if (argumentsContainCatchParameter || !visited.add(expression)) {
     return;
   }
   super.visitReferenceExpression(expression);
   final PsiElement target = expression.resolve();
   if (!parameter.equals(target)) {
     if (target instanceof PsiLocalVariable) {
       final PsiLocalVariable variable = (PsiLocalVariable) target;
       final Query<PsiReference> query =
           ReferencesSearch.search(variable, variable.getUseScope(), false);
       query.forEach(
           reference -> {
             final PsiElement element = reference.getElement();
             final PsiElement parent =
                 PsiTreeUtil.skipParentsOfType(element, PsiParenthesizedExpression.class);
             if (!(parent instanceof PsiReferenceExpression)) {
               return true;
             }
             final PsiElement grandParent = parent.getParent();
             if (!(grandParent instanceof PsiMethodCallExpression)) {
               return true;
             }
             final PsiMethodCallExpression methodCallExpression =
                 (PsiMethodCallExpression) grandParent;
             final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
             final PsiExpression[] arguments = argumentList.getExpressions();
             for (PsiExpression argument : arguments) {
               argument.accept(ReferenceFinder.this);
             }
             return true;
           });
       final PsiExpression initializer = variable.getInitializer();
       if (initializer != null) {
         initializer.accept(this);
       }
     }
     return;
   }
   if (ignoreGetMessage) {
     argumentsContainCatchParameter = true;
   } else {
     final PsiElement parent = expression.getParent();
     if (parent instanceof PsiReferenceExpression) {
       final PsiElement grandParent = parent.getParent();
       if (grandParent instanceof PsiMethodCallExpression) {
         return;
       }
     }
     argumentsContainCatchParameter = true;
   }
 }
 @Override
 public void visitReferenceExpression(final PsiReferenceExpression reference) {
   if (myLineRange.intersects(reference.getTextRange())) {
     final PsiElement psiElement = reference.resolve();
     if (psiElement instanceof PsiVariable) {
       final PsiVariable var = (PsiVariable) psiElement;
       if (var instanceof PsiField) {
         if (myCollectExpressions
             && !DebuggerUtils.hasSideEffectsOrReferencesMissingVars(
                 reference, myVisibleLocals)) {
           /*
           if (var instanceof PsiEnumConstant && reference.getQualifier() == null) {
             final PsiClass enumClass = ((PsiEnumConstant)var).getContainingClass();
             if (enumClass != null) {
               final PsiExpression expression = JavaPsiFacade.getInstance(var.getProject()).getParserFacade().createExpressionFromText(enumClass.getName() + "." + var.getName(), var);
               final PsiReference ref = expression.getReference();
               if (ref != null) {
                 ref.bindToElement(var);
                 myExpressions.add(new TextWithImportsImpl(expression));
               }
             }
           }
           else {
             myExpressions.add(new TextWithImportsImpl(reference));
           }
           */
           final PsiModifierList modifierList = var.getModifierList();
           boolean isConstant =
               (var instanceof PsiEnumConstant)
                   || (modifierList != null
                       && modifierList.hasModifierProperty(PsiModifier.STATIC)
                       && modifierList.hasModifierProperty(PsiModifier.FINAL));
           if (!isConstant) {
             myExpressions.add(new TextWithImportsImpl(reference));
           }
         }
       } else {
         if (myVisibleLocals.contains(var.getName())) {
           myVars.add(var.getName());
         } else {
           // fix for variables used in inner classes
           if (!Comparing.equal(
               PsiTreeUtil.getParentOfType(reference, PsiClass.class),
               PsiTreeUtil.getParentOfType(var, PsiClass.class))) {
             myExpressions.add(new TextWithImportsImpl(reference));
           }
         }
       }
     }
   }
   super.visitReferenceExpression(reference);
 }
    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);
    }
 private boolean isAddedToCollection(PsiExpression expression) {
   final PsiElement parent = expression.getParent();
   if (!(parent instanceof PsiExpressionList)) {
     return false;
   }
   final PsiExpressionList expressionList = (PsiExpressionList) parent;
   final PsiElement grandParent = expressionList.getParent();
   if (!(grandParent instanceof PsiMethodCallExpression)) {
     return false;
   }
   final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) grandParent;
   final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
   @NonNls final String methodName = methodExpression.getReferenceName();
   if (!"put".equals(methodName) && !"set".equals(methodName) && !"add".equals(methodName)) {
     return false;
   }
   final PsiExpression qualifier = methodExpression.getQualifierExpression();
   return TypeUtils.expressionHasTypeOrSubtype(
           qualifier, CommonClassNames.JAVA_UTIL_COLLECTION, CommonClassNames.JAVA_UTIL_MAP)
       != null;
 }
 private boolean isIteratorNext(PsiElement element, String iteratorName, PsiType contentType) {
   if (element == null) {
     return false;
   }
   if (element instanceof PsiTypeCastExpression) {
     final PsiTypeCastExpression castExpression = (PsiTypeCastExpression) element;
     final PsiType type = castExpression.getType();
     if (type == null) {
       return false;
     }
     if (!type.equals(contentType)) {
       return false;
     }
     final PsiExpression operand = castExpression.getOperand();
     return isIteratorNext(operand, iteratorName, contentType);
   }
   if (!(element instanceof PsiMethodCallExpression)) {
     return false;
   }
   final PsiMethodCallExpression callExpression = (PsiMethodCallExpression) element;
   final PsiExpressionList argumentList = callExpression.getArgumentList();
   final PsiExpression[] args = argumentList.getExpressions();
   if (args.length != 0) {
     return false;
   }
   final PsiReferenceExpression reference = callExpression.getMethodExpression();
   final PsiExpression qualifier = reference.getQualifierExpression();
   if (qualifier == null) {
     return false;
   }
   if (!iteratorName.equals(qualifier.getText())) {
     return false;
   }
   final String referenceName = reference.getReferenceName();
   return HardcodedMethodConstants.NEXT.equals(referenceName);
 }
 @Override
 public void visitMethodCallExpression(PsiMethodCallExpression expression) {
   super.visitMethodCallExpression(expression);
   final PsiReferenceExpression methodExpression = expression.getMethodExpression();
   @NonNls final String name = methodExpression.getReferenceName();
   if (HardcodedMethodConstants.TO_STRING.equals(name)) {
     final PsiExpressionList argumentList = expression.getArgumentList();
     final PsiExpression[] arguments = argumentList.getExpressions();
     if (arguments.length != 0) {
       return;
     }
     final PsiExpression qualifier = methodExpression.getQualifierExpression();
     checkExpression(qualifier);
   } else if ("append".equals(name)) {
     final PsiExpression qualifier = methodExpression.getQualifierExpression();
     if (!TypeUtils.expressionHasTypeOrSubtype(
         qualifier, CommonClassNames.JAVA_LANG_ABSTRACT_STRING_BUILDER)) {
       return;
     }
     final PsiExpressionList argumentList = expression.getArgumentList();
     final PsiExpression[] arguments = argumentList.getExpressions();
     if (arguments.length != 1) {
       return;
     }
     final PsiExpression argument = arguments[0];
     checkExpression(argument);
   } else if ("valueOf".equals(name)) {
     final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
     if (!(qualifierExpression instanceof PsiReferenceExpression)) {
       return;
     }
     final PsiReferenceExpression referenceExpression =
         (PsiReferenceExpression) qualifierExpression;
     final String canonicalText = referenceExpression.getCanonicalText();
     if (!CommonClassNames.JAVA_LANG_STRING.equals(canonicalText)) {
       return;
     }
     final PsiExpressionList argumentList = expression.getArgumentList();
     final PsiExpression[] arguments = argumentList.getExpressions();
     if (arguments.length != 1) {
       return;
     }
     final PsiExpression argument = arguments[0];
     checkExpression(argument);
   }
 }
 @NotNull
 private List<PsiMethod> getMethodsToImport() {
   PsiShortNamesCache cache = PsiShortNamesCache.getInstance(myMethodCall.getProject());
   PsiMethodCallExpression element = myMethodCall.getElement();
   PsiReferenceExpression reference = element.getMethodExpression();
   PsiExpressionList argumentList = element.getArgumentList();
   String name = reference.getReferenceName();
   List<PsiMethod> list = new ArrayList<PsiMethod>();
   if (name == null) return list;
   GlobalSearchScope scope = element.getResolveScope();
   PsiMethod[] methods = cache.getMethodsByNameIfNotMoreThan(name, scope, 20);
   List<PsiMethod> applicableList = new ArrayList<PsiMethod>();
   final PsiResolveHelper resolveHelper =
       JavaPsiFacade.getInstance(element.getProject()).getResolveHelper();
   for (PsiMethod method : methods) {
     ProgressManager.checkCanceled();
     if (JavaCompletionUtil.isInExcludedPackage(method)) continue;
     if (!method.hasModifierProperty(PsiModifier.STATIC)) continue;
     PsiFile file = method.getContainingFile();
     if (file instanceof PsiJavaFile
         // do not show methods from default package
         && ((PsiJavaFile) file).getPackageName().length() != 0
         && PsiUtil.isAccessible(method, element, method.getContainingClass())) {
       list.add(method);
       PsiSubstitutor substitutorForMethod =
           resolveHelper.inferTypeArguments(
               method.getTypeParameters(),
               method.getParameterList().getParameters(),
               argumentList.getExpressions(),
               PsiSubstitutor.EMPTY,
               element.getParent(),
               DefaultParameterTypeInferencePolicy.INSTANCE);
       if (PsiUtil.isApplicable(method, substitutorForMethod, argumentList)) {
         applicableList.add(method);
       }
     }
   }
   List<PsiMethod> result = applicableList.isEmpty() ? list : applicableList;
   for (int i = result.size() - 1; i >= 0; i--) {
     ProgressManager.checkCanceled();
     PsiMethod method = result.get(i);
     PsiClass containingClass = method.getContainingClass();
     for (int j = i + 1; j < result.size(); j++) {
       PsiMethod exMethod = result.get(j);
       if (!Comparing.strEqual(exMethod.getName(), method.getName())) continue;
       PsiClass exContainingClass = exMethod.getContainingClass();
       if (containingClass != null
           && exContainingClass != null
           && !Comparing.equal(
               containingClass.getQualifiedName(), exContainingClass.getQualifiedName())) continue;
       // same named methods, drop one
       result.remove(i);
       break;
     }
     // check for manually excluded
     if (isExcluded(method)) {
       result.remove(i);
     }
   }
   Collections.sort(result, new PsiProximityComparator(argumentList));
   return result;
 }
 @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 =
       ParenthesesUtils.stripParentheses(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();
 }
 @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 PsiType type = arrayReference.getType();
   if (!(type instanceof PsiArrayType)) {
     return null;
   }
   final PsiArrayType arrayType = (PsiArrayType) type;
   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 createCollectionIterationText(@NotNull PsiForStatement forStatement)
     throws IncorrectOperationException {
   final PsiStatement body = forStatement.getBody();
   final PsiStatement firstStatement = getFirstStatement(body);
   final PsiStatement initialization = forStatement.getInitialization();
   if (!(initialization instanceof PsiDeclarationStatement)) {
     return null;
   }
   final PsiDeclarationStatement declaration = (PsiDeclarationStatement) initialization;
   final PsiElement declaredIterator = declaration.getDeclaredElements()[0];
   if (!(declaredIterator instanceof PsiVariable)) {
     return null;
   }
   final PsiVariable iteratorVariable = (PsiVariable) declaredIterator;
   final PsiMethodCallExpression initializer =
       (PsiMethodCallExpression) iteratorVariable.getInitializer();
   if (initializer == null) {
     return null;
   }
   final PsiType iteratorType = initializer.getType();
   if (iteratorType == null) {
     return null;
   }
   final PsiType iteratorContentType = extractContentTypeFromType(iteratorType);
   final PsiType iteratorVariableType = iteratorVariable.getType();
   final PsiType contentType;
   final PsiClassType javaLangObject = TypeUtils.getObjectType(forStatement);
   if (iteratorContentType == null) {
     final PsiType iteratorVariableContentType =
         extractContentTypeFromType(iteratorVariableType);
     if (iteratorVariableContentType == null) {
       contentType = javaLangObject;
     } else {
       contentType = iteratorVariableContentType;
     }
   } else {
     contentType = iteratorContentType;
   }
   final PsiReferenceExpression methodExpression = initializer.getMethodExpression();
   final PsiExpression collection = methodExpression.getQualifierExpression();
   final String iteratorName = iteratorVariable.getName();
   final boolean isDeclaration =
       isIteratorNextDeclaration(firstStatement, iteratorName, contentType);
   final PsiStatement statementToSkip;
   @NonNls final String finalString;
   final String contentVariableName;
   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 {
     if (collection instanceof PsiReferenceExpression) {
       final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) collection;
       final String collectionName = referenceExpression.getReferenceName();
       contentVariableName = createNewVariableName(forStatement, contentType, collectionName);
     } else {
       contentVariableName = createNewVariableName(forStatement, contentType, null);
     }
     final Project project = forStatement.getProject();
     final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
     if (codeStyleSettings.GENERATE_FINAL_LOCALS) {
       finalString = "final ";
     } else {
       finalString = "";
     }
     statementToSkip = null;
   }
   final String contentTypeString = contentType.getCanonicalText();
   @NonNls final StringBuilder out = new StringBuilder();
   out.append("for(");
   out.append(finalString);
   out.append(contentTypeString);
   out.append(' ');
   out.append(contentVariableName);
   out.append(": ");
   if (!contentType.equals(javaLangObject)) {
     @NonNls final String iterableTypeString = "java.lang.Iterable<" + contentTypeString + '>';
     if (iteratorContentType == null) {
       out.append('(');
       out.append(iterableTypeString);
       out.append(')');
     }
   }
   if (collection == null) {
     out.append("this");
   } else {
     out.append(collection.getText());
   }
   out.append(')');
   replaceIteratorNext(
       body, contentVariableName, iteratorName, statementToSkip, out, contentType);
   return out.toString();
 }
 private boolean checkCondition(
     @Nullable PsiExpression condition,
     @NotNull PsiStatement context,
     List<PsiExpression> notUpdated) {
   if (condition == null) {
     return false;
   }
   if (PsiUtil.isConstantExpression(condition) || PsiKeyword.NULL.equals(condition.getText())) {
     return true;
   }
   if (condition instanceof PsiInstanceOfExpression) {
     final PsiInstanceOfExpression instanceOfExpression = (PsiInstanceOfExpression) condition;
     final PsiExpression operand = instanceOfExpression.getOperand();
     return checkCondition(operand, context, notUpdated);
   } else if (condition instanceof PsiParenthesizedExpression) {
     // catch stuff like "while ((x)) { ... }"
     final PsiExpression expression = ((PsiParenthesizedExpression) condition).getExpression();
     return checkCondition(expression, context, notUpdated);
   } else if (condition instanceof PsiPolyadicExpression) {
     // while (value != x) { ... }
     // while (value != (x + y)) { ... }
     // while (b1 && b2) { ... }
     final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression) condition;
     for (PsiExpression operand : polyadicExpression.getOperands()) {
       if (!checkCondition(operand, context, notUpdated)) {
         return false;
       }
     }
     return true;
   } else if (condition instanceof PsiReferenceExpression) {
     final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) condition;
     final PsiElement element = referenceExpression.resolve();
     if (element instanceof PsiField) {
       final PsiField field = (PsiField) element;
       final PsiType type = field.getType();
       if (field.hasModifierProperty(PsiModifier.FINAL) && type.getArrayDimensions() == 0) {
         if (field.hasModifierProperty(PsiModifier.STATIC)) {
           return true;
         }
         final PsiExpression qualifier = referenceExpression.getQualifierExpression();
         if (qualifier == null) {
           return true;
         } else if (checkCondition(qualifier, context, notUpdated)) {
           return true;
         }
       }
     } else if (element instanceof PsiVariable) {
       final PsiVariable variable = (PsiVariable) element;
       if (variable.hasModifierProperty(PsiModifier.FINAL)) {
         // final variables cannot be updated, don't bother to
         // flag them
         return true;
       } else if (element instanceof PsiLocalVariable || element instanceof PsiParameter) {
         if (!VariableAccessUtils.variableIsAssigned(variable, context)) {
           notUpdated.add(referenceExpression);
           return true;
         }
       }
     }
   } else if (condition instanceof PsiPrefixExpression) {
     final PsiPrefixExpression prefixExpression = (PsiPrefixExpression) condition;
     final IElementType tokenType = prefixExpression.getOperationTokenType();
     if (JavaTokenType.EXCL.equals(tokenType)
         || JavaTokenType.PLUS.equals(tokenType)
         || JavaTokenType.MINUS.equals(tokenType)) {
       final PsiExpression operand = prefixExpression.getOperand();
       return checkCondition(operand, context, notUpdated);
     }
   } else if (condition instanceof PsiArrayAccessExpression) {
     // Actually the contents of the array could change nevertheless
     // if it is accessed through a different reference like this:
     //   int[] local_ints = new int[]{1, 2};
     //   int[] other_ints = local_ints;
     //   while (local_ints[0] > 0) { other_ints[0]--; }
     //
     // Keep this check?
     final PsiArrayAccessExpression accessExpression = (PsiArrayAccessExpression) condition;
     final PsiExpression indexExpression = accessExpression.getIndexExpression();
     return checkCondition(indexExpression, context, notUpdated)
         && checkCondition(accessExpression.getArrayExpression(), context, notUpdated);
   } else if (condition instanceof PsiConditionalExpression) {
     final PsiConditionalExpression conditionalExpression = (PsiConditionalExpression) condition;
     final PsiExpression thenExpression = conditionalExpression.getThenExpression();
     final PsiExpression elseExpression = conditionalExpression.getElseExpression();
     if (thenExpression == null || elseExpression == null) {
       return false;
     }
     return checkCondition(conditionalExpression.getCondition(), context, notUpdated)
         && checkCondition(thenExpression, context, notUpdated)
         && checkCondition(elseExpression, context, notUpdated);
   } else if (condition instanceof PsiThisExpression) {
     return true;
   } else if (condition instanceof PsiMethodCallExpression && !ignoreIterators) {
     final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) condition;
     if (!IteratorUtils.isCallToHasNext(methodCallExpression)) {
       return false;
     }
     final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
     final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
     if (qualifierExpression instanceof PsiReferenceExpression) {
       final PsiReferenceExpression referenceExpression =
           (PsiReferenceExpression) qualifierExpression;
       final PsiElement element = referenceExpression.resolve();
       if (!(element instanceof PsiVariable)) {
         return false;
       }
       final PsiVariable variable = (PsiVariable) element;
       if (!IteratorUtils.containsCallToScannerNext(context, variable, true)) {
         notUpdated.add(qualifierExpression);
         return true;
       }
     } else {
       if (!IteratorUtils.containsCallToScannerNext(context, null, true)) {
         notUpdated.add(methodCallExpression);
         return true;
       }
     }
   }
   return false;
 }
  private static void reportConstantReferenceValues(
      ProblemsHolder holder, StandardInstructionVisitor visitor, Set<PsiElement> reportedAnchors) {
    for (Pair<PsiReferenceExpression, DfaConstValue> pair : visitor.getConstantReferenceValues()) {
      PsiReferenceExpression ref = pair.first;
      if (ref.getParent() instanceof PsiReferenceExpression || !reportedAnchors.add(ref)) {
        continue;
      }

      final Object value = pair.second.getValue();
      PsiVariable constant = pair.second.getConstant();
      final String presentableName = constant != null ? constant.getName() : String.valueOf(value);
      final String exprText = String.valueOf(value);
      if (presentableName == null || exprText == null) {
        continue;
      }

      holder.registerProblem(
          ref,
          "Value <code>#ref</code> #loc is always '" + presentableName + "'",
          new LocalQuickFix() {
            @NotNull
            @Override
            public String getName() {
              return "Replace with '" + presentableName + "'";
            }

            @NotNull
            @Override
            public String getFamilyName() {
              return "Replace with constant value";
            }

            @Override
            public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
              if (!FileModificationService.getInstance()
                  .preparePsiElementsForWrite(descriptor.getPsiElement())) {
                return;
              }

              PsiElement problemElement = descriptor.getPsiElement();
              if (problemElement == null) return;

              PsiMethodCallExpression call =
                  problemElement.getParent() instanceof PsiExpressionList
                          && problemElement.getParent().getParent()
                              instanceof PsiMethodCallExpression
                      ? (PsiMethodCallExpression) problemElement.getParent().getParent()
                      : null;
              PsiMethod targetMethod = call == null ? null : call.resolveMethod();

              JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
              problemElement.replace(
                  facade.getElementFactory().createExpressionFromText(exprText, null));

              if (targetMethod != null) {
                ExtractMethodUtil.addCastsToEnsureResolveTarget(targetMethod, call);
              }
            }
          });
    }
  }
 private static boolean shortcutReplace(PsiExpression expression, String classToConstruct) {
   if (!(expression instanceof PsiMethodCallExpression)) {
     return false;
   }
   final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) expression;
   final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
   final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
   if (qualifierExpression == null) {
     return false;
   }
   if (classToConstruct.equals(CommonClassNames.JAVA_LANG_INTEGER)) {
     if (MethodCallUtils.isCallToMethod(
         methodCallExpression, CommonClassNames.JAVA_LANG_INTEGER, PsiType.INT, "intValue")) {
       expression.replace(qualifierExpression);
       return true;
     }
   } else if (classToConstruct.equals(CommonClassNames.JAVA_LANG_SHORT)) {
     if (MethodCallUtils.isCallToMethod(
         methodCallExpression, CommonClassNames.JAVA_LANG_SHORT, PsiType.SHORT, "shortValue")) {
       expression.replace(qualifierExpression);
       return true;
     }
   } else if (classToConstruct.equals(CommonClassNames.JAVA_LANG_BYTE)) {
     if (MethodCallUtils.isCallToMethod(
         methodCallExpression, CommonClassNames.JAVA_LANG_BYTE, PsiType.BYTE, "byteValue")) {
       expression.replace(qualifierExpression);
       return true;
     }
   } else if (classToConstruct.equals(CommonClassNames.JAVA_LANG_CHARACTER)) {
     if (MethodCallUtils.isCallToMethod(
         methodCallExpression,
         CommonClassNames.JAVA_LANG_CHARACTER,
         PsiType.CHAR,
         "charValue")) {
       expression.replace(qualifierExpression);
       return true;
     }
   } else if (classToConstruct.equals(CommonClassNames.JAVA_LANG_LONG)) {
     if (MethodCallUtils.isCallToMethod(
         methodCallExpression, CommonClassNames.JAVA_LANG_LONG, PsiType.LONG, "longValue")) {
       expression.replace(qualifierExpression);
       return true;
     }
   } else if (classToConstruct.equals(CommonClassNames.JAVA_LANG_FLOAT)) {
     if (MethodCallUtils.isCallToMethod(
         methodCallExpression, CommonClassNames.JAVA_LANG_FLOAT, PsiType.FLOAT, "floatValue")) {
       expression.replace(qualifierExpression);
       return true;
     }
   } else if (classToConstruct.equals(CommonClassNames.JAVA_LANG_DOUBLE)) {
     if (MethodCallUtils.isCallToMethod(
         methodCallExpression,
         CommonClassNames.JAVA_LANG_DOUBLE,
         PsiType.DOUBLE,
         "doubleValue")) {
       expression.replace(qualifierExpression);
       return true;
     }
   }
   return false;
 }