@Override
 public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
   super.visitMethodCallExpression(expression);
   final PsiReferenceExpression methodExpression = expression.getMethodExpression();
   @NonNls final String methodName = methodExpression.getReferenceName();
   if (methodName == null) {
     return;
   }
   if (!methodName.startsWith("get") && !methodName.startsWith("update")) {
     return;
   }
   final PsiExpressionList argumentList = expression.getArgumentList();
   final PsiExpression[] arguments = argumentList.getExpressions();
   if (arguments.length == 0) {
     return;
   }
   final PsiExpression argument = arguments[0];
   if (!TypeUtils.expressionHasType(argument, PsiKeyword.INT)) {
     return;
   }
   if (!PsiUtil.isConstantExpression(argument)) {
     return;
   }
   final Integer val = (Integer) ConstantExpressionUtil.computeCastTo(argument, PsiType.INT);
   if (val == null || val.intValue() != 0) {
     return;
   }
   final PsiExpression qualifier = methodExpression.getQualifierExpression();
   if (!TypeUtils.expressionHasTypeOrSubtype(qualifier, "java.sql.ResultSet")) {
     return;
   }
   registerError(argument);
 }
 @Nullable
 private PsiType extractListTypeFromContainingClass(
   PsiElement element) {
   PsiClass listClass = PsiTreeUtil.getParentOfType(element,
                                                    PsiClass.class);
   if (listClass == null) {
     return null;
   }
   final PsiMethod[] getMethods =
     listClass.findMethodsByName("get", true);
   if (getMethods.length == 0) {
     return null;
   }
   final PsiType type = getMethods[0].getReturnType();
   if (!(type instanceof PsiClassType)) {
     return null;
   }
   final PsiClassType classType = (PsiClassType)type;
   final PsiClass parameterClass = classType.resolve();
   if (parameterClass == null) {
     return null;
   }
   PsiClass subClass = null;
   while (listClass != null && !listClass.hasTypeParameters()) {
     subClass = listClass;
     listClass = listClass.getSuperClass();
   }
   if (listClass == null || subClass == null) {
     return TypeUtils.getObjectType(element);
   }
   final PsiTypeParameter[] typeParameters =
     listClass.getTypeParameters();
   if (!parameterClass.equals(typeParameters[0])) {
     return TypeUtils.getObjectType(element);
   }
   final PsiReferenceList extendsList = subClass.getExtendsList();
   if (extendsList == null) {
     return null;
   }
   final PsiJavaCodeReferenceElement[] referenceElements =
     extendsList.getReferenceElements();
   if (referenceElements.length == 0) {
     return null;
   }
   final PsiType[] types =
     referenceElements[0].getTypeParameters();
   if (types.length == 0) {
     return TypeUtils.getObjectType(element);
   }
   return types[0];
 }
 @Override
 public void visitThrowStatement(PsiThrowStatement statement) {
   super.visitThrowStatement(statement);
   final PsiCatchSection catchSection =
       PsiTreeUtil.getParentOfType(statement, PsiCatchSection.class, true, PsiClass.class);
   if (catchSection == null) {
     return;
   }
   final PsiParameter parameter = catchSection.getParameter();
   if (parameter == null) {
     return;
   }
   @NonNls final String parameterName = parameter.getName();
   if (PsiUtil.isIgnoredName(parameterName)) {
     return;
   }
   final PsiExpression exception = statement.getException();
   if (exception == null) {
     return;
   }
   if (ignoreCantWrap) {
     final PsiType thrownType = exception.getType();
     if (thrownType instanceof PsiClassType) {
       final PsiClassType classType = (PsiClassType) thrownType;
       final PsiClass exceptionClass = classType.resolve();
       if (exceptionClass != null) {
         final PsiMethod[] constructors = exceptionClass.getConstructors();
         final PsiClassType throwableType =
             TypeUtils.getType(CommonClassNames.JAVA_LANG_THROWABLE, statement);
         boolean canWrap = false;
         outer:
         for (PsiMethod constructor : constructors) {
           final PsiParameterList parameterList = constructor.getParameterList();
           final PsiParameter[] parameters = parameterList.getParameters();
           for (PsiParameter constructorParameter : parameters) {
             final PsiType type = constructorParameter.getType();
             if (throwableType.equals(type)) {
               canWrap = true;
               break outer;
             }
           }
         }
         if (!canWrap) {
           return;
         }
       }
     }
   }
   final ReferenceFinder visitor = new ReferenceFinder(parameter);
   exception.accept(visitor);
   if (visitor.usesParameter()) {
     return;
   }
   registerStatementError(statement);
 }
 @Override
 public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
   super.visitMethodCallExpression(expression);
   final PsiReferenceExpression methodExpression = expression.getMethodExpression();
   @NonNls final String methodName = methodExpression.getReferenceName();
   if (methodName == null) {
     return;
   }
   final boolean resultSet;
   if (methodName.startsWith("get") || methodName.startsWith("update")) {
     resultSet = true;
   } else if (methodName.startsWith("set")) {
     resultSet = false;
   } else {
     return;
   }
   final PsiExpressionList argumentList = expression.getArgumentList();
   final PsiExpression[] arguments = argumentList.getExpressions();
   if (arguments.length == 0) {
     return;
   }
   final PsiExpression argument = arguments[0];
   final Object val = ExpressionUtils.computeConstantExpression(argument);
   if (!(val instanceof Integer) || ((Integer) val).intValue() != 0) {
     return;
   }
   final PsiExpression qualifier = methodExpression.getQualifierExpression();
   if (resultSet) {
     if (TypeUtils.expressionHasTypeOrSubtype(qualifier, "java.sql.ResultSet")) {
       registerError(argument, Boolean.valueOf(resultSet));
     }
   } else {
     if (TypeUtils.expressionHasTypeOrSubtype(qualifier, "java.sql.PreparedStatement")) {
       registerError(argument, Boolean.valueOf(resultSet));
     }
   }
 }
 @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);
   }
 }
 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 void checkTypeElement(PsiTypeElement typeElement) {
   if (typeElement == null || !TypeUtils.isOptional(typeElement.getType())) {
     return;
   }
   registerError(typeElement, typeElement);
 }
 @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 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 static boolean isCharacter(PsiExpression expression) {
   return TypeUtils.expressionHasType(expression, PsiKeyword.CHAR)
       || TypeUtils.expressionHasType(expression, CommonClassNames.JAVA_LANG_CHARACTER);
 }