anchor.diff:                   (funcall continuation node (graph-node-children node) #'walk))))
         (funcall continuation graph (graph-root-nodes graph) #'walk))))
   
  -(defmethod layout-graph-nodes ((graph-output-record tree-graph-output-record)
  +(defmethod generate-graph-nodes ((graph-output-record tree-graph-output-record)
  +                                 stream root-objects
  +                                 object-printer inferior-producer
  +                                 &key &allow-other-keys)
  +;;;  (with-slots (merge-duplicates) graph-output-record
  +;;;    (when merge-duplicates
  +      ;; I'm not sure what to do here. Saying you want a tree, but want
  +      ;; duplicates merged seems wrong. OTOH, if you go out of your way
  +      ;; to do it, at your own risk, is it our place to say "no"?
  +      ;; [2005/08/11:rpg]
  +      ;; Let's not signal an error, but proceed such that that the output
  +      ;; will be equivalent to the DAG graph type. --JAC 2017/09/04
  +;;;     (cerror "Set to NIL and continue?"
  +;;;	        "Merge duplicates specified to be true when using :tree layout")
  +;;;     (setf merge-duplicates nil)))
  +  (call-next-method))
  +
  +(defmethod generate-graph-nodes ((graph-output-record dag-graph-output-record)
  +                                 stream root-objects
  +                                 object-printer inferior-producer
  +                                 &key &allow-other-keys)
  +  (with-slots (merge-duplicates) graph-output-record
  +    ;; This case is more serious than the converse above. If we're not allowed to
  +    ;; merge duplicate nodes then we can't output a DAG... get the user to acknowledge
  +    ;; this. --JAC 2017/09/04
  +    (unless merge-duplicates
  +      (cerror "Set to T and continue?"
  +              "DAG graph-layout type only supports merge-duplicates to be T")
  +      (setf merge-duplicates t)))
  +  (call-next-method))
  +
  +(defmethod generate-graph-nodes ((graph-output-record digraph-graph-output-record)
  +                                 stream root-objects
  +                                 object-printer inferior-producer
  +                                 &key &allow-other-keys)
  +  (with-slots (merge-duplicates) graph-output-record
  +    (unless merge-duplicates
  +      (cerror "Set to T and continue?"
  +              "Digraph graph-layout type only supports merge-duplicates to be T")
  +      (setf merge-duplicates t)))
  +  (call-next-method))
  +
  +
  +;;; The CLIM II specification gives a broad hint that what we are doing here is fine:
  +;;; "Typically, different graph types will use different output record classes and layout
  +;;; engines to lay out the graph. However, it is permissible for all of the required graph
  +;;; types to use exactly the same graph layout engine." We have specialized versions
  +;;; of layout-graph-nodes since we have a single engine that works tolerably well for all.
  +
  +(defmethod layout-graph-nodes ((graph-output-record standard-graph-output-record)
                                  stream arc-drawer arc-drawing-options)
  -  ;; work in progress! --GB 2002-08-14
  +  "Layout for DAGs, digraphs and trees. There are three phases that traverse the
  +graph topologically. The first assigns a depth to each node, the second
  +computes minor and major dimensions, and the final one lays nodes out by depth.
  +Assumes that GENERATE-GRAPH-NODES has generated only nodes up to the cutoff-depth."
     (declare (ignore arc-drawer arc-drawing-options))
  -  (with-slots (orientation center-nodes generation-separation within-generation-separation root-nodes) graph-output-record
  -    (check-type orientation (member :horizontal :vertical)) ;xxx move to init.-inst.
  -    ;; here major dimension is the dimension in which we grow the
  -    ;; tree.
  -    (let ((within-generation-separation (parse-space stream within-generation-separation
  -                                                     (case orientation
  -                                                       (:horizontal :vertical)
  -                                                       (:vertical :horizontal))))
  -          (generation-separation (parse-space stream generation-separation orientation)))
  -      ;; generation sizes is an adjustable array that tracks the major
  -      ;; dimension of each of the generations [2005/07/18:rpg]
  -      (let ((generation-sizes (make-array 10 :adjustable t :initial-element 0)))
  -        (labels ((node-major-dimension (node)
  -                   (if (eq orientation :vertical)
  -                       (bounding-rectangle-height node)
  -                       (bounding-rectangle-width node)))
  -                 (node-minor-dimension (node)
  -                   (if (eq orientation :vertical)
  -                       (bounding-rectangle-width node)
  -                       (bounding-rectangle-height node)))
  -		 ;; WALK returns a node minor dimension for the node,
  -		 ;; AFAICT, allowing space for that node's children
  -		 ;; along the minor dimension. [2005/07/18:rpg]
  -                 (walk (node depth)
  -                   (unless (graph-node-minor-size node)
  -                     (when (>= depth (length generation-sizes))
  -                       (setf generation-sizes (adjust-array generation-sizes (ceiling (* depth 1.2)) :initial-element 0)))
  -                     (setf (aref generation-sizes depth)
  -                           (max (aref generation-sizes depth) (node-major-dimension node)))
  -                     (setf (graph-node-minor-size node) 0)
  -                     (max (node-minor-dimension node)
  -                          (setf (graph-node-minor-size node)
  -                                (let ((sum 0) (n 0))
  -                                  (map nil (lambda (child)
  -                                             (let ((x (walk child (+ depth 1))))
  -                                               (when x
  -                                                 (incf sum x)
  -                                                 (incf n))))
  -                                       (graph-node-children node))
  -                                  (+ sum
  -                                     (* (max 0 (- n 1)) within-generation-separation))))))))
  -          (map nil #'(lambda (x) (walk x 0)) root-nodes)
  -          (let ((hash (make-hash-table :test #'eq)))
  -            (labels ((foo (node majors u0 v0)
  -                       (cond ((gethash node hash)
  -                              v0)
  -                             (t
  -                              (setf (gethash node hash) t)
  -                              (let ((d (- (node-minor-dimension node)
  -                                          (graph-node-minor-size node))))
  -                                (let ((v (+ v0 (/ (min 0 d) -2))))
  -                                  (setf (output-record-position node)
  -                                        (if (eq orientation :vertical)
  -                                            (transform-position (medium-transformation stream) v u0)
  -                                            (transform-position (medium-transformation stream) u0 v)))
  -                                  (add-output-record node graph-output-record))
  -                                ;;
  -                                (let ((u (+ u0 (car majors)))
  -                                      (v (+ v0 (max 0 (/ d 2))))
  -                                      (firstp t))
  -                                  (map nil (lambda (q)
  -                                             (unless (gethash q hash)
  -                                               (if firstp
  -                                                   (setf firstp nil)
  -                                                   (incf v within-generation-separation))
  -                                               (setf v (foo q (cdr majors)
  -                                                            u v))))
  -                                           (graph-node-children node)))
  -                                ;;
  -                                (+ v0 (max (node-minor-dimension node)
  -                                           (graph-node-minor-size node))))))))
  -              ;;
  -              (let ((majors (mapcar (lambda (x) (+ x generation-separation))
  -                                    (coerce generation-sizes 'list))))
  -                (let ((u (+ 0 (car majors)))
  -                      (v 0))
  -                  (maplist (lambda (rest)
  -                             (setf v (foo (car rest) majors u v))
  -                             (unless (null rest)
  -                               (incf v within-generation-separation)))
  -                           (graph-root-nodes graph-output-record)))))))))))
  -
  -;;;; Edges
  -
  -(defclass standard-edge-output-record (standard-sequence-output-record)
  -  ((stream)
  -   (arc-drawer)
  -   (arc-drawing-options)
  -   (from-node :initarg :from-node)
  -   (to-node :initarg :to-node)))
  -
  -
  -(defmethod layout-graph-nodes ((graph-output-record dag-graph-output-record)
  -                               stream arc-drawer arc-drawing-options)
  -  "This is a first shot at a DAG layout.  First does a TOPO sort that associates 
  -each node with a depth, then lays out by depth.  Tries to reuse a maximum of the
  -tree graph layout code.
  -PRECONDITION:  This code assumes that we have generated only nodes up to the 
  -cutoff-depth.  GENERATE-GRAPH-NODES seems to obey this precondition."
  -  (declare (ignore arc-drawer arc-drawing-options))
  -  (with-slots (orientation center-nodes generation-separation within-generation-separation root-nodes
  -			   merge-duplicates) graph-output-record
  -    ;; this code is snarly enough, handling merge-duplicates.  If
  -    ;; you're not merging duplicates, you're out of luck, at least for
  -    ;; now... [2005/07/18:rpg]
  -    (unless merge-duplicates
  -      (cerror "Set to T and continue?" "DAG graph-layout type only supports merge-duplicates to be T")
  -      (setf merge-duplicates t))
  -	      
  -    (check-type orientation (member :horizontal :vertical)) ;xxx move to init.-inst.
  -
  -    ;; here major dimension is the dimension in which we grow the
  -    ;; tree.
  +  (with-slots (orientation center-nodes generation-separation within-generation-separation
  +                           root-nodes maximize-generations)
  +      graph-output-record
  +
  +    ;; major dimension is the dimension in which we grow the graph, i.e. horizontal for
  +    ;; horizontal orientation
       (let ((within-generation-separation (parse-space stream within-generation-separation
                                                        (case orientation
                                                          (:horizontal :vertical)
  
positive.code:              (princ node s)))
       #'(lambda (x) (if (consp x) (list (car x) (cdr x))))
       :cutoff-depth nil
       :graph-type :tree
       :merge-duplicates t
       :arc-drawer #'arrow-arc-drawer
       :arc-drawing-options (list :ink +red+ :line-thickness 1)
       :orientation orientation
       :stream stream)))
  ||#
  
negative.code:       (within-generation-separation
         :initarg :within-generation-separation
         :initform '(1/2 :line))
        (maximize-generations
         :initarg :maximize-generations
         :initform nil)
        (root-nodes
         :accessor graph-root-nodes)
        ))
  
  (defclass tree-graph-output-record (standard-graph-output-record)
    ())
  
  (defclass dag-graph-output-record (standard-graph-output-record)
    ())
  
  (defclass digraph-graph-output-record (standard-graph-output-record)
    ())
  