private ConstructedValueExpression AddInstantiationExpressionForObjectInstance(MapTypeContext context)
        {
            var instanceVar                    = context.CreateVariable(context.TargetType, "instance");
            var typeInfo                       = context.Settings.GetTypeSettings(context.TargetType);
            var defaultSubtypeInfo             = typeInfo.GetDefault();
            var defaultInstantiationExpression = AddInstantiationExpressionForSpecificType(context, defaultSubtypeInfo, instanceVar);
            var subclasses                     = typeInfo.GetSpecificTypes().ToList();

            // If we have no configured subclass predicates, instantiate the target type directly
            if (subclasses.Count == 0)
            {
                return(new ConstructedValueExpression(defaultInstantiationExpression.Expressions, instanceVar, defaultInstantiationExpression.Variables.Concat(new[] { instanceVar })));
            }

            // If we have configured subclass predicates, unroll the loop and write expressions for
            // all cases. The default case will be executed if no subclass predicates match.
            var endLabel    = context.CreateLabel("haveinstance");
            var expressions = new List <Expression>();

            foreach (var subclass in subclasses.Where(s => s.Predicate != null))
            {
                var instantiateExpressions = AddInstantiationExpressionForSpecificType(context, subclass, instanceVar);
                // Check the subclass predicate. If it matches, we enter into a block where we
                // create the subclass instance and then jump to the end label. Otherwise we
                // fall through to the next subclass.
                expressions.Add(
                    Expression.IfThen(
                        Expression.Call(
                            Expression.Constant(subclass.Predicate.Target),
                            subclass.Predicate.Method,
                            context.RecordParameter
                            ),
                        Expression.Block(
                            instantiateExpressions.Variables,
                            instantiateExpressions.Expressions.Concat(new[] {
                    Expression.Goto(endLabel.Target)
                })
                            )
                        )
                    );
            }
            // A block where we fall back to the default instantiation rules for the type, and then
            // fall through to the endLabel. The block here allows us to scope variables a little
            // more tightly
            expressions.Add(
                Expression.Block(
                    defaultInstantiationExpression.Variables,
                    defaultInstantiationExpression.Expressions
                    )
                );
            expressions.Add(endLabel);

            return(new ConstructedValueExpression(expressions, instanceVar, new[] { instanceVar }));
        }