/// <summary>
        /// Gets the <see cref="I:System.Collections.Generic.IEnumerable{System.String}" /> of matched component uris
        /// </summary>
        /// <param name="brokerQuery"><see cref="T:TcmCDService.Contracts.BrokerQuery" /></param>
        /// <returns>
        ///   <see cref="I:System.Collections.Generic.IEnumerable{System.String}" />
        /// </returns>
        public IEnumerable <String> BrokerQuery(Contracts.BrokerQuery brokerQuery)
        {
            Logger.Debug("BrokerQuery: brokerQuery \"{0}\".", brokerQuery != null ? "<Object>" : String.Empty);

            return(ContentDelivery.DynamicContent.Query.QueryCache.Execute(brokerQuery));
        }
        /// <summary>
        /// Gets the <see cref="I:System.Collections.Generic.IEnumerable{TcmCDService.Contracts.ComponentPresentation}" /> of matched components
        /// </summary>
        /// <param name="brokerQuery"><see cref="T:TcmCDService.Contracts.BrokerQuery" /></param>
        /// <returns>
        ///   <see cref="I:System.Collections.Generic.IEnumerable{TcmCDService.Contracts.ComponentPresentation}" />
        /// </returns>
        public IEnumerable <Contracts.ComponentPresentation> BrokerQueryPresentations(Contracts.BrokerQuery brokerQuery)
        {
            Logger.Debug("BrokerQueryPresentations: brokerQueries \"{0}\".", brokerQuery != null ? "<Object>" : String.Empty);

            return(ContentDelivery.DynamicContent.Query.QueryCache.Execute(brokerQuery).Select(u => this.ComponentPresentationWithHighestPriority(u)));
        }
        /// <summary>
        /// Executes the specified <see cref="T:TcmCDService.Contracts.BrokerQuery" />
        /// </summary>
        /// <param name="brokerQuery"><see cref="T:TcmCDService.Contracts.BrokerQuery" /></param>
        /// <returns><see cref="I:System.Collections.Generic.IEnumerable{System.String}" /></returns>
        public static IEnumerable<String> Execute(BrokerQuery brokerQuery)
        {
            if (brokerQuery != null)
            {
                List<IDisposable> disposableItems = new List<IDisposable>();
                List<Criteria> criteria = new List<Criteria>();

                try
                {
                    // Query for ItemType: Component
                    if (brokerQuery.ItemType != 0)
                        criteria.Add(new ItemTypeCriteria((int)brokerQuery.ItemType));

                    // Query for Publication
                    if (!String.IsNullOrEmpty(brokerQuery.Publication))
                        criteria.Add(new PublicationCriteria(new TcmUri(brokerQuery.Publication).ItemId));

                    // Query based on Schema
                    if (brokerQuery.SchemaUris != null && brokerQuery.SchemaUris.Any())
                        criteria.Add(CriteriaFactory.Or(brokerQuery.SchemaUris.Select((u) =>
                        {
                            ItemSchemaCriteria itemSchemaCriteria = new ItemSchemaCriteria(new TcmUri(u).ItemId);
                            disposableItems.Add(itemSchemaCriteria);

                            return itemSchemaCriteria;
                        }).ToArray()));

                    // Query based on Component Template
                    if (!String.IsNullOrEmpty(brokerQuery.ComponentTemplateUri))
                        criteria.Add(new ItemTemplateCriteria(new TcmUri(brokerQuery.ComponentTemplateUri).ItemId));

                    // Add any SubQuery entries (MetaQuery or KeywordQueries which are specified)
                    if (brokerQuery.SubQueries != null && brokerQuery.SubQueries.Any())
                        criteria.AddRange(brokerQuery.SubQueries.Where(q => q != null).Select((q) =>
                        {
                            Criteria subCriteria = q is MetaQuery ? ToCriteria(q as MetaQuery) : ToCriteria(q as KeywordQuery);
                            disposableItems.Add(subCriteria);

                            return subCriteria;
                        }));

                    using (Tridion.ContentDelivery.DynamicContent.Query.Query query = new Tridion.ContentDelivery.DynamicContent.Query.Query(CriteriaFactory.And(criteria.ToArray())))
                    {
                        // Limit the amount of results
                        using (LimitFilter filter = new LimitFilter(brokerQuery.ResultLimit.GetValueOrDefault(100)))
                        {
                            query.SetResultFilter(filter);
                            query.AddSorting(new SortParameter(SortParameter.ItemModificationDate, SortParameter.Descending));

                            return query.ExecuteQuery();
                        }
                    }
                }
                finally
                {
                    // Ensure all created Java objects are disposed
                    foreach (Criteria entry in criteria)
                    {
                        if (entry != null)
                            entry.Dispose();
                    }

                    foreach (IDisposable entry in disposableItems)
                    {
                        if (entry != null)
                            entry.Dispose();
                    }
                }
            }

            return new String[] { };
        }