@Override
 public void visitElement(@NotNull PsiElement element) {
   if (hasSuperCall) {
     return;
   }
   super.visitElement(element);
 }
 @Override
 public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
   super.visitReferenceElement(reference);
   final PsiElement element = reference.resolve();
   if (element != null) {
     myResult.add(element);
   }
 }
 @Override
 public void visitAnnotation(PsiAnnotation annotation) {
   super.visitAnnotation(annotation);
   @NonNls final String qualifiedName = annotation.getQualifiedName();
   if (qualifiedName == null || !qualifiedName.startsWith("org.junit.")) {
     return;
   }
   myJUnit4AnnotationFound = true;
 }
 public void visitReferenceExpression(PsiReferenceExpression expression) {
   super.visitReferenceExpression(expression);
   if (isProhibitedReference(expression)) {
     final PsiField field = getReferencedField(expression);
     if (!hasGetter(field)
         && !isStaticFinal(field)
         && !field.getModifierList().hasModifierProperty(PsiModifier.PUBLIC)) {
       fieldsNeedingGetter.add(field);
     }
   }
 }
 @Override
 public void visitReferenceExpression(@NotNull PsiReferenceExpression ref) {
   if (used) {
     return;
   }
   super.visitReferenceExpression(ref);
   final PsiElement resolvedElement = ref.resolve();
   if (variable.equals(resolvedElement)) {
     used = true;
   }
 }
 @Override
 public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
   super.visitReferenceElement(reference);
   if (reference.getQualifier() != null) {
     return;
   }
   final PsiElement target = reference.resolve();
   if (!(target instanceof PsiClass) || !PsiUtil.isLocalClass((PsiClass) target)) {
     return;
   }
   referenceToLocalClass = true;
 }
    public void visitAssignmentExpression(PsiAssignmentExpression expression) {
      super.visitAssignmentExpression(expression);

      final PsiExpression lhs = expression.getLExpression();
      if (isProhibitedReference(lhs)) {
        final PsiField field = getReferencedField(lhs);
        if (!hasGetter(field)
            && !isStaticFinal(field)
            && !field.getModifierList().hasModifierProperty(PsiModifier.PUBLIC)) {
          fieldsNeedingSetter.add(field);
        }
      }
    }
 @Override
 public void visitBlockStatement(PsiBlockStatement statement) {
   final PsiElement parent = statement.getParent();
   final boolean isAlreadyCounted =
       parent instanceof PsiDoWhileStatement
           || parent instanceof PsiWhileStatement
           || parent instanceof PsiForStatement
           || parent instanceof PsiIfStatement
           || parent instanceof PsiSynchronizedStatement;
   if (!isAlreadyCounted) {
     enterScope(statement);
   }
   super.visitBlockStatement(statement);
 }
  @Override
  public void visitPackage(final PsiPackage aPackage) {
    final PsiDirectory[] dirs = aPackage.getDirectories();

    for (PsiDirectory dir : dirs) {
      final PsiFile[] files = dir.getFiles();

      for (final PsiFile file : files) {
        if (file instanceof PsiJavaFile) {
          super.visitJavaFile(((PsiJavaFile) file));
        }
      }
    }
  }
 @Override
 public void visitIfStatement(@NotNull PsiIfStatement statement) {
   boolean isAlreadyCounted = false;
   PsiElement parent = statement.getParent();
   if (parent instanceof PsiIfStatement) {
     final PsiStatement elseBranch = ((PsiIfStatement) parent).getElseBranch();
     if (statement.equals(elseBranch)) {
       isAlreadyCounted = true;
     }
   }
   if (!isAlreadyCounted) {
     enterScope(statement);
   }
   super.visitIfStatement(statement);
 }
 public void visitAssignmentExpression(PsiAssignmentExpression assignment) {
   super.visitAssignmentExpression(assignment);
   final PsiExpression lhs = assignment.getLExpression();
   final PsiExpression rhs = assignment.getRExpression();
   if (!(lhs instanceof PsiReferenceExpression)) {
     return;
   }
   if (!(rhs instanceof PsiReferenceExpression)) {
     return;
   }
   final PsiElement referent = ((PsiReference) rhs).resolve();
   if (referent == null || !referent.equals(param)) {
     return;
   }
   final PsiElement assigned = ((PsiReference) lhs).resolve();
   if (assigned == null || !(assigned instanceof PsiField)) {
     return;
   }
   fieldAssigned = (PsiField) assigned;
 }
 @Override
 public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
   if (hasSuperCall) {
     return;
   }
   super.visitMethodCallExpression(expression);
   final PsiReferenceExpression methodExpression = expression.getMethodExpression();
   final PsiExpression qualifier = methodExpression.getQualifierExpression();
   if (qualifier == null) {
     return;
   }
   final String text = qualifier.getText();
   if (!PsiKeyword.SUPER.equals(text)) {
     return;
   }
   final PsiMethod method = expression.resolveMethod();
   if (method == null) {
     return;
   }
   if (method.equals(methodToSearchFor)) {
     hasSuperCall = true;
   }
 }
 @Override
 public void visitWhileStatement(@NotNull PsiWhileStatement statement) {
   enterScope(statement);
   super.visitWhileStatement(statement);
 }
 @Override
 public void visitSwitchStatement(@NotNull PsiSwitchStatement statement) {
   enterScope(statement);
   super.visitSwitchStatement(statement);
 }
 @Override
 public void visitSynchronizedStatement(@NotNull PsiSynchronizedStatement statement) {
   enterScope(statement);
   super.visitSynchronizedStatement(statement);
 }
 @Override
 public void visitElement(@NotNull PsiElement element) {
   if (!used) {
     super.visitElement(element);
   }
 }
 @Override
 public void visitElement(PsiElement element) {
   if (myIsMovable) {
     super.visitElement(element);
   }
 }
 public void visitPrefixExpression(PsiPrefixExpression expression) {
   super.visitPrefixExpression(expression);
   checkSetterNeeded(expression.getOperand(), expression.getOperationSign());
 }
 @Override
 public void visitReferenceExpression(PsiReferenceExpression expression) {
   if (myWritten && myRead) {
     return;
   }
   super.visitReferenceExpression(expression);
   final PsiElement target = expression.resolve();
   if (target != myVariable) {
     return;
   }
   if (PsiUtil.isAccessedForWriting(expression)) {
     final PsiElement parent =
         PsiTreeUtil.skipParentsOfType(expression, PsiParenthesizedExpression.class);
     if (parent instanceof PsiAssignmentExpression) {
       final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression) parent;
       final PsiExpression rhs = assignmentExpression.getRExpression();
       if (isComplexArrayExpression(rhs)) {
         myWritten = true;
         myRead = true;
       } else if (!isSimpleArrayExpression(rhs)) {
         myWritten = true;
       }
     }
     return;
   }
   myIsReferenced = true;
   PsiElement parent = getParent(expression);
   if (parent instanceof PsiArrayAccessExpression) {
     PsiArrayAccessExpression arrayAccessExpression = (PsiArrayAccessExpression) parent;
     parent = getParent(parent);
     while (parent instanceof PsiArrayAccessExpression) {
       arrayAccessExpression = (PsiArrayAccessExpression) parent;
       parent = getParent(parent);
     }
     final PsiType type = arrayAccessExpression.getType();
     if (type != null) {
       final int dimensions = type.getArrayDimensions();
       if (dimensions > 0 && dimensions != myVariable.getType().getArrayDimensions()) {
         myWritten = true;
       }
     }
     if (PsiUtil.isAccessedForWriting(arrayAccessExpression)) {
       myWritten = true;
     }
     if (PsiUtil.isAccessedForReading(arrayAccessExpression)) {
       myRead = true;
     }
   } else if (parent instanceof PsiReferenceExpression) {
     final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) parent;
     final String name = referenceExpression.getReferenceName();
     if ("length".equals(name)
         || ("clone".equals(name)
             && referenceExpression.getParent() instanceof PsiMethodCallExpression)) {
       myRead = true;
     }
   } else if (parent instanceof PsiForeachStatement) {
     final PsiForeachStatement foreachStatement = (PsiForeachStatement) parent;
     final PsiExpression iteratedValue = foreachStatement.getIteratedValue();
     if (PsiTreeUtil.isAncestor(iteratedValue, expression, false)) {
       myRead = true;
     }
   } else if (parent instanceof PsiExpressionList) {
     final PsiExpressionList expressionList = (PsiExpressionList) parent;
     parent = parent.getParent();
     if (parent instanceof PsiMethodCallExpression) {
       final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) parent;
       final PsiMethod method = methodCallExpression.resolveMethod();
       if (method != null) {
         final PsiClass aClass = method.getContainingClass();
         if (aClass != null) {
           final String methodName = method.getName();
           final String qualifiedName = aClass.getQualifiedName();
           if ("java.lang.System".equals(qualifiedName)) {
             if ("arraycopy".equals(methodName)) {
               final PsiExpression[] expressions = expressionList.getExpressions();
               if (expressions.length == 5) {
                 if (PsiTreeUtil.isAncestor(expressions[0], expression, false)) {
                   myRead = true;
                   return;
                 } else if (PsiTreeUtil.isAncestor(expressions[2], expression, false)) {
                   myWritten = true;
                   return;
                 }
               }
             }
           } else if (CommonClassNames.JAVA_UTIL_ARRAYS.equals(qualifiedName)) {
             if ("fill".equals(methodName)
                 || "parallelPrefix".equals(methodName)
                 || "parallelSetAll".equals(methodName)
                 || "parallelSort".equals(methodName)
                 || "setAll".equals(methodName)
                 || "sort".equals(methodName)) {
               myWritten = true;
             } else {
               myRead = true;
             }
             return;
           }
         }
       }
     }
     myRead = true;
     myWritten = true;
   } else {
     myWritten = true;
     myRead = true;
   }
 }
 @Override
 public void visitElement(PsiElement element) {
   if (conflict != null) return;
   super.visitElement(element);
 }