/**
   * DOCUMENT ME!
   *
   * @param edge DOCUMENT ME!
   * @return DOCUMENT ME!
   */
  public final boolean edgeRemove(final int edge) {
    if ((edge < 0) || (edge == Integer.MAX_VALUE)) {
      return false;
    }

    final Edge e = m_edges.getEdgeAtIndex(edge);

    if (e == null) {
      return false;
    }

    final Node source = m_nodes.getNodeAtIndex(e.sourceNode);
    final Node target = m_nodes.getNodeAtIndex(e.targetNode);

    if (e.prevOutEdge != null) {
      e.prevOutEdge.nextOutEdge = e.nextOutEdge;
    } else {
      source.firstOutEdge = e.nextOutEdge;
    }

    if (e.nextOutEdge != null) {
      e.nextOutEdge.prevOutEdge = e.prevOutEdge;
    }

    if (e.prevInEdge != null) {
      e.prevInEdge.nextInEdge = e.nextInEdge;
    } else {
      target.firstInEdge = e.nextInEdge;
    }

    if (e.nextInEdge != null) {
      e.nextInEdge.prevInEdge = e.prevInEdge;
    }

    if (e.directed) {
      source.outDegree--;
      target.inDegree--;
    } else {
      source.undDegree--;
      target.undDegree--;
    }

    if (source == target) { // Self-edge.

      if (e.directed) {
        source.selfEdges--;
      } else {
        source.undDegree++;
      }
    }

    m_edges.setEdgeAtIndex(null, edge);
    e.prevOutEdge = null;
    e.nextInEdge = null;
    e.prevInEdge = null;
    m_edgeDepot.recycleEdge(e);
    m_edgeCount--;

    return true;
  }
  /**
   * DOCUMENT ME!
   *
   * @param sourceNode DOCUMENT ME!
   * @param targetNode DOCUMENT ME!
   * @param directed DOCUMENT ME!
   * @return DOCUMENT ME!
   */
  public final int edgeCreate(final int sourceNode, final int targetNode, final boolean directed) {
    if ((sourceNode < 0) || (sourceNode == Integer.MAX_VALUE)) {
      return -1;
    }

    final Node source = m_nodes.getNodeAtIndex(sourceNode);

    if ((targetNode < 0) || (targetNode == Integer.MAX_VALUE)) {
      return -1;
    }

    final Node target = m_nodes.getNodeAtIndex(targetNode);

    if ((source == null) || (target == null)) {
      return -1;
    }

    final Edge e = m_edgeDepot.getEdge();
    final int returnThis;

    if (e.edgeId < 0) {
      returnThis = (e.edgeId = ++m_maxEdge);
    } else {
      returnThis = e.edgeId;
    }

    m_edges.setEdgeAtIndex(e, returnThis);
    m_edgeCount++;

    if (directed) {
      source.outDegree++;
      target.inDegree++;
    } else {
      source.undDegree++;
      target.undDegree++;
    }

    if (source == target) { // Self-edge.

      if (directed) {
        source.selfEdges++;
      } else {
        source.undDegree--;
      }
    }

    e.nextOutEdge = source.firstOutEdge;

    if (source.firstOutEdge != null) {
      source.firstOutEdge.prevOutEdge = e;
    }

    source.firstOutEdge = e;
    e.nextInEdge = target.firstInEdge;

    if (target.firstInEdge != null) {
      target.firstInEdge.prevInEdge = e;
    }

    target.firstInEdge = e;
    e.directed = directed;
    e.sourceNode = sourceNode;
    e.targetNode = targetNode;

    return returnThis;
  }