ParseService { @MutableCopy @NotNull @VisibleForTesting static List<Parser> getSortedMatchingParsers( @NotNull IndexingConfig config, @NotNull File file, @NotNull String filename) throws IOException { class Match { final Parser parser; boolean mimeMatch = false; boolean extMatch = false; public Match(@NotNull Parser parser) { this.parser = parser; } public int getMatchCount() { return (mimeMatch ? 1 : 0) + (extMatch ? 1 : 0); } } Set<Match> matches = Sets.newTreeSet(new Comparator<Match>() { public int compare(Match m1, Match m2) { int cmp = -1 * Ints.compare(m1.getMatchCount(), m2.getMatchCount()); if (cmp != 0) return cmp; if (m1.mimeMatch && !m2.mimeMatch) return -1; if (!m1.mimeMatch && m2.mimeMatch) return 1; String name1 = m1.parser.getClass().getSimpleName(); String name2 = m2.parser.getClass().getSimpleName(); return name1.compareTo(name2); } }); List<String> mimeTypes = getPossibleMimeTypes(file); String ext = Util.getExtension(filename); for (Parser parser : parsers) { Match match = new Match(parser); if (!Collections.disjoint(mimeTypes, parser.getTypes())) match.mimeMatch = true; for (String candidateExt : getExtensions(config, parser)) { if (candidateExt.toLowerCase().equals(ext)) { match.extMatch = true; break; } } if (match.mimeMatch || match.extMatch) matches.add(match); } List<Parser> parsers = Util.createEmptyList(matches); for (Match match : matches) parsers.add(match.parser); return parsers; } private  ParseService(); @Immutable @NotNull static List<Parser> getParsers(); @NotNull static ParseResult parse(@NotNull IndexingConfig config,
	                                @NotNull File file,
	                                @NotNull String filename,
	                                @NotNull Path filepath,
	                                @NotNull IndexingReporter reporter,
	                                @NotNull Cancelable cancelable); @NotNull static String renderText(@NotNull IndexingConfig config,
	                                @NotNull File file,
	                                @NotNull String filename,
									@NotNull String parserName); static boolean canParseByName(	@NotNull IndexingConfig config,
											@NotNull String filename); static boolean isBuiltInExtension(	@NotNull IndexingConfig config,
												@NotNull String extension);  }
@Test public void testMimeTypeOverlap() throws Exception { IndexingConfig config = new IndexingConfig(); File odtFile = TestFiles.lorem_ipsum_odt.get(); List<Parser> odtParsers = ParseService.getSortedMatchingParsers( config, odtFile, odtFile.getName()); assertTrue(equalClasses(odtParsers, OpenOfficeParser.OpenOfficeWriterParser.class, MSOffice2007Parser.MSExcel2007Parser.class, MSOffice2007Parser.MSPowerPoint2007Parser.class, MSOffice2007Parser.MSWord2007Parser.class, OpenOfficeParser.OpenOfficeCalcParser.class, OpenOfficeParser.OpenOfficeDrawParser.class, OpenOfficeParser.OpenOfficeImpressParser.class )); File docxFile = TestFiles.lorem_ipsum_docx.get(); List<Parser> docxParsers = ParseService.getSortedMatchingParsers( config, docxFile, docxFile.getName()); assertTrue(equalClasses(docxParsers, MSOffice2007Parser.MSWord2007Parser.class, MSOffice2007Parser.MSExcel2007Parser.class, MSOffice2007Parser.MSPowerPoint2007Parser.class, OpenOfficeParser.OpenOfficeCalcParser.class, OpenOfficeParser.OpenOfficeDrawParser.class, OpenOfficeParser.OpenOfficeImpressParser.class, OpenOfficeParser.OpenOfficeWriterParser.class )); }