public void test_remove_tooBig() {
   NodeList<ASTNode> list = new NodeList<ASTNode>(argumentList());
   try {
     list.remove(1);
     fail("Expected IndexOutOfBoundsException");
   } catch (IndexOutOfBoundsException exception) {
     // Expected
   }
 }
  public void test_remove() {
    ArrayList<ASTNode> nodes = new ArrayList<ASTNode>();
    ASTNode firstNode = booleanLiteral(true);
    ASTNode secondNode = booleanLiteral(false);
    ASTNode thirdNode = booleanLiteral(true);
    nodes.add(firstNode);
    nodes.add(secondNode);
    nodes.add(thirdNode);
    NodeList<ASTNode> list = new NodeList<ASTNode>(argumentList());
    list.addAll(nodes);
    assertSize(3, list);

    assertSame(secondNode, list.remove(1));
    assertSize(2, list);
    assertSame(firstNode, list.get(0));
    assertSame(thirdNode, list.get(1));
  }
  /*
   * Finds all sources in graphNodes and adds them to the sL NodeList.
   */
  private void findSources(NodeList children) {
    NodeList sources = new NodeList();
    findInitialSources(children, sources);
    while (!sources.isEmpty()) {
      Node source = sources.getNode(sources.size() - 1);
      sL.add(source);
      sources.remove(source);
      removeSource(source, sources);

      // Check to see if the removal has made the parent node a source
      if (source.getParent() != null) {
        Node parent = source.getParent();
        setChildCount(parent, getChildCount(parent) - 1);
        if (isSource(parent) && canBeRemoved(parent)) {
          sources.add(parent);
          parent.flag = true;
        }
      }
    }
  }
  /*
   * Execution of the modified greedy cycle removal algorithm.
   */
  private void cycleRemove(NodeList children) {
    NodeList sR = new NodeList();
    do {
      findSinks(children, sR);
      findSources(children);

      // all sinks and sources added, find node with highest
      // outDegree - inDegree
      Node max = findNodeWithMaxDegree(children);
      if (max != null) {
        for (int i = 0; i < children.size(); i++) {
          Node child = (Node) children.get(i);
          if (child.flag) continue;
          if (child == max) restoreSinks(max, sR);
          else restoreSources(child);
        }
        remove(max);
      }
    } while (!allFlagged(children));
    while (!sR.isEmpty()) sL.add(sR.remove(sR.size() - 1));
  }
  /*
   * Finds all sinks in graphNodes and adds them to the passed NodeList
   */
  private void findSinks(NodeList children, NodeList rightList) {
    //	NodeList rightList = new NodeList();
    NodeList sinks = new NodeList();
    findInitialSinks(children, sinks);
    while (!sinks.isEmpty()) {
      Node sink = sinks.getNode(sinks.size() - 1);
      rightList.add(sink);
      sinks.remove(sink);
      removeSink(sink, sinks);

      // Check to see if the removal has made the parent node a sink
      if (sink.getParent() != null) {
        Node parent = sink.getParent();
        setChildCount(parent, getChildCount(parent) - 1);
        if (isSink(parent) && canBeRemoved(parent)) {
          sinks.add(parent);
          parent.flag = true;
        }
      }
    }
  }
 /**
  * Brings back all nodes nested in the given node.
  *
  * @param node the node to restore
  * @param sr current sinks
  */
 private void restoreSources(Node node) {
   if (node.flag && sL.contains(node)) {
     node.flag = false;
     if (node.getParent() != null)
       setChildCount(node.getParent(), getChildCount(node.getParent()) + 1);
     sL.remove(node);
     for (int i = 0; i < node.incoming.size(); i++) {
       Edge e = node.incoming.getEdge(i);
       restoreEdge(e);
     }
     for (int i = 0; i < node.outgoing.size(); i++) {
       Edge e = node.outgoing.getEdge(i);
       restoreEdge(e);
     }
   }
   if (node instanceof Subgraph) {
     Subgraph s = (Subgraph) node;
     for (int i = 0; i < s.members.size(); i++) {
       Node member = s.members.getNode(i);
       restoreSources(member);
     }
   }
 }