/**
  * {@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);
 }