class TracerouteAnswererHelper {

  @VisibleForTesting
  Set<Flow> getFlows() {
    Set<Location> srcLocations =
        SpecifierFactories.getLocationSpecifierOrDefault(
                _sourceLocationStr, AllInterfacesLocationSpecifier.INSTANCE)
            .resolve(_specifierContext).stream()
            .filter(_isActiveLocation::visit)
            .collect(Collectors.toSet());

    checkArgument(
        !srcLocations.isEmpty(), "Found no active locations matching %s", _sourceLocationStr);

    ImmutableSet.Builder<Flow> setBuilder = ImmutableSet.builder();
    ImmutableSet.Builder<String> allProblems = ImmutableSet.builder();

    // Perform cross-product of all locations to flows
    for (Location srcLocation : srcLocations) {
      try {
        Flow.Builder flowBuilder = _flowBuilder;
        // Extract and source IP from header constraints,
        setSrcIp(_packetHeaderConstraints, srcLocation, flowBuilder);
        setStartLocation(_specifierContext.getConfigs(), flowBuilder, srcLocation);
        setBuilder.add(flowBuilder.build());
      } catch (IllegalArgumentException e) {
        // Try to ignore silently if possible
        allProblems.add(e.getMessage());
      }
    }

    Set<Flow> flows = setBuilder.build();
    checkArgument(
        !flows.isEmpty(),
        "Could not construct a flow for traceroute. Found issues: %s",
        String.join(",", allProblems.build()));
    return flows;
  }

  public  TracerouteAnswererHelper(
      PacketHeaderConstraints packetHeaderConstraints,
      String sourceLocationStr,
      SpecifierContext specifierContext);

}