@NotNull
  private static List<PsiElement> calculateResolveModule(@NotNull ResolveModuleParams params) {
    final QualifiedName qualifiedName = params.getName();
    final int relativeLevel = params.getLevel();
    final PsiFile sourceFile = params.getFile();
    final boolean importIsAbsolute = params.isAbsolute();

    final String marker = qualifiedName + "#" + Integer.toString(relativeLevel);
    final Set<String> beingImported = ourBeingImported.get();
    if (beingImported.contains(marker)) {
      return Collections.emptyList(); // break endless loop in import
    }
    try {
      beingImported.add(marker);
      final QualifiedNameResolver visitor =
          new QualifiedNameResolverImpl(qualifiedName).fromElement(sourceFile);
      if (relativeLevel > 0) {
        // "from ...module import"
        visitor.withRelative(relativeLevel).withoutRoots();
      } else {
        // "from module import"
        if (!importIsAbsolute) {
          visitor.withRelative(0);
        }
      }
      return visitor.resultsAsList();
    } finally {
      beingImported.remove(marker);
    }
  }
 @Nullable
 public static PsiElement resolveModuleInRoots(
     @NotNull QualifiedName moduleQualifiedName, @Nullable PsiElement foothold) {
   if (foothold == null) return null;
   QualifiedNameResolver visitor =
       new QualifiedNameResolverImpl(moduleQualifiedName).fromElement(foothold);
   return visitor.firstResult();
 }