public static void scopeCrawlUp(@NotNull PsiScopeProcessor processor, @Nullable ScopeOwner scopeOwner,
                                  @Nullable ScopeOwner originalScopeOwner, @Nullable String name, @Nullable PsiElement roof) {
    while (scopeOwner != null) {
      final Scope scope = ControlFlowCache.getScope(scopeOwner);
      if (name != null) {
        final boolean includeNestedGlobals = scopeOwner instanceof PyFile;
        for (PsiNamedElement resolved : scope.getNamedElements(name, includeNestedGlobals)) {
          if (isClassLevelDefinitionInvisibleToReference(resolved, scopeOwner, originalScopeOwner)) continue;
          if (!processor.execute(resolved, ResolveState.initial())) {
            return;
          }
        }
      }
      else {
        for (PsiNamedElement element : scope.getNamedElements()) {
          if (isClassLevelDefinitionInvisibleToReference(element, scopeOwner, originalScopeOwner)) continue;
          if (!processor.execute(element, ResolveState.initial())) {
            return;
          }
        }
      }
      for (PyImportedNameDefiner definer : scope.getImportedNameDefiners()) {
        if (isClassLevelDefinitionInvisibleToReference(definer, scopeOwner, originalScopeOwner)) continue;
        if (!processor.execute(definer, ResolveState.initial())) {
          return;
        }
      }
      if (scopeOwner == roof) {
        return;
      }
      if (name != null && scopeOwner instanceof PyClass && scopeOwner == originalScopeOwner) {
        scopeOwner = parentScopeForUnresolvedClassLevelName((PyClass)scopeOwner, name);
      }
      else {
        scopeOwner = ScopeUtil.getScopeOwner(scopeOwner);
      }
    }
  }
public static void scopeCrawlUp(@NotNull PsiScopeProcessor processor, @Nullable ScopeOwner scopeOwner,
                                  @Nullable ScopeOwner originalScopeOwner, @Nullable String name, @Nullable PsiElement roof)