@NotNull
  private static List<RatedResolveResult> resolveInDirectory(
      @NotNull final String referencedName,
      @Nullable final PsiFile containingFile,
      final PsiDirectory dir,
      boolean isFileOnly,
      boolean checkForPackage) {
    final PsiDirectory subdir = dir.findSubdirectory(referencedName);
    if (subdir != null && (!checkForPackage || PyUtil.isPackage(subdir, containingFile))) {
      return ResolveResultList.to(subdir);
    }

    final PsiFile module = findPyFileInDir(dir, referencedName);
    if (module != null) {
      return ResolveResultList.to(module);
    }

    if (!isFileOnly) {
      // not a subdir, not a file; could be a name in parent/__init__.py
      final PsiFile initPy = dir.findFile(PyNames.INIT_DOT_PY);
      if (initPy == containingFile) {
        return Collections.emptyList(); // don't dive into the file we're in
      }
      if (initPy instanceof PyFile) {
        return ((PyFile) initPy).multiResolveName(referencedName);
      }
    }
    return Collections.emptyList();
  }
 @NotNull
 private static List<RatedResolveResult> resolveInPackageDirectory(
     @Nullable PsiElement parent,
     @NotNull String referencedName,
     @Nullable PsiFile containingFile,
     boolean fileOnly,
     boolean checkForPackage) {
   final PsiElement parentDir = PyUtil.turnInitIntoDir(parent);
   if (parentDir instanceof PsiDirectory) {
     final List<RatedResolveResult> resolved =
         resolveInDirectory(
             referencedName, containingFile, (PsiDirectory) parentDir, fileOnly, checkForPackage);
     if (!resolved.isEmpty()) {
       for (RatedResolveResult result : resolved) {
         if (result.getRate() > RatedResolveResult.RATE_LOW) {
           return resolved;
         }
       }
     }
     if (parent instanceof PsiFile) {
       final PsiElement foreign = resolveForeignImports((PsiFile) parent, referencedName);
       if (foreign != null) {
         final ResolveResultList results = new ResolveResultList();
         results.addAll(resolved);
         results.poke(foreign, RatedResolveResult.RATE_NORMAL);
         return results;
       }
     }
     return resolved;
   }
   return Collections.emptyList();
 }
  @NotNull
  private static List<RatedResolveResult> resolveInPackageModule(
      @NotNull PyFile parent,
      @NotNull String referencedName,
      @Nullable PsiFile containingFile,
      boolean fileOnly,
      boolean checkForPackage) {
    final List<RatedResolveResult> moduleMembers = resolveModuleMember(parent, referencedName);
    final List<RatedResolveResult> resolvedInModule = Lists.newArrayList();
    final List<RatedResolveResult> results = Lists.newArrayList();
    for (RatedResolveResult member : moduleMembers) {
      final PsiElement moduleMember = member.getElement();
      if (!fileOnly || PyUtil.instanceOf(moduleMember, PsiFile.class, PsiDirectory.class)) {
        results.add(member);
        if (moduleMember != null && !preferResolveInDirectoryOverModule(moduleMember)) {
          resolvedInModule.add(member);
        }
      }
    }
    if (!resolvedInModule.isEmpty()) {
      return resolvedInModule;
    }

    final List<RatedResolveResult> resolvedInDirectory =
        resolveInPackageDirectory(
            parent, referencedName, containingFile, fileOnly, checkForPackage);
    if (!resolvedInDirectory.isEmpty()) {
      return resolvedInDirectory;
    }

    return results;
  }
 /**
  * Resolves a module reference in a general case.
  *
  * @param qualifiedName qualified name of the module reference to resolve
  * @param sourceFile where that reference resides; serves as PSI foothold to determine module,
  *     project, etc.
  * @param importIsAbsolute if false, try old python 2.x's "relative first, absolute next"
  *     approach.
  * @param relativeLevel if > 0, step back from sourceFile and resolve from there (even if
  *     importIsAbsolute is false!).
  * @return list of possible candidates
  */
 @NotNull
 public static List<PsiElement> resolveModule(
     @Nullable QualifiedName qualifiedName,
     @Nullable PsiFile sourceFile,
     boolean importIsAbsolute,
     int relativeLevel) {
   if (qualifiedName == null || sourceFile == null) {
     return Collections.emptyList();
   }
   final ResolveModuleParams params =
       new ResolveModuleParams(qualifiedName, sourceFile, importIsAbsolute, relativeLevel);
   return PyUtil.getParameterizedCachedValue(
       sourceFile, params, ResolveImportUtil::calculateResolveModule);
 }
 /**
  * Finds a directory that many levels above a given file, making sure that every level has an
  * __init__.py.
  *
  * @param base file that works as a reference.
  * @param depth must be positive, 1 means the dir that contains base, 2 is one dir above, etc.
  * @return found directory, or null.
  */
 @Nullable
 public static PsiDirectory stepBackFrom(PsiFile base, int depth) {
   if (depth == 0) {
     return base.getContainingDirectory();
   }
   PsiDirectory result;
   if (base != null) {
     base = base.getOriginalFile(); // just to make sure
     result = base.getContainingDirectory();
     int count = 1;
     while (result != null && PyUtil.isPackage(result, base)) {
       if (count >= depth) return result;
       result = result.getParentDirectory();
       count += 1;
     }
   }
   return null;
 }
 public static ResolveResultList rateResults(List<? extends PsiElement> targets) {
   ResolveResultList ret = new ResolveResultList();
   for (PsiElement target : targets) {
     if (target instanceof PsiDirectory) {
       target = PyUtil.getPackageElement((PsiDirectory) target, null);
     }
     if (target != null) {
       int rate = RatedResolveResult.RATE_HIGH;
       if (target instanceof PyFile) {
         for (PyResolveResultRater rater :
             Extensions.getExtensions(PyResolveResultRater.EP_NAME)) {
           rate += rater.getImportElementRate(target);
         }
       } else if (isDunderAll(target)) {
         rate = RatedResolveResult.RATE_NORMAL;
       }
       ret.poke(target, rate);
     }
   }
   return ret;
 }
  @NotNull
  public static List<RatedResolveResult> resolveNameInFromImport(
      PyFromImportStatement importStatement, @NotNull QualifiedName qName) {
    PsiFile file = importStatement.getContainingFile().getOriginalFile();
    String name = qName.getComponents().get(0);

    final List<PsiElement> candidates = importStatement.resolveImportSourceCandidates();
    List<PsiElement> resultList = new ArrayList<PsiElement>();
    for (PsiElement candidate : candidates) {
      if (!candidate.isValid()) {
        throw new PsiInvalidElementAccessException(
            candidate,
            "Got an invalid candidate from resolveImportSourceCandidates(): "
                + candidate.getClass());
      }
      if (candidate instanceof PsiDirectory) {
        candidate = PyUtil.getPackageElement((PsiDirectory) candidate, importStatement);
      }
      List<RatedResolveResult> results = resolveChildren(candidate, name, file, false, true);
      if (!results.isEmpty()) {
        for (RatedResolveResult result : results) {
          final PsiElement element = result.getElement();
          if (element != null) {
            if (!element.isValid()) {
              throw new PsiInvalidElementAccessException(
                  element, "Got an invalid candidate from resolveChild(): " + element.getClass());
            }
            resultList.add(element);
          }
        }
      }
    }
    if (!resultList.isEmpty()) {
      return rateResults(resultList);
    }
    return Collections.emptyList();
  }
 private static boolean preferResolveInDirectoryOverModule(@NotNull PsiElement resolved) {
   return PsiTreeUtil.getStubOrPsiParentOfType(resolved, PyExceptPart.class) != null
       || PyUtil.instanceOf(resolved, PsiFile.class, PsiDirectory.class)
       || // XXX: Workaround for PY-9439
       isDunderAll(resolved);
 }