/**
   * Process an edge and its labels.
   *
   * @param edge an edge
   * @param edgeRouting the global edge routing setting
   */
  private KVector processEdge(final KEdge edge, final EdgeRouting edgeRouting) {
    KEdgeLayout edgeLayout = edge.getData(KEdgeLayout.class);
    boolean sameHierarchy = edge.getSource().getParent() == edge.getTarget().getParent();
    KVector maxv = new KVector();
    KVectorChain bendPoints = edgeLayout.getProperty(LayoutOptions.BEND_POINTS);
    // we need at least two bend points, since the source point and target point must be included
    if (bendPoints != null && bendPoints.size() >= 2) {
      edgeLayout.applyVectorChain(bendPoints);
    }

    // determine maximal coordinates
    if (sameHierarchy) {
      for (KPoint point : edgeLayout.getBendPoints()) {
        maxv.x = Math.max(maxv.x, point.getX());
        maxv.y = Math.max(maxv.y, point.getY());
      }
    }

    // set the fixed position of the edge labels, or leave them as they are
    for (KLabel label : edge.getLabels()) {
      KShapeLayout labelLayout = label.getData(KShapeLayout.class);
      KVector pos = labelLayout.getProperty(LayoutOptions.POSITION);
      if (pos != null) {
        labelLayout.applyVector(pos);
      }
      if (sameHierarchy) {
        maxv.x = Math.max(maxv.x, labelLayout.getXpos() + labelLayout.getWidth());
        maxv.y = Math.max(maxv.y, labelLayout.getYpos() + labelLayout.getHeight());
      }
    }

    return maxv;
  }
  /** {@inheritDoc} */
  @Override
  public void applyLayout() {
    // applying the compacted positions
    applyNodePositions();

    // calculating new graph size and offset
    KVector topLeft = new KVector(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
    KVector bottomRight = new KVector(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
    for (CNode cNode : cGraph.cNodes) {
      topLeft.x = Math.min(topLeft.x, cNode.hitbox.x);
      topLeft.y = Math.min(topLeft.y, cNode.hitbox.y);
      bottomRight.x = Math.max(bottomRight.x, cNode.hitbox.x + cNode.hitbox.width);
      bottomRight.y = Math.max(bottomRight.y, cNode.hitbox.y + cNode.hitbox.height);
    }
    layeredGraph.getOffset().reset().add(topLeft.clone().negate());
    layeredGraph.getSize().reset().add(bottomRight.clone().sub(topLeft));

    // resetting lists
    cGraph.cGroups.clear();
    cGraph.cNodes.clear();
  }