/**
  * Parse assertions which are a collection of others
  *
  * @param string    $connective How are they combined? E.g. "||"
  * @param \stdClass $annotation The annotation to create chained assertions from
  *
  * @return \AppserverIo\Doppelgaenger\Entities\Assertions\ChainedAssertion
  */
 protected function createChainedAssertion($connective, \stdClass $annotation)
 {
     // Get all the parts of the string
     $assertionArray = explode(' ', $annotation->values['typeHint']);
     // Check all string parts for the | character
     $combinedPart = '';
     $combinedIndex = 0;
     foreach ($assertionArray as $key => $assertionPart) {
         // Check which part contains the | but does not only consist of it
         if ($this->filterOrCombinator($assertionPart) && trim($assertionPart) !== $connective) {
             $combinedPart = trim($assertionPart);
             $combinedIndex = $key;
             break;
         }
     }
     // Now we have to create all the separate assertions for each part of the $combinedPart string
     $assertionList = new AssertionList();
     foreach (explode($connective, $combinedPart) as $partString) {
         // Rebuild the assertion string with one partial string of the combined part
         $tmp = $assertionArray;
         $tmp[$combinedIndex] = $partString;
         $annotation->values['typeHint'] = $partString;
         $assertion = $this->getInstance($annotation);
         if (is_bool($assertion)) {
             continue;
         } else {
             $assertionList->add($assertion);
         }
     }
     // We got everything. Create a ChainedAssertion instance
     return new ChainedAssertion($assertionList, '||');
 }
 /**
  * Will get the conditions for a certain assertion indicating keyword like @requires or, if configured, @param
  *
  * @param string       $docBlock         The DocBlock to search in
  * @param string       $conditionKeyword The keyword we are searching for, use assertion defining tags here!
  * @param boolean|null $privateContext   If we have to mark the parsed annotations as having a private context
  *                                       as we would have trouble finding out for ourselves.
  *
  * @return boolean|\AppserverIo\Doppelgaenger\Entities\Lists\AssertionList
  */
 public function getConditions($docBlock, $conditionKeyword, $privateContext = null)
 {
     // There are only 3 valid condition types
     if ($conditionKeyword !== Requires::ANNOTATION && $conditionKeyword !== Ensures::ANNOTATION && $conditionKeyword !== Invariant::ANNOTATION) {
         return false;
     }
     // get the annotations for the passed condition keyword
     $annotations = $this->getAnnotationsByType($docBlock, $conditionKeyword);
     // if we have to enforce basic type safety we need some more annotations
     if ($this->config->getValue('enforcement/enforce-default-type-safety') === true) {
         // lets switch the
         switch ($conditionKeyword) {
             case Ensures::ANNOTATION:
                 // we have to consider @return annotations as well
                 $annotations = array_merge($annotations, $this->getAnnotationsByType($docBlock, 'return'));
                 break;
             case Requires::ANNOTATION:
                 // we have to consider @param annotations as well
                 $annotations = array_merge($annotations, $this->getAnnotationsByType($docBlock, 'param'));
                 break;
             default:
                 break;
         }
     }
     // lets build up the result array
     $assertionFactory = new AssertionFactory();
     $result = new AssertionList();
     foreach ($annotations as $annotation) {
         // try to create assertion instances for all annotations
         try {
             $assertion = $assertionFactory->getInstance($annotation);
         } catch (\Exception $e) {
             error_log($e->getMessage());
             continue;
         }
         if ($assertion !== false) {
             // Do we already got a private context we can set? If not we have to find out four ourselves
             if ($privateContext !== null) {
                 // Add the context (wether private or not)
                 $assertion->setPrivateContext($privateContext);
             } else {
                 // Add the context (private or not)
                 $this->determinePrivateContext($assertion);
             }
             // finally determine the minimal scope of this assertion and add it to our result
             $this->determineMinimalScope($assertion);
             $result->add($assertion);
         }
     }
     return $result;
 }