@Nullable
  public static DataIndexer<TodoIndexEntry, Integer, FileContent> getTodoIndexer(
      FileType fileType, final VirtualFile virtualFile) {
    final DataIndexer<TodoIndexEntry, Integer, FileContent> extIndexer;
    if (fileType instanceof SubstitutedFileType
        && !((SubstitutedFileType) fileType).isSameFileType()) {
      SubstitutedFileType sft = (SubstitutedFileType) fileType;
      extIndexer =
          new CompositeTodoIndexer(
              getTodoIndexer(sft.getOriginalFileType(), virtualFile),
              getTodoIndexer(sft.getFileType(), virtualFile));
    } else {
      extIndexer = TodoIndexers.INSTANCE.forFileType(fileType);
    }
    if (extIndexer != null) {
      return extIndexer;
    }

    if (fileType instanceof LanguageFileType) {
      final Language lang = ((LanguageFileType) fileType).getLanguage();
      final ParserDefinition parserDef = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
      final TokenSet commentTokens = parserDef != null ? parserDef.getCommentTokens() : null;
      if (commentTokens != null) {
        return new TokenSetTodoIndexer(commentTokens, virtualFile);
      }
    }

    if (fileType instanceof CustomSyntaxTableFileType) {
      return new TokenSetTodoIndexer(ABSTRACT_FILE_COMMENT_TOKENS, virtualFile);
    }

    return null;
  }
 public static boolean isTodoIndexerRegistered(@NotNull FileType fileType) {
   return TodoIndexers.INSTANCE.forFileType(fileType) != null
       || fileType instanceof InternalFileType;
 }