private void PrintDataModelHelp(DataModel dataModel)
        {
            // Initialize the output stream
            Stream outputStream = InitializeOutputStream();

            dataModel.PrintHelp(outputStream);
        }
        internal void ProcessQuery(Stream outputStream = null)
        {
            bool closeOutputStream = true;

            // Base OpenSearch URL
            log.Debug("Initialize urls");
            List<Uri> baseUrls = InitializeUrl();

            // Initialize the output stream
            log.Debug("Initialize output");
            if (outputStream == null)
                outputStream = InitializeOutputStream();
            else
                closeOutputStream = false;

            // Init data Model
            log.Debug("Init data models");
            dataModelParameters = PrepareDataModelParameters();
            dataModel = DataModel.CreateFromArgs(queryModelArg, dataModelParameters);

            NameValueCollection parametersNvc;

            List<List<Uri>> altBaseUrlLists = alternative ?
                new List<List<Uri>>(baseUrls.Select(u => new List<Uri>() { u })) :
                new List<List<Uri>>() { baseUrls };

            List<List<NetworkCredential>> altNetCredsLists = alternative ?
                new List<List<NetworkCredential>>(netCreds.Select(u => new List<NetworkCredential>() { u })) :
                new List<List<NetworkCredential>>() { netCreds };

            for (int i = 0; i < altBaseUrlLists.Count(); i++)
            {
                bool outputStarted = false;

                try
                {

                    log.DebugFormat("Alternative #{0} : {1}", i, string.Join(",", altBaseUrlLists[i]));

                    // Find OpenSearch Entity
                    IOpenSearchable entity = null;
                    int retry = 5;
                    int index = 1;
                    while (retry >= 0)
                    {
                        // Perform the query
                        try
                        {
                            entity = dataModel.CreateOpenSearchable(altBaseUrlLists[i], queryFormatArg, ose, altNetCredsLists[i], lax);
                            index = entity.GetOpenSearchDescription().DefaultUrl.IndexOffset;
                            log.Debug("IndexOffset : " + index);
                            break;
                        }
                        catch (Exception e)
                        {
                            log.Warn(e.Message);
                            if (retry == 0)
                                throw e;
                            retry--;
                            searchCache.ClearCache(".*", DateTime.MinValue);
                        }
                    }

                    NameValueCollection parameters = PrepareQueryParameters(entity);
                    string startIndex = parameters.Get("startIndex");
                    if (startIndex != null)
                    {
                        index = int.Parse(startIndex);
                    }

                    IOpenSearchResultCollection osr = null;
                    long totalCount = 0;
                    log.Debug(totalResults + " entries requested");
                    while (totalResults > 0)
                    {

                        log.Debug("startIndex : " + index);
                        parametersNvc = ResolveParameters(parameters, entity);

                        retry = 5;
                        while (retry >= 0)
                        {
                            // Perform the query
                            log.Debug("Launching query...");
                            try
                            {
                                osr = QueryOpenSearch(ose, entity, parametersNvc);
                                break;
                            }
                            catch (AggregateException ae)
                            {
                                if (retry == 0)
                                {
                                    throw ae;
                                }
                                foreach (Exception e in ae.InnerExceptions)
                                {
                                    log.Warn("Exception " + e.Message);
                                }
                                retry--;
                                searchCache.ClearCache(".*", DateTime.MinValue);
                            }
                            catch (KeyNotFoundException e)
                            {
                                log.Error("Query not found : " + e.Message);
                                throw e;
                            }
                            catch (Exception e)
                            {
                                if (retry == 0)
                                {
                                    throw e;
                                }

                                log.Warn("Exception " + e.Message);
                                retry--;
                                searchCache.ClearCache(".*", DateTime.MinValue);
                            }

                        }

                        int count = CountResults(osr);
                        if (alternative && totalCount == 0 && count == 0)
                            throw new Exception("No results found");

                        // Transform the result
                        OutputResult(osr, outputStream);

                        outputStarted = true;

                        log.Debug(count + " entries found");
                        if (count == 0)
                            break;
                        int expectedCount = count;
                        if (!string.IsNullOrEmpty(parameters["count"]) && int.TryParse(parameters["count"], out expectedCount) && count < expectedCount)
                            break;

                        totalResults -= count;
                        totalCount += count;
                        log.Debug(count + " entries found on " + totalResults + " requested");
                        int paramCount;
                        if (Int32.TryParse(parameters.Get("count"), out paramCount) && totalResults < paramCount)
                        {
                            parameters.Set("count", "" + totalResults);
                        }
                        index += count;

                        parameters.Set("startIndex", "" + index);

                    }

                    if (alternative && totalCount > 0)
                        break;

                }
                catch (Exception e)
                {
                    if (outputStarted || i + 1 == altBaseUrlLists.Count())
                        throw e;
                    searchCache.ClearCache(".*", DateTime.MinValue);
                    continue;
                }
            }

            if (closeOutputStream) outputStream.Close();
        }