anchor.diff:  
   (in-package :score-script-support)
   
  -(defparameter *warstats* nil)
  -(defparameter *text-warstats* nil)
  -(defparameter *title-warstats* nil)
  -
  -(defvar *tree-address*)
  -(defvar *ballot-box*)
  -(defvar *text-ballot-box*)
  -(defvar *title-ballot-box*)
  -(defvar *warstat*)
  -(defvar *text-warstat*)
  -(defvar *title-warstat*)
  -(defvar *apply-to*)
  -(defvar *cascade*)
  -(defvar *other-flag*)
  -(defvar *direction*)
  -(defvar *target-author* nil)
  -
  -(defvar *side-opinions*)
  +(defvar *dispatch*)
  +(defparameter *score-data* nil)
   
   (in-package :warflagger)
   
  
positive.code:    (:effect 0)
     (:controversy 0)))
  
  (defun stick-other-flag-on-target (flag ballot-box warstat)
    (multiple-value-bind (right up wrong down) (warflagger:ballot-box-totals ballot-box)
      (let ((pos (+ right up))
            (neg (+ wrong down)))
        (when (warflagger:score-vast-majority-p pos neg)
          (setf (gethash flag warstat) (nth-value 0 (warflagger:score-controversy pos neg)))))))
  
  (defun add-to-replies-count (warstats childcount)
    (unless (key-in-hash? :replies-immediate warstats)
      (setf (gethash :replies-immediate warstats) 0))
    (unless (key-in-hash? :replies-total warstats)
      (setf (gethash :replies-total warstats) 0))
    (incf (gethash :replies-immediate warstats))
    (incf (gethash :replies-total warstats) (1+ childcount)))
  
  (defun set-direction (warstat direction)
    (setf (gethash :direction warstat) (or direction :neutral)))
  
  ;;FIXME: doesn't seem to function. Tree freshness should never be nil
  (defun set-tree-freshness (warstat &rest timestamps)
    (setf
     (gethash :tree-freshness warstat)
     (car (or (sort (remove-if #'null timestamps) #'string< :key #'warflagger:js-compatible-utcstamp)
              (error "No timestamp found in tree")))))
  
  (defun add-alternative (iid)
    (hu:collecting-hash-table (:mode :append :existing *side-opinions*)
      (hu:collect (assoc-cdr :target (warflagger:opinion-by-id iid)) iid)))
  
  (defun add-side-opinion (iid)
    (hu:collecting-hash-table (:mode :append :existing *side-opinions*)
      (hu:collect (assoc-cdr :target (warflagger:opinion-by-id iid)) iid)))
  
  (defun apply-to (aspect iid)
    (unless (equal iid (lastcar *tree-address*))
      (error "IID problem: can't apply-to"))
    (if *apply-to*
        (warn "Apply-to is already set. No action taken.")
        (setf *apply-to* aspect)))
  
  (defun applied-to (applyto)
    (case applyto
      (:text (values *text-warstat* *text-ballot-box*))
      (:title (values *title-warstat* *title-ballot-box*))
      (otherwise (values *warstat* *ballot-box*))))
  
  (defun collect-warstats (key warstats &optional type)
    (let ((ws-store (case type
                      (:text *text-warstats*)
                      (:title *title-warstats*)
                      (otherwise *warstats*))))
      (setf (gethash key ws-store) warstats)))
  
  (defun execute-modifiers (modifiers tree-address other-flag direction author)
    (hu:collecting-hash-table (:mode :replace)
      (let ((*target-author* author)
            (*ballot-box* (warflagger:make-ballot-box))
            (*text-ballot-box* (warflagger:make-ballot-box))
            (*title-ballot-box* (warflagger:make-ballot-box))
            (*warstat* (initialize-warstats))
            (*text-warstat* (make-hash-table))
            (*title-warstat* (make-hash-table))
            (*apply-to* nil)
            (*other-flag* other-flag)
            (*direction* direction)
            (*tree-address* tree-address))
        (when (functionp modifiers)
          (funcall modifiers))
        (hu:collect :ballot-box *ballot-box*)
        (hu:collect :text-ballot-box *text-ballot-box*)
        (hu:collect :title-ballot-box *title-ballot-box*)
        (hu:collect :warstat *warstat*)
        (hu:collect :text-warstat *text-warstat*)
        (hu:collect :title-warstat *title-warstat*)
        (hu:collect :apply-to *apply-to*)
        (hu:collect :direction *direction*)
        (hu:collect :other-flag *other-flag*))))
  
  ;;FIXME: flag-core is a little dense. Individual flags and directives should have a clearer
  ;; api. Consider rewriting with dispatch functions instead of dynamics.
  (defun flag-core (other-flag direction iid author modifiers)
    (hu:with-keys (:ballot-box :text-ballot-box :title-ballot-box :warstat :text-warstat :title-warstat
                   :apply-to :direction :other-flag)
        (execute-modifiers modifiers (append *tree-address* (list iid)) other-flag direction author)
      ;;accumulate own warstats
      (set-direction warstat direction)
      ;; ws and bb belong to the target, not the current item.
      (multiple-value-bind (ws bb) (applied-to apply-to)
        (unless (warflagger:ballot-box-empty-p ballot-box)
          (warflagger:apply-ballot-box-to-warstats ballot-box warstat))
        (collect-warstats iid warstat)
        ;;FIXME: do we deal with text warstats for nonroot targets?
        (unless (warflagger:ballot-box-empty-p text-ballot-box)
          (warflagger:apply-ballot-box-to-warstats text-ballot-box text-warstat))
        (collect-warstats iid text-warstat :text)
        (unless (warflagger:ballot-box-empty-p title-ballot-box)
          (warflagger:apply-ballot-box-to-warstats title-ballot-box title-warstat))
        (collect-warstats iid title-warstat :title)
        ;;FIXME: Are there cases when an opinion and descendants should not be counted?
        (add-to-replies-count ws
                              (+ (gethash :replies-total warstat 0)
                                 (gethash :replies-total text-warstat 0)
                                 (gethash :replies-total title-warstat 0)))
        (unless (gethash :tree-freshness warstat)
          (set-tree-freshness warstat (assoc-cdr :datestamp (warflagger:opinion-by-id iid))))
        (set-tree-freshness ws
                            (gethash :tree-freshness ws)
                            (gethash :tree-freshness warstat) (gethash :tree-freshness text-warstat)
                            (gethash :tree-freshness title-warstat))
        (when other-flag
          (warflagger:cast-vote! ballot-box :up iid author)
          (stick-other-flag-on-target other-flag ballot-box ws))
        (cond
          ;;We don't cast own vote if it's not an other-flag. Return appropriate ballot box instead.
          ;;FIXME: how does our vote get in that ballot box?
          ((eq direction :pro)
           (warflagger:merge-ballot-boxes! bb ballot-box)
           bb)
          ((eq direction :con)
           (warflagger:merge-with-inverted-ballot-boxes! bb ballot-box)
           bb)
          (t nil)))))
  
  (in-package :score-script)
  
  ;; Initial implementation of consensus scorer
  
  (defun negative-spam (&key iid author modifiers)
    (scss:flag-core :spam nil iid author modifiers))
  (defun negative-inflammatory (&key iid author modifiers)
    (scss:flag-core :inflammatory nil iid author modifiers))
  (defun negative-disagree (&key iid author modifiers)
    (when-let ((balbox (scss:flag-core nil :con iid author modifiers)))
      (warflagger:cast-vote! balbox :down iid author)))
  (defun negative-dislike (&key iid author modifiers)
    (when-let ((balbox (scss:flag-core nil :con iid author modifiers)))
      (warflagger:cast-vote! balbox :down iid author)))
  (defun negative-language-warning (&key iid author modifiers)
    (scss:flag-core :language-warning nil iid author modifiers))
  (defun negative-disturbing (&key iid author modifiers)
    (scss:flag-core :disturbing nil iid author modifiers))
  (defun negative-logical-fallacy (&key iid author modifiers)
    (scss:flag-core :logical-fallacy nil iid author modifiers))
  (defun negative-needs-evidence (&key iid author modifiers)
    (when-let ((balbox (scss:flag-core nil :con iid author modifiers)))
      (warflagger:cast-vote! balbox :wrong iid author)))
  (defun negative-raise-question (&key iid author modifiers)
    (when-let ((balbox (scss:flag-core nil :con iid author modifiers)))
      (warflagger:cast-vote! balbox :wrong iid author)))
  (defun negative-out-of-bounds (&key iid author modifiers)
    (scss:flag-core :out-of-bounds nil iid author modifiers))
  (defun positive-funny (&key iid author modifiers)
    (scss:flag-core :funny nil iid author modifiers))
  (defun positive-agree (&key iid author modifiers)
    (when-let ((balbox (scss:flag-core nil :pro iid author modifiers)))
      (warflagger:cast-vote! balbox :up iid author)))
  (defun positive-like (&key iid author modifiers)
    (when-let ((balbox (scss:flag-core nil :pro iid author modifiers)))
      (warflagger:cast-vote! balbox :up iid author)))
  (defun positive-interesting (&key iid author modifiers)
    (scss:flag-core :interesting nil iid author modifiers))
  ;;FIXME: this should go away
  (defun statements-evidence (&key iid author modifiers)
    (let ((vv (assoc-cdr :vote-value (warflagger:opinion-by-id iid))))
  
negative.code:    #:prep-scsc-for-execution
     #:*warstats*
     #:*text-warstats*
     #:*title-warstats*))
  
  (defpackage #:score-script
    (:use #:cl #:gadgets #:alexandria)
  