public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			JObject o = JObject.Load(reader);
			var result = existingValue as Dictionary<string, CharFilterBase> ?? new Dictionary<string, CharFilterBase>();

			foreach (var childProperty in o.Children<JProperty>())
			{
				var propertyName = childProperty.Name;
				var typeProperty = ((JObject)childProperty.Value).Property("type");
				typeProperty.Remove();

				var typePropertyValue = typeProperty.Value.ToString().Replace("_", string.Empty);

				CharFilterBase item;
				var itemType = Type.GetType("Nest." + typePropertyValue + "CharFilter", false, true);
				if (itemType != null)
				{
					item = serializer.Deserialize(childProperty.Value.CreateReader(), itemType) as CharFilterBase;
				}
				else
				{
					continue;
				}

				result[propertyName] = item;
			}
			return result;
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			JObject o = JObject.Load(reader);
			var result = existingValue as AnalysisSettings ?? new AnalysisSettings();

			foreach (var rootProperty in o.Children<JProperty>())
			{
				if (rootProperty.Name.Equals("analyzer", StringComparison.InvariantCultureIgnoreCase))
				{
					result.Analyzers = serializer.Deserialize<IDictionary<string,AnalyzerBase>>(rootProperty.Value.CreateReader());
				}
				else if (rootProperty.Name.Equals("filter", StringComparison.InvariantCultureIgnoreCase))
				{
					result.TokenFilters = serializer.Deserialize<IDictionary<string, TokenFilterBase>>(rootProperty.Value.CreateReader());
				}
				else if (rootProperty.Name.Equals("tokenizer", StringComparison.InvariantCultureIgnoreCase))
				{
					result.Tokenizers = serializer.Deserialize<IDictionary<string, TokenizerBase>>(rootProperty.Value.CreateReader());
				}
				else if (rootProperty.Name.Equals("char_filter", StringComparison.InvariantCultureIgnoreCase))
				{
					result.CharFilters = serializer.Deserialize<IDictionary<string, CharFilterBase>>(rootProperty.Value.CreateReader());
				}
			}

			return result;
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			JObject o = JObject.Load(reader);
			var result = existingValue as Dictionary<string, TokenizerBase> ?? new Dictionary<string, TokenizerBase>();

			foreach (var childProperty in o.Children<JProperty>())
			{
				var propertyName = childProperty.Name;
				var typeProperty = ((JObject)childProperty.Value).Property("type");
				typeProperty.Remove();

				var typePropertyValue = typeProperty.Value.ToString().Replace("_", string.Empty);
				if (typePropertyValue.Equals("uax_url_email", StringComparison.InvariantCultureIgnoreCase))
				{
					typePropertyValue = "UaxEmailUrl";
				}

				TokenizerBase item;
				var itemType = Type.GetType("Nest." + typePropertyValue + "Tokenizer", false, true);
				if (itemType != null)
				{
					item = serializer.Deserialize(childProperty.Value.CreateReader(), itemType) as TokenizerBase;
				}
				else
				{
					continue;
				}

				result[propertyName] = item;
			}
			return result;
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			var j = JObject.Load(reader);
			if (j == null || !j.HasValues)
				return null;

			IPrefixFilter filter = new PrefixFilter();
			foreach (var jv in j)
			{
				switch (jv.Key)
				{
					case "_cache":
						filter.Cache = jv.Value.Value<bool?>();
						break;
					case "_cacheKey":
					case "_cache_key":
						filter.CacheKey = jv.Value.Value<string>();
						break;
					case "_name":
						filter.FilterName = jv.Value.Value<string>();
						break;
					default:
						var field = jv.Key;
						filter.Field = field;
						filter.Prefix = jv.Value.Value<string>();
						break;
				}
			}
			return filter;

		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			var j = JObject.Load(reader);
			if (j == null || !j.HasValues)
				return null;
			IRegexpFilter filter = new RegexpFilterDescriptor<object>();
			foreach (var jv in j)
			{
				switch (jv.Key)
				{
					case "_cache":
						filter.Cache = jv.Value.Value<bool>();
						break;
					case "_cache_key":
						filter.CacheKey = jv.Value.Value<string>();
						break;
					case "_name":
						filter.FilterName = jv.Value.Value<string>();
						break;
					default:
						filter.Field = jv.Key;
						var value = jv.Value["value"];
						if (value != null)
							filter.Value = value.Value<string>();
						var flags = jv.Value["flags"];
						if (flags != null)
							filter.Flags = flags.Value<string>();
						break;
				}
			}

			return filter;

		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			var filter = new TermsQueryDescriptor<object, object>();
			ITermsQuery f = filter;
			if (reader.TokenType != JsonToken.StartObject)
				return null;

			var depth = reader.Depth;
			while (reader.Read() && reader.Depth >= depth && reader.Value != null)
			{
				var property = reader.Value as string;
				switch (property)
				{
					case "disable_coord":
						reader.Read();
						f.DisableCoord = reader.Value as bool?;
						break;
					case "minimum_should_match":
						f.MinimumShouldMatch = reader.ReadAsString();	
						break;
					case "boost":
						reader.Read();
						f.Boost = reader.Value as double?;
						break;
					default:
						f.Field = property;
						//reader.Read();
						ReadTerms(f, reader);
						//reader.Read();
						break;
				}
			}
			return filter;

		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
										JsonSerializer serializer)
		{
			JObject o = JObject.Load(reader);

			var esType = this.GetTypeFromJObject(o, serializer);
			return esType;
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			if (reader.TokenType == JsonToken.String)
			{
				string typeName = reader.Value.ToString();
				return (TypeNameMarker) typeName;
			}
			return null;
		}
    /// <summary>
    /// Reads the JSON representation of the object.
    /// </summary>
    /// <param name="reader"></param>
    /// <param name="objectType"></param>
    /// <param name="existingValue"></param>
    /// <param name="serializer"></param>
    /// <returns></returns>
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
      if (reader.TokenType == JsonToken.String)
        return new Uri((string)reader.Value);

      if (reader.TokenType == JsonToken.Null)
        return null;

      throw new InvalidOperationException("Unhandled case for UriConverter. Check to see if this converter has been applied to the wrong serialization type.");
    }
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			var dict = new Dictionary<string, Dictionary<string, Dictionary<string, IndexSettings>>>();
			serializer.Populate(reader, dict);
			var response = new IndexSettingsResponse();
			if (!dict.HasAny() || !dict.First().Value.HasAny() || !dict.First().Value.First().Value.HasAny())
				return response;
			response.Nodes = dict.ToDictionary(k => k.Key, v => v.Value.First().Value.First().Value);
			return response;
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			var j = JObject.Load(reader);
			if (j == null || !j.HasValues)
				return null;
			IGeoDistanceRangeFilter filter = new GeoDistanceRangeFilterDescriptor();
			foreach (var jv in j)
			{
				switch (jv.Key)
				{
					case "include_lower":
						filter.IncludeLower = jv.Value.Value<bool>();
						break;
					case "include_upper":
						filter.IncludeUpper = jv.Value.Value<bool>();
						break;
					case "from":
						if (jv.Value.Type == JTokenType.String)
							filter.From = jv.Value.Value<string>();
						else
							filter.From = jv.Value.Value<double>();
						break;
					case "to":
						filter.To = jv.Value.Value<object>();
						break;
					case "distance_type":
						filter.DistanceType = jv.Value.Value<string>().ToEnum<GeoDistance>();
						break;
					case "optimize_bbox":
						filter.OptimizeBoundingBox = jv.Value.Value<string>().ToEnum<GeoOptimizeBBox>();
						break;
					case "unit":
						filter.Unit = jv.Value.Value<string>().ToEnum<GeoUnit>();
						break;
					case "_cache":
						filter.Cache = jv.Value.Value<bool>();
						break;
					case "_cache_key":
						filter.CacheKey = jv.Value.Value<string>();
						break;
					case "_name":
						filter.FilterName = jv.Value.Value<string>();
						break;
					default:
						filter.Field = jv.Key;
						filter.Location = jv.Value.Value<string>();
						break;
				}
			}



			return filter;

		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
										JsonSerializer serializer)
		{
			if (reader.TokenType != JsonToken.Integer)
			{
				throw new System.Exception("Wrong Token Type");
			}

			var time = (long)reader.Value;
			return EpochUtc.AddMilliseconds(time);
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			if (reader.TokenType != JsonToken.StartObject) return null;
			reader.Read();
			if (reader.TokenType != JsonToken.PropertyName) return null;
			var prop = reader.Value;
			if ((string) reader.Value != "filter") return null;
			reader.Read();
			var agg = new FilterAggregator();
			serializer.Populate(reader, agg);
			return agg;
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
										JsonSerializer serializer)
		{
			var jObject = JObject.Load(reader);
			var types = ((JArray)jObject.Property("types").Value).Values<string>().ToArray()
				.Select(s=>(TypeNameMarker)s);
			var source = jObject.Property("source").Value.ToString();

			return new WarmerMapping
			{
				Types = types, 
			};
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			var response = new SuggestResponse();
			var jsonObject = JObject.Load(reader);
			foreach (var prop in jsonObject.Properties())
			{
				if (prop.Name == "_shards")
					response.Shards = prop.Value.ToObject<ShardsMetaData>();
				else 
					response.Suggestions.Add(prop.Name, prop.Value.ToObject<Suggest[]>());
			}

			return response;
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
										JsonSerializer serializer)
		{
			if (reader.TokenType == JsonToken.StartArray)
			{
				var list = new List<ShardsSegment>();
				serializer.Populate(reader, list);
				return list.First();
			}

			var o = new ShardsSegment();
			serializer.Populate(reader, o);
			return o;
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			JObject o = JObject.Load(reader);
			var result = existingValue as SimilaritySettings ?? new SimilaritySettings();

			foreach(var rootProperty in o.Children<JProperty>())
			{
				var typeProperty = ((JObject)rootProperty.Value).Property("type");
				var itemType = Type.GetType("Nest." + typeProperty.Value.ToString() + "Similarity", false, true);
				var similarity = serializer.Deserialize(rootProperty.Value.CreateReader(), itemType) as SimilarityBase;
				result.CustomSimilarities.Add(rootProperty.Name, similarity);
			}

			return result;
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			if (reader.TokenType == JsonToken.String)
				return Fuzziness.Auto;
			if (reader.TokenType == JsonToken.Integer)
			{
				var editDistance = (reader.Value as int?).GetValueOrDefault(0);
				return Fuzziness.EditDistance(editDistance);
			}
			if (reader.TokenType == JsonToken.Float)
			{
				var ratio = (reader.Value as double?).GetValueOrDefault(0);
				return Fuzziness.Ratio(ratio);
			}
			return null;
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
										JsonSerializer serializer)
		{
			JObject o = JObject.Load(reader);

			JToken typeToken;
			if (o.TryGetValue("_type", out typeToken))
			{
				var type = typeToken.Value<string>();
				switch (type)
				{
					case "terms":
						return serializer.Deserialize(o.CreateReader(), typeof(TermFacet));

					case "range":
						var firstRange = o.Value<JArray>("ranges")[0];
						if (firstRange.Value<string>("from_str") != null || firstRange.Value<string>("to_str") != null)
						{
							return serializer.Deserialize(o.CreateReader(), typeof(DateRangeFacet));
						}
						else
						{
							return serializer.Deserialize(o.CreateReader(), typeof(RangeFacet));
						}

					case "histogram":
						return serializer.Deserialize(o.CreateReader(), typeof(HistogramFacet));

					case "date_histogram":
						return serializer.Deserialize(o.CreateReader(), typeof(DateHistogramFacet));

					case "statistical":
						return serializer.Deserialize(o.CreateReader(), typeof(StatisticalFacet));

					case "terms_stats":
						return serializer.Deserialize(o.CreateReader(), typeof(TermStatsFacet));
					case "geo_distance":
						return serializer.Deserialize(o.CreateReader(), typeof(GeoDistanceFacet));
					case "filter":
						return serializer.Deserialize(o.CreateReader(), typeof(FilterFacet));
					case "query":
						return serializer.Deserialize(o.CreateReader(), typeof(QueryFacet));
				}
			}

			return serializer.Deserialize(o.CreateReader(), objectType);
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			var j = JObject.Load(reader);
			if (j == null || !j.HasValues)
				return null;
			IRangeFilter filter = new RangeFilterDescriptor<object>();
			foreach (var jv in j)
			{
				switch (jv.Key)
				{
					case "_cache":
						filter.Cache = jv.Value.Value<bool>();
						break;
					case "_cache_key":
						filter.CacheKey = jv.Value.Value<string>();
						break;
					case "_name":
						filter.FilterName = jv.Value.Value<string>();
						break;
					default:
						filter.Field = jv.Key;
					
						var gte = jv.Value["gte"];
						if (gte != null)
							filter.GreaterThanOrEqualTo = ToString(gte);
						
						var gt = jv.Value["gt"];
						if (gt != null)
							filter.GreaterThanOrEqualTo = ToString(gt);

						var lte = jv.Value["lte"];
						if (lte != null)
							filter.LowerThanOrEqualTo = ToString(lte);
							
						var lt = jv.Value["lt"];
						if (lt != null)
							filter.LowerThanOrEqualTo = ToString(lt);
						
						break;
				}
			}

			return filter;

		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			var v = reader.Value;
			if (v == null)
				return null;

			var sv = v.ToString().ToLowerInvariant();
			switch (sv)
			{
				case "false":
					return DynamicMappingOption.Ignore;
				case "strict":
					return DynamicMappingOption.Strict;
				default:
					return DynamicMappingOption.Allow;

			}
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
										JsonSerializer serializer)
		{
			reader.Read();
			if (reader.TokenType != JsonToken.PropertyName)
				return null;

			var key = reader.Value as string;
			reader.Read();
			switch (key)
			{
				case "delete":
					var deleteItem = new BulkDeleteResponseItem();
					serializer.Populate(reader, deleteItem);
					if (deleteItem != null)
						deleteItem.Operation = key;
					reader.Read();
					return deleteItem;
				case "update":
					var updateItem = new BulkUpdateResponseItem();
					serializer.Populate(reader, updateItem);
					if (updateItem != null)
						updateItem.Operation = key;
					reader.Read();
					return updateItem;
				case "index":
					var indexItem = new BulkIndexResponseItem();
					serializer.Populate(reader, indexItem);
					if (indexItem != null)
						indexItem.Operation = key;
					reader.Read();
					return indexItem;
				case "create":
					var createItem = new BulkCreateResponseItem();
					serializer.Populate(reader, createItem);
					if (createItem != null)
						createItem.Operation = key;
					reader.Read();
					return createItem;
			}
			return null;
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			var j = JObject.Load(reader);
			if (j == null || !j.HasValues)
				return null;
			IGeoPolygonFilter filter = new GeoPolygonFilterDescriptor();
			foreach (var jv in j)
			{
				switch (jv.Key)
				{
					case "_cache":
						filter.Cache = jv.Value.Value<bool>();
						break;
					case "_cache_key":
						filter.CacheKey = jv.Value.Value<string>();
						break;
					case "_name":
						filter.FilterName = jv.Value.Value<string>();
						break;
					default:
						filter.Field = jv.Key;
						var points = jv.Value["points"];
						if (points == null)
						{
							filter.Points = Enumerable.Empty<string>();
							break;
						}
						
						var stringValues = points.Values<string>();
						//var doublePairArray = points.Values<double[]>()
						//	.Where(dd=>dd.Count() == 2)
						//	.Select(dd=>"{0}, {1}".F(dd[0], dd[1]));
						//var latLongs = points.Values<LatLon>().Select(ll=>"{0}, {1}".F(ll.Lon, ll.Lat));

						filter.Points = stringValues;
						break;
				}
			}

			return filter;

		}
		private IAggregation GetPercentilesMetricAggregation(JsonReader reader, JsonSerializer serializer)
		{
			var metric = new PercentilesMetric();
			var percentileItems = new List<PercentileItem>();
			if (reader.TokenType == JsonToken.StartObject)
				reader.Read();
			while (reader.TokenType != JsonToken.EndObject)
			{
				var percentile = double.Parse(reader.Value as string, CultureInfo.InvariantCulture);
				reader.Read();
				var value = reader.Value as double?;
				percentileItems.Add(new PercentileItem()
				{
					Percentile = percentile,
					Value = value.GetValueOrDefault(0)
				});
				reader.Read();
			}
			metric.Items = percentileItems;
			return metric;
		}
		private IAggregation ReadAggregation(JsonReader reader, JsonSerializer serializer)
		{
			if (reader.TokenType != JsonToken.StartObject)
				return null;
			reader.Read();
			
			if (reader.TokenType != JsonToken.PropertyName)
				return null;

			var property = reader.Value as string; 
			if (_numeric.IsMatch(property))
				return GetPercentilesMetricAggregation(reader, serializer);

			switch (property)
			{
				case "values":
					reader.Read();
					reader.Read();
					return GetPercentilesMetricAggregation(reader, serializer);
				case "value":
					return GetValueMetricOrAggregation(reader, serializer);
				case "buckets":
					return GetBucketAggregation(reader, serializer);
				case "key":
					return GetKeyedBucketItem(reader, serializer);
				case "from":
				case "to":
					return GetRangeAggregation(reader, serializer);
				case "key_as_string":
					return GetDateHistogramAggregation(reader, serializer);
				case "count":
					return GetStatsAggregation(reader, serializer);
				case "doc_count":
					return GetSingleBucketAggregation(reader, serializer);
				default:
					return null; 

			}
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			JObject o = JObject.Load(reader);
			var result = existingValue as Dictionary<string, AnalyzerBase> ?? new Dictionary<string, AnalyzerBase>();

			foreach (var childProperty in o.Children<JProperty>())
			{
				var propertyName = childProperty.Name;
				var typeProperty = ((JObject)childProperty.Value).Property("type");
				typeProperty.Remove();

				var typePropertyValue = typeProperty.Value.ToString();
				Language language;
				if (Enum.TryParse(typePropertyValue, true, out language))
				{
					typePropertyValue = "Language";
				}

				var itemType = Type.GetType("Nest." + typePropertyValue + "Analyzer", false, true);
				AnalyzerBase item;
				if (itemType == typeof(LanguageAnalyzer))
				{
					item = new LanguageAnalyzer(language);
					serializer.Populate(childProperty.Value.CreateReader(), item);
				}
				else if (itemType != null)
				{
					item = serializer.Deserialize(childProperty.Value.CreateReader(), itemType) as AnalyzerBase;
				}
				else
				{
					continue;
				}

				result[propertyName] = item;
			}
			return result;
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
										JsonSerializer serializer)
		{
			var r = new Dictionary<PropertyNameMarker, IElasticCoreType>();

			JObject o = JObject.Load(reader);

			foreach (var p in o.Properties())
			{
				var name = p.Name;
				var po = p.First as JObject;
				if (po == null)
					continue;

				var esType = this.GetTypeFromJObject(po, serializer);
				if (esType == null)
					continue;

				r.Add(name, esType);

			}
			return r;
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			var filter = new GeoBoundingBoxFilterDescriptor();
			IGeoBoundingBoxFilter f = filter;
			if (reader.TokenType != JsonToken.StartObject)
				return null;

			var depth = reader.Depth;
			while (reader.Read() && reader.Depth >= depth && reader.Value != null)
			{
				var property = reader.Value as string;
				switch(property)
				{
					case "_cache":
						reader.Read();
						f.Cache = reader.Value as bool?;
						break;
					case "_name":
						reader.Read();
						f.FilterName = reader.Value as string;
						break;
					case "_cache_key":
						reader.Read();
						f.CacheKey = reader.Value as string;
						break;
					case "type":
						reader.Read();
						f.GeoExecution = (reader.Value as string).ToEnum<GeoExecution>();
						break;
					default:
						f.Field = property;
						ReadBox(f, reader);
						break;
				}
			}
			return filter;
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
											JsonSerializer serializer)
		{
			var dict = new Dictionary<string, DynamicTemplate>();

			JArray o = JArray.Load(reader);

			foreach (JObject p in o)
			{
				var prop = p.Properties().First();
				var po = prop.Value as JObject;
				var name = prop.Name;
				if (po ==null)
					continue;

				var template = serializer.Deserialize(po.CreateReader(), typeof(DynamicTemplate)) as DynamicTemplate;
				if (template == null)
					continue;

				dict.Add(name, template);

			}
			return dict;
		}
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			var j = JObject.Load(reader);
			if (j == null || !j.HasValues)
				return null;

			string cacheKey = null, cacheName = null, field = null;
			bool? cache = null;
			IGeoShapeBaseFilter filter = null;
			foreach (var jv in j)
			{
				switch (jv.Key)
				{
					case "_cache":
						cache = jv.Value.Value<bool>();
						break;
					case "_cache_key":
						cacheKey = jv.Value.Value<string>();
						break;
					case "_name":
						cacheName = jv.Value.Value<string>();
						break;
					default:
						field = jv.Key;

						var shape = jv.Value["shape"];
						var indexedShape = jv.Value["indexed_shape"];
						if (shape != null)
						{
							var type = shape["type"];
							if (type != null)
							{
								var typeName = type.Value<string>();
								if (typeName == "circle")
								{
									IGeoShapeCircleFilter f = new GeoShapeCircleFilterDescriptor();
									f.Shape = new CircleGeoShape();
									f.Shape.Coordinates = GetCoordinates<IEnumerable<double>>(shape);
									var radius = shape["radius"];
									if (radius != null)
										f.Shape.Radius = radius.Value<string>();
									filter = f;
									break;
								}
								else if (typeName == "envelope")
								{
									IGeoShapeEnvelopeFilter f = new GeoShapeEnvelopeFilterDescriptor();
									f.Shape = new EnvelopeGeoShape();
									f.Shape.Coordinates = GetCoordinates<IEnumerable<IEnumerable<double>>>(shape);
									filter = f;
									break;
								}
								else if (typeName == "linestring")
								{
									IGeoShapeLineStringFilter f = new GeoShapeLineStringFilterDescriptor();
									f.Shape = new LineStringGeoShape();
									f.Shape.Coordinates = GetCoordinates<IEnumerable<IEnumerable<double>>>(shape);
									filter = f;
									break;
								}
								else if (typeName == "multilinestring")
								{
									IGeoShapeMultiLineStringFilter f = new GeoShapeMultiLineStringFilterDescriptor();
									f.Shape = new MultiLineStringGeoShape();
									f.Shape.Coordinates = GetCoordinates<IEnumerable<IEnumerable<IEnumerable<double>>>>(shape);
									filter = f;
									break;
								}
								else if (typeName == "point")
								{
									IGeoShapePointFilter f = new GeoShapePointFilterDescriptor();
									f.Shape = new PointGeoShape();
									f.Shape.Coordinates = GetCoordinates<IEnumerable<double>>(shape);
									filter = f;
									break;
								}
								else if (typeName == "multipoint")
								{
									IGeoShapeMultiPointFilter f = new GeoShapeMultiPointFilterDescriptor();
									f.Shape = new MultiPointGeoShape();
									f.Shape.Coordinates = GetCoordinates<IEnumerable<IEnumerable<double>>>(shape);
									filter = f;
									break;
								}
								else if (typeName == "polygon")
								{
									IGeoShapePolygonFilter f = new GeoShapePolygonFilterDescriptor();
									f.Shape = new PolygonGeoShape();
									f.Shape.Coordinates = GetCoordinates<IEnumerable<IEnumerable<IEnumerable<double>>>>(shape);
									filter = f;
									break;
								}
								else if (typeName == "multipolygon")
								{
									IGeoShapeMultiPolygonFilter f = new GeoShapeMultiPolygonFilterDescriptor();
									f.Shape = new MultiPolygonGeoShape();
									f.Shape.Coordinates = GetCoordinates<IEnumerable<IEnumerable<IEnumerable<IEnumerable<double>>>>>(shape);
									filter = f;
									break;
								}
							}
						}
						else if (indexedShape != null)
						{
							IGeoIndexedShapeFilter f = new GeoIndexedShapeFilterDescriptor();
							f.IndexedShape = new IndexedGeoShape();
							var id = indexedShape["id"];
							var index = indexedShape["index"];
							var type = indexedShape["type"];
							var shapeField = indexedShape["path"];

							if (id != null) f.IndexedShape.Id = id.Value<string>();
							if (index != null) f.IndexedShape.Index = index.Value<string>();
							if (type != null) f.IndexedShape.Type = type.Value<string>();
							if (shapeField != null) f.IndexedShape.Field = shapeField.Value<string>();
							filter = f;
							break;
						}
						break;
				}
			}
			if (filter == null) return null;
			filter.Field = field;
			filter.Cache = cache;
			filter.CacheKey = cacheKey;
			filter.FilterName = cacheName;
			return filter;

		}