public function testGetConjunctiveCompoundDescriptionForCurrentDisjunction()
 {
     $instance = new DescriptionProcessor();
     $currentDescription = new Disjunction();
     $newDescription = $instance->getDescriptionForPropertyObjectValue(new DIProperty('Foo'), 'foobar');
     $this->assertInstanceOf('SMW\\Query\\Language\\Conjunction', $instance->getConjunctiveCompoundDescriptionFrom($currentDescription, $newDescription));
 }
 /**
  * Parse a property description (the part of an inline query that
  * is in between "[[Some property::" and the closing "]]" and create a
  * suitable description. The "::" is the first chunk on the current
  * string.
  */
 private function getPropertyDescription($propertyName, &$setNS)
 {
     $this->readChunk();
     // consume separator ":=" or "::"
     // first process property chain syntax (e.g. "property1.property2::value"), escaped by initial " ":
     $propertynames = $propertyName[0] == ' ' ? array($propertyName) : explode('.', $propertyName);
     $properties = array();
     $typeid = '_wpg';
     $inverse = false;
     foreach ($propertynames as $name) {
         if (!$this->isPagePropertyType($typeid)) {
             // non-final property in chain was no wikipage: not allowed
             $this->descriptionProcessor->addErrorWithMsgKey('smw_valuesubquery', $name);
             return null;
             ///TODO: read some more chunks and try to finish [[ ]]
         }
         $property = SMWPropertyValue::makeUserProperty($name);
         if (!$property->isValid()) {
             // illegal property identifier
             $this->descriptionProcessor->addError($property->getErrors());
             return null;
             ///TODO: read some more chunks and try to finish [[ ]]
         }
         $typeid = $property->getDataItem()->findPropertyTypeID();
         $inverse = $property->isInverse();
         $properties[] = $property;
     }
     ///NOTE: after iteration, $property and $typeid correspond to last value
     $innerdesc = null;
     $continue = true;
     while ($continue) {
         $chunk = $this->readChunk();
         switch ($chunk) {
             case '+':
                 // wildcard, add namespaces for page-type properties
                 if (!is_null($this->defaultNamespace) && ($this->isPagePropertyType($typeid) || $inverse)) {
                     $innerdesc = $this->descriptionProcessor->getDisjunctiveCompoundDescriptionFrom($innerdesc, $this->defaultNamespace);
                 } else {
                     $innerdesc = $this->descriptionProcessor->getDisjunctiveCompoundDescriptionFrom($innerdesc, new ThingDescription());
                 }
                 $chunk = $this->readChunk();
                 break;
             case '<q>':
                 // subquery, set default namespaces
                 if ($this->isPagePropertyType($typeid) || $inverse) {
                     $this->pushDelimiter('</q>');
                     $setsubNS = true;
                     $innerdesc = $this->descriptionProcessor->getDisjunctiveCompoundDescriptionFrom($innerdesc, $this->getSubqueryDescription($setsubNS));
                 } else {
                     // no subqueries allowed for non-pages
                     $this->descriptionProcessor->addErrorWithMsgKey('smw_valuesubquery', end($propertynames));
                     $innerdesc = $this->descriptionProcessor->getDisjunctiveCompoundDescriptionFrom($innerdesc, new ThingDescription());
                 }
                 $chunk = $this->readChunk();
                 break;
             default:
                 // normal object value
                 // read value(s), possibly with inner [[...]]
                 $open = 1;
                 $value = $chunk;
                 $continue2 = true;
                 // read value with inner [[, ]], ||
                 while ($open > 0 && $continue2) {
                     $chunk = $this->readChunk('\\[\\[|\\]\\]|\\|\\||\\|');
                     switch ($chunk) {
                         case '[[':
                             // open new [[ ]]
                             $open++;
                             break;
                         case ']]':
                             // close [[ ]]
                             $open--;
                             break;
                         case '|':
                         case '||':
                             // terminates only outermost [[ ]]
                             if ($open == 1) {
                                 $open = 0;
                             }
                             break;
                         case '':
                             ///TODO: report error; this is not good right now
                             $continue2 = false;
                             break;
                     }
                     if ($open != 0) {
                         $value .= $chunk;
                     }
                 }
                 ///NOTE: at this point, we normally already read one more chunk behind the value
                 $innerdesc = $this->descriptionProcessor->getDisjunctiveCompoundDescriptionFrom($innerdesc, $this->descriptionProcessor->getDescriptionForPropertyObjectValue($property->getDataItem(), $value));
         }
         $continue = $chunk == '||';
     }
     if (is_null($innerdesc)) {
         // make a wildcard search
         $innerdesc = !is_null($this->defaultNamespace) && $this->isPagePropertyType($typeid) ? $this->descriptionProcessor->getDisjunctiveCompoundDescriptionFrom($innerdesc, $this->defaultNamespace) : $this->descriptionProcessor->getDisjunctiveCompoundDescriptionFrom($innerdesc, new ThingDescription());
         $this->descriptionProcessor->addErrorWithMsgKey('smw_propvalueproblem', $property->getWikiValue());
     }
     $properties = array_reverse($properties);
     foreach ($properties as $property) {
         $innerdesc = new SomeProperty($property->getDataItem(), $innerdesc);
     }
     $result = $innerdesc;
     return $this->finishLinkDescription($chunk, false, $result, $setNS);
 }