/// <summary>
        /// Query the store using a SPARQL query
        /// </summary>
        /// <param name="storeName">Store to query</param>
        /// <param name="queryExpression">SPARQL query string</param>
        /// <param name="defaultGraphUris"></param>
        /// <param name="ifNotModifiedSince">OPTIONAL : If this parameter is provided and the store has not been changed since the time specified,
        /// a BrightstarClientException will be raised with the message "Store not modified".</param>
        /// <param name="resultsFormat">OPTIONAL: The serialization format for the SPARQL results set. Defaults to <see cref="SparqlResultsFormat.Xml"/>.</param>
        /// <returns>A stream containing XML SPARQL result XML</returns>
        /// <remarks>If the <paramref name="ifNotModifiedSince"/> parameter is used by an application, then the default caching provided
        /// by this class will be bypassed</remarks>
        public Stream ExecuteQuery(string storeName, string queryExpression, IEnumerable<string> defaultGraphUris, DateTime? ifNotModifiedSince = null, SparqlResultsFormat resultsFormat = null)
        {
            ValidateStoreName(storeName);
            if (queryExpression == null)
                throw new ArgumentNullException("queryExpression", Strings.BrightstarServiceClient_QueryMustNotBeNull);
            if (String.Empty.Equals(queryExpression))
                throw new ArgumentException(Strings.BrightstarServiceClient_QueryMustNotBeEmptyString, "queryExpression");

            var g = defaultGraphUris == null ? null : defaultGraphUris.ToArray();
            string cacheKey = null;
            CachedQueryResult cachedResult = null;
            if (ifNotModifiedSince == null && _queryCache != null)
            {
                cacheKey = storeName + "_" + queryExpression.GetHashCode();
                if (defaultGraphUris != null)
                {
                    cacheKey = cacheKey + "_" + String.Join(",", g).GetHashCode();
                }
                cachedResult = _queryCache.Lookup<CachedQueryResult>(cacheKey);
                if (cachedResult != null)
                {
                    ifNotModifiedSince = cachedResult.Timestamp;
                }
            }

            try
            {
                var mediaType = resultsFormat == null
                                    ? SparqlResultsFormat.Xml.MediaTypes.First() + "; charset=utf-8"
                                    : resultsFormat.ToString();
                var resultStream = _service.ExecuteQuery(storeName, queryExpression, defaultGraphUris == null ? null : g.ToArray(), ifNotModifiedSince, mediaType);
                if (_queryCache != null && cacheKey != null && LastResponseTimestamp.HasValue)
                {
                    using (var streamReader = new StreamReader(resultStream))
                    {
                        var resultString = streamReader.ReadToEnd();
                        cachedResult = new CachedQueryResult(LastResponseTimestamp.Value, resultString);
                        _queryCache.Insert(cacheKey, cachedResult, CachePriority.Normal);
                        return new MemoryStream(streamReader.CurrentEncoding.GetBytes(cachedResult.Result));
                    }
                }
                else
                {
                    return resultStream;
                }
            }
            catch (FaultException<ExceptionDetail> fault)
            {
                if (cachedResult != null)
                {
                    if (fault.Detail.Type.Equals("BrightstarDB.Client.BrightstarClientException") &&
                        fault.Detail.InnerException != null &&
                        fault.Detail.InnerException.Type.Equals("BrightstarDB.BrightstarStoreNotModifiedException"))
                    {
                        // Cached result is still fine
                        return new MemoryStream(
                            resultsFormat == null
                                ? Encoding.UTF8.GetBytes(cachedResult.Result)
                                : resultsFormat.Encoding.GetBytes(cachedResult.Result));
                    }
                }
                throw new BrightstarClientException(fault);
            }
        }
        /// <summary>
        /// Query the store using a SPARQL query
        /// </summary>
        /// <param name="storeName">Store to query</param>
        /// <param name="queryExpression">SPARQL query string</param>
        /// <param name="ifNotModifiedSince">OPTIONAL : If this parameter is provided and the store has not been changed since the time specified,
        /// a BrightstarClientException will be raised with the message "Store not modified".</param>
        /// <param name="resultsFormat">OPTIONAL: The serialization format for the SPARQL results set. Defaults to <see cref="SparqlResultsFormat.Xml"/>.</param>
        /// <returns>A stream containing XML SPARQL result XML</returns>
        /// <remarks>If the <paramref name="ifNotModifiedSince"/> parameter is used by an application, then the default caching provided
        /// by this class will be bypassed</remarks>
        public Stream ExecuteQuery(string storeName, string queryExpression, DateTime?ifNotModifiedSince = null, SparqlResultsFormat resultsFormat = null)
        {
            ValidateStoreName(storeName);
            if (queryExpression == null)
            {
                throw new ArgumentNullException("queryExpression", Strings.BrightstarServiceClient_QueryMustNotBeNull);
            }
            if (String.Empty.Equals(queryExpression))
            {
                throw new ArgumentException(Strings.BrightstarServiceClient_QueryMustNotBeEmptyString, "queryExpression");
            }

            string            cacheKey     = null;
            CachedQueryResult cachedResult = null;

            if (ifNotModifiedSince == null && _queryCache != null)
            {
                cacheKey     = storeName + "_" + queryExpression.GetHashCode();
                cachedResult = _queryCache.Lookup <CachedQueryResult>(cacheKey);
                if (cachedResult != null)
                {
                    ifNotModifiedSince = cachedResult.Timestamp;
                }
            }

            try
            {
                var mediaType = resultsFormat == null
                                    ? SparqlResultsFormat.Xml.MediaTypes.First() + "; charset=utf-8"
                                    : resultsFormat.ToString();

                var resultStream = _service.ExecuteQuery(storeName, queryExpression, ifNotModifiedSince, mediaType);
                if (_queryCache != null && cacheKey != null && LastResponseTimestamp.HasValue)
                {
                    using (var streamReader = new StreamReader(resultStream))
                    {
                        var resultString = streamReader.ReadToEnd();
                        cachedResult = new CachedQueryResult(LastResponseTimestamp.Value, resultString);
                        _queryCache.Insert(cacheKey, cachedResult, CachePriority.Normal);
                        return(new MemoryStream(streamReader.CurrentEncoding.GetBytes(cachedResult.Result)));
                    }
                }
                else
                {
                    return(resultStream);
                }
            }
            catch (FaultException <ExceptionDetail> fault)
            {
                if (cachedResult != null)
                {
                    if (fault.Detail.Type.Equals("BrightstarDB.Client.BrightstarClientException") &&
                        fault.Detail.InnerException != null &&
                        fault.Detail.InnerException.Type.Equals("BrightstarDB.BrightstarStoreNotModifiedException"))
                    {
                        // Cached result is still fine
                        return(new MemoryStream(
                                   resultsFormat == null
                                ? Encoding.UTF8.GetBytes(cachedResult.Result)
                                : resultsFormat.Encoding.GetBytes(cachedResult.Result)));
                    }
                }
                throw new BrightstarClientException(fault);
            }
        }