/// <summary>
        /// Generates a Conditional Expression that will retrieve the given entity value by type and set it into the current property. 
        /// </summary>
        /// <param name="type">The entity type</param>
        /// <param name="property">The property to deserialize into</param>
        /// <param name="instanceParam">An Expression that represents the entity instance</param>
        /// <param name="currentEntityProperty">An Expression that represents the current EntityProperty expression</param>
        /// <returns></returns>
        private static Expression GeneratePropertyReadExpressionByType(Type type, PropertyInfo property, Expression instanceParam, Expression currentEntityProperty)
        {
            if (property.PropertyType == typeof(string))
            {
                return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.String)),
                Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_StringPI.FindGetProp())));
            }
            else if (property.PropertyType == typeof(byte[]))
            {
                return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Binary)),
                Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_BinaryPI.FindGetProp())));
            }
            else if (property.PropertyType == typeof(bool?))
            {
                return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Boolean)),
                Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_BoolPI.FindGetProp())));
            }
            else if (property.PropertyType == typeof(bool))
            {
                MethodInfo hasValuePI = typeof(bool?).FindProperty("HasValue").FindGetProp();
                MethodInfo valuePI = typeof(bool?).FindProperty("Value").FindGetProp();
                return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Boolean)),
                    Expression.IfThen(Expression.IsTrue(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_BoolPI.FindGetProp()), hasValuePI)),
                Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_BoolPI.FindGetProp()), valuePI))));
            }
            else if (property.PropertyType == typeof(DateTime?))
            {
                MethodInfo hasValuePI = typeof(DateTimeOffset?).FindProperty("HasValue").FindGetProp();
                MethodInfo valuePI = typeof(DateTimeOffset?).FindProperty("Value").FindGetProp();
                MethodInfo utcDateTimePI = typeof(DateTimeOffset).FindProperty("UtcDateTime").FindGetProp();

                ParameterExpression tempVal = Expression.Variable(typeof(DateTime?), "tempVal");
                ConditionalExpression valToSetExpr = Expression.IfThenElse(

                  // entityProperty.DateTimeOffsetValue.HasValue                   
                  Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DateTimeOffsetPI.FindGetProp()), hasValuePI),

                  // then //entityProperty.DateTimeOffsetValue.Value.UtcDateTime   
                  Expression.Assign(tempVal, Expression.TypeAs(Expression.Call(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DateTimeOffsetPI.FindGetProp()), valuePI), utcDateTimePI), typeof(DateTime?))),

                  // else
                  Expression.Assign(tempVal, Expression.TypeAs(Expression.Constant(null), typeof(DateTime?))));

                return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.DateTime)),
                            Expression.Block(new[] { tempVal },
                            valToSetExpr,
                            Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), tempVal)));
            }
            else if (property.PropertyType == typeof(DateTime))
            {
                MethodInfo valuePI = typeof(DateTimeOffset?).FindProperty("Value").FindGetProp();
                MethodInfo utcDateTimePI = typeof(DateTimeOffset).FindProperty("UtcDateTime").FindGetProp();

                return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.DateTime)),
                Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(),

                // entityProperty.DateTimeOffsetValue.Value.UtcDateTime   
                Expression.Call(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DateTimeOffsetPI.FindGetProp()), valuePI), utcDateTimePI)));
            }
            else if (property.PropertyType == typeof(DateTimeOffset?))
            {
                return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.DateTime)),
                Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_DateTimeOffsetPI.FindGetProp())));
            }
            else if (property.PropertyType == typeof(DateTimeOffset))
            {
                MethodInfo hasValuePI = typeof(DateTimeOffset?).FindProperty("HasValue").FindGetProp();
                MethodInfo valuePI = typeof(DateTimeOffset?).FindProperty("Value").FindGetProp();

                return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.DateTime)),
                       Expression.IfThen(Expression.IsTrue(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DateTimeOffsetPI.FindGetProp()), hasValuePI)),
                Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DateTimeOffsetPI.FindGetProp()), valuePI))));
            }
            else if (property.PropertyType == typeof(double?))
            {
                return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Double)),
                Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_DoublePI.FindGetProp())));
            }
            else if (property.PropertyType == typeof(double))
            {
                MethodInfo hasValuePI = typeof(double?).FindProperty("HasValue").FindGetProp();
                MethodInfo valuePI = typeof(double?).FindProperty("Value").FindGetProp();

                return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Double)),
                     Expression.IfThen(Expression.IsTrue(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DoublePI.FindGetProp()), hasValuePI)),
                Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DoublePI.FindGetProp()), valuePI))));
            }
            else if (property.PropertyType == typeof(Guid?))
            {
                return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Guid)),
                Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_GuidPI.FindGetProp())));
            }
            else if (property.PropertyType == typeof(Guid))
            {
                MethodInfo hasValuePI = typeof(Guid?).FindProperty("HasValue").FindGetProp();
                MethodInfo valuePI = typeof(Guid?).FindProperty("Value").FindGetProp();

                return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Guid)),
                     Expression.IfThen(Expression.IsTrue(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_GuidPI.FindGetProp()), hasValuePI)),
                Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_GuidPI.FindGetProp()), valuePI))));
            }
            else if (property.PropertyType == typeof(int?))
            {
                return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Int32)),
                Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_Int32PI.FindGetProp())));
            }
            else if (property.PropertyType == typeof(int))
            {
                MethodInfo hasValuePI = typeof(int?).FindProperty("HasValue").FindGetProp();
                MethodInfo valuePI = typeof(int?).FindProperty("Value").FindGetProp();

                return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Int32)),
                     Expression.IfThen(Expression.IsTrue(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_Int32PI.FindGetProp()), hasValuePI)),
                Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_Int32PI.FindGetProp()), valuePI))));
            }
            else if (property.PropertyType == typeof(long?))
            {
                return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Int64)),
                Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_Int64PI.FindGetProp())));
            }
            else if (property.PropertyType == typeof(long))
            {
                MethodInfo hasValuePI = typeof(long?).FindProperty("HasValue").FindGetProp();
                MethodInfo valuePI = typeof(long?).FindProperty("Value").FindGetProp();

                return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Int64)),
                     Expression.IfThen(Expression.IsTrue(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_Int64PI.FindGetProp()), hasValuePI)),
                Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_Int64PI.FindGetProp()), valuePI))));
            }

            return null;
        }
        /// <summary>
        /// Determines if the given property should be skipped based on its name, if it exposes a public getter and setter, and if the IgnoreAttribute is not defined.
        /// </summary>
        /// <param name="property">The PropertyInfo of the property to check</param>
        /// <param name="operationContext">An <see cref="OperationContext"/> object used to track the execution of the operation.</param>
        /// <returns>True if the property should be skipped, false otherwise. </returns>
        private static bool ShouldSkipProperty(PropertyInfo property, OperationContext operationContext)
        {
            // reserved properties
            string propName = property.Name;
            if (propName == TableConstants.PartitionKey ||
                propName == TableConstants.RowKey ||
                propName == TableConstants.Timestamp ||
                propName == TableConstants.Etag)
            {
                return true;
            }

            MethodInfo setter = property.FindSetProp();
            MethodInfo getter = property.FindGetProp();

            // Enforce public getter / setter
            if (setter == null || !setter.IsPublic || getter == null || !getter.IsPublic)
            {
                Logger.LogInformational(operationContext, SR.TraceNonPublicGetSet, property.Name);
                return true;
            }

            // Skip static properties
            if (setter.IsStatic)
            {
                return true;
            }

            // properties with [IgnoreAttribute]
#if WINDOWS_RT
            if (property.GetCustomAttribute(typeof(IgnorePropertyAttribute)) != null)
#else
            if (Attribute.IsDefined(property, typeof(IgnorePropertyAttribute)))
#endif
            {
                Logger.LogInformational(operationContext, SR.TraceIgnoreAttribute, property.Name);
                return true;
            }

            return false;
        }