protected function storeFormFieldValuesForModel(Model $model, array $values)
    {
        // Prepare field data and strategies

        /** @var ModelFormFieldDataInterface[]|ModelFormFieldData[] $fields */
        /** @var FormFieldStoreStrategyInterface[] $strategies */
        $fields     = [];
        $strategies = [];

        foreach (array_keys($values) as $key) {

            $field = $this->getModelFormFieldDataForKey($key);
            if ( ! $this->allowedToUseFormFieldData($field)) continue;

            $fields[ $key ]     = $field;
            $strategies[ $key ] = $this->getFormFieldStoreStrategyInstanceForField($fields[ $key ]);

            $strategies[ $key ]->setFormFieldData($fields[ $key ]);
            $strategies[ $key ]->setParameters(
                $this->getFormFieldStoreStrategyParametersForField($fields[ $key ])
            );
        }

        // First store values (such as necessary belongsTo-related instances),
        // before storing the model
        foreach ($values as $key => $value) {
            if ( ! array_key_exists($key, $strategies)) continue;

            try {
                $strategies[ $key ]->store($model, $fields[ $key ]->source(), $value);

                // @codeCoverageIgnoreStart
            } catch (Exception $e) {
                $class   = get_class($strategies[ $key ]);
                $message = "Failed storing value for form field '{$key}' (using $class): \n{$e->getMessage()}";

                throw new StrategyApplicationException($message, $e->getCode(), $e);
                // @codeCoverageIgnoreEnd
            }
        }

        // Save the model itself
        $success = $model->save();

        if ( ! $success) {
            // @codeCoverageIgnoreStart
            return false;
            // @codeCoverageIgnoreEnd
        }

        // Then store values that can only be stored after the model exists
        // and is succesfully saved
        foreach ($values as $key => $value) {
            if ( ! array_key_exists($key, $strategies)) continue;

            try {
                $strategies[ $key ]->storeAfter($model, $fields[ $key ]->source(), $value);

            } catch (Exception $e) {
                $class   = get_class($strategies[ $key ]);
                $message = "Failed storing value for form field '{$key}' (using $class (after)): \n{$e->getMessage()}";

                throw new StrategyApplicationException($message, $e->getCode(), $e);
            }
        }

        // If the model is still dirty after this, save it again
        if ($model->isDirty()) {
            $success = $model->save();
        }

        // Call hooks to finish store strategies
        foreach ($values as $key => $value) {
            if ( ! array_key_exists($key, $strategies)) continue;

            try {
                $strategies[ $key ]->finish();

            } catch (Exception $e) {
                $class   = get_class($strategies[ $key ]);
                $message = "Failed finishing strategy form field '{$key}' (using $class): \n{$e->getMessage()}";

                throw new StrategyApplicationException($message, $e->getCode(), $e);
            }
        }

        return $success;
    }