anchor.diff:                 :format-control "Property ~A is unbound for sheep ~S"
                  :format-args (list property-name sheep)))))
   
  -(defgeneric has-property-p (sheep property-name))
  -(defmethod has-property-p ((sheep standard-sheep) property-name)
  -  "Returns T if a property with PROPERTY-NAME is available to SHEEP."
  -  (handler-case
  -      (when (property-owner sheep property-name)
  -        t)
  -    (unbound-property () nil)))
  -
  -(defgeneric (setf property-value) (new-value sheep property-name)
  -  (:documentation "Sets NEW-VALUE as the value of a direct-property belonging to SHEEP, named
  -PROPERTY-NAME. If the property does not already exist anywhere in the hierarchy list, an error
  -is signaled."))
  -(defmethod (setf property-value) (new-value (sheep standard-sheep) property-name)
  -  (unless (symbolp property-name)
  -    (error "Property-name must be a symbol"))
  +
  +(defmethod (setf property-value) (new-value (sheep standard-sheep) (property-name symbol))
     (if (has-property-p sheep property-name)
  -      (let ((property-table (sheep-property-value-table sheep)))
  -        (setf (gethash property-name property-table) new-value))
  +      (let ((property (gethash property-name (sheep-property-spec-table sheep))))
  +        (setf (property-value sheep property) new-value))
         (error "Property ~A does not exist for sheep ~A." property-name sheep)))
  +(defmethod (setf property-value) (new-value (sheep standard-sheep) (property property-spec))
  +  (let ((property-table (sheep-property-value-table sheep)))
  +    (setf (gethash (property-spec-name property) property-table) new-value)))
   
   ;; Reflection
  -(defmethod print-object ((property-spec property-spec) stream)
  -  (print-unreadable-object (property-spec stream :identity t)
  -    (format stream "Property-Spec ~A" (property-spec-name property-spec))))
   (defun sheep-direct-properties (sheep)
     "Returns a set of direct property-spec definition metaobjects."
     (loop for pname being the hash-keys of (sheep-property-value-table sheep)
  
positive.code:     (setf (gethash property-name (sheep-property-spec-table sheep))
            property-spec)))
  
  (defmethod add-property ((sheep standard-sheep) property-name value 
                           &key (allocation :sheep))
    "Allocates VALUE as one of SHEEP's direct-properties. :allocation determines where the value
  is actually allocated. For the standard method, anything other than :sheep signals an error."
    (if (eq allocation :sheep)
        (let ((property-table (sheep-property-value-table sheep)))
          (when (has-direct-property-p sheep property-name)
            (warn "~A already has a direct property named ~A. Overwriting." sheep property-name))
          (setf (gethash property-name property-table) value)
          sheep)
        (error "Standard sheep can only have :sheep allocation.")))
  
  (defgeneric has-direct-property-p (sheep property-name)
    (:documentation "Returns T if SHEEP has a direct property with name PROPERTY-NAME, NIL otherwise."))
  (defmethod has-direct-property-p ((sheep standard-sheep) property-name)
    (nth-value 1 (gethash property-name (sheep-property-value-table sheep))))
  
  (defgeneric remove-property (sheep property-name)
    (:documentation "If PROPERTY-NAME is a direct property of SHEEP, this function removes it. If
  PROPERTY-NAME is inherited from one of SHEEP's parents, or if PROPERTY-NAME does not exist in SHEEP's
  hierarchy list, an error is signaled. This function returns SHEEP after property removal."))
  (defmethod remove-property ((sheep standard-sheep) property-name)
    (if (has-direct-property-p sheep property-name)
        (progn (remhash property-name (sheep-property-value-table sheep))
               (remhash property-name (sheep-property-spec-table sheep))
               sheep)
        (error "Cannot remove property: ~A is not a direct property of ~A" property-name sheep)))
  
  (defgeneric remove-all-direct-properties (sheep))
  (defmethod remove-all-direct-properties ((sheep standard-sheep))
    (clrhash (sheep-property-value-table sheep))
    (clrhash (sheep-property-spec-table sheep))
    sheep)
  
  (defgeneric direct-property-value (sheep property-name)
    (:documentation "Returns the property-value set locally in SHEEP for PROPERTY-NAME. If the value
  is non-local (is delegated or does not exist in the hierarchy list), an UNBOUND-PROPERTY is signaled."))
  (defmethod direct-property-value ((sheep standard-sheep) property-name)
    (unless (symbolp property-name)
      (error "Property-name must be a symbol"))
    (multiple-value-bind (value hasp)
        (gethash property-name (sheep-property-value-table sheep))
      (if hasp
          value
          (error 'unbound-property
                 :format-control "~A has no direct property with name ~A"
                 :format-args (list sheep property-name)))))
  
  (defgeneric property-value (sheep property-name)
    (:documentation ""))
  (defmethod property-value ((sheep standard-sheep) property-name)
    (property-value-with-hierarchy-list sheep property-name))
  
  (defun property-value-with-hierarchy-list (sheep property-name)
    (let ((hl (sheep-hierarchy-list sheep)))
      (or (loop for sheep in hl
  
negative.code:     (signal 'unbound-property))
    (nth-value 0 (gethash property-name (sheep-property-spec-table sheep))))
  
  (defmethod property-owner ((sheep standard-sheep) property-name &optional (errorp t))
    (let ((owner
           (loop for obj in (sheep-hierarchy-list sheep)
  