public object GetValue(Expression expression)
        {
            var call = ((MethodCallExpression)expression);

            var targetObject = call.Object != null
                ? call.Object.GetValue <object>()
                : null;

            var parameters = call.Method.GetParameters();

            var args = call.Arguments
                       .Select((expr, i) =>
            {
                var paramIType = parameters[i].ParameterType;

                if (typeof(Expression).IsAssignableFrom(paramIType))
                {
                    switch (expr.NodeType)
                    {
                    case ExpressionType.Lambda:
                        return(expr);

                    case ExpressionType.Quote:
                        return(((UnaryExpression)expr).Operand);

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }

                return(ExpressionExtensions.GetValue <object>(expr));
            })
                       .ToArray();

            return(call.Method.Invoke(targetObject, args));
        }
        public object GetValue(Expression expression)
        {
            var mi = (MemberInitExpression)expression;

            var obj = mi.NewExpression.GetValue <object>();

            foreach (var memberBinding in mi.Bindings)
            {
                switch (memberBinding.BindingType)
                {
                case MemberBindingType.Assignment:
                {
                    var ma          = (MemberAssignment)memberBinding;
                    var memberValue = ma.Expression.GetValue <object>();

                    switch (memberBinding.Member.MemberType)
                    {
                    case MemberTypes.Field:
                        ((FieldInfo)memberBinding.Member).SetValue(obj, memberValue);
                        break;

                    case MemberTypes.Property:
                        ((PropertyInfo)memberBinding.Member).SetValue(obj, memberValue);
                        break;

                    default:
                        throw new NotSupportedException($"Member type '{memberBinding.Member.MemberType}' not supported");
                    }
                }
                break;

                //case MemberBindingType.MemberBinding:
                //    break;
                case MemberBindingType.ListBinding:
                {
                    var lb = (MemberListBinding)memberBinding;

                    switch (lb.Member.MemberType)
                    {
                    case MemberTypes.Property:
                    {
                        var propMember  = (PropertyInfo)lb.Member;
                        var propertyVal = propMember.GetValue(obj);
                        foreach (var lbInitializer in lb.Initializers)
                        {
                            lbInitializer.AddMethod.Invoke(propertyVal,
                                                           lbInitializer.Arguments
                                                           .Select(a => ExpressionExtensions.GetValue <object>(a))
                                                           .ToArray());
                        }
                    }
                    break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
                break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            return(obj);
        }