namespace AgileObjects.AgileMapper.ObjectPopulation
{
    using System.Linq.Expressions;
    using DataSources;
    using Extensions;
    using Members;

    internal class ExistingOrDefaultValueDataSourceFactory : IDataSourceFactory
    {
        public static readonly IDataSourceFactory Instance = new ExistingOrDefaultValueDataSourceFactory();

        public IDataSource Create(IMemberMappingData mappingData)
            => mappingData.MapperData.TargetMember.IsReadable
                ? new ExistingMemberValueOrEmptyDataSource(mappingData.MapperData)
                : DefaultValueDataSourceFactory.Instance.Create(mappingData);

        private class ExistingMemberValueOrEmptyDataSource : DataSourceBase
        {
            public ExistingMemberValueOrEmptyDataSource(IMemberMapperData mapperData)
                : base(mapperData.SourceMember, GetValue(mapperData), mapperData)
            {
            }

            private static Expression GetValue(IMemberMapperData mapperData)
            {
                var existingValue = mapperData.GetTargetMemberAccess();

                if (!mapperData.TargetMember.IsEnumerable)
                {
                    return existingValue;
                }

                var existingValueNotNull = existingValue.GetIsNotDefaultComparison();
                var emptyEnumerable = mapperData.TargetMember.GetEmptyInstanceCreation();

                return Expression.Condition(
                    existingValueNotNull,
                    existingValue,
                    emptyEnumerable,
                    existingValue.Type);
            }
        }
    }
}
namespace AgileObjects.AgileMapper.ObjectPopulation
{
    using System.Linq.Expressions;
    using DataSources;
    using Members;

    internal class ExistingOrDefaultValueDataSourceFactory : IDataSourceFactory
    {
        public static readonly IDataSourceFactory Instance = new ExistingOrDefaultValueDataSourceFactory();

        public IDataSource Create(IMemberMappingData mappingData)
            => mappingData.MapperData.TargetMember.IsReadable
                ? new ExistingMemberValueOrEmptyDataSource(mappingData.MapperData)
                : DefaultValueDataSourceFactory.Instance.Create(mappingData);

        private class ExistingMemberValueOrEmptyDataSource : DataSourceBase
        {
            public ExistingMemberValueOrEmptyDataSource(IMemberMapperData mapperData)
                : base(mapperData.SourceMember, GetValue(mapperData), mapperData)
            {
            }

            private static Expression GetValue(IMemberMapperData mapperData)
            {
                var existingValue = mapperData.GetTargetMemberAccess();

                if (!mapperData.TargetMember.IsEnumerable)
                {
                    return existingValue;
                }

                var emptyEnumerable = mapperData.TargetMember.GetEmptyInstanceCreation();

                return Expression.Coalesce(existingValue, emptyEnumerable);
            }
        }
    }
}
Revert "Using ternary instead of coalesce in fallback enumerable value selection"
Revert "Using ternary instead of coalesce in fallback enumerable value selection"

This reverts commit 1f2b459fd70323866b9443e388a77368e194e5ed.
