/// <summary>
        /// Tries to write out a possible geography value into json
        /// </summary>
        /// <param name="geographyValue">The geography value to serialize into Json</param>
        /// <param name="writer">The Json writer being used to write out a Json payload</param>
        /// <returns>true, if the value is a geography object that is supported, false otherwise.</returns>
        private static bool TryWriteGeography(object geographyValue, JsonWriter writer)
        {
            Assert.IsNotNull(geographyValue, "Can't write a null geography.");
            Assert.IsNotNull(writer, "JsonWriter is null.");

            Type type = geographyValue.GetType();

            if (typeof(GeographyPoint).IsAssignableFrom(type))
            {
                GeographyPoint point = (GeographyPoint)geographyValue;
                WriteGeographyPoint(point, writer);
                return true;
            }
            else if (typeof(GeographyLineString).IsAssignableFrom(type))
            {
                GeographyLineString lineString = (GeographyLineString)geographyValue;
                WriteGeographyLineString(lineString, writer);
                return true;
            }

            return false;
        }
        /// <summary>
        /// Writes out a GeographyLineString value in geojson format.
        /// {
        ///      "__metadata": {"type": "Edm.GeographyLineString"}, 
        ///      { "type" :"LineString",
        ///          "coordinates": { [-122.1202778,47.6741667] } ,
        ///          "crs":{"type":"name","properties":{"name":"EPSG:4326"}}
        ///      }
        /// }
        /// </summary>
        /// <param name="geographyLineStringValue">The geography value to serialize into Json</param>
        /// <param name="writer">The Json writer being used to write out a Json payload</param>
        private static void WriteGeographyLineString(GeographyLineString lineString, JsonWriter writer)
        {
            // { 
            writer.StartObjectScope();

            //  "__metadata":
            writer.WriteName(JsonMetadataString);
            //      {
            writer.StartObjectScope();

            // "type"
            writer.WriteName(JsonTypeString);

            // "Edm.GeographyLineString"
            writer.WriteValue(Gml_Edm_GeographyLineStringName);

            //      }
            writer.EndScope();

            //  "type":"LineString",
            writer.WriteName(JsonTypeString);
            writer.WriteValue(GmlLineString);

            //  "coordinates":
            writer.WriteName(JsonCoOrdinatesString);

            // [
            writer.StartArrayScope();
            foreach (var point in lineString.Points)
            {
                WritePointCoordinates(writer, point);
            }

            // ]
            writer.EndScope();

            // 	"crs": {"type": "name", "properties": {"name": "EPSG:4326"}}
            WriteCrsElement(writer, lineString.CoordinateSystem.EpsgId);

            // }
            writer.EndScope();
        }
        /// <summary>
        /// Attempts to convert the specified primitive value to a serializable string.
        /// </summary>
        /// <param name="value">Non-null value to convert.</param>
        private static void WritePrimitiveJsonValue(JsonWriter writer, object value)
        {
            Debug.Assert(value != null, "value != null");

            Type valueType = value.GetType();
            if (typeof(String) == valueType)
            {
                writer.WriteValue((string)value);
            }
            else if (typeof(System.Xml.Linq.XElement) == valueType)
            {
                writer.WriteValue(((System.Xml.Linq.XElement)value).ToString(System.Xml.Linq.SaveOptions.None));
            }
            else if (typeof(SByte) == valueType)
            {
                writer.WriteValue((SByte)value);
            }
            else if (typeof(Boolean) == value.GetType())
            {
                writer.WriteValue((bool)value);
            }
            else if (typeof(Byte) == value.GetType())
            {
                writer.WriteValue((byte)value);
            }
            else if (typeof(DateTime) == value.GetType())
            {
                writer.WriteValue((DateTime)value);
            }
            else if (typeof(Decimal) == value.GetType())
            {
                writer.WriteValue((Decimal)value);
            }
            else if (typeof(Double) == value.GetType())
            {
                writer.WriteValue((Double)value);
            }
            else if (typeof(Guid) == value.GetType())
            {
                writer.WriteValue((Guid)value);
            }
            else if (typeof(Int16) == value.GetType())
            {
                writer.WriteValue((Int16)value);
            }
            else if (typeof(Int32) == value.GetType())
            {
                writer.WriteValue((Int32)value);
            }
            else if (typeof(Int64) == value.GetType())
            {
                writer.WriteValue((Int64)value);
            }
            else if (typeof(Single) == value.GetType())
            {
                writer.WriteValue((Single)value);
            }
            else if (typeof(byte[]) == value.GetType())
            {
                byte[] byteArray = (byte[])value;
                string result = Convert.ToBase64String(byteArray, Base64FormattingOptions.None);
                writer.WriteValue(result);
            }
            else if (!TryWriteGeography(value, writer))
            {
                Debug.Assert(typeof(System.Data.Linq.Binary) == value.GetType(), "typeof(Binary) == value.GetType() (" + value.GetType() + ")");
                WritePrimitiveJsonValue(writer, ((System.Data.Linq.Binary)value).ToArray());
            }
        }
 /// <summary>
 /// Creates a Json serializer.
 /// </summary>
 /// <param name="output">Output stream.</param>
 /// <param name="encoding">Stream encoding.</param>
 public DSPResourceJsonSerializer(Stream output, Encoding encoding)
 {
     encoding = encoding ?? Encoding.UTF8;
     writer = new JsonWriter(new StreamWriter(output, encoding));
 }
 /// <summary>
 /// Writes out a geography point's Co-ordinates in JSON
 /// </summary>
 /// <param name="writer">The Json Writer being used to write out the results.</param>
 /// <param name="point">The Point to serialize into JSON</param>
 private static void WritePointCoordinates(JsonWriter writer, GeographyPoint point)
 {
     writer.StartArrayScope();
     writer.WriteValue(point.Longitude);
     writer.WriteValue(point.Latitude);
     writer.EndScope();
 }
        /// <summary>
        /// Writes out the Co-ordinate reference system element in JSON
        /// http://en.wikipedia.org/wiki/Coordinate_reference_system
        /// </summary>
        /// <param name="writer">The Json Writer being used to write out the results.</param>
        /// <param name="epsgId">the EpsgId value to serialize</param>
        private static void WriteCrsElement(JsonWriter writer, int? epsgId)
        {
            //  "crs"
            writer.WriteName(JsonCrsString);

            // { 
            writer.StartObjectScope();

            // "type"
            writer.WriteName(JsonTypeString);

            // :"name"
            writer.WriteValue(JsonNameString);

            // "properties"
            writer.WriteName(PropertiesElementName);

            // :    {
            writer.StartObjectScope();

            // "name":
            writer.WriteName(JsonNameString);

            string epsgidValue = epsgId.HasValue ? epsgId.Value.ToString() : "0";

            // "EPSG:<EpsgIdValue>"
            writer.WriteValue(String.Format(JsonEPSGValueStringFormat, epsgidValue));

            //      }
            writer.EndScope();

            //    }
            writer.EndScope();
        }
        /// <summary>
        /// Writes out a GeographyPoint value in geojson format.
        /// {
        ///      "__metadata":{"type":"Edm.GeographyPoint"},
        ///      "type":"Point",
        ///      "coordinates":[Lattitude,Longitude],
        ///      "crs":{"type":"name","properties":{"name":"EPSG:EPSGValue"}}
        /// }
        /// </summary>
        /// <param name="geographyLineStringValue">The geography value to serialize into Json</param>
        /// <param name="writer">The Json writer being used to write out a Json payload</param>
        private static void WriteGeographyPoint(GeographyPoint point, JsonWriter writer)
        {
            // see http://geojson.org/geojson-spec.html#id9
            // {
            writer.StartObjectScope();

            //  "__metadata":
            writer.WriteName(JsonMetadataString);

            //      {
            writer.StartObjectScope();

            // "type"
            writer.WriteName(JsonTypeString);

            // "Edm.GeographyPoint"
            writer.WriteValue(Gml_Edm_GeographyPointName);

            //      }
            writer.EndScope();

            //  "type":"Point",
            writer.WriteName(JsonTypeString);
            writer.WriteValue(GmlPoint);

            //  "coordinates":[-122.1202778,47.6741667],
            writer.WriteName(JsonCoOrdinatesString);
            WritePointCoordinates(writer, point);

            // 	"crs": {"type": "name", "properties": {"name": "EPSG:4326"}}
            WriteCrsElement(writer, point.CoordinateSystem.EpsgId);

            // }
            writer.EndScope();
        }