@Nonnull
    public Map<String, List<PipelineDao>> groupByRuleName(@Nonnull Supplier<Collection<PipelineDao>> pipelines, @Nonnull Set<String> ruleNames) {
        if (ruleNames.isEmpty()) {
            return ImmutableMap.of();
        }

        final Map<String, List<PipelineDao>> result = new HashMap<>();

        pipelines.get().stream()
                .flatMap(pipelineDao -> {
                    try {
                        final Pipeline parsedPipeline = pipelineParser.parsePipeline(pipelineDao.id(), pipelineDao.source());
                        return Stream.of(new ParsedPipelineWithSource(pipelineDao, parsedPipeline));
                    } catch (ParseException e) {
                        logger.warn("Ignoring non-parseable pipeline <{}/{}> with errors <{}>", pipelineDao.title(), pipelineDao.id(), e.getErrors());
                        return Stream.empty();
                    }
                }).forEach(pp -> {
                    for (String ruleName : ruleNames) {
                        if (!result.containsKey(ruleName)) {
                            result.put(ruleName, new ArrayList<>());
                        }
                        if (pp.parsed.containsRule(ruleName)) {
                            result.get(ruleName).add(pp.source);
                        }
                    }
                });

        return ImmutableMap.copyOf(result);
    }
@Test
    public void groupByRuleName_returnsAllPipelinesUsingProvidedRules() {
        // given
        saveNewPipelineDao("Pipeline 1", pipelineSource("Pipeline 1",
                "rule \"debug#1\"\n" + "rule\"debug#2\"\n", ""));

        saveNewPipelineDao("Pipeline 2", pipelineSource("Pipeline 2", "", ""));

        saveNewPipelineDao("Pipeline 3", pipelineSource("Pipeline 3",
                "rule   \"debug#2\"\n",
                "rule  \"debug#3\"\n"));

        saveNewPipelineDao("Pipeline 4", pipelineSource("Pipeline 4",
                "rule     \"debug#3\"\n",
                ""));

        saveNewPipelineDao("Broken Pipeline", pipelineSource("Pipeline 4",
                "ruleadasd     \"XXX\"\n",
                "aaaaa"));

        // when + then
        assertThat(underTest.groupByRuleName(() -> pipelines, Set.of("debug#3"))).satisfies(map -> {
            assertThat(map.get("debug#3")).satisfies(containsPipelines("Pipeline 3", "Pipeline 4"));
        });
        assertThat(underTest.groupByRuleName(() -> pipelines, Set.of("debug#2", "debug#3", "debug#4"))).satisfies(map -> {
            assertThat(map.get("debug#2")).satisfies(containsPipelines("Pipeline 1", "Pipeline 3"));
            assertThat(map.get("debug#3")).satisfies(containsPipelines("Pipeline 3", "Pipeline 4"));
            assertThat(map.get("debug#4")).isEmpty();
        });
        assertThat(underTest.groupByRuleName(() -> pipelines, Set.of())).isEmpty();
        assertThat(underTest.groupByRuleName(() -> pipelines, Set.of("debug#4"))).satisfies(map -> {
            assertThat(map.get("debug#4")).isEmpty();
        });
    }