@Nullable
 private PyClass getClassOwner(@Nullable PsiElement element) {
   for (ScopeOwner owner = ScopeUtil.getScopeOwner(element);
       owner != null;
       owner = ScopeUtil.getScopeOwner(owner)) {
     if (owner instanceof PyClass) {
       return (PyClass) owner;
     }
   }
   return null;
 }
 @Override
 public void visitPyTargetExpression(final PyTargetExpression node) {
   final ScopeOwner owner = ScopeUtil.getScopeOwner(node);
   if (owner instanceof PyFile || owner instanceof PyClass) {
     processElement(node);
   }
 }
 @NotNull
 @Override
 public SearchScope getUseScope() {
   final ScopeOwner scopeOwner = ScopeUtil.getScopeOwner(this);
   if (scopeOwner instanceof PyFunction) {
     return new LocalSearchScope(scopeOwner);
   }
   return super.getUseScope();
 }
 private static boolean inConstructor(@NotNull PsiElement expression) {
   final PsiElement expr = expression instanceof PyClass ? expression : expression.getParent();
   PyClass clazz = PyUtil.getContainingClassOrSelf(expr);
   final ScopeOwner current = ScopeUtil.getScopeOwner(expression);
   if (clazz != null && current != null && current instanceof PyFunction) {
     PyFunction init = clazz.findMethodByName(PyNames.INIT, false, null);
     if (current == init) {
       return true;
     }
   }
   return false;
 }
 public Object[] getCompletionVariants(
     String completionPrefix, PsiElement location, ProcessingContext context) {
   List<LookupElement> result = new ArrayList<LookupElement>();
   ScopeOwner scopeOwner = ScopeUtil.getScopeOwner(location);
   assert scopeOwner != null;
   final List<PyImportElement> importTargets = PyModuleType.getVisibleImports(scopeOwner);
   final int imported = myImportedModule.getImportedPrefix().getComponentCount();
   for (PyImportElement importTarget : importTargets) {
     final QualifiedName qName = importTarget.getImportedQName();
     if (qName != null && qName.matchesPrefix(myImportedModule.getImportedPrefix())) {
       final List<String> components = qName.getComponents();
       if (components.size() > imported) {
         String module = components.get(imported);
         result.add(LookupElementBuilder.create(module));
       }
     }
   }
   return result.toArray(new Object[result.size()]);
 }
 @Nullable
 public PyType getQualifiedReferenceTypeByControlFlow(@NotNull TypeEvalContext context) {
   PyExpression qualifier = getQualifier();
   if (context.allowDataFlow(this) && qualifier != null) {
     PyExpression next = qualifier;
     while (next != null) {
       qualifier = next;
       next =
           qualifier instanceof PyQualifiedExpression
               ? ((PyQualifiedExpression) qualifier).getQualifier()
               : null;
     }
     final ScopeOwner scopeOwner = ScopeUtil.getScopeOwner(this);
     final QualifiedName qname = asQualifiedName();
     if (qname != null && scopeOwner != null) {
       return getTypeByControlFlow(qname.toString(), context, qualifier, scopeOwner);
     }
   }
   return null;
 }
 private void processElement(@NotNull final PsiNameIdentifierOwner element) {
   if (isConditional(element)) {
     return;
   }
   final String name = element.getName();
   final ScopeOwner owner = ScopeUtil.getScopeOwner(element);
   if (owner != null && name != null) {
     final Instruction[] instructions = ControlFlowCache.getControlFlow(owner).getInstructions();
     PsiElement elementInControlFlow = element;
     if (element instanceof PyTargetExpression) {
       final PyImportStatement importStatement =
           PsiTreeUtil.getParentOfType(element, PyImportStatement.class);
       if (importStatement != null) {
         elementInControlFlow = importStatement;
       }
     }
     final int startInstruction =
         ControlFlowUtil.findInstructionNumberByElement(instructions, elementInControlFlow);
     if (startInstruction < 0) {
       return;
     }
     final Ref<PsiElement> readElementRef = Ref.create(null);
     final Ref<PsiElement> writeElementRef = Ref.create(null);
     ControlFlowUtil.iteratePrev(
         startInstruction,
         instructions,
         new Function<Instruction, ControlFlowUtil.Operation>() {
           @Override
           public ControlFlowUtil.Operation fun(Instruction instruction) {
             if (instruction instanceof ReadWriteInstruction
                 && instruction.num() != startInstruction) {
               final ReadWriteInstruction rwInstruction = (ReadWriteInstruction) instruction;
               if (name.equals(rwInstruction.getName())) {
                 final PsiElement originalElement = rwInstruction.getElement();
                 if (originalElement != null) {
                   if (rwInstruction.getAccess().isReadAccess()) {
                     readElementRef.set(originalElement);
                   }
                   if (rwInstruction.getAccess().isWriteAccess()) {
                     if (originalElement != element) {
                       writeElementRef.set(originalElement);
                     }
                   }
                 }
                 return ControlFlowUtil.Operation.CONTINUE;
               }
             }
             return ControlFlowUtil.Operation.NEXT;
           }
         });
     final PsiElement writeElement = writeElementRef.get();
     if (writeElement != null && readElementRef.get() == null) {
       final List<LocalQuickFix> quickFixes = new ArrayList<LocalQuickFix>();
       if (suggestRename(element, writeElement)) {
         quickFixes.add(new PyRenameElementQuickFix());
       }
       final PsiElement identifier = element.getNameIdentifier();
       registerProblem(
           identifier != null ? identifier : element,
           PyBundle.message("INSP.redeclared.name", name),
           ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
           null,
           quickFixes.toArray(new LocalQuickFix[quickFixes.size()]));
     }
   }
 }
 @Override
 public void visitPyReferenceExpression(final PyReferenceExpression node) {
   if (node.getContainingFile() instanceof PyExpressionCodeFragment) {
     return;
   }
   // Ignore global statements arguments
   if (PyGlobalStatementNavigator.getByArgument(node) != null) {
     return;
   }
   // Ignore qualifier inspections
   if (node.getQualifier() != null) {
     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 = getSession().getUserData(LARGE_FUNCTIONS_KEY);
   assert largeFunctions != null;
   if (owner == null || largeFunctions.contains(owner)) {
     return;
   }
   // Ignore references declared in outer scopes
   if (owner != ScopeUtil.getScopeOwner(node)) {
     return;
   }
   final Scope scope = ControlFlowCache.getScope(owner);
   // Ignore globals and if scope even doesn't contain such a declaration
   if (scope.isGlobal(name) || (!scope.containsDeclaration(name))) {
     return;
   }
   // 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);
   } catch (DFALimitExceededException e) {
     largeFunctions.add(owner);
     registerLargeFunction(owner);
     return;
   }
   if (variable == null) {
     if (!isFirstUnboundRead(node, owner)) {
       return;
     }
     final PsiPolyVariantReference ref = node.getReference(resolveWithoutImplicits());
     if (ref == null) {
       return;
     }
     final PsiElement resolved = ref.resolve();
     final boolean isBuiltin = PyBuiltinCache.getInstance(node).hasInBuiltins(resolved);
     if (owner instanceof PyClass) {
       if (isBuiltin || ScopeUtil.getDeclarationScopeOwner(owner, name) != null) {
         return;
       }
     }
     if (PyUnreachableCodeInspection.hasAnyInterruptedControlFlowPaths(node)) {
       return;
     }
     if (owner instanceof PyFile) {
       if (isBuiltin) {
         return;
       }
       if (resolved != null && !PyUtil.inSameFile(node, resolved)) {
         return;
       }
       registerProblem(node, PyBundle.message("INSP.unbound.name.not.defined", name));
     } else {
       registerProblem(
           node,
           PyBundle.message("INSP.unbound.local.variable", node.getName()),
           ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
           null,
           new AddGlobalQuickFix());
     }
   }
 }
 protected List<PsiElement> getOccurrences(
     PsiElement element, @NotNull final PyExpression expression) {
   return PyRefactoringUtil.getOccurrences(expression, ScopeUtil.getScopeOwner(expression));
 }