/** Adds all switches and corresponding links to the overall cluster. */
  protected void addLinks() {
    // add all switches to cluster.
    for (long sw : switches) {
      cluster.add(sw);
    }

    // add corresponding links to cluster.
    for (long sw : switches) {
      if (switchPorts.get(sw) == null) continue;
      for (int p : switchPorts.get(sw)) {
        NodePortTuple npt = new NodePortTuple(sw, p);
        if (allSwitchPortLinks.get(npt) == null) continue;
        for (Link l : allSwitchPortLinks.get(npt)) {
          if (isBlockedLink(l)) continue;
          cluster.addLink(l);
        }
      }
    }
  }
  /** Sets the link weights and calculates a spanning tree using Dijkstra's algorithm. */
  protected void calculateShortestPathTree() {
    topologyDestinationRootedTrees.clear();

    Map<Link, Integer> linkCost = new HashMap<Link, Integer>();
    int tunnel_weight = switchPorts.size() + 1;

    // calculate and set link costs.
    for (NodePortTuple npt : tunnelPorts) {
      if (switchPortLinks.get(npt) == null) continue;
      for (Link link : switchPortLinks.get(npt)) {
        if (link == null) continue;
        linkCost.put(link, tunnel_weight);
      }
    }

    // calculate the spanning tree using dijkstra's algorithm.
    for (Long node : cluster.getLinks().keySet()) {
      BroadcastTree tree = dijkstra(cluster, node, linkCost, true);
      topologyDestinationRootedTrees.put(node, tree);
    }
  }
 /**
  * Calculates the overall broadcast tree by choosing on tree out of all destination rooted trees.
  */
 protected void calculateBroadcastTree() {
   // cluster.getId() returns the smallest node that's in the cluster
   broadcastTree = topologyDestinationRootedTrees.get(cluster.getId());
 }