diff --git a/library/HTMLPurifier.includes.php b/library/HTMLPurifier.includes.php
index f4956fa4..88ad66d3 100644
--- a/library/HTMLPurifier.includes.php
+++ b/library/HTMLPurifier.includes.php
@@ -136,6 +136,7 @@ require 'HTMLPurifier/ConfigSchema/Validator.php';
require 'HTMLPurifier/ConfigSchema/Validator/Alnum.php';
require 'HTMLPurifier/ConfigSchema/Validator/Composite.php';
require 'HTMLPurifier/ConfigSchema/Validator/Exists.php';
+require 'HTMLPurifier/ConfigSchema/Validator/If.php';
require 'HTMLPurifier/ConfigSchema/Validator/NamespaceExists.php';
require 'HTMLPurifier/ConfigSchema/Validator/Or.php';
require 'HTMLPurifier/ConfigSchema/Validator/ParseDefault.php';
diff --git a/library/HTMLPurifier/ConfigSchema/Interchange.php b/library/HTMLPurifier/ConfigSchema/Interchange.php
index 31e28775..58df5d70 100644
--- a/library/HTMLPurifier/ConfigSchema/Interchange.php
+++ b/library/HTMLPurifier/ConfigSchema/Interchange.php
@@ -60,7 +60,7 @@ class HTMLPurifier_ConfigSchema_Interchange
$directive->addValidator($this->make('Alnum', '_DIRECTIVE'));
$directive->addValidator($this->make('NamespaceExists'));
- // Directive: Type tests
+ // Directive: Type and Default tests
$directive->addValidator($this->make('Exists', 'TYPE'));
$directive->addValidator($this->make('ParseType'));
$directive->addValidator($this->make('Exists', '_TYPE'));
diff --git a/library/HTMLPurifier/ConfigSchema/Validator/If.php b/library/HTMLPurifier/ConfigSchema/Validator/If.php
new file mode 100644
index 00000000..470fb802
--- /dev/null
+++ b/library/HTMLPurifier/ConfigSchema/Validator/If.php
@@ -0,0 +1,49 @@
+setCondition($cond);
+ }
+
+ /**
+ * @param $validator Validator to run as a condition. Exceptions thrown by it
+ * do not bubble up.
+ */
+ public function setCondition($validator) {
+ $this->condition = $validator;
+ }
+
+ /**
+ * @param $validator Validator to run if condition is true
+ */
+ public function setThen($validator) {
+ $this->then = $validator;
+ }
+
+ /**
+ * @param $validator Validator to run if condition is false
+ */
+ public function setElse($validator) {
+ $this->else = $validator;
+ }
+
+ public function validate(&$arr, $interchange) {
+ try {
+ $this->condition->validate($arr, $interchange);
+ } catch (HTMLPurifier_ConfigSchema_Exception $e) {
+ if ($this->else) $this->else->validate($arr, $interchange);
+ return;
+ }
+ if ($this->then) $this->then->validate($arr, $interchange);
+ }
+
+}
diff --git a/tests/HTMLPurifier/ConfigSchema/Validator/IfTest.php b/tests/HTMLPurifier/ConfigSchema/Validator/IfTest.php
new file mode 100644
index 00000000..73dbdb34
--- /dev/null
+++ b/tests/HTMLPurifier/ConfigSchema/Validator/IfTest.php
@@ -0,0 +1,31 @@
+ 'RD');
+ $this->validator->setCondition(new HTMLPurifier_ConfigSchema_Validator_Exists('ID'));
+ $this->validator->setThen($mock1 = new HTMLPurifier_ConfigSchema_ValidatorMock());
+ $mock1->expectOnce('validate', array($arr, $this->interchange));
+ $this->validator->setElse($mock2 = new HTMLPurifier_ConfigSchema_ValidatorMock());
+ $mock2->expectNever('validate');
+ $this->validator->validate($arr, $this->interchange);
+ }
+
+ public function testValidateConditionIsFalse() {
+ $arr = array('ID' => 'RD');
+ $this->validator->setCondition(new HTMLPurifier_ConfigSchema_Validator_Exists('ALTID'));
+ $this->validator->setThen($mock1 = new HTMLPurifier_ConfigSchema_ValidatorMock());
+ $mock1->expectNever('validate');
+ $this->validator->setElse($mock2 = new HTMLPurifier_ConfigSchema_ValidatorMock());
+ $mock2->expectOnce('validate', array($arr, $this->interchange));
+ $this->validator->validate($arr, $this->interchange);
+ }
+
+}