anchor.diff:  
   ;;----------------------------------------------------------------------
   
  -(defparameter *ids* (make-hash-table))
  +(deftclass event-source
  +  (combos (make-array 0 :element-type 'function
  +		      :adjustable t :fill-pointer 0)))
   
  -(let ((id -1))
  -  (defun %next-id ()
  -    (incf id)))
  +(deftclass (combo (:include event-source))
  +  (predicate (error "Bug found in skitter: combos must always be created with predicate logic")))
   
   ;;----------------------------------------------------------------------
  -
  -(deftclass event-source
  -  (local-combos (make-array 0 :element-type 'function
  -			    :adjustable t :fill-pointer 0)))
  -
  -(deftclass (regular-source (:include event-source)))
  -
  -(deftclass (combo-source (:include event-source))
  -  (body (error "Bug found in skitter: combo-source must always be created with a body")))
  -
  -;;----------------------------------------------------------------------
  -
  -(deftype source-array ()
  -  '(array (or null regular-source) (*)))
  -
  -(deftclass source-group
  -  (sources (make-array 0 :element-type 'source-array
  -		       :adjustable t :fill-pointer 0)
  -	   :type (array source-array (*)))
  -  (global-combos (make-array 0 :element-type 'combo-source
  -			     :adjustable t :fill-pointer 0)
  -		 :type (array combo-source (*))))
   
   (defmacro defkind (name &body slots)
     (labels ((parse-slot (s)
  
positive.code: 			       slots))
  	 ;;-internal vars
  	 (this (gensym "this")))
      `(progn
         (deftclass (,name (:include regular-source) (:conc-name nil))
  	 ,@hidden-slots
  	 (,body-func #',logic :type function)
  	 (,active nil :type boolean))
         (defun ,logic (,this ,event-var)
  	 (let ((result
  		(symbol-macrolet
  		    ,(mapcar (lambda (n hn) `(,n (,hn ,event-var)))
  			     original-slot-names hidden-slot-names)
  		  ,@body))
  	       (old-active (,active ,this))
  	       (new-active (not (null result))))
  	   (setf (,active ,this) new-active)
  	   (when (not (eq old-active new-active))
  	     ;; new events :)
  	     )
  	   nil))
         (defun ,add (group &rest listening-to)
  	 (let* ((g (source-group-combos group)))
  	   (vector-push-extend (,make) (source-group-combos group))
  	   (loop :for (source-kind source-index) :across listening-to :do
  	      (let ((source-kind-index (or (gethash ))))
  		(vector-push-extend #',logic
  				    (aref (aref (source-group-sources group)
  						source-kind-index)
  					  source-index))))
  	   group)))))
  
  (def-combo-event-source double-click
      ((last-down 0 :type fix))
      (:event-var evt)
    1)
  
  ;;----------------------------------------------------------------------
  
  (defvar +mice+
    (make-array 0 :element-type 'source-group
  	      :adjustable t :fill-pointer 0))
  
  (defvar +keyboards+
    (make-array 0 :element-type 'source-group
  	      :adjustable t :fill-pointer 0))
  
negative.code: (def-event-source wheel
    (val 0f0 :type single-float))
  
  ;; (apply-button x ts :down-p t)
  
  ;;----------------------------------------------------------------------
  
  (defun propagate (source timestamp)
    (labels ((fire-combo (combo source timestamp)
  	     (funcall (combo-predicate combo) combo source timestamp)))
      (loop :for c :in (event-source-combos source) :do
         (fire-combo c source timestamp))))
  
  (defmacro def-combo (name source-types (&key event-var (timestamp-var 'timestamp))
  
  					  slots &body body)
    (assert (symbolp event-var))
    (assert (listp source-types))
    (let* (;; funcs
  	 (make (intern (format nil "MAKE-~a" name) (symbol-package name)))
  	 (constructor (intern (format nil "%MAKE-~a" name) (symbol-package name)))
  	 (logic (intern (format nil "%~a-BODY" name) (symbol-package name)))
  	 (active (intern (format nil "~s-ACTIVE-P" name)
  			 (symbol-package name)))
  	 ;;state-slots
  	 (original-slot-names (mapcar #'first slots))
  	 (accessor-names (mapcar (lambda (x)
  