diff --git a/include/class.signal.php b/include/class.signal.php
index 86540054ed6d4d703b6f5e9175067298c51fa428..ac7a6a6388bc4f3f9018f23abfca12cb53575a9a 100644
--- a/include/class.signal.php
+++ b/include/class.signal.php
@@ -46,18 +46,27 @@ class Signal {
      * Optionally, if $object is a class and is passed into the ::connect()
      * method, only instances of the named class or subclass will actually
      * be connected to the callable function.
+     *
+     * A predicate function, $check, can be used to filter calls to the
+     * signal handler. The function will receive the signal data and should
+     * return true if the signal handler should be called.
      */
-    /*static*/ function connect($signal, $callable, $object=null) {
+    /*static*/ function connect($signal, $callable, $object=null,
+            $check=null) {
         global $_subscribers;
         if (!isset($_subscribers[$signal])) $_subscribers[$signal] = array();
         // XXX: Ensure $object if set is a class
         if ($object && !is_string($object))
             trigger_error("Invalid object: $object: Expected class");
-        $_subscribers[$signal][] = array($object, $callable);    
+        elseif ($check && !is_callable($check)) {
+            trigger_error("Invalid check function: Must be callable");
+            $check = null;
+        }
+        $_subscribers[$signal][] = array($object, $callable, $check);
     }
 
     /**
-     * Publish a signal. 
+     * Publish a signal.
      *
      * Signal::send('user.login', $this, array('username'=>'blah'));
      *
@@ -81,9 +90,11 @@ class Signal {
         if (!isset($_subscribers[$signal]))
             return;
         foreach ($_subscribers[$signal] as $sub) {
-            list($s, $callable) = $sub;
+            list($s, $callable, $check) = $sub;
             if ($s && !is_a($object, $s))
                 continue;
+            elseif ($check && !call_user_func($check, $data))
+                continue;
             call_user_func($callable, $data);
         }
     }