public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
    {
        $qb = $this->createQueryBuilder('a');

        if ($limit) {
            $qb->setMaxResults($limit);
        }
        if ($offset) {
            $qb->setFirstResult($offset);
        }

        $orderByNode = $qb->orderBy();

        if ($orderBy) {
            foreach ($orderBy as $field => $order) {
                $order = strtolower($order);
                if (!in_array($order, ['asc', 'desc'])) {
                    throw new InvalidArgumentException(sprintf(
                        'Invalid order specified by order, expected either "asc" or "desc", got "%s"',
                        $order
                    ));
                }

                $method = $order == 'asc' ? 'asc' : 'desc';

                $orderByNode->$method()->field('a.'.$field);
            }
        }

        $first = true;
        foreach ($criteria as $field => $value) {
            if ($first) {
                $first = false;
                $where = $qb->where();
            } else {
                $where = $qb->andWhere();
            }

            if (is_array($value)) {
                $where = $where->orX();
                foreach ($value as $oneValue) {
                    $this->constraintField($where, $field, $oneValue, 'a');
                }
            } else {
                $this->constraintField($where, $field, $value, 'a');
            }
        }

        return $qb->getQuery()->execute();
    }