diff --git a/Examples/draggable-graph.lisp b/Examples/draggable-graph.lisp
index 4d938a5..2cdadc7 100644
--- a/Examples/draggable-graph.lisp
+++ b/Examples/draggable-graph.lisp
@@ -96,18 +96,13 @@
 	    (x-offset (- x px))
 	    (y-offset (- y py)))
 	(assert (typep graph 'graph-output-record))
-	(erase-output-record graph-node *standard-output*)
 	(dolist (edge edges)
 	  (clear-output-record edge))
 	(when edges (repaint-sheet *standard-output* erase-region))
-	(multiple-value-bind (final-x final-y)
+	(multiple-value-bind (final-x final-y) 
 	    (drag-output-record *standard-output* graph-node
-				:erase-final t
 				:finish-on-release t)
-	  (setf (output-record-position graph-node)
-		(values (- final-x x-offset) (- final-y y-offset)))
-          
-	  (add-output-record graph-node graph)
+	  (declare (ignore final-x final-y))
 	  (redisplay-edges graph edges)
 	  (repaint-sheet *standard-output* graph-node))))))
          
diff --git a/pointer-tracking.lisp b/pointer-tracking.lisp
index 8615ca1..f136180 100644
--- a/pointer-tracking.lisp
+++ b/pointer-tracking.lisp
@@ -14,8 +14,8 @@
 ;;; Library General Public License for more details.
 ;;;
 ;;; You should have received a copy of the GNU Library General Public
-;;; License along with this library; if not, write to the 
-;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
+;;; License along with this library; if not, write to the
+;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;;; Boston, MA  02111-1307  USA.
 
 ;;; TODO:
@@ -48,7 +48,7 @@
 	    (,the-sheet ,sheet)
 	    (,the-pointer (or ,pointer (port-pointer ,the-port)))
 	    (,grabbed nil))
