@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 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);
 }
  private static boolean isConditionDependsOnUpdatedCollections(
      PsiExpression condition, PsiExpression qualifierExpression) {
    final PsiElement collection =
        qualifierExpression instanceof PsiReferenceExpression
            ? ((PsiReferenceExpression) qualifierExpression).resolve()
            : null;
    if (collection != null) {
      return ReferencesSearch.search(collection, new LocalSearchScope(condition)).findFirst()
          != null;
    }

    final boolean[] dependsOnCollection = {false};
    condition.accept(
        new JavaRecursiveElementWalkingVisitor() {
          @Override
          public void visitMethodCallExpression(PsiMethodCallExpression expression) {
            super.visitMethodCallExpression(expression);
            final PsiExpression callQualifier =
                expression.getMethodExpression().getQualifierExpression();
            if (callQualifier == null
                || callQualifier instanceof PsiThisExpression
                    && ((PsiThisExpression) callQualifier).getQualifier() == null
                || callQualifier instanceof PsiSuperExpression
                    && ((PsiSuperExpression) callQualifier).getQualifier() == null) {
              dependsOnCollection[0] = true;
            }
          }

          @Override
          public void visitThisExpression(PsiThisExpression expression) {
            super.visitThisExpression(expression);
            if (expression.getQualifier() == null
                && expression.getParent() instanceof PsiExpressionList) {
              dependsOnCollection[0] = true;
            }
          }

          @Override
          public void visitClass(PsiClass aClass) {}

          @Override
          public void visitLambdaExpression(PsiLambdaExpression expression) {}
        });

    return dependsOnCollection[0];
  }