@Override
 public void visitReferenceExpression(@NotNull PsiReferenceExpression ref) {
   if (used) {
     return;
   }
   super.visitReferenceExpression(ref);
   final PsiElement resolvedElement = ref.resolve();
   if (variable.equals(resolvedElement)) {
     used = 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(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;
   }
 }