/**
  * Find ticket by id.
  *
  * @param TicketId $id
  *
  * @return Ticket|null
  */
 public function findById(TicketId $id)
 {
     $tickets = $this->matching(Criteria::create()->where(Criteria::expr()->equal('id', $id)));
     if ($tickets->count()) {
         return $tickets->first();
     }
     return null;
 }
 /**
  * The process to calculate the nested set left, right, and depth.
  *
  * @param Collection $data
  * @param string     $id
  * @param int        $left
  * @param int        $depth
  *
  * @return int
  * @throws \Exception
  */
 private function calculateTree(Collection $data, $id = null, $left = 0, $depth = 0)
 {
     /** @var NestedSetInterface $node */
     $node = $data->matching(Criteria::create()->where(Criteria::expr()->equal('id', $id)))->first();
     if (!$node instanceof NestedSetInterface) {
         throw new \Exception('Node is not a NestedSetInterface');
     }
     $left += 1;
     $prevRight = $left;
     $children = $data->matching(Criteria::create()->where(Criteria::expr()->equal('parentId', $id)));
     foreach ($children as $childNode) {
         $childNodeId = $childNode->getId();
         $prevRight = $this->calculateTree($data, $childNodeId, $prevRight, $depth + 1);
     }
     $node->setLeft($left);
     $node->setRight($prevRight + 1);
     $node->setDepth($depth);
     $this->nestedSetRepository->save($node);
     return $node->getRight();
 }
 /**
  * Find collection by id.
  *
  * @param mixed $id
  *
  * @return ReadModelInterface
  */
 public function findById($id)
 {
     $collection = $this->matching(Criteria::create()->where(Criteria::expr()->equal('id', $id)));
     return $collection->first();
 }
 /**
  * {@inheritdoc}
  *
  * @return Collection
  */
 public function matching(Criteria $criteria)
 {
     $elements = $this->elements;
     if ($expression = $criteria->getExpression()) {
         $visitor = new ClosureExpressionVisitor();
         $filter = $visitor->dispatch($expression);
         $elements = array_filter($elements, $filter);
     }
     if ($orderings = $criteria->getOrderings()) {
         $next = null;
         foreach (array_reverse($orderings) as $field => $ordering) {
             $next = ClosureExpressionVisitor::sortByField($field, $ordering == Criteria::ORDER_DESC ? -1 : 1, $next);
         }
         usort($elements, $next);
     }
     $offset = $criteria->getFirstResult();
     $length = $criteria->getMaxResults();
     if ($offset || $length) {
         $elements = array_splice($elements, (int) $offset, $length);
     }
     return new static($elements);
 }