protected function doMapping($source, $targetType, PropertyMappingConfigurationInterface $configuration, &$currentPropertyPath)
    {
        if ($source === null) {
            return null;
        }

        $typeConverter = $this->getTypeConverter($source, $targetType, $configuration);
        $targetType = ltrim($typeConverter->getTargetTypeForSource($source, $targetType), '\\');

        if (Core::get()->classExists($targetType)) {
            $targetType = $this->handleMixedType($source, $targetType, $currentPropertyPath);
            $source = $this->handleDataPreProcessor($source, $targetType, $currentPropertyPath);

            if (MixedTypesResolver::OBJECT_TYPE_NONE === $targetType) {
                return null;
            }
        }

        $convertedChildProperties = (is_array($source))
            ? $this->convertChildProperties($source, $targetType, $typeConverter, $configuration, $currentPropertyPath)
            : [];

        $this->configurationObjectConversionDTO
            ->setSource($source)
            ->setTargetType($targetType)
            ->setConvertedChildProperties($convertedChildProperties)
            ->setCurrentPropertyPath($currentPropertyPath)
            ->setResult(null);
        $this->serviceFactory->runServicesFromEvent(ObjectConversionBeforeServiceEventInterface::class, 'objectConversionBefore', $this->configurationObjectConversionDTO);

        if (null === $this->configurationObjectConversionDTO->getResult()) {
            $result = $typeConverter->convertFrom($source, $targetType, $convertedChildProperties);
            $this->configurationObjectConversionDTO->setResult($result);
        }

        $this->serviceFactory->runServicesFromEvent(ObjectConversionAfterServiceEventInterface::class, 'objectConversionAfter', $this->configurationObjectConversionDTO);
        $result = $this->configurationObjectConversionDTO->getResult();

        if ($result instanceof Error) {
            $this->messages
                ->forProperty(implode('.', $currentPropertyPath))
                ->addError($result);
        }

        return $result;
    }