public function testNestedOptionalRequirementsOfDifferentTypes()
 {
     $true = new TrueRequirement();
     $false = new FalseRequirement();
     $level1And = new RequirementSet();
     $level2FirstAnd = new RequirementSet(true);
     $level2SecondAnd = new RequirementSet(true);
     $level1And->merge($level2FirstAnd)->merge($level2SecondAnd);
     $level3FirstOr = new RequirementSet(true, RequirementSet::MODE_OR);
     $level3SecondOr = new RequirementSet(true, RequirementSet::MODE_OR);
     $level2FirstAnd->merge($level3FirstOr)->merge($level3SecondOr);
     $level2SecondAnd->merge($level3FirstOr)->merge($level3SecondOr);
     $level3FirstOr->add($false);
     $level3SecondOr->add($false);
     $this->assertFalse($level1And->fulfilled());
     $this->assertTrue($level2FirstAnd->fulfilled());
     $this->assertTrue($level2SecondAnd->fulfilled());
     $level1Or = new RequirementSet(false, RequirementSet::MODE_OR);
     $level2FirstOr = new RequirementSet(true, RequirementSet::MODE_OR);
     $level2SecondOr = new RequirementSet(true, RequirementSet::MODE_OR);
     $level1Or->merge($level2FirstOr)->merge($level2SecondOr);
     $level3FirstAnd = new RequirementSet(true);
     $level3SecondAnd = new RequirementSet(true);
     $level2FirstOr->merge($level3FirstAnd)->merge($level3SecondAnd);
     $level2SecondOr->merge($level3FirstAnd)->merge($level3SecondAnd);
     $level3FirstAnd->add($true)->add($true);
     $level3SecondAnd->add($false)->add($true);
     $this->assertTrue($level1Or->fulfilled());
 }