anchor.diff:     (%active-on :initarg :active-on :initform () :accessor active-on))
     (:documentation "Class for containing rulesets."))
   
  +(uc:define-serializer (rule rule T)
  +  (make-array 8 :initial-contents (list (name rule) (regex rule) (rule-type rule) (probation rule)
  +                                        (breach-msg rule) (apology-msg rule) (punish-msg rule)
  +                                        (active-on rule))))
  +
  +(uc:define-deserializer (rule array T)
  +  (make-instance 'rule
  +                 :name (aref array 0) :regex (aref array 1) :type (aref array 2) :probation (aref array 3)
  +                 :breach-msg (aref array 4) :apology-msg (aref array 5) :punish-msg (aref array 6)
  +                 :active-on (aref array 7)))
  +
   (defmethod print-object ((rule rule) stream)
     (print-unreadable-object (rule stream :type T)
       (format stream "~a \"~a\"" (rule-type rule) (regex rule))))
  -
  -(defmethod yason:encode ((rule rule) &optional (stream *standard-output*))
  -  (yason:with-output (stream)
  -    (yason:with-object ()
  -      (yason:encode-object-element "regex" (regex rule))
  -      (yason:encode-object-element "type" (string-upcase (rule-type rule)))
  -      (yason:encode-object-element "probation" (probation rule))
  -      (yason:encode-object-element "breach-msg" (breach-msg rule))
  -      (yason:encode-object-element "apology-msg" (apology-msg rule))
  -      (yason:encode-object-element "punish-msg" (punish-msg rule))
  -      (yason:encode-object-element "active-on" (active-on rule)))))
  -
  -(defmethod start ((rules rules))
  -  (with-open-file (stream *save-file* :if-does-not-exist NIL)
  -    (when stream
  -      (let ((data (yason:parse stream)))
  -        (loop for name being the hash-key of data
  -           for object being the hash-value of data
  -           do (setf (gethash name (rules rules))
  -                    (make-instance
  -                     'rule :name name
  -                     :regex (gethash "regex" object)
  -                     :type (find-symbol (gethash "type" object) :KEYWORD)
  -                     :probation (gethash "probation" object)
  -                     :breach-msg (gethash "breach-msg" object)
  -                     :apology-msg (gethash "apology-msg" object)
  -                     :punish-msg (gethash "punish-msg" object)
  -                     :active-on (gethash "active-on" object))))
  -        (v:info :rules "Loaded ~d rules." (hash-table-count data)))))
  -  (setf (whitelist rules) (config-tree :rules :whitelist)))
  -
  -(defmethod stop ((rules rules))
  -  (with-open-file (stream *save-file* :direction :output :if-exists :supersede :if-does-not-exist :create)
  -    (yason:encode (rules rules) stream)
  -    (v:info :rules "Saved ~d rules." (hash-table-count (rules rules))))
  -  (setf (config-tree :rules :whitelist) (whitelist rules)))
   
   (defun rule-format (event rule probation-count message)
     (format-message event message
                     (cons "\\$RULE\\$" (name rule))
                     (cons "\\$COUNT\\$" (format NIL "~a" probation-count))))
   
  -
   (defparameter *apology-regex* (cl-ppcre:create-scanner "^(Colleen:\\s*)?(Sorry for|I apologize for|I'm sorry for)\\s+(breaking|violating|breaching|not minding|disregarding|saying)?\\s*(the\\s+)?(\\w+).*" :case-insensitive-mode T))
   (define-handler (privmsg-event event) ()
     (when (not (find (format NIL "~a/~a" (string-upcase (name (server event))) (string-upcase (nick event)))
  -                   (whitelist module) :test #'string-equal))
  +                   (uc:config-tree :whitelist) :test #'string-equal))
       (let ((name-format (format NIL "~a/~a" (name (server event)) (nick event)))
             (server-format (format NIL "~a/~a" (name (server event)) (channel event))))
         (unless (cl-ppcre:register-groups-bind (NIL NIL NIL NIL name) (*apology-regex* (message event))
  -                (let ((rule (gethash name (rules module))))
  +                (let ((rule (uc:config-tree :rules name)))
                     (when (and rule (find server-format (active-on rule) :test #'string-equal))
                       (if (gethash name-format (users-on-probation rule))
                           (progn
  
positive.code: #|
  This file is a part of Colleen
  (c) 2013 TymoonNET/NexT http://tymoon.eu (shinmera@tymoon.eu)
  Author: Nicolas Hafner <shinmera@tymoon.eu>
  |#
  
  (in-package :org.tymoonnext.colleen)
  
negative.code: (define-command (rules activate) (name &optional channel server) (:authorization T :documentation "Activate a rule for a channel.")
    (unless channel (setf channel (channel event)))
    (unless server (setf server (name (server event))))
    (let ((rule (uc:config-tree :rules name)))
      (if rule
          (progn
            (pushnew (format NIL "~a/~a" server channel) (active-on rule) :test #'string-equal)
  