@Override
    public void visitLocalVariable(@NotNull PsiLocalVariable variable) {
      super.visitLocalVariable(variable);
      if (variable.getType() == PsiTypes.nullType() || variable instanceof PsiResourceVariable) {
        return;
      }
      final PsiExpression initializer = variable.getInitializer();
      if (!isMovable(initializer)) {
        return;
      }
      final List<PsiReferenceExpression> references = findReferences(variable);
      if (references.isEmpty()) {
        return;
      }
      PsiElement commonParent = ScopeUtils.getCommonParent(references);
      if (commonParent == null) {
        return;
      }
      final PsiElement variableScope = PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class, PsiForStatement.class);
      if (variableScope == null) {
        return;
      }
      if (initializer != null) {
        commonParent = ScopeUtils.moveOutOfLoopsAndClasses(commonParent, variableScope);
        if (commonParent == null) {
          return;
        }
      }
      if (PsiTreeUtil.isAncestor(commonParent, variableScope, true)) {
        return;
      }
      if (PsiTreeUtil.isAncestor(variableScope, commonParent, true)) {
        registerVariableError(variable, variable);
        return;
      }
      if (m_onlyLookAtBlocks) {
        return;
      }
      if (commonParent instanceof PsiForStatement) {
        return;
      }
      final PsiElement referenceElement = references.get(0);
      final PsiElement blockChild = ScopeUtils.getChildWhichContainsElement(variableScope, referenceElement);
      if (blockChild == null) {
        return;
      }
      final PsiElement insertionPoint = ScopeUtils.findTighterDeclarationLocation(blockChild, variable, true);
      if (insertionPoint == null) {
        if (!isAssignmentToVariable(blockChild, variable)) {
          final PsiElement tightestInsertionPoint = ScopeUtils.findTighterDeclarationLocation(blockChild, variable, false);
          if (tightestInsertionPoint != null) {
            final PsiElement nameIdentifier = variable.getNameIdentifier();
            if (nameIdentifier == null) {
              return;
            }
            // register at information level because two declaration statements can always be switched, so the other declaration
            // is closer to usage in a common case, for example:
            // String s = "";
            // String t = "";
            // String u = s + t;
            if (isOnTheFly()) {
              registerError(nameIdentifier, ProblemHighlightType.INFORMATION, variable);
            }
          }
          return;
        }
      }
      if (insertionPoint != null && FileTypeUtils.isInServerPageFile(insertionPoint)) {
        PsiElement elementBefore = insertionPoint.getPrevSibling();
        elementBefore = PsiTreeUtil.skipWhitespacesBackward(elementBefore);
        if (elementBefore instanceof PsiDeclarationStatement) {
          final PsiElement variableParent = variable.getParent();
          if (elementBefore.equals(variableParent)) {
            return;
          }
        }
      }
      registerVariableError(variable, variable);
    }
@Override
    public void visitLocalVariable(@NotNull PsiLocalVariable variable)