public ConstructedValueExpression Compile(MapTypeContext context)
        {
            if (!IsSupportedType(context.TargetType))
            {
                return(ConstructedValueExpression.Nothing);
            }

            // Get the concrete type to construct, the element type to populate, and the Add
            // method to call for each value
            var(collectionType, elementType, constructor, addMethod) = GetConcreteTypeInfo(context);
            Debug.Assert(collectionType != null);
            Debug.Assert(context.TargetType.IsAssignableFrom(collectionType));
            Debug.Assert(elementType != null);
            Debug.Assert(addMethod != null);
            Debug.Assert(constructor != null);

            var originalTargetType = context.TargetType;

            context = context.ChangeTargetType(collectionType);

            // Get a list of expressions to create the collection instance and populate it with
            // values
            var collectionVar = CollectionExpressionFactory.GetMaybeInstantiateCollectionExpression(context, constructor);
            var addStmts      = CollectionExpressionFactory.GetCollectionPopulateStatements(_scalars, _nonScalars, context, elementType, collectionVar.FinalValue, addMethod);

            return(new ConstructedValueExpression(
                       collectionVar.Expressions.Concat(addStmts.Expressions),
                       Expression.Convert(collectionVar.FinalValue, originalTargetType),
                       collectionVar.Variables.Concat(addStmts.Variables)
                       ));
        }
        public ConstructedValueExpression Compile(MapTypeContext context)
        {
            if (!IsSupportedType(context.TargetType))
            {
                return(ConstructedValueExpression.Nothing);
            }

            // We have a concrete type which implements IEnumerable/IEnumerable<T> and has an Add
            // method. Get these things.
            var(collectionType, elementType, constructor, addMethod) = GetTypeInfo(context);
            Debug.Assert(collectionType != null);
            Debug.Assert(context.TargetType.IsAssignableFrom(collectionType));
            Debug.Assert(elementType != null);
            Debug.Assert(addMethod != null);
            Debug.Assert(constructor != null);

            var collectionVar = CollectionExpressionFactory.GetMaybeInstantiateCollectionExpression(context, constructor);
            var addStmts      = CollectionExpressionFactory.GetCollectionPopulateStatements(_scalars, _nonScalars, context, elementType, collectionVar.FinalValue, addMethod);

            return(new ConstructedValueExpression(
                       collectionVar.Expressions.Concat(addStmts.Expressions),
                       collectionVar.FinalValue,
                       collectionVar.Variables.Concat(addStmts.Variables)));
        }