/**
   * DOCUMENT ME!
   *
   * @param node0 DOCUMENT ME!
   * @param node1 DOCUMENT ME!
   * @param outgoing DOCUMENT ME!
   * @param incoming DOCUMENT ME!
   * @param undirected DOCUMENT ME!
   * @return DOCUMENT ME!
   */
  public final IntIterator edgesConnecting(
      final int node0,
      final int node1,
      final boolean outgoing,
      final boolean incoming,
      final boolean undirected) {
    final IntEnumerator node0Adj = edgesAdjacent(node0, outgoing, incoming, undirected);
    final IntEnumerator node1Adj = edgesAdjacent(node1, incoming, outgoing, undirected);

    if ((node0Adj == null) || (node1Adj == null)) {
      return null;
    }

    final IntEnumerator theAdj;
    final int nodeZero;
    final int nodeOne;

    if (node0Adj.numRemaining() <= node1Adj.numRemaining()) {
      theAdj = node0Adj;
      nodeZero = node0;
      nodeOne = node1;
    } else {
      theAdj = node1Adj;
      nodeZero = node1;
      nodeOne = node0;
    }

    return new ConnectingEdgesIterator(theAdj, nodeZero, nodeOne, this);
  }
  /**
   * DOCUMENT ME!
   *
   * @param node DOCUMENT ME!
   * @return DOCUMENT ME!
   */
  public final boolean nodeRemove(final int node) {
    final IntEnumerator edges = edgesAdjacent(node, true, true, true);

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

    m_stack.empty();

    while (edges.numRemaining() > 0) m_stack.push(edges.nextInt());

    while (m_stack.size() > 0) edgeRemove(m_stack.pop());

    final Node n = m_nodes.getNodeAtIndex(node);

    if (n.prevNode != null) {
      n.prevNode.nextNode = n.nextNode;
    } else {
      m_firstNode = n.nextNode;
    }

    if (n.nextNode != null) {
      n.nextNode.prevNode = n.prevNode;
    }

    m_nodes.setNodeAtIndex(null, node);
    n.prevNode = null;
    n.firstOutEdge = null;
    n.firstInEdge = null;
    m_nodeDepot.recycleNode(n);
    m_nodeCount--;

    return true;
  }
  private static final void _REPEAT_TEST_CASE_(final int[] elements, final int[] output) {
    _THE_HEAP_.empty();
    _THE_HEAP_.toss(elements, 0, elements.length);

    final IntEnumerator iter = _THE_HEAP_.orderedElements(true);
    final int numElements = iter.numRemaining();

    if (numElements != output.length)
      throw new IllegalStateException("output array is incorrect size");

    for (int i = 0; i < numElements; i++) output[i] = iter.nextInt();
  }
  private static final int[] _THE_TEST_CASE_(final int[] elements) {
    _THE_HEAP_ = new MinIntHeap();
    _THE_HEAP_.toss(elements, 0, elements.length);

    final IntEnumerator iter = _THE_HEAP_.orderedElements(true);
    final int[] returnThis = new int[iter.numRemaining()];
    final int numElements = returnThis.length;

    for (int i = 0; i < numElements; i++) returnThis[i] = iter.nextInt();

    return returnThis;
  }
    private void ensureComputeNext() {
      if (nextEdge != -1) {
        return;
      }

      while (theAdj.numRemaining() > 0) {
        final int edge = theAdj.nextInt();

        if (nodeOne == (nodeZero ^ graph.edgeSource(edge) ^ graph.edgeTarget(edge))) {
          nextEdge = edge;

          return;
        }
      }

      nextEdge = -2;
    }