class RoutesAnswererUtil {

  static <T extends AbstractRouteDecorator> Multiset<Row> getMainRibRoutes(
      SortedMap<String, SortedMap<String, GenericRib<T>>> ribs,
      Set<String> matchingNodes,
      @Nullable Prefix network,
      RoutingProtocolSpecifier protocolSpec,
      String vrfRegex,
      @Nullable Map<Ip, Set<String>> ipOwners) {
    Multiset<Row> rows = HashMultiset.create();
    Pattern compiledVrfRegex = Pattern.compile(vrfRegex);
    Map<String, ColumnMetadata> columnMetadataMap =
        getTableMetadata(RibProtocol.MAIN).toColumnMap();
    ribs.forEach(
        (node, vrfMap) -> {
          if (matchingNodes.contains(node)) {
            vrfMap.forEach(
                (vrfName, rib) -> {
                  if (compiledVrfRegex.matcher(vrfName).matches()) {
                    rib.getRoutes().stream()
                        .filter(
                            route ->
                                (network == null || network.equals(route.getNetwork()))
                                    && protocolSpec.getProtocols().contains(route.getProtocol()))
                        .forEach(
                            route ->
                                rows.add(
                                    abstractRouteToRow(
                                        node, vrfName, route, columnMetadataMap, ipOwners)));
                  }
                });
          }
        });
    return rows;
  }

}