/// <summary>
        /// Determine a Model Type based on semantic mappings (and a given base model type).
        /// </summary>
        /// <param name="baseModelType">The base type as obtained from the View Model.</param>
        /// <returns>The given base Model Type or a subclass if a more specific class can be resolved via semantic mapping.</returns>
        /// <remarks>
        /// This method makes it possible (for example) to let the <see cref="Teaser.Media"/> property get an instance of <see cref="Image"/>
        /// rather than just <see cref="MediaItem"/> (the type of the View Model property).
        /// </remarks>
        public Type GetModelTypeFromSemanticMapping(Type baseModelType)
        {
            Type[]   foundAmbiguousMappings = null;
            string[] semanticTypeNames      = GetSemanticTypeNames();
            foreach (string semanticTypeName in semanticTypeNames)
            {
                IEnumerable <Type> mappedModelTypes = ModelTypeRegistry.GetMappedModelTypes(semanticTypeName);
                if (mappedModelTypes == null)
                {
                    continue;
                }

                Type[] matchingModelTypes = mappedModelTypes.Where(t => baseModelType.IsAssignableFrom(t)).ToArray();
                if (matchingModelTypes.Length == 1)
                {
                    // Exactly one matching model type; return it.
                    return(matchingModelTypes[0]);
                }

                if (matchingModelTypes.Length > 1)
                {
                    // Multiple candidate models types found. Continue scanning; maybe we'll find a unique one for another semantic type.
                    foundAmbiguousMappings = matchingModelTypes;
                }
            }

            string errorMessage;

            if (foundAmbiguousMappings == null)
            {
                errorMessage =
                    $"No semantic mapping found between Schema {Id} ({String.Join(", ", semanticTypeNames)}) and model type '{baseModelType.FullName}'";
            }
            else
            {
                errorMessage =
                    $"Ambiguous semantic mappings found between Schema {Id} ({String.Join(", ", semanticTypeNames)}) and model type '{String.Join(", ", foundAmbiguousMappings.Select(t => t.FullName))}'. Found types: {baseModelType.FullName}";
            }

            if (baseModelType.IsAbstract)
            {
                // Base model type is abstract and we didn't find an (unambigous) concrete subtype to instantiate.
                throw new DxaException(errorMessage);
            }

            // Base model type is concrete, so we can fall back to instantiating that type.
            if (foundAmbiguousMappings == null)
            {
                Log.Debug("{0}. Sticking with model type.", errorMessage);
            }
            else
            {
                Log.Warn("{0}. Sticking with model type.", errorMessage);
            }

            return(baseModelType);
        }
        /// <summary>
        /// Determine a Model Type based on semantic mappings (and a given base model type).
        /// </summary>
        /// <param name="baseModelType">The base type as obtained from the View Model.</param>
        /// <returns>The given base Model Type or a subclass if a more specific class can be resolved via semantic mapping.</returns>
        /// <remarks>
        /// This method makes it possible (for example) to let the <see cref="Teaser.Media"/> property get an instance of <see cref="Image"/>
        /// rather than just <see cref="MediaItem"/> (the type of the View Model property).
        /// </remarks>
        public Type GetModelTypeFromSemanticMapping(Type baseModelType)
        {
            Type[]   foundAmbiguousMappings = null;
            string[] semanticTypeNames      = GetSemanticTypeNames();
            foreach (string semanticTypeName in semanticTypeNames)
            {
                IEnumerable <Type> mappedModelTypes = ModelTypeRegistry.GetMappedModelTypes(semanticTypeName);
                if (mappedModelTypes == null)
                {
                    continue;
                }

                Type[] matchingModelTypes = mappedModelTypes.Where(t => baseModelType.IsAssignableFrom(t)).ToArray();
                if (matchingModelTypes.Length == 1)
                {
                    // Exactly one matching model type; return it.
                    return(matchingModelTypes[0]);
                }

                if (matchingModelTypes.Length > 1)
                {
                    // Multiple candidate models types found. Continue scanning; maybe we'll find a unique one for another semantic type.
                    foundAmbiguousMappings = matchingModelTypes;
                }
            }

            if (foundAmbiguousMappings == null)
            {
                Log.Warn("No semantic mapping found between Schema {0} ({1}) and model type '{2}'. Sticking with model type.",
                         Id, String.Join(", ", semanticTypeNames), baseModelType.FullName);
            }
            else
            {
                Log.Warn("Ambiguous semantic mappings found between Schema {0} ({1}) and model type '{2}'. Found types: {3}. Sticking with model type.",
                         Id, String.Join(", ", semanticTypeNames), String.Join(", ", foundAmbiguousMappings.Select(t => t.FullName)), baseModelType.FullName);
            }

            return(baseModelType);
        }