final public function read($record = null, string $alias = null, $trash = false, $clean = false): Collection
    {
        $record = Record::parse(coalesce($record, []));

        $action = coalesce($alias, Action::READ);

        if (!$this->before($action, $record)) {
            throw new SimplesHookError(get_class($this), $action, 'before');
        }

        $filters = [];
        $values = [];
        if (!$record->isEmpty()) {
            $filters = $this->parseFilterFields($record->all());
            $values = $this->parseFilterValues($filters);
        }

        if ($this->destroyKeys) {
            $filters[] = $this->getDestroyFilter($this->destroyKeys['at'], $trash);
        }

        $fields = $this->getActionFields(Action::READ, false);
        if ($clean) {
            $fields = $this->clear($fields);
        }

        $order = is_array($this->order) ? $this->order : [$this->order];

        $where = off($this->getClauses(), 'where', []);
        if ($where) {
            $filters = array_merge($filters, $where);
            $values = array_merge($values, off($this->getClauses(), 'values', []));
        }

        $array = $this
            ->source($this->getCollection())
            ->relation($this->parseReadRelations($this->fields))
            ->fields($fields)
            ->order($order)
            ->where($filters)// TODO: needs review
            ->recover($values);

        $this->reset();

        $after = $this->after($action, $record, $array);
        if (!is_array($after)) {
            throw new SimplesHookError(get_class($this), $action, 'after');
        }
        $array = $after;

        return Collection::make($array);
    }