protected void Reserialize(JsonWriter writer, object value, JsonSerializer serializer, Action <JsonWriter> inlineWriter = null)
        {
            var properties = value.GetType().GetCachedObjectProperties();

            if (properties.Count == 0)
            {
                return;
            }
            writer.WriteStartObject();
            inlineWriter?.Invoke(writer);
            foreach (var p in properties)
            {
                if (p.Ignored)
                {
                    continue;
                }
                var vv = p.ValueProvider.GetValue(value);
                if (vv == null)
                {
                    continue;
                }
                writer.WritePropertyName(p.PropertyName);
                if (p.Converter?.GetType() == typeof(SourceValueWriteConverter))
                {
                    SourceValueWriteConverter.Write(writer, vv, serializer);
                }
                else
                {
                    serializer.Serialize(writer, vv);
                }
            }
            writer.WriteEndObject();
        }
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            if (!(value is ITermsQuery t))
            {
                return;
            }

            var settings = serializer.GetConnectionSettings();
            var field    = settings.Inferrer.Field(t.Field);

            writer.WriteStartObject();
            {
                if (t.IsVerbatim)
                {
                    if (t.TermsLookup != null)
                    {
                        writer.WritePropertyName(field);
                        serializer.Serialize(writer, t.TermsLookup);
                    }
                    else if (t.Terms != null)
                    {
                        writer.WritePropertyName(field);
                        writer.WriteStartArray();
                        foreach (var o in t.Terms)
                        {
                            SourceValueWriteConverter.Write(writer, o, serializer);
                        }
                        writer.WriteEndArray();
                    }
                }
                else
                {
                    if (t.Terms.HasAny())
                    {
                        writer.WritePropertyName(field);
                        writer.WriteStartArray();
                        foreach (var o in t.Terms)
                        {
                            SourceValueWriteConverter.Write(writer, o, serializer);
                        }
                        writer.WriteEndArray();
                    }
                    else if (t.TermsLookup != null)
                    {
                        writer.WritePropertyName(field);
                        serializer.Serialize(writer, t.TermsLookup);
                    }
                }

                if (t.Boost.HasValue)
                {
                    writer.WritePropertyName("boost");
                    writer.WriteValue(t.Boost.Value);
                }
                if (!t.Name.IsNullOrEmpty())
                {
                    writer.WritePropertyName("_name");
                    writer.WriteValue(t.Name);
                }
            }
            writer.WriteEndObject();
        }