public static void WriteLongEncoded(this IBinaryOutputStream stream, long?value)
 {
     if (value == null)
     {
         stream.WriteLong(int.MinValue);
     }
     else
     {
         stream.WriteLong(value.Value);
     }
 }
 public static void WriteBooleanEncoded(this IBinaryOutputStream stream, bool?value)
 {
     if (value == null)
     {
         stream.WriteByte(0);
     }
     else
     {
         stream.WriteByte((byte)(value.Value ? 2 : 1));
     }
 }
 public static void WriteIntEncoded(this IBinaryOutputStream stream, int?value)
 {
     if (value == null)
     {
         stream.WriteInt(int.MinValue);
     }
     else
     {
         stream.WriteInt(value.Value);
     }
 }
 public static void WriteStringEncoded(this IBinaryOutputStream stream, string value)
 {
     if (value == null)
     {
         stream.WriteInt(0);
     }
     else
     {
         stream.WriteBytes(Encoding.UTF8.GetBytes(value));
     }
 }
 public static void WriteDoubleEncoded(this IBinaryOutputStream stream, double?value)
 {
     if (value == null)
     {
         stream.WriteDouble(int.MinValue);
     }
     else
     {
         stream.WriteDouble(value.Value);
     }
 }
 public static void WriteArrayEncoded(this IBinaryOutputStream stream, JArray value)
 {
     if (value == null)
     {
         stream.WriteInt(-1);
     }
     else
     {
         stream.WriteInt(value.Count);
         foreach (var item in value)
         {
             WriteTypeEncoded(stream, item);
         }
     }
 }
 public static void WriteJsonEncoded(this IBinaryOutputStream stream, JObject keyValues)
 {
     if (keyValues == null)
     {
         stream.WriteInt(-1);
     }
     else
     {
         stream.WriteInt(keyValues.Count);
         foreach (var item in keyValues)
         {
             stream.WriteStringEncoded(item.Key);
             stream.WriteTypeEncoded(item.Value);
         }
     }
 }
        private static void WriteTypeEncoded(this IBinaryOutputStream stream, JToken value)
        {
            if (value == null)
            {
                stream.WriteByte(0);
            }

            switch (value.Type)
            {
            case JTokenType.Boolean:
                stream.WriteByte(1);
                stream.WriteBooleanEncoded((bool?)value);
                break;

            case JTokenType.Array:
                stream.WriteByte(2);
                stream.WriteArrayEncoded((JArray)value);
                break;

            case JTokenType.Integer:     // + byte
                stream.WriteByte(3);
                stream.WriteIntEncoded((int?)value);
                break;

            case JTokenType.Object:
                stream.WriteByte(4);
                stream.WriteJsonEncoded((JObject)value);
                break;

            case JTokenType.String:
                stream.WriteByte(5);
                stream.WriteStringEncoded((string)value);
                break;

            case JTokenType.Float:     // + double und long
                stream.WriteByte(8);
                stream.WriteFloatEncoded((float)value);
                break;
            }
        }