public virtual ISearchResults Search(string scope, ISearchCriteria criteria)
		{
			var builder = new QueryBuilder<ESDocument>();
			var command = new SearchCommand(scope, criteria.DocumentType);

			// Add sort order
			if (criteria.Sort != null)
			{
				var fields = criteria.Sort.GetSort();
				foreach (var field in fields)
				{
					command.Sort(field.FieldName, field.IsDescending ? SortDirection.desc : SortDirection.asc);
				}
			}

			command.Size(criteria.RecordsToRetrieve);
			command.From(criteria.StartingRecord);

			// Add search facets
			var facets = GetFacets(criteria);
			builder.Facets(f => facets);

			// Add spell checking
			// TODO: options.SpellCheck = new SpellCheckingParameters { Collate = true };

			// Build query
			var query = (BoolQuery<ESDocument>)_queryBuilder.BuildQuery(criteria);

			builder.Query(q => q.Bool(b => query));
			SearchResult<ESDocument> resultDocs;

			// Add some error handling
			try
			{
				resultDocs = Client.Search(command, builder);
			}
			catch (Exception ex)
			{
				throw new ElasticSearchException("Search using Elastic Search server failed, check logs for more details.", ex);
			}

			// Parse documents returned
			var documents = new ResultDocumentSet { TotalCount = resultDocs.hits.total };
			var docList = new List<ResultDocument>();
			foreach (var indexDoc in resultDocs.Documents)
			{
				var document = new ResultDocument();
				foreach (var field in indexDoc.Keys)
					document.Add(new DocumentField(field, indexDoc[field]));

				docList.Add(document);
			}

			documents.Documents = docList.ToArray();

			// Create search results object
			var results = new SearchResults(criteria, new [] { documents });

			// Now add facet results
			var groups = new List<FacetGroup>();

			if (resultDocs.facets != null)
			{
				foreach (var filter in criteria.Filters)
				{
					var groupCount = 0;

					var group = new FacetGroup(filter.Key);
					var attributeFilter = filter as AttributeFilter;
					if (attributeFilter != null)
					{
						var myFilter = attributeFilter;
						var values = myFilter.Values;
						if (values != null)
						{
							var key = filter.Key.ToLower();
							if (!resultDocs.facets.ContainsKey(key))
								continue;

							var facet = resultDocs.facets[key] as TermsFacetResult;
							if (facet != null)
							{
								foreach (var value in values)
								{
									//facet.terms
									var termCount = from f in facet.terms where f.term.Equals(value.Id, StringComparison.OrdinalIgnoreCase) select f.count;

									var enumerable = termCount as int[] ?? termCount.ToArray();
									if (!enumerable.Any())
										continue;

									//var facet = from resultFacet
									var newFacet = new Facet(@group, value.Id, GetDescription(value, criteria.Locale), enumerable.SingleOrDefault());
									@group.Facets.Add(newFacet);
								}

								groupCount++;
							}
						}
					}
					else
					{
						var rangeFilter = filter as PriceRangeFilter;
						if (rangeFilter != null && rangeFilter.Currency.Equals(criteria.Currency, StringComparison.OrdinalIgnoreCase))
						{
							var myFilter = rangeFilter;
							var values = myFilter.Values;
							if (values != null)
							{
								values = rangeFilter.Values;

								foreach (var value in values)
								{
									var key = String.Format("{0}-{1}", myFilter.Key, value.Id).ToLower();

									if (!resultDocs.facets.ContainsKey(key))
										continue;

									var facet = resultDocs.facets[key] as FilterFacetResult;

									if (facet != null && facet.count > 0)
									{
										if (facet.count == 0)
											continue;

										var myFacet = new Facet(@group, value.Id, GetDescription(value, criteria.Locale), facet.count);
										@group.Facets.Add(myFacet);

										groupCount++;
									}
								}
							}
						}
						else
						{
							var filter1 = filter as RangeFilter;
							if (filter1 != null)
							{
								var myFilter = filter1;
								var values = myFilter.Values;
								if (values != null)
								{
									values = filter1.Values;

									foreach (var value in values)
									{
										var facet = resultDocs.facets[filter.Key] as FilterFacetResult;

										if (facet == null || facet.count <= 0)
										{
											continue;
										}

										var myFacet = new Facet(@group, value.Id, GetDescription(value, criteria.Locale), facet.count);
										@group.Facets.Add(myFacet);

										groupCount++;
									}
								}
							}
						}
					}

					// Add only if items exist under
					if (groupCount > 0)
					{
						groups.Add(group);
					}
				}
			}

			results.FacetGroups = groups.ToArray();
			return results;
		}