class ForwardingAnalysisImpl implements ForwardingAnalysis, Serializable {

  @VisibleForTesting
  static Map<String, Map<String, Map<Edge, Set<AbstractRoute>>>> computeRoutesWithDestIpEdge(
      Topology topology,
      Map<String, Map<String, Map<String, Set<AbstractRoute>>>> routesWhereDstIpCanBeArpIp) {
    Span span =
        GlobalTracer.get().buildSpan("ForwardingAnalysisImpl.computeRoutesWithDestIpEdge").start();
    try (Scope scope = GlobalTracer.get().scopeManager().activate(span)) {
      assert scope != null; // avoid unused warning

      return toImmutableMap(
          routesWhereDstIpCanBeArpIp,
          Entry::getKey, // node
          nodeEntry ->
              toImmutableMap(
                  nodeEntry.getValue(),
                  Entry::getKey, // vrf
                  vrfEntry ->
                      vrfEntry.getValue().entrySet().stream()
                          .flatMap(
                              ifaceEntry -> {
                                NodeInterfacePair out =
                                    NodeInterfacePair.of(nodeEntry.getKey(), ifaceEntry.getKey());
                                Set<AbstractRoute> routes = ifaceEntry.getValue();
                                return topology.getNeighbors(out).stream()
                                    .map(
                                        receiver ->
                                            Maps.immutableEntry(new Edge(out, receiver), routes));
                              })
                          .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue))));
    } finally {
      span.finish();
    }
  }

  public  ForwardingAnalysisImpl(
      Map<String, Configuration> configurations,
      Map<String, Map<String, Fib>> fibs,
      Topology topology,
      Map<Location, LocationInfo> locationInfo);

}