@Nullable
  public static SourceFolder getModuleSourceRoot(@NotNull VirtualFile root, @NotNull Project project) {
    final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();
    if (!root.equals(projectFileIndex.getSourceRootForFile(root))) return null;
    
    final Module module = projectFileIndex.getModuleForFile(root);
    if (module == null || module.isDisposed()) return null;

    VirtualFile contentRoot = projectFileIndex.getContentRootForFile(root);
    if (contentRoot == null) return null;
    
    for (ContentEntry contentEntry : ModuleRootManager.getInstance(module).getContentEntries()) {
      if (contentRoot.equals(contentEntry.getFile())) {
        /*
         If there are several source roots pointing to the same directory, DirectoryIndex::getSourceFolder will return the last of them.
         It appears that we have code which relies on this behavior, so we'll temporarily keep it. 
        */
        SourceFolder @NotNull [] folders = contentEntry.getSourceFolders();
        for (int i = folders.length - 1; i >= 0; i--) {
          SourceFolder folder = folders[i];
          if (root.equals(folder.getFile())) {
            return folder;
          }
        }
      }
    }

    return null;
  }
@Nullable
  public static SourceFolder getModuleSourceRoot(@NotNull VirtualFile root, @NotNull Project project)