final public function update($record = null, string $alias = null, bool $trash = false): Record
    {
        $record = Record::parse($record);

        foreach ($this->getParents() as $parent) {
            /** @var DataMapper $parent */
            $record->import($parent->update($record)->all());
        }

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

        $previous = $this->previous($record, $this->hashKey, $trash);

        if ($previous->isEmpty()) {
            throw new SimplesResourceError([$this->getHashKey() => $record->get($this->getHashKey())]);
        }

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

        $record->setPrivate($this->getHashKey());

        $update = $this->configureRecord(Action::UPDATE, $record, $previous, !$trash);
        $fields = $update->keys();
        $values = $update->values();

        foreach ($this->updateKeys as $type => $timestampsKey) {
            $fields[] = $timestampsKey;
            $values[] = $this->getTimestampValue($type);
        }

        $filter = new Filter($this->get($this->getPrimaryKey()), $record->get($this->getPrimaryKey()));

        $updated = $this
            ->source($this->getCollection())
            ->fields($fields)
            ->where([$filter])// TODO: needs review
            ->change($values, [$filter->getValue()]);

        $this->reset();

        if (!$updated) {
            throw new SimplesActionError(get_class($this), $action);
        }
        $record->setPublic($this->getHashKey());
        $record = $previous->merge($record->all());

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