/**
  * Toggle the selection state of the given figures. Implemented as a template method so that
  * subclasses can override the behavior.
  */
 protected void toggleSelection(List hitFigures) {
   SelectionModel m = _interp.getController().getSelectionModel();
   for (Iterator i = hitFigures.iterator(); i.hasNext(); ) {
     Figure f = (Figure) i.next();
     if (!(m.containsSelection(f))) {
       m.addSelection(f);
     } else {
       m.removeSelection(f);
     }
   }
 }
  /**
   * Render the current graph again by recreating the figures for all nodes and edges, but do not
   * alter the connectivity in the graph. This should be called when changes to renderers are made.
   */
  public void rerender() {
    // FIXME: it would be nice to be able to do this without all
    // stupid business with the selection model.
    List selectedEdges = new LinkedList();
    List selectedNodes = new LinkedList();

    // Remove any old objects that no longer exist in the model Do
    // the edges first, then the nodes, since we cannot blow away
    // selection on an edge before getting rid of the endpoints of
    // the edge.
    Iterator figures = (new HashSet(_map.values())).iterator();

    while (figures.hasNext()) {
      Figure figure = (Figure) figures.next();
      Object object = figure.getUserObject();

      if (_model.isEdge(object)) {
        if (!GraphUtilities.isPartiallyContainedEdge(object, _model.getRoot(), _model)) {
          if (_selectionModel.containsSelection(figure)) {
            _selectionModel.removeSelection(figure);
          }

          clearEdge(object);

          // Previously, the figure was being left in _map,
          // which results in an accumulation over time
          // of figures that should not be rendered.
          // EAL 4/29/04.
          _map.remove(object);
        }
      }
    }

    figures = (new HashSet(_map.values())).iterator();

    while (figures.hasNext()) {
      Figure figure = (Figure) figures.next();
      Object object = figure.getUserObject();

      if (_model.isNode(object)) {
        if (!GraphUtilities.isContainedNode(object, _model.getRoot(), _model)) {
          if (_selectionModel.containsSelection(figure)) {
            _selectionModel.removeSelection(figure);
          }

          clearNode(object);

          // Previously, the figure was being left in _map,
          // which results in an accumulation over time
          // of figures that should not be rendered.
          // EAL 4/29/04.
          _map.remove(object);
        }
      }
    }

    // Save the selected edges.
    Iterator edges = GraphUtilities.totallyContainedEdges(_model.getRoot(), _model);

    while (edges.hasNext()) {
      Object edge = edges.next();
      Figure oldFigure = getFigure(edge);
      boolean selected = _selectionModel.containsSelection(oldFigure);

      if (selected) {
        selectedEdges.add(edge);
      }
    }

    // Save the selected nodes.
    Iterator nodes = (GraphUtilities.nodeSet(_model.getRoot(), _model)).iterator();

    while (nodes.hasNext()) {
      Object node = nodes.next();
      Figure oldFigure = getFigure(node);
      boolean selected = _selectionModel.containsSelection(oldFigure);

      if (selected) {
        selectedNodes.add(node);
      }
    }

    // Clear all the selections (note that there may be selected objects
    // which no longer exist!)
    _selectionModel.clearSelection();

    // Draw the nodes to be rendered before the edges.
    nodes = _model.nodesBeforeEdges(_model.getRoot());

    while (nodes.hasNext()) {
      Object node = nodes.next();
      drawNode(node);
    }

    // Draw the edges that are connected to any of the above nodes.
    edges = GraphUtilities.partiallyContainedEdges(_model.getRoot(), _model);

    while (edges.hasNext()) {
      Object edge = edges.next();
      drawEdge(edge);

      if (selectedEdges.contains(edge)) {
        _selectionModel.addSelection(getFigure(edge));
      }
    }

    // Draw the nodes to be rendered after the edges.
    nodes = _model.nodesAfterEdges(_model.getRoot());

    while (nodes.hasNext()) {
      Object node = nodes.next();
      drawNode(node);
    }

    // Restore the selected nodes.
    nodes = (GraphUtilities.nodeSet(_model.getRoot(), _model)).iterator();

    while (nodes.hasNext()) {
      Object node = nodes.next();

      if (selectedNodes.contains(node)) {
        _selectionModel.addSelection(getFigure(node));
      }
    }
  }