protected function getWidget($fieldName, $serializedId, $propertyValue)
    {
        $environment    = $this->getEnvironment();
        $property       = $environment->getDataDefinition()->getPropertiesDefinition()->getProperty($fieldName);
        $propertyValues = new PropertyValueBag();

        if (null !== $serializedId) {
            $model = $this->getModelFromSerializedId($serializedId);
        } else {
            $dataProvider = $environment->getDataProvider();
            $model        = $dataProvider->getEmptyModel();
        }

        $widgetManager = new ContaoWidgetManager($environment, $model);

        // Process input and update changed properties.
        $treeType      = \substr($property->getWidgetType(), 0, 4);
        $propertyValue = $this->getTreeValue($treeType, $propertyValue);
        if (('file' === $treeType) || ('page' === $treeType)) {
            $extra = $property->getExtra();
            if (\is_array($propertyValue) && !isset($extra['multiple'])) {
                $propertyValue = $propertyValue[0];
            } else {
                $propertyValue = \implode(',', (array) $propertyValue);
            }
        }

        $propertyValues->setPropertyValue($fieldName, $propertyValue);
        $widgetManager->processInput($propertyValues);
        $model->setProperty($fieldName, $propertyValues->getPropertyValue($fieldName));

        return $widgetManager->getWidget($fieldName);
    }