+(defcomponent validation-mixin ()
+ ((validation-conditions
+ :accessor validation-conditions
+ :initform nil
+ :backtrack t)
+ (inhibit-call-if-invalid-p
+ :accessor inhibit-call-if-invalid-p
+ :initform t
+ :initarg :inhibit-call-if-invalid-p)
+ (inhibit-answer-if-invalid-p
+ :accessor inhibit-answer-if-invalid-p
+ :initform t
+ :initarg :inhibit-answer-if-invalid-p)))
+
+(defmethod render :wrap-around ((self validation-mixin))
+ (call-next-method)
+ (setf (validation-conditions self) nil))
+
+(defun component-valid-p (component)
+ (not (validation-conditions component)))
+
+(defmethod/cc call-component :around ((from validation-mixin) to)
+ (if (inhibit-call-if-invalid-p from)
+ (when (component-valid-p from)
+ (call-next-method from to))
+ (call-next-method from to)))
+
+(defmethod answer-component :around ((target validation-mixin) value)
+ (if (inhibit-answer-if-invalid-p target)
+ (when (component-valid-p target)
+ (call-next-method))
+ (call-next-method)))