@NotNull
 public static Collection<FqName> getTopLevelFunctionFqNames(
     @NotNull Project project, @NotNull GlobalSearchScope scope, boolean shouldBeExtension) {
   Collection<FqName> result = Sets.newHashSet();
   Collection<PsiClass> packageClasses =
       getClassesByAnnotation(KotlinPackage.class.getSimpleName(), project, scope);
   for (PsiClass psiClass : packageClasses) {
     String qualifiedName = psiClass.getQualifiedName();
     if (qualifiedName == null) {
       continue;
     }
     FqName packageFqName = new FqName(qualifiedName).parent();
     PackageData data = getPackageData(psiClass);
     if (data == null) {
       continue;
     }
     NameResolver nameResolver = data.getNameResolver();
     for (ProtoBuf.Callable callable : data.getPackageProto().getMemberList()) {
       if (callable.hasReceiverType() == shouldBeExtension) {
         Name name = nameResolver.getName(callable.getName());
         result.add(packageFqName.child(name));
       }
     }
   }
   return result;
 }
  /**
   * Get names that could have jet descriptor equivalents. It could be inaccurate and return more
   * results than necessary.
   */
  static Collection<String> getPossiblePackageDeclarationsNames(
      Project project, GlobalSearchScope scope) {
    Collection<String> result = new ArrayList<String>();

    for (PsiClass packageClass : getClassesForKotlinPackages(project, scope)) {
      for (PsiMethod psiMethod : packageClass.getMethods()) {
        if (psiMethod.getModifierList().hasModifierProperty(PsiModifier.STATIC)) {
          result.add(psiMethod.getName());
        }
      }
    }

    return result;
  }
  @Nullable
  static FqName getJetTopLevelDeclarationFQN(@NotNull PsiMethod method) {
    PsiClass containingClass = method.getContainingClass();

    if (containingClass != null) {
      String qualifiedName = containingClass.getQualifiedName();
      assert qualifiedName != null;

      FqName classFQN = new FqName(qualifiedName);

      if (JavaResolverPsiUtils.isCompiledKotlinPackageClass(containingClass)) {
        FqName classParentFQN = QualifiedNamesUtil.withoutLastSegment(classFQN);
        return QualifiedNamesUtil.combine(classParentFQN, Name.identifier(method.getName()));
      }
    }

    return null;
  }
  static Collection<PsiClass> getCompiledClassesForTopLevelObjects(
      Project project, GlobalSearchScope scope) {
    Set<PsiClass> jetObjectClasses = Sets.newHashSet();

    Collection<PsiClass> classesByAnnotation =
        getClassesByAnnotation(KotlinClass.class.getSimpleName(), project, scope);

    for (PsiClass psiClass : classesByAnnotation) {
      ClassKind kind = getCompiledClassKind(psiClass);
      if (kind == null) {
        continue;
      }
      if (psiClass.getContainingClass() == null && kind == ClassKind.OBJECT) {
        jetObjectClasses.add(psiClass);
      }
    }

    return jetObjectClasses;
  }
 @Nullable
 private static String[] getAnnotationDataForKotlinClass(@NotNull PsiClass psiClass) {
   VirtualFile virtualFile = getVirtualFileForPsiClass(psiClass);
   if (virtualFile != null) {
     KotlinJvmBinaryClass kotlinClass =
         VirtualFileFinder.SERVICE
             .getInstance(psiClass.getProject())
             .createKotlinClass(virtualFile);
     KotlinClassHeader header = kotlinClass.getClassHeader();
     if (header != null) {
       return header.getAnnotationData();
     }
   }
   return null;
 }
 // TODO: common utility
 // TODO: doesn't work for inner classes and stuff
 @Nullable
 private static VirtualFile getVirtualFileForPsiClass(@NotNull PsiClass psiClass) {
   PsiFile psiFile = psiClass.getContainingFile();
   return psiFile == null ? null : psiFile.getVirtualFile();
 }