-       ;; Don't end up in the debugger with the pointer grabbed! 
+       ;; Don't end up in the debugger with the pointer grabbed!
        (handler-bind ((error #'(lambda (c)
 				 (declare (ignore c))
 				 (when ,grabbed
@@ -169,140 +169,307 @@
 
 ;;; DRAG-OUTPUT-RECORD and DRAGGING-OUTPUT.
 ;;;
-;;; XXX Unresolved issues:
-;;; multiple-window is completely unsupported.
-;;; window-repaint events while dragging.
-
-(defun bound-rectangles (r1-x1 r1-y1 r1-x2 r1-y2 r2-x1 r2-y1 r2-x2 r2-y2)
-  (values (min r1-x1 r2-x1) (min r1-y1 r2-y1)
-	  (max r1-x2 r2-x2) (max r1-y2 r2-y2)))
-
+;;; XXX: :multiple-window is supported but without understanding how
+;;; it should behave. There is mess in the specifications. The key
+;;; `:multiple-window' is absent in original CLIM 2.0 spec from
+;;; Symbolics/Apple/Xerox. Both CLIM 2.0 from LW and CLIM 2.2.2 from
+;;; Franz don't clearly explain the meaning. -- EMZ
 
 (defgeneric drag-output-record
-    (stream output
-     &key repaint erase feedback finish-on-release multiple-window))
-
-;;; Fancy double-buffered feedback function
-(defun make-buffered-feedback-function (record finish-on-release erase-final)
-  (multiple-value-bind (record-x record-y)
-      (output-record-position record)
-    (lambda (record stream initial-x initial-y x y event)
-      (flet ((simple-erase ()
-	       (when erase-final
-		 (when (output-record-parent record)
-		   (delete-output-record record (output-record-parent record)))
-		 (with-double-buffering
-		     ((stream record) (buffer-rectangle))
-		   (stream-replay stream buffer-rectangle)))))
-	(let ((dx (- record-x initial-x))
-	      (dy (- record-y initial-y)))
-	  (typecase event
-	    (null
-	     (setf (output-record-position record) (values (+ dx x) (+ dy y)))
-	     (stream-add-output-record stream record)
-	     (stream-replay stream record))
-	    (pointer-motion-event
-	     ;; Don't do an explicit erase. Instead, update the position of the
-	     ;; output record and redraw the union of the old and new
-	     ;; positions.
-	     (with-bounding-rectangle* (old-x1 old-y1 old-x2 old-y2)
-	       record
-	       (when (output-record-parent record)
-		 (delete-output-record record (output-record-parent record)))
-	       (setf (output-record-position record)
-		     (values (+ dx x) (+  dy y)))
-	       (stream-add-output-record stream record)
-	       (with-bounding-rectangle* (new-x1 new-y1 new-x2 new-y2)
-		 record
-		 (multiple-value-bind (area-x1 area-y1 area-x2 area-y2)
-		     (bound-rectangles old-x1 old-y1 old-x2 old-y2
-				       new-x1 new-y1 new-x2 new-y2)
-		   (with-double-buffering
-		       ((stream area-x1 area-y1 area-x2 area-y2)
-			(buffer-rectangle))
-		     (stream-replay stream buffer-rectangle))))))
-	    (pointer-button-press-event
-	     (unless finish-on-release
-	       (simple-erase)))
-	    (pointer-button-release-event
-	     (when finish-on-release
-	       (simple-erase)))
-	    (t nil)))))))
-
-;;; If the user supplies a feedback function, create a function to
-;;; call it with the simple :draw / :erase arguments.
-
-(defun make-simple-feedback-function
-    (record feedback finish-on-release erase-final)
-  (declare (ignore record))
-  (lambda (record stream initial-x initial-y x y event)
-    (typecase event
-      (null
-       (funcall feedback record stream initial-x initial-y x y :draw))
-      (pointer-motion-event
-       (funcall feedback record stream initial-x initial-y x y :erase)
-       (funcall feedback record stream initial-x initial-y x y :draw))
-      (pointer-button-press-event
-       (unless finish-on-release
-	 (when erase-final
-	   (funcall feedback record stream initial-x initial-y x y :erase))))
-      (pointer-button-release-event
-       (when (and finish-on-release erase-final)
-	 (funcall feedback record stream initial-x initial-y x y :erase)))
-      (t nil))))
-
+    (stream record
+	    &key repaint erase feedback finish-on-release multiple-window))
+
+;; Q: What about the returned values?
+;;
+;; Original CLIM 2.0 spec says about only two returned values x and y
+;; as final pointer position. CLIM 2.2.2 says nothing about the
+;; returned values. However, the sample program from the specification
+;; shows that four values (x y delta-x delta-y) are returned. The code
+;; below from simple CAD example shows that delta-x and delta-y are
+;; the initial pointer offset from the upper left corner of output
+;; record. LW's CLIM 2.0 also states: "The returned values are the
+;; final x and y positions of the pointer, and the delta-x and delta-y
+;; position of the mouse with respect to the origin of the object at
+;; the time it was originally selected by the pointer". We will return
+;; the four values. A legacy code, that was written in accordance with
+;; original specification, would take only the first two values from
+;; this tuple.
+
+;; An example from CLIM 2.2.2 specification (Franz)
+;; ================================================
+;;
+;; (define-cad-demo-command (com-move-component :menu "Move")
+;;   ((component 'component :gesture :select))
+;;  (let ((stream (clim:get-frame-pane clim:*application-frame* 'design-area)))
+;;   (draw-self component stream :ink +background-ink+)
+;;   (multiple-value-bind (x y delta-x delta-y)
+;;     (let ((*draw-connections* nil))
+;;      (clim:drag-output-record
+;;       stream component
+;;       :repaint t
+;;       :erase #'(lambda (c s)
+;;             (draw-body c s :ink clim:+background-ink+))
+;;       :finish-on-release t))
+;;    (move component (- x delta-x) (+ *component-size* (- y delta-y))))
+;;   (draw-self component stream)))
+
+
+;; Example from Symbolics with simple :feedback function
+;; =====================================================
+;;
+;; Date: Wed, 18 Aug 1993 11:41 -0400
+;; From: Scott McKay <SWM@stony-brook.scrc.symbolics.com>
+;; Subject: dragging-output
+;; To: jga@harlequin.com, paolucci+@pitt.edu
+;; Cc: clim@bbn.com
+;;
+;; ;;; Now make a drawer that simplifies the object as it moves it
+;; (define-presentation-action move-the-shape-with-outline
+;;     (movable-object nil funbox :gesture :describe)
+;;     (presentation window)
+;;   (flet ((drawer (record stream init-x init-y x y alu)
+;; 	   (declare (ignore alu init-x init-y x y))
+;; 	   (with-bounding-rectangle* (lef top rit bot) record
+;; 	     (draw-rectangle* stream lef top rit bot
+;; 			      :filled nil :ink +flipping-ink+))))
+;;     (drag-output-record window presentation
+;; 			:finish-on-release t :feedback #'drawer)))
+;;
+;;
+;; What could we deduce from this example and author's comment?
+;;
+;; * When `:feedback' is provided, the record is not appeared on
+;; screen while moved. This follows from the author's comment "Now
+;; make a drawer that simplifies the object as it moves it". Franz'
+;; CLIM imlementation has the the same behaviour.
+;;
+;; * The record changes its position offscreen, what follows from the
+;; `:feedback' function, where record's bounding rectangle is used.
+;;
+;; * When `:feedback/:erase' is called, both the record and pointer
+;; positions from previous step are passed to user; whenever
+;; `:feedback/:draw', the `drag-output-record' gets the new ones.
+;;
+;; * `:feedback' and `:erase' are called with disabled recording.
 
 (defmethod drag-output-record
     ((stream output-recording-stream) (record output-record)
      &key (repaint t) (erase #'erase-output-record)
-     feedback finish-on-release multiple-window
-     feedback-event erase-final)
-  (declare (ignore erase repaint multiple-window))
-  (let ((feedback-event-fn
-	 (cond (feedback-event
-		feedback-event)
-	       (feedback
-		(make-simple-feedback-function record
-					       feedback
-					       finish-on-release
-					       erase-final))
-	       (t (make-buffered-feedback-function record
-						   finish-on-release
-						   erase-final)))))
-    (setf (stream-current-output-record stream)
-	  (stream-output-history stream))
-    (let* ((pointer (port-pointer (port stream)))
-	   (pointer-state (pointer-button-state pointer)))
-      (multiple-value-bind (x0 y0)
-	  (stream-pointer-position stream)
-	(funcall feedback-event-fn record stream x0 y0 x0 y0 nil)
-	(tracking-pointer (stream)
-	 (:pointer-motion (&key event x y)
-	   ;; XXX What about the sheet?
-	   (funcall feedback-event-fn record stream x0 y0 x y event)
-	   (funcall feedback-event-fn record stream x0 y0 x y event))
-	 (:pointer-button-press (&key event x y)
-	   (unless finish-on-release
-	     (funcall feedback-event-fn record stream x0 y0 x y event)
-	     (return-from drag-output-record (values x y))))
-	 (:pointer-button-release (&key event x y)
-	   ;; If the button released was one of those held down on entry to
-	   ;; drag-output-record, we're done.
-	   (when (and finish-on-release
-		      (not (zerop (logand pointer-state
-					  (pointer-event-button event)))))
-	     (funcall feedback-event-fn record stream x0 y0 x y event)
-	     (return-from drag-output-record (values x y)))))))))
-  
-(defmacro dragging-output ((&optional (stream '*standard-output*) &rest args
-			    &key (repaint t) finish-on-release multiple-window)
+     (feedback nil) (finish-on-release nil) multiple-window)
+  (declare (ignore multiple-window repaint))
+  (multiple-value-bind (x0 y0)
+      (stream-pointer-position stream)
+    (multiple-value-bind (record-x record-y)
+	(output-record-position record)
+      (let* ((pointer (port-pointer (port stream)))
+	     (pointer-state (pointer-button-state pointer))
+	     (parent (output-record-parent record))
+	     (delta-x (- x0 record-x))
+	     (delta-y (- y0 record-y))
+	     (x-old x0)
+	     (y-old y0))
+	(labels
+	    ((do-feedback (x y op)
+	       (with-output-recording-options (stream :record nil)
+		 (funcall feedback record stream x0 y0 x y op)))
+	     (do-final-erase ()
+	       (when feedback
+		 (do-feedback x-old y-old :erase)
+		 ;; Add the record to it's parent
+		 (unless (output-record-parent record)
+		   (add-output-record record parent))
+		 (with-double-buffering ((stream record) (buffer))
+		   (stream-replay stream buffer)))))
+	       
+	  ;; XXX: I want to unhighlight previously highlighted
+	  ;; presentation. I have copied this from tracking-pointer
+	  ;; for a while.  
+	  ;;
+	  ;; TODO: Implement `unhighlight-highlited-presentation' from
+	  ;; specification. -- EMZ 2010-01-06
+
+	  (let ((hilited (frame-hilited-presentation *application-frame*)))
+	    (when hilited
+	      (highlight-presentation-1 (car hilited) (cdr hilited)
+					:unhighlight)))
+
+	  ;; Franz' CLIM draws initial feedback (if provided) when we
+	  ;; enter into `drag-output-record'. We will do the
+	  ;; same. Possible alternative is to draw initial feedback
+	  ;; only when the user moves pointer first time. A particular
+	  ;; behaviour is unspecified.
+
+	  (when feedback
+	      (erase-output-record record stream)
+	      (do-feedback x0 y0 :draw))
+
+	  ;; `tracking-pointer' macro is not used here because we need
+	  ;; to handle `window-repaint-event'.
+
+	  (loop
+	     for event = (event-read stream)
+	     do
+	     ;; TODO: Think about `:multiple-window nil' to be
+	     ;; implemented by grabbing pointer for stream.
+	     (if (and (not (eq (event-sheet event) stream))
+		      multiple-window)
+		 (handle-event (event-sheet event) event)
+		 (typecase event
+	       
+		   (pointer-motion-event
+		    (multiple-value-bind (x y)
+			(pointer-event-position* event)
+		      (if feedback
+			  (progn
+			    ;; Double buffering belongs to user.
+			    (do-feedback x-old y-old :erase)
+			    (setf (output-record-position record)
+				  (values (- x delta-x) (- y delta-y)))
+			    (do-feedback x y :draw))
+			  ;; Franz' CLIM always erases the record from
+			  ;; history at the beginning of
+			  ;; drag-output-record and then constantly
+			  ;; erases and replays it without re-adding
+			  ;; it back into the history. My current
+			  ;; solution is something different: the
+			  ;; record always stays in output
+			  ;; history. However, this behaviour could be
+			  ;; changed in the future. The details are
+			  ;; not described in spec. -- EMZ
+			  (with-double-buffering 
+			      ((stream (region-union 
+					(transform-region
+					 (make-translation-transformation 
+					  (- x x-old) (- y y-old)) record)
+					record)) (buffer))
+			    ;; Erase record (recording is off)
+			    (with-output-recording-options (stream :record nil)
+			      (funcall erase record stream))
+			    ;; Move the record
+			    (setf (output-record-position record)
+				  (values (- x delta-x) (- y delta-y)))
+			    ;; Add the record to the it's original
+			    ;; parent again if it has been previously
+			    ;; deleted from the output history
+			    (unless (output-record-parent record)
+			      (add-output-record record parent))
+			    (if repaint
+				;; repaint the whole region
+				(stream-replay stream buffer)
+				;; replay only the record
+				(replay-output-record record stream))))
+		      (setq x-old x y-old y)))
+		    
+		   (window-repaint-event
+		    (if feedback
+			(progn
+			  (do-feedback x-old y-old :erase)
+			  (handle-event stream event)
+			  (do-feedback x-old y-old :draw))
+			;; If :feedback is not provided. As far as the
+			;; record always stays in the output history,
+			;; it will be safely repainted by generic
+			;; repainting routine.
+			(handle-event stream event)))
+
+		   ;; (i) We have not such arguments to pass
+		   ;; `drag-output-record' an information about what
+		   ;; button had been pressed and where the pointer
+		   ;; had been positioned when output record was
+		   ;; selected. We capture pointer state
+		   ;; (`pointer-state' variable) and position x0, y0
+		   ;; at the beginning of `drag-output-record'.
+
+		   ;; (ii) We should take into accont a time gap
+		   ;; between the moment when the output record is
+		   ;; selected and the moment when the pointer state
+		   ;; is captured. User may press, hold or release any
+		   ;; button within this gap. This follows to
+		   ;; incorrect pointer-state. Fortunately, we can
+		   ;; catch these actions in subsequent
+		   ;; pointer-button-press-event handler and strip the
+		   ;; pointer-state by clearing undesirable buttons.
+
+		   ;; (iii) We should ignore all other buttons that
+		   ;; can be pressed or released after the pointer
+		   ;; state had been captured.
+
+		   ;; (iv) If more then one button had been pressed
+		   ;; and held before the moment of selection of
+		   ;; output record, we are not able to distinguish,
+		   ;; what button was used for selecting the
+		   ;; record. We will wait until all of pressed
+		   ;; buttons will be released.
+
+		   ;; 1. `:finish-on-release' is t. Simple solution:
+		   ;; we will constantly clear event buttons from
+		   ;; pointer-state in pointer-button-release and
+		   ;; pointer-button-press handlers. When the
+		   ;; pointer-state will become 0, then exit.
+
+		   ;; 2. `:finish-on-release' is nil. Currently, a
+		   ;; click on any pointer button can be used to
+		   ;; finish dragging operation. Franz' CLIM behaves
+		   ;; the same.
+
+		   (pointer-button-press-event
+		    (multiple-value-bind (x y)
+			(pointer-event-position* event)
+		      (if finish-on-release
+			  (setq pointer-state 
+				(logandc2 pointer-state 
+					  (pointer-event-button event)))
+			  (progn
+			    (do-final-erase)
+			    (return-from drag-output-record
+			      (values x y delta-x delta-y))))))
+
+		   (pointer-button-release-event
+		    (multiple-value-bind (x y)
+			(pointer-event-position* event)
+		      (when finish-on-release
+			(setq pointer-state 
+			      (logandc2 pointer-state
+					(pointer-event-button event)))
+			(when (zerop pointer-state)
+			  (do-final-erase)
+			  (return-from drag-output-record
+			    (values x y delta-x delta-y))))))
+
+		   (t (handle-event stream event))))))))))
+
+
+;; CLIM specification describes implementation details for this macro:
+;; record should be created with `with-output-to-output-record'; a
+;; dragging of this newly created record should be performed by
+;; `drag-output-record'. We will follow them. However, the
+;; specification doesn't limit us to particular `:feedback' or
+;; `:erase' function.
+(defmacro dragging-output ((&optional (stream '*standard-output*)
+				      &rest args
+				      &key (repaint t) finish-on-release
+				      multiple-window)
 			   &body body)
   (declare (ignore repaint finish-on-release multiple-window))
   (setq stream (stream-designator-symbol stream '*standard-output*))
-  (with-gensyms (record)
-    `(let ((,record (with-output-to-output-record (,stream)
-		      ,@body)))
-       (drag-output-record ,stream ,record :erase-final t ,@args))))
+  (with-gensyms (record r s x y delta-x delta-y x1 y1 x2 y2)
+    `(let ((,record (with-output-to-output-record (,stream) ,@body)))
+       (stream-add-output-record ,stream ,record)
+       (multiple-value-bind (,x ,y ,delta-x ,delta-y)
+	   (drag-output-record 
+	    ,stream ,record 
+	    ;; Custom :erase is faster than default
+	    ;; erase-output-record/add-output-record cycle.
+	    :erase #'(lambda (,r ,s)
+		       (with-bounding-rectangle* (,x1 ,y1 ,x2 ,y2) ,r
+			 (draw-rectangle* ,s ,x1 ,y1 ,x2 ,y2 :filled t 
+					  :ink +background-ink+)))
+	    ,@args)
+	 ;; Spec: The record is not inserted into stream's output
+	 ;; history.
+	 (erase-output-record ,record ,stream)
+	 (values ,x ,y ,delta-x ,delta-y)))))
+
 
 (defun dragging-drawing (stream drawer &key (finish-on-release t)
                          (pointer (port-pointer (port stream)))
