internal static bool TryUriStringToPrimitive(string text, IEdmTypeReference targetType, out object targetValue, out string reason)
        {
            Debug.Assert(text != null, "text != null");
            Debug.Assert(targetType != null, "targetType != null");

            reason = null;

            if (targetType.IsNullable)
            {
                if (text == ExpressionConstants.KeywordNull)
                {
                    targetValue = null;
                    return(true);
                }
            }

            IEdmPrimitiveTypeReference primitiveTargetType = targetType.AsPrimitiveOrNull();

            if (primitiveTargetType == null)
            {
                targetValue = null;
                return(false);
            }

            EdmPrimitiveTypeKind targetTypeKind = primitiveTargetType.PrimitiveKind();

            byte[] byteArrayValue;
            bool   binaryResult = TryUriStringToByteArray(text, out byteArrayValue);

            if (targetTypeKind == EdmPrimitiveTypeKind.Binary)
            {
                targetValue = (object)byteArrayValue;
                return(binaryResult);
            }
            else if (binaryResult)
            {
                string keyValue = Encoding.UTF8.GetString(byteArrayValue, 0, byteArrayValue.Length);
                return(TryUriStringToPrimitive(keyValue, targetType, out targetValue));
            }
            else if (targetTypeKind == EdmPrimitiveTypeKind.Guid)
            {
                Guid guidValue;
                bool result = UriUtils.TryUriStringToGuid(text, out guidValue);
                targetValue = guidValue;
                return(result);
            }
            else if (targetTypeKind == EdmPrimitiveTypeKind.DateTimeOffset)
            {
                DateTimeOffset dateTimeOffsetValue;
                bool           result = UriUtils.TryUriStringToDateTimeOffset(text, out dateTimeOffsetValue);
                targetValue = dateTimeOffsetValue;
                return(result);
            }
            else if (targetTypeKind == EdmPrimitiveTypeKind.Duration)
            {
                TimeSpan timespanValue;
                bool     result = TryUriStringToDuration(text, out timespanValue);
                targetValue = timespanValue;
                return(result);
            }
            else if (targetTypeKind == EdmPrimitiveTypeKind.Geography)
            {
                Geography geographyValue;
                bool      result = TryUriStringToGeography(text, out geographyValue, out reason);
                targetValue = geographyValue;
                return(result);
            }
            else if (targetTypeKind == EdmPrimitiveTypeKind.Geometry)
            {
                Geometry geometryValue;
                bool     result = TryUriStringToGeometry(text, out geometryValue, out reason);
                targetValue = geometryValue;
                return(result);
            }

            bool quoted = targetTypeKind == EdmPrimitiveTypeKind.String;

            if (quoted != IsUriValueQuoted(text))
            {
                targetValue = null;
                return(false);
            }

            if (quoted)
            {
                text = RemoveQuotes(text);
            }

            try
            {
                switch (targetTypeKind)
                {
                case EdmPrimitiveTypeKind.String:
                    targetValue = text;
                    break;

                case EdmPrimitiveTypeKind.Boolean:
                    targetValue = XmlConvert.ToBoolean(text);
                    break;

                case EdmPrimitiveTypeKind.Byte:
                    targetValue = XmlConvert.ToByte(text);
                    break;

                case EdmPrimitiveTypeKind.SByte:
                    targetValue = XmlConvert.ToSByte(text);
                    break;

                case EdmPrimitiveTypeKind.Int16:
                    targetValue = XmlConvert.ToInt16(text);
                    break;

                case EdmPrimitiveTypeKind.Int32:
                    targetValue = XmlConvert.ToInt32(text);
                    break;

                case EdmPrimitiveTypeKind.Int64:
                    TryRemoveLiteralSuffix(ExpressionConstants.LiteralSuffixInt64, ref text);
                    targetValue = XmlConvert.ToInt64(text);
                    break;

                case EdmPrimitiveTypeKind.Single:
                    TryRemoveLiteralSuffix(ExpressionConstants.LiteralSuffixSingle, ref text);
                    targetValue = XmlConvert.ToSingle(text);
                    break;

                case EdmPrimitiveTypeKind.Double:
                    TryRemoveLiteralSuffix(ExpressionConstants.LiteralSuffixDouble, ref text);
                    targetValue = XmlConvert.ToDouble(text);
                    break;

                case EdmPrimitiveTypeKind.Decimal:
                    TryRemoveLiteralSuffix(ExpressionConstants.LiteralSuffixDecimal, ref text);
                    try
                    {
                        targetValue = XmlConvert.ToDecimal(text);
                    }
                    catch (FormatException)
                    {
                        // we need to support exponential format for decimals since we used to support them in V1
                        decimal result;
                        if (Decimal.TryParse(text, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out result))
                        {
                            targetValue = result;
                        }
                        else
                        {
                            targetValue = default(Decimal);
                            return(false);
                        }
                    }

                    break;

                default:
                    throw new ODataException(ODataErrorStrings.General_InternalError(InternalErrorCodes.UriPrimitiveTypeParser_TryUriStringToPrimitive));
                }

                return(true);
            }
            catch (FormatException)
            {
                targetValue = null;
                return(false);
            }
            catch (OverflowException)
            {
                targetValue = null;
                return(false);
            }
        }