private static Property GetProperty <TOut>(Expression <Func <T, TOut> > expression)
        {
            var memberExpression = expression.Body as MemberExpression;

            if (memberExpression == null)
            {
                throw new Exception("Could not determine member from " + expression);
            }

            var setter = GenerateSetterMethod <TOut>(memberExpression);

            return(TypedProperty <T, TOut> .Create(memberExpression.Member.Name, memberExpression.Type, expression.Compile(), setter));
        }
        private void SerializeMultiValueProperty <TMultiValue, TElement>(TypedProperty <TMultiValue> multiValueProperty)
            where TMultiValue : TypedValueCollection <TElement>, new()
            where TElement : ODataPayloadElement, ITypedValue
        {
            ExceptionUtilities.CheckArgumentNotNull(multiValueProperty, "multiValueProperty");
            ExceptionUtilities.CheckArgumentNotNull(multiValueProperty.Value, "multiValueProperty.Value");

            // when name is null, it means that it is in the top level. We should use <m:value
            XElement propertyElement = multiValueProperty.Name == null?CreateMetadataElement(this.currentXElement, AtomValueElement) : CreateDataServicesElement(this.currentXElement, multiValueProperty.Name);

            this.AttachValueAttributes(propertyElement, multiValueProperty.Value);

            if (!multiValueProperty.Value.IsNull)
            {
                var collectionElementName = multiValueProperty.Value.GetCollectionItemElementName();
                if (collectionElementName == null)
                {
                    collectionElementName = XName.Get("element", DataServicesMetadataNamespace);
                }

                foreach (var element in multiValueProperty.Value)
                {
                    var elementName = element.GetCollectionItemElementName();
                    if (elementName == null)
                    {
                        elementName = collectionElementName;
                    }

                    var primitiveValue = element as PrimitiveValue;
                    var elementXml     = CreateElement(propertyElement, DataServicesMetadataNamespacePrefix, elementName.LocalName, elementName.NamespaceName);
                    if (primitiveValue != null)
                    {
                        this.VisitPayloadElement(primitiveValue, elementXml);
                    }
                    else
                    {
                        ExceptionUtilities.Assert(typeof(TElement) == typeof(ComplexInstance), "Unsupported collection element type: {0}", typeof(TElement));
                        this.VisitPayloadElement(element, elementXml);
                    }
                }
            }

            PostProcessXElement(multiValueProperty.Value, propertyElement);
            PostProcessXElement(multiValueProperty, propertyElement);
        }