class CompareFiltersAnswerer extends Answerer {

  @VisibleForTesting
  static Stream<FilterDifference> compareFilters(
      String hostname,
      String filtername,
      List<PermitAndDenyBdds> currentLineBdds,
      List<PermitAndDenyBdds> referenceLineBdds,
      BDDPacket bddPacket) {
    checkArgument(!currentLineBdds.isEmpty());
    checkArgument(!referenceLineBdds.isEmpty());
    assert bddPacket
        .getFactory()
        .orAll(
            currentLineBdds.stream()
                .flatMap(bdds -> Stream.of(bdds.getPermitBdd(), bdds.getDenyBdd()))
                .collect(ImmutableList.toImmutableList()))
        .isOne();
    assert bddPacket
        .getFactory()
        .orAll(
            referenceLineBdds.stream()
                .flatMap(bdds -> Stream.of(bdds.getPermitBdd(), bdds.getDenyBdd()))
                .collect(ImmutableList.toImmutableList()))
        .isOne();

    return IntStream.range(0, currentLineBdds.size())
        .mapToObj(
            i -> {
              PermitAndDenyBdds currentLineBdd = currentLineBdds.get(i);
              return IntStream.range(0, referenceLineBdds.size())
                  // Filter to reference lines that cover packets in common with the current line
                  // but take different actions on them
                  .filter(j -> takeDifferentActions(currentLineBdd, referenceLineBdds.get(j)))
                  .mapToObj(
                      j ->
                          new FilterDifference(
                              hostname,
                              filtername,
                              i < currentLineBdds.size() - 1 ? i : null,
                              j < referenceLineBdds.size() - 1 ? j : null));
            })
        .flatMap(Function.identity());
  }

  public  CompareFiltersAnswerer(CompareFiltersQuestion question, IBatfish batfish);

}