/**
   * @param hexEdge ...
   * @param weight ...
   */
  public void merge(HexEdge<D, W> hexEdge, W weight) {
    int oldIndex = DOMAIN.labelOf(hexEdge.weight());

    hexEdge.mergeWeightWith(weight);

    int newIndex = DOMAIN.labelOf(hexEdge.weight());

    if (oldIndex != newIndex) {
      updateUsedIndexExtrema(newIndex);

      INDEX[oldIndex] = hexEdge.removeFromEqualWeightLabelList(INDEX[oldIndex]);

      hexEdge.addToEqualWeightLabelList(INDEX[newIndex]);
      INDEX[newIndex] = hexEdge;
    }
  }
  /** @param hexEdge ... */
  public void add(HexEdge<D, W> hexEdge) {
    int index = DOMAIN.labelOf(hexEdge.weight());
    updateUsedIndexExtrema(index);

    hexEdge.addToEqualWeightLabelList(INDEX[index]);
    INDEX[index] = hexEdge;
  }
  /** @param domain ... */
  @SuppressWarnings("unchecked")
  public ByWeightIndex(EdgeWeightDomain<W> domain) {
    DOMAIN = domain;
    INDEX = new HexEdge /*<D, W>*/[domain.size()];

    greatestUsedIndex = -1;
    smallestUsedIndex = INDEX.length;
  }
  private Map<Integer, Set<HexEdge<D, W>>> theoreticalByWeightIndex(
      Collection<HexEdge<D, W>> allEdges) {
    Map<Integer, Set<HexEdge<D, W>>> theoretical = new HashMap<Integer, Set<HexEdge<D, W>>>();

    for (int i = 0; i < INDEX.length; i++) {
      theoretical.put(i, new HashSet<HexEdge<D, W>>());
    }

    for (HexEdge<D, W> hexEdge : allEdges) {
      assert theoretical.get(DOMAIN.labelOf(hexEdge.weight())).add(hexEdge);
    }

    return theoretical;
  }
 /** @param hexEdge ... */
 public void remove(HexEdge<D, W> hexEdge) {
   int index = DOMAIN.labelOf(hexEdge.weight());
   INDEX[index] = hexEdge.removeFromEqualWeightLabelList(INDEX[index]);
 }