protected function applyReference(Reference $reference)
 {
     if (!$this->writer->hasData()) {
         throw new EvaluatorException("No data at '{$reference->getPath()}'");
     }
     if ($this->writer->isArray()) {
         if ($reference->getType() == $reference::TYPE_NEXT_INDEX) {
             $this->writer->selectNewElement();
         } elseif ($reference->getType() == $reference::TYPE_INDEX) {
             $index = (int) $reference->getKey();
             $elementCount = $this->writer->getElementCount();
             if ($index == $elementCount) {
                 $this->writer->selectNewElement();
             } elseif ($index < $elementCount && $index >= 0) {
                 $this->writer->selectElement($index);
             } else {
                 throw new EvaluatorException("Invalid index #{$index} at '{$reference->getPath()}'");
             }
         } else {
             throw new EvaluatorException("Invalid index '{$reference->getKey()}' at '{$reference->getPath()}'");
         }
     } elseif ($this->writer->isObject()) {
         $property = (string) $reference->getKey();
         $this->writer->selectProperty($property);
     } else {
         throw new EvaluatorException("Scalar data at '{$reference->getPath()}'");
     }
     return $this;
 }
 protected function applyReference(Reference $reference)
 {
     if ($this->selector->isArray()) {
         if ($reference->getType() != $reference::TYPE_INDEX) {
             throw new EvaluatorException("Invalid index '{$reference->getKey()}' at {$reference->getPath()}");
         }
         $index = (int) $reference->getKey();
         $this->selector->selectElement($index);
         if (!$this->selector->hasData()) {
             throw new EvaluatorException("No index #{$index} at {$reference->getPath()}");
         }
     } elseif ($this->selector->isObject()) {
         $property = (string) $reference->getKey();
         $this->selector->selectProperty($property);
         if (!$this->selector->hasData()) {
             throw new EvaluatorException("No property '{$property}' at {$reference->getPath()}");
         }
     } else {
         throw new EvaluatorException("Scalar data at {$reference->getPath()}");
     }
     return $this;
 }
 protected function applyReference(Reference $reference)
 {
     if ($this->selector->isArray()) {
         if ($reference->getType() != $reference::TYPE_INDEX) {
             return $this->setResultFromBool(false);
         }
         $index = (int) $reference->getKey();
         $hasData = $this->selector->selectElement($index)->hasData();
         if (!$hasData) {
             return $this->setResultFromBool(false);
         }
     } elseif ($this->selector->isObject()) {
         $property = (string) $reference->getKey();
         $hasData = $this->selector->selectProperty($property)->hasData();
         if (!$hasData) {
             return $this->setResultFromBool(false);
         }
     } else {
         return $this->setResultFromBool(false);
     }
     return $this;
 }