public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			var f = value as IGeoBoundingBoxFilter;
			if (f == null || (f.IsConditionless && !f.IsVerbatim)) return;
			
			var contract = serializer.ContractResolver as SettingsContractResolver;
			if (contract == null)
				return;
			
			var field = contract.Infer.PropertyPath(f.Field);
			if (field.IsNullOrEmpty())
				return;

			writer.WriteStartObject();
			{
				writer.WritePropertyName(field);
				writer.WriteStartObject();
				{
					WriteProperty(writer, f, "top_left", f.TopLeft);
					WriteProperty(writer, f, "bottom_right", f.BottomRight);
				}
				writer.WriteEndObject();
				SerializeProperty(writer, serializer, f, "type", f.GeoExecution);
				
				WriteProperty(writer, f, "_cache", f.Cache);
				WriteProperty(writer, f, "_cache_key", f.CacheKey);
				WriteProperty(writer, f, "_name", f.FilterName);
			}
			writer.WriteEndObject();
		}
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			var f = value as ITermsBaseFilter;
			if (f == null || (f.IsConditionless && !f.IsVerbatim)) return;
			
			var contract = serializer.ContractResolver as SettingsContractResolver;
			if (contract == null)
				return;
			
			var field = contract.Infer.PropertyPath(f.Field);
			if (field.IsNullOrEmpty())
				return;

			writer.WriteStartObject();
			{
				var lf = f as ITermsLookupFilter;
				if (lf != null)
				{
					writer.WritePropertyName(field);
					writer.WriteStartObject();
					{
						WriteProperty(writer, f, "id", lf.Id);
						SerializeProperty(writer, serializer, f, "type", lf.Type);
						SerializeProperty(writer, serializer, f, "index", lf.Index);
						SerializeProperty(writer, serializer, f, "path", lf.Path);
						WriteProperty(writer, f, "routing", lf.Routing);
						WriteProperty(writer, f, "cache", lf.CacheLookup);
					}
					writer.WriteEndObject();
				}
				var tf = f as ITermsFilter;
				if (tf != null)
				{
					writer.WritePropertyName(field);
					serializer.Serialize(writer, tf.Terms);
				}
				if (f.Execution.HasValue)
				{
					writer.WritePropertyName("execution");
					serializer.Serialize(writer, f.Execution.Value);
				}

				WriteProperty(writer, f, "_cache", f.Cache);
				WriteProperty(writer, f, "_cache_key", f.CacheKey);
				WriteProperty(writer, f, "_name", f.FilterName);
				
			}
			writer.WriteEndObject();		
		}
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			var contract = serializer.ContractResolver as SettingsContractResolver;

			IDictionary dictionary = (IDictionary) value;
			writer.WriteStartObject();

			foreach (DictionaryEntry entry in dictionary)
			{
				if (entry.Value == null)
					continue;
				string key;
				var pp = entry.Key as PropertyPathMarker;
				var pn = entry.Key as PropertyNameMarker;
				var im = entry.Key as IndexNameMarker;
				if (contract == null)
					key = Convert.ToString(entry.Key, CultureInfo.InvariantCulture);
				else if (pp != null)
					key = contract.Infer.PropertyPath(pp);
				else if (pn != null)
					key = contract.Infer.PropertyName(pn);
				else if (im != null)
					key = contract.Infer.IndexName(im);
				else
					key = Convert.ToString(entry.Key, CultureInfo.InvariantCulture);
				writer.WritePropertyName(key);
				serializer.Serialize(writer, entry.Value);
			}

			writer.WriteEndObject();
		}
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			var analysisValue = (AnalysisSettings)value;
			writer.WriteStartObject();
			{
				if (analysisValue.Analyzers.Count > 0)
				{
					writer.WritePropertyName("analyzer");
					serializer.Serialize(writer, analysisValue.Analyzers);
				}

				if (analysisValue.TokenFilters.Count > 0)
				{
					writer.WritePropertyName("filter");
					serializer.Serialize(writer, analysisValue.TokenFilters);
				}

				if (analysisValue.Tokenizers.Count > 0)
				{
					writer.WritePropertyName("tokenizer");
					serializer.Serialize(writer, analysisValue.Tokenizers);
				}

				if (analysisValue.CharFilters.Count > 0)
				{
					writer.WritePropertyName("char_filter");
					serializer.Serialize(writer, analysisValue.CharFilters);
				}
			}
			writer.WriteEndObject();

		}
		private void WriteSettings(JsonWriter writer, JsonSerializer serializer, IndexSettings indexSettings)
		{
			writer.WritePropertyName("settings");
			writer.WriteStartObject();
			WriteIndexSettings(writer, serializer, indexSettings);
			writer.WriteEndObject();
		}
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			var f = value as IGeoDistanceRangeFilter;
			if (f == null || (f.IsConditionless && !f.IsVerbatim)) return;
			
			var contract = serializer.ContractResolver as SettingsContractResolver;
			if (contract == null)
				return;
			
			var field = contract.Infer.PropertyPath(f.Field);
			if (field.IsNullOrEmpty())
				return;

			writer.WriteStartObject();
			{
				WriteProperty(writer, f, field, f.Location);
				WriteProperty(writer, f, "from", f.From);
				WriteProperty(writer, f, "to", f.To);
				WriteProperty(writer, f, "include_lower", f.IncludeLower);
				WriteProperty(writer, f, "include_upper", f.IncludeUpper);
				SerializeProperty(writer, serializer, f, "unit", f.Unit);
				SerializeProperty(writer, serializer, f, "optimize_bbox", f.OptimizeBoundingBox);
				SerializeProperty(writer, serializer, f, "distance_type", f.DistanceType);
				
				WriteProperty(writer, f, "_cache", f.Cache);
				WriteProperty(writer, f, "_cache_key", f.CacheKey);
				WriteProperty(writer, f, "_name", f.FilterName);
			}
			writer.WriteEndObject();
		}
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			var items = (IDictionary<string, CharFilterBase>)value;
			writer.WriteStartObject();
			foreach (var item in items)
			{
				writer.WritePropertyName(item.Key);
				serializer.Serialize(writer, item.Value);
			}
			writer.WriteEndObject();
		}
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			var mapping = (WarmerMapping) value;
			writer.WriteStartObject();

			writer.WritePropertyName("types");
			serializer.Serialize(writer, mapping.Types);

			writer.WritePropertyName("source");
			serializer.Serialize(writer, mapping.Source);

			writer.WriteEndObject();
		}
		private void WriteSettingObject(JsonWriter writer, JObject obj)
		{
			writer.WriteStartObject();
			foreach (var property in obj.Children<JProperty>())
			{
				writer.WritePropertyName(property.Name);
				if (property.Value is JObject)
					this.WriteSettingObject(writer, property.Value as JObject);
				else
					writer.WriteValue(property.Value);
			}
			writer.WriteEndObject();

		}
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			writer.WriteStartArray();
			var sortItems = value as IList<KeyValuePair<PropertyPathMarker, ISort>>;
			foreach (var item in sortItems)
			{
				writer.WriteStartObject();
				var contract = serializer.ContractResolver as SettingsContractResolver;
				var fieldName = contract.Infer.PropertyPath(item.Key);
				writer.WritePropertyName(fieldName);
				serializer.Serialize(writer, item.Value);
				writer.WriteEndObject();
			}
			writer.WriteEndArray();
		}
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			var indexSettings = (IndexSettings)value;

			writer.WriteStartObject();

			WriteSettings(writer, serializer, indexSettings);
			
			WriteMappings(writer, serializer, indexSettings);
			
			WriteWarmers(writer, serializer, indexSettings);
			
			WriteAliases(writer, serializer, indexSettings);
			
			writer.WriteEndObject();
		}
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			var dict = value  as Dictionary<string, DynamicTemplate>;
			if (dict == null || !dict.HasAny())
				return;

			writer.WriteStartArray();
			foreach (var p in dict)
			{
				writer.WriteStartObject();
				{
					writer.WritePropertyName(p.Key);
					serializer.Serialize(writer, p.Value);
				}
				writer.WriteEndObject();
			}

			writer.WriteEndArray();
		}
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			var t = value as ITermsQuery;
			if (t == null) return;

			string field = null;

			var contract = serializer.ContractResolver as SettingsContractResolver;
			if (contract != null && contract.ConnectionSettings != null)
				field = contract.Infer.PropertyPath(t.Field);

			writer.WriteStartObject();
			{
				if (t.Terms.HasAny())
				{
					writer.WritePropertyName(field);
					serializer.Serialize(writer, t.Terms);
				}
				else if (t.ExternalField != null)
				{
					writer.WritePropertyName(field);
					serializer.Serialize(writer, t.ExternalField);
				}
				if (t.DisableCoord.HasValue)
				{
					writer.WritePropertyName("disable_coord");
					writer.WriteValue(t.DisableCoord.Value);
				}
				if (!t.MinimumShouldMatch.IsNullOrEmpty())
				{
					writer.WritePropertyName("minimum_should_match");
					writer.WriteValue(t.MinimumShouldMatch);
				}
				if (t.Boost.HasValue)
				{
					writer.WritePropertyName("boost");
					writer.WriteValue(t.Boost.Value);
				}
				
			}
			writer.WriteEndObject();
		}
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			var f = value as IPrefixFilter;
			if (f == null || (f.IsConditionless && !f.IsVerbatim)) return;
			
			var contract = serializer.ContractResolver as SettingsContractResolver;
			if (contract == null)
				return;
			
			var field = contract.Infer.PropertyPath(f.Field);
			if (field.IsNullOrEmpty())
				return;

			writer.WriteStartObject();
			{
				WriteProperty(writer, f, field, f.Prefix);
				WriteProperty(writer, f, "_cache", f.Cache);
				WriteProperty(writer, f, "_cache_key", f.CacheKey);
				WriteProperty(writer, f, "_name", f.FilterName);
				
			}
			writer.WriteEndObject();
		}
        /// <summary>
        /// Writes the JSON representation of the object.
        /// </summary>
        /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
        /// <param name="serializer">The calling serializer.</param>
        /// <param name="value">The value.</param>
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            IXmlNode node = WrapXml(value);

            XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable());
            PushParentNamespaces(node, manager);

            if (!OmitRootObject)
                writer.WriteStartObject();

            SerializeNode(writer, node, manager, !OmitRootObject);

            if (!OmitRootObject)
                writer.WriteEndObject();
        }
        internal static void JsonWritePayload(JsonWriter writer, EventEntry entry)
        {
            writer.WriteStartObject();

            var eventSchema = entry.Schema;

            for (int i = 0; i < entry.Payload.Count; i++)
            {
                JsonWriteProperty(writer, eventSchema.Payload[i], entry.Payload[i]);
            }

            writer.WriteEndObject();
        }
		private void WriteIndexSettings(JsonWriter writer, JsonSerializer serializer, IndexSettings indexSettings)
		{
			writer.WritePropertyName("index");
			writer.WriteStartObject();
			if (indexSettings.Settings.HasAny())
			{
				foreach (var kv in indexSettings.Settings)
				{
					writer.WritePropertyName(kv.Key);
					if (kv.Value is JObject)
						this.WriteSettingObject(writer, kv.Value as JObject);
					else
						writer.WriteValue(kv.Value);
				}
			}

			if (
				indexSettings.Analysis.Analyzers.Count > 0
				|| indexSettings.Analysis.TokenFilters.Count > 0
				|| indexSettings.Analysis.Tokenizers.Count > 0
				|| indexSettings.Analysis.CharFilters.Count > 0
				)
			{
				writer.WritePropertyName("analysis");
				serializer.Serialize(writer, indexSettings.Analysis);
			}

			if (
				indexSettings.Similarity.CustomSimilarities.Count > 0
				|| !string.IsNullOrEmpty(indexSettings.Similarity.Default)
				)
			{
				writer.WritePropertyName("similarity");
				serializer.Serialize(writer, indexSettings.Similarity);
			}

			writer.WriteEndObject();
		}
        private void SerializeNode(JsonWriter writer, IXmlNode node, XmlNamespaceManager manager, bool writePropertyName)
        {
            switch (node.NodeType)
            {
                case XmlNodeType.Document:
                case XmlNodeType.DocumentFragment:
                    SerializeGroupedNodes(writer, node, manager, writePropertyName);
                    break;
                case XmlNodeType.Element:
                    if (IsArray(node) && node.ChildNodes.All(n => n.LocalName == node.LocalName) && node.ChildNodes.Count > 0)
                    {
                        SerializeGroupedNodes(writer, node, manager, false);
                    }
                    else
                    {
                        manager.PushScope();

                        foreach (IXmlNode attribute in node.Attributes)
                        {
                            if (attribute.NamespaceUri == "http://www.w3.org/2000/xmlns/")
                            {
                                string namespacePrefix = (attribute.LocalName != "xmlns")
                                    ? attribute.LocalName
                                    : string.Empty;
                                string namespaceUri = attribute.Value;

                                manager.AddNamespace(namespacePrefix, namespaceUri);
                            }
                        }

                        if (writePropertyName)
                            writer.WritePropertyName(GetPropertyName(node, manager));

                        if (!ValueAttributes(node.Attributes).Any() && node.ChildNodes.Count == 1
                            && node.ChildNodes[0].NodeType == XmlNodeType.Text)
                        {
                            // write elements with a single text child as a name value pair
                            writer.WriteValue(node.ChildNodes[0].Value);
                        }
                        else if (node.ChildNodes.Count == 0 && CollectionUtils.IsNullOrEmpty(node.Attributes))
                        {
                            IXmlElement element = (IXmlElement)node;

                            // empty element
                            if (element.IsEmpty)
                                writer.WriteNull();
                            else
                                writer.WriteValue(string.Empty);
                        }
                        else
                        {
                            writer.WriteStartObject();

                            for (int i = 0; i < node.Attributes.Count; i++)
                            {
                                SerializeNode(writer, node.Attributes[i], manager, true);
                            }

                            SerializeGroupedNodes(writer, node, manager, true);

                            writer.WriteEndObject();
                        }

                        manager.PopScope();
                    }

                    break;
                case XmlNodeType.Comment:
                    if (writePropertyName)
                        writer.WriteComment(node.Value);
                    break;
                case XmlNodeType.Attribute:
                case XmlNodeType.Text:
                case XmlNodeType.CDATA:
                case XmlNodeType.ProcessingInstruction:
                case XmlNodeType.Whitespace:
                case XmlNodeType.SignificantWhitespace:
                    if (node.NamespaceUri == "http://www.w3.org/2000/xmlns/" && node.Value == JsonNamespaceUri)
                        return;

                    if (node.NamespaceUri == JsonNamespaceUri)
                    {
                        if (node.LocalName == "Array")
                            return;
                    }

                    if (writePropertyName)
                        writer.WritePropertyName(GetPropertyName(node, manager));
                    writer.WriteValue(node.Value);
                    break;
                case XmlNodeType.XmlDeclaration:
                    IXmlDeclaration declaration = (IXmlDeclaration)node;
                    writer.WritePropertyName(GetPropertyName(node, manager));
                    writer.WriteStartObject();

                    if (!string.IsNullOrEmpty(declaration.Version))
                    {
                        writer.WritePropertyName("@version");
                        writer.WriteValue(declaration.Version);
                    }
                    if (!string.IsNullOrEmpty(declaration.Encoding))
                    {
                        writer.WritePropertyName("@encoding");
                        writer.WriteValue(declaration.Encoding);
                    }
                    if (!string.IsNullOrEmpty(declaration.Standalone))
                    {
                        writer.WritePropertyName("@standalone");
                        writer.WriteValue(declaration.Standalone);
                    }

                    writer.WriteEndObject();
                    break;
                case XmlNodeType.DocumentType:
                    IXmlDocumentType documentType = (IXmlDocumentType)node;
                    writer.WritePropertyName(GetPropertyName(node, manager));
                    writer.WriteStartObject();

                    if (!string.IsNullOrEmpty(documentType.Name))
                    {
                        writer.WritePropertyName("@name");
                        writer.WriteValue(documentType.Name);
                    }
                    if (!string.IsNullOrEmpty(documentType.Public))
                    {
                        writer.WritePropertyName("@public");
                        writer.WriteValue(documentType.Public);
                    }
                    if (!string.IsNullOrEmpty(documentType.System))
                    {
                        writer.WritePropertyName("@system");
                        writer.WriteValue(documentType.System);
                    }
                    if (!string.IsNullOrEmpty(documentType.InternalSubset))
                    {
                        writer.WritePropertyName("@internalSubset");
                        writer.WriteValue(documentType.InternalSubset);
                    }

                    writer.WriteEndObject();
                    break;
                default:
                    throw new JsonSerializationException("Unexpected XmlNodeType when serializing nodes: " + node.NodeType);
            }
        }