private static void SerializeProperty(JsonWriter writer, JsonSerializer serializer , IFilter filter, string field, object value)
		{
			if ((field.IsNullOrEmpty() || value == null))
				return;
			writer.WritePropertyName(field);
			serializer.Serialize(writer, value);
		}
		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();
		}
		private static void WriteProperty(JsonWriter writer, IFilter filter, string field, object value)
		{
			if ((field.IsNullOrEmpty() || value == null))
				return;
			writer.WritePropertyName(field);
			writer.WriteValue(value);
		}
		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();

		}
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			if (value == null)
				writer.WriteValue("no");
			else 
				writer.WriteValue(((bool)value) ? "yes" : "no");
		}
		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 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 IFilterAggregator;
			if (f == null || f.Filter == null) return;

			serializer.Serialize(writer, f.Filter);
		}
		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 v = value as IFuzziness;
			if (v.Auto) writer.WriteValue("AUTO"); 
			else if (v.EditDistance.HasValue) writer.WriteValue(v.EditDistance.Value); 
			else if (v.Ratio.HasValue) writer.WriteValue(v.Ratio.Value);
			else writer.WriteNull(); 
		}
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			var marker = value as PropertyNameMarker;
			if (marker == null)
			{
				writer.WriteNull();
				return;
			}
			writer.WriteValue(this._infer.PropertyName(marker));
		}
		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();
		}
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			var custom = value as ICustomJson;
			if (custom == null)
				return;

			var json = custom.GetCustomJson();
			var rawJson = json as RawJson;
			if (rawJson != null)
				writer.WriteRawValue(rawJson.Data);
			else 
				serializer.Serialize(writer, json);
		}
        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 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)
		{
			long val;
			if (value is DateTime)
			{
				val = (long)((DateTime)value - EpochUtc).TotalMilliseconds;
			}
			else
			{
				throw new System.Exception("Expected date object value.");
			}

			writer.WriteValue(val);
		}
		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();		
		}
        /// <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();
        }
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			var similarityValue = (SimilaritySettings)value;

			if(similarityValue.CustomSimilarities.Count > 0)
			{
				serializer.Serialize(writer, similarityValue.CustomSimilarities);
			}

			if (!string.IsNullOrEmpty(similarityValue.Default))
			{
				writer.WritePropertyName("similarity.default.type");
				writer.WriteValue(similarityValue.Default);
			}
		}
		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 marker = value as TypeNameMarker;
			if (marker == null)
			{
				writer.WriteNull();
				return;
			}
			var contract = serializer.ContractResolver as SettingsContractResolver;
			if (contract != null && contract.ConnectionSettings != null)
			{
				var typeName = contract.Infer.TypeName(marker);
				writer.WriteValue(typeName);
			}
			else throw new System.Exception("If you use a custom contract resolver be sure to subclass from ElasticResolver");
		}
    /// <summary>
    /// Writes the JSON representation of the object.
    /// </summary>
    /// <param name="writer"></param>
    /// <param name="value"></param>
    /// <param name="serializer"></param>
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
      if (null == value)
      {
        writer.WriteNull();
        return;
      }

      var uriValue = value as Uri;
      if (uriValue != null)
      {
        writer.WriteValue(uriValue.OriginalString);
        return;
      }

      throw new InvalidOperationException("Unhandled case for UriConverter. Check to see if this converter has been applied to the wrong serialization type.");
    }
		private static void WriteMappings(JsonWriter writer, JsonSerializer serializer, IndexSettings indexSettings)
		{
			if (indexSettings.Mappings.Count <= 0) return;
			var contract = serializer.ContractResolver as SettingsContractResolver;
			if (contract == null || contract.ConnectionSettings == null) return;
			
			writer.WritePropertyName("mappings");
			serializer.Serialize(
				writer,
				indexSettings.Mappings.ToDictionary(m =>
				{
					var name = contract.Infer.PropertyName(m.Name);
					if (name.IsNullOrEmpty())
						throw new DslException("{0} should have a name!".F(m.GetType()));
					return name;
				})
			);
		}
		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 v = value as DynamicMappingOption?;
			if (!v.HasValue)
			{
				writer.WriteValue(true);
				return;
			}
			switch (v.Value)
			{
				case DynamicMappingOption.Strict:
					writer.WriteValue("strict");
					break;
				case DynamicMappingOption.Ignore:
					writer.WriteValue(false);
					break;
				default:
					writer.WriteValue(true);
					break;
			}
		}
		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();
		}
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
		}