private function processProperty(PropertyValueBag $valueBag, $property)
    {
        // NOTE: the passed input values are RAW DATA from the input provider - aka widget known values and not
        // native data as in the model.
        // Therefore we do not need to decode them but MUST encode them.
        $widget = $this->getWidget($property, $valueBag);
        $widget->validate();

        if ($widget->hasErrors()) {
            foreach ($widget->getErrors() as $error) {
                $valueBag->markPropertyValueAsInvalid($property, $error);
            }

            return;
        }

        if (!$widget->submitInput()) {
            // Handle as abstaining property.
            $valueBag->removePropertyValue($property);
            return;
        }

        try {
            $valueBag->setPropertyValue($property, $this->encodeValue($property, $widget->value, $valueBag));
        } catch (\Exception $e) {
            $widget->addError($e->getMessage());
            foreach ($widget->getErrors() as $error) {
                $valueBag->markPropertyValueAsInvalid($property, $error);
            }
        }
    }