class Topology extends BfObject {

  public static Topology create(
      String testrigName,
      Map<String, Configuration> configurations,
      org.batfish.datamodel.Topology topology) {

    Topology pojoTopology = new Topology(testrigName);

    for (String nodeName : topology.getNodeEdges().keySet()) {
      Configuration configuration = configurations.get(nodeName);
      if (configuration == null) {
        throw new BatfishException("Node '" + nodeName + "' not found in configurations");
      }
      Node pojoNode =
          new Node(
              configuration.getHostname(),
              configuration.getDeviceModel(),
              configuration.getDeviceType());
      pojoTopology.getNodes().add(pojoNode);

      Map<String, org.batfish.datamodel.Interface> nodeInterfaces =
          configuration.getAllInterfaces();
      // add interfaces and links
      for (Edge edge : topology.getNodeEdges().get(nodeName)) {
        if (!edge.getNode1().equals(nodeName)) {
          // only consider edges where node1 is the source
          continue;
        }
        String interface1 = edge.getInt1();
        String interface2 = edge.getInt2();

        InterfaceType iface1type =
            nodeInterfaces.containsKey(interface1)
                ? nodeInterfaces.get(interface1).getInterfaceType()
                : InterfaceType.UNKNOWN;

        Configuration configuration2 = configurations.get(edge.getNode2());
        assert configuration2 != null; // assuming topology is valid
        InterfaceType iface2type =
            configuration2.getAllInterfaces().containsKey(interface2)
                ? configuration2.getAllInterfaces().get(interface2).getInterfaceType()
                : InterfaceType.UNKNOWN;

        Interface pojoInterface = new Interface(pojoNode.getId(), interface1, iface1type);

        LinkType linkType = Link.interfaceTypesToLinkType(iface1type, iface2type);
        Link pojoLink =
            new Link(
                pojoInterface.getId(),
                Interface.getId(Node.makeId(edge.getNode2()), interface2),
                linkType);

        pojoTopology.getInterfaces().add(pojoInterface);
        pojoTopology.getLinks().add(pojoLink);
      }
    }

    // add nodes that were not in Topology (because they have no Edges)
    for (Configuration configuration : configurations.values()) {
      Node pojoNode =
          new Node(
              configuration.getHostname(),
              configuration.getDeviceModel(),
              configuration.getDeviceType());
      pojoTopology.getNodes().add(pojoNode);
      // add AWS aggregates; put node in the smallest container we can find for them,
      // and then put that container in their container
      if (configuration.getConfigurationFormat() == ConfigurationFormat.AWS) {
        putInAwsAggregate(pojoTopology, configuration, pojoNode);
      }
    }
    return pojoTopology;
  }

  public  Topology(String testrigName);
  @JsonCreator public  Topology(
      @JsonProperty(PROP_ID) String topologyId,
      @JsonProperty(PROP_TESTRIG_NAME) String testrigName);

}