@Override
    public void visitPyReferenceExpression(final @NotNull PyReferenceExpression node) {
      if (PyResolveUtil.allowForwardReferences(node)) {
        return;
      }

      if (node.getContainingFile() instanceof PyExpressionCodeFragment) {
        return;
      }
      // Ignore global statements arguments
      if (PyGlobalStatementNavigator.getByArgument(node) != null) {
        return;
      }
      // Ignore qualifier inspections
      if (node.isQualified()) {
        return;
      }
      // Ignore import subelements
      if (PsiTreeUtil.getParentOfType(node, PyImportStatementBase.class) != null) {
        return;
      }
      final String name = node.getReferencedName();
      if (name == null) {
        return;
      }
      final ScopeOwner owner = ScopeUtil.getDeclarationScopeOwner(node, name);
      final Set<ScopeOwner> largeFunctions = LARGE_FUNCTIONS;
      assert largeFunctions != null;
      if (owner == null || largeFunctions.contains(owner)) {
        return;
      }
      // Check if it is nonlocal to search in appropriate scope later
      boolean isNonLocal = false;
      ScopeOwner currentScopeOwner = ScopeUtil.getScopeOwner(node);
      if (currentScopeOwner != null) {
        isNonLocal = ControlFlowCache.getScope(currentScopeOwner).isNonlocal(name);
      }
      if (owner != currentScopeOwner && !isNonLocal) {
        return;
      }
      final Scope scope = ControlFlowCache.getScope(isNonLocal ? currentScopeOwner : owner);
      // Start DFA from the assignment statement in case of augmented assignments
      final PsiElement anchor;
      final PyAugAssignmentStatement augAssignment = PsiTreeUtil.getParentOfType(node, PyAugAssignmentStatement.class);
      if (augAssignment != null && name.equals(augAssignment.getTarget().getName())) {
        anchor = augAssignment;
      }
      else {
        anchor = node;
      }
      final ScopeVariable variable;
      try {
        variable = scope.getDeclaredVariable(anchor, name, myTypeEvalContext);
      }
      catch (DFALimitExceededException e) {
        largeFunctions.add(owner);
        registerLargeFunction(owner);
        return;
      }
      if (variable == null) {
        if (!isFirstUnboundRead(node, owner)) {
          return;
        }
        final PsiPolyVariantReference ref = node.getReference(getResolveContext());
        final PsiElement resolved = ref.resolve();
        final boolean isBuiltin = PyBuiltinCache.getInstance(node).isBuiltin(resolved);
        if (owner instanceof PyClass) {
          if (isBuiltin || ScopeUtil.getDeclarationScopeOwner(owner, name) != null) {
            return;
          }
        }
        if (PyDelStatementNavigator.getDelStatementByTarget(node) != null) {
          return;
        }
        if (resolvedUnderWithStatement(node, resolved) || resolvedUnderAssignmentExpressionAndCondition(node, resolved)) {
          return;
        }
        if (PyInspectionsUtil.hasAnyInterruptedControlFlowPaths(node, myTypeEvalContext)) {
          return;
        }
        if (owner instanceof PyFile) {
          if (isBuiltin) {
            return;
          }
          if (resolved != null && !PyUtil.inSameFile(node, resolved)) {
            return;
          }
          registerProblem(node, PyPsiBundle.message("INSP.unbound.name.undefined", name));
        }
        else if (scope.isGlobal(name)) {
          registerProblem(node, PyPsiBundle.message("INSP.unbound.name.undefined", name));
        }
        else if (isNonLocal) {
          registerProblem(node, PyPsiBundle.message("INSP.unbound.local.variable", name));
        }
        else {
          registerProblem(node, PyPsiBundle.message("INSP.unbound.local.variable", node.getName()),
                          ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
                          null,
                          new AddGlobalQuickFix());
        }
      }
    }
@Override
    public void visitPyReferenceExpression(final @NotNull PyReferenceExpression node)