public static Set<String> findKeywordsFromCrashReport(String crashReport) {
        Matcher matcher = CRASH_REPORT_STACK_TRACE_PATTERN.matcher(crashReport);
        Set<String> result = new HashSet<>();
        if (matcher.find()) {
            for (String line : matcher.group("stacktrace").split("\\n")) {
                Matcher lineMatcher = STACK_TRACE_LINE_PATTERN.matcher(line);
                if (lineMatcher.find()) {
                    String[] method = lineMatcher.group("method").split("\\.");
                    for (int i = 0; i < method.length - 2; i++) {
                        if (PACKAGE_KEYWORD_BLACK_LIST.contains(method[i])) {
                            continue;
                        }
                        result.add(method[i]);
                    }

                    Matcher moduleMatcher = STACK_TRACE_LINE_MODULE_PATTERN.matcher(line);
                    if (moduleMatcher.find()) {
                        for (String module : moduleMatcher.group("tokens").split(",")) {
                            String[] split = module.split(":");
                            if (split.length >= 2 && "xf".equals(split[0])) {
                                if (PACKAGE_KEYWORD_BLACK_LIST.contains(split[1])) {
                                    continue;
                                }

                                result.add(split[1]);
                            }
                        }
                    }
                }
            }
        }
        return result;
    }
@Test
    public void flammpfeil() throws IOException {
        assertEquals(
                new HashSet<>(Arrays.asList("slashblade", "flammpfeil")),
                CrashReportAnalyzer.findKeywordsFromCrashReport(loadLog("/crash-report/mod/flammpfeil.txt")));
    }