/// <summary>
        /// Reads the JSON representation of the object.
        /// </summary>
        /// <param name="reader">The <see cref="JsonReader" /> to read from.</param>
        /// <param name="objectType">Type of the object.</param>
        /// <param name="existingValue">The existing value of object being read.</param>
        /// <param name="serializer">The calling serializer.</param>
        /// <returns>The object value.</returns>
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
            {
                return(null);
            }

            var index = new StreamingStartIndex();

            while (reader.Read() && reader.TokenType == JsonToken.PropertyName)
            {
                var propertyName = reader.Value.ToString();
                reader.Read();

                if (!ItemPropertyName.Equals(propertyName))
                {
                    continue;
                }

                var  value = serializer.Deserialize(reader);
                long longValue;

                // Handle case where avro-json format is not used
                if (value is int || value is long)
                {
                    index.Item = value;
                }
                // Handle number sent as string
                else if (value is string && long.TryParse(value.ToString(), out longValue))
                {
                    index.Item = longValue;
                }
                else if (value is JObject)
                {
                    var jObject      = value as JObject;
                    var intProperty  = jObject.Property(IntDataType);
                    var longProperty = jObject.Property(LongDataType);

                    if (intProperty != null)
                    {
                        index.Item = intProperty.Value.Value <int>();
                    }
                    else if (longProperty != null)
                    {
                        index.Item = longProperty.Value.Value <long>();
                    }
                    else
                    {
                        throw new JsonSerializationException($"Unsupported data type: {value}");
                    }
                }
                else if (value != null)
                {
                    throw new JsonSerializationException($"Unsupported data type: {value}");
                }
            }

            return(index);
        }
        public void StreamingStartIndexConverter_WriteJson_serializes_null_value()
        {
            var index = new StreamingStartIndex
            {
                Item = null
            };

            const string expected = "{\"item\":null}";
            var          json     = EtpExtensions.Serialize(index);

            Assert.AreEqual(expected, json);
        }
        public void StreamingStartIndexConverter_WriteJson_serializes_long_value()
        {
            var index = new StreamingStartIndex
            {
                Item = 10L
            };

            var expected = "{\"item\":{\"long\":10}}";
            var json     = EtpExtensions.Serialize(index);

            Assert.AreEqual(expected, json);
        }
        public void StreamingStartIndexConverter_WriteJson_raises_error_for_unsupported_data_type()
        {
            var index = new StreamingStartIndex
            {
                Item = "abc"
            };

            var pass = false;

            try
            {
                EtpExtensions.Serialize(index);
            }
            catch (JsonSerializationException)
            {
                pass = true;
            }

            Assert.IsTrue(pass);
        }