public function save(array $options = []) {
        $options = $options + ['validate' => true, 'atomic' => true, 'force' => false];
        $passed = $options['validate'] ? $this->validate() : true;

        // Validation failed, exit early
        if (!$passed) {
            return 0;
        }

        // Save fields that have changed, else save them all
        $data = $this->getChanged();

        if (!$data || $options['force']) {
            $data = $this->toArray();
        }

        // Be sure to persist the ID for updates
        if (empty($data[$this->primaryKey]) && ($id = $this->id())) {
            $data[$this->primaryKey] = $id;
        }

        // Upsert the record and modify flags on success
        $model = $this;
        $operation = function() use ($model, $data, $options) {
            if ($id = $model->getRepository()->upsert($data, null, $options)) {
                $model->mapData($model->_attributes);
                $model->set($model->getPrimaryKey(), $id);
                $model->_exists = true;
                $model->_changed = false;

                return $id;
            }

            $model->_exists = false;

            return 0;
        };

        // Wrap in a transaction if atomic
        if ($options['atomic']) {
            try {
                $id = $this->getRepository()->getDriver()->transaction($operation);
            } catch (Exception $e) {
                return 0;
            }
        } else {
            $id = call_user_func($operation);
        }

        return $id;
    }