public override IEnumerable <TElement> FindElements <TElement>(SolrCompositeQuery compositeQuery)
        {
            var results = this.Execute(compositeQuery, typeof(TElement));

            var selectMethods = compositeQuery.Methods.Where(m => m.MethodType == QueryMethodType.Select).Select(m => (SelectMethod)m).ToList();

            var selectMethod = selectMethods.Count() == 1 ? selectMethods[0] : null;

            var processedResults = new SolrSearchResults <TElement>(this.context, results, selectMethod, compositeQuery.ExecutionContexts, compositeQuery.VirtualFieldProcessors);

            return(processedResults.GetSearchResults());
        }
        public override TResult Execute <TResult>(SolrCompositeQuery compositeQuery)
        {
            var  queryWithHighlighting = compositeQuery as SolrCompositeQueryWithHighlights;
            bool resWithHighlights     = queryWithHighlighting != null && typeof(TResult).GetGenericTypeDefinition() == typeof(SearchResultsWithHighlights <>);

            // TODO Check this condition in more details
            if (typeof(TResult).IsGenericType && (typeof(TResult).GetGenericTypeDefinition() == typeof(SearchResults <>) || resWithHighlights))
            {
                var documentType = typeof(TResult).GetGenericArguments()[0];
                var results      = this.Execute(compositeQuery, documentType);

                var solrSearchResultsType        = typeof(SolrSearchResults <>);
                var solrSearchResultsGenericType = solrSearchResultsType.MakeGenericType(documentType);

                var applyScalarMethodsMethod = this.GetType().GetMethod("ApplyScalarMethods", BindingFlags.Instance | BindingFlags.NonPublic);

                // We need to handle the search result for the GetResultsWithHighlights as for the default GetResults case:
                Type returnType = (resWithHighlights) ? typeof(SearchResults <>).MakeGenericType(documentType) : typeof(TResult);
                var  applyScalarMethodsGenericMethod = applyScalarMethodsMethod.MakeGenericMethod(returnType, documentType);

                var selectMethod = GetSelectMethod(compositeQuery);

                // Execute query methods
                var processedResults = ReflectionUtility.CreateInstance(solrSearchResultsGenericType, this.context, results, selectMethod, compositeQuery.ExecutionContexts, compositeQuery.VirtualFieldProcessors);

                var searchResult = applyScalarMethodsGenericMethod.Invoke(this, new object[] { compositeQuery, processedResults, results });

                if (resWithHighlights)
                {
                    return((TResult)ReflectionUtility.CreateInstance(typeof(TResult), searchResult, results.Highlights));
                }

                return((TResult)searchResult);
            }
            else
            {
                var results = this.Execute(compositeQuery, typeof(TResult));

                var selectMethod = GetSelectMethod(compositeQuery);

                var processedResults = new SolrSearchResults <TResult>(this.context, results, selectMethod, compositeQuery.ExecutionContexts, compositeQuery.VirtualFieldProcessors);

                return(this.ApplyScalarMethods <TResult, TResult>(compositeQuery, processedResults, results));
            }
        }
        private TResult ApplyScalarMethods <TResult, TDocument>(SolrCompositeQuery compositeQuery, SolrSearchResults <TDocument> processedResults, SolrQueryResults <Dictionary <string, object> > results)
        {
            var method = compositeQuery.Methods.First();

            object result;

            switch (method.MethodType)
            {
            case QueryMethodType.All:
                result = true;
                break;

            case QueryMethodType.Any:
                result = processedResults.Any();
                break;

            case QueryMethodType.Count:
                result = processedResults.Count();
                break;

            case QueryMethodType.ElementAt:
                if (((ElementAtMethod)method).AllowDefaultValue)
                {
                    result = processedResults.ElementAtOrDefault(((ElementAtMethod)method).Index);
                }
                else
                {
                    result = processedResults.ElementAt(((ElementAtMethod)method).Index);
                }

                break;

            case QueryMethodType.First:
                if (((FirstMethod)method).AllowDefaultValue)
                {
                    result = processedResults.FirstOrDefault();
                }
                else
                {
                    result = processedResults.First();
                }

                break;

            case QueryMethodType.Last:
                if (((LastMethod)method).AllowDefaultValue)
                {
                    result = processedResults.LastOrDefault();
                }
                else
                {
                    result = processedResults.Last();
                }

                break;

            case QueryMethodType.Single:
                if (((SingleMethod)method).AllowDefaultValue)
                {
                    result = processedResults.SingleOrDefault();
                }
                else
                {
                    result = processedResults.Single();
                }

                break;

            case QueryMethodType.GetResults:
                var resultList = processedResults.GetSearchHits();
                var facets     = this.FormatFacetResults(processedResults.GetFacets(), compositeQuery.FacetQueries);
                result = ReflectionUtility.CreateInstance(typeof(TResult), resultList, processedResults.NumberFound, facets);     // Create instance of SearchResults<TDocument>
                break;


            case QueryMethodType.GetFacets:
                result = this.FormatFacetResults(processedResults.GetFacets(), compositeQuery.FacetQueries);
                break;

            default:
                throw new InvalidOperationException("Invalid query method");
            }

            return((TResult)System.Convert.ChangeType(result, typeof(TResult)));
        }