/// <summary>
        ///  Saves current SM statistics into storage slot.
        /// </summary>
        /// <param name="slotId">The slot id.</param>
        /// <returns>True is operation succeeded.</returns>
        public bool SaveSlot(int slotId)
        {
            bool result = false;

            lock (this.exclusiveLock)
            {
                StatisticsSnapshot ss;
                if (!this.savedStats.TryGetValue(slotId, out ss))
                {
                    TimeSpan currentDuration = this.LastEndDate - this.LastStartDate;
                    if (this.LastHTTPLog != null)
                    {
                        ss = new StatisticsSnapshot(this.LastHTTPLog, currentDuration);
                        this.LastHTTPLog = null;
                    }
                    else
                    {
                        ss = new StatisticsSnapshot(this.totals, currentDuration);
                    }

                    this.savedStats.Add(slotId, ss);
                    this.totals.Reset();
                    this.statsByStream.Reset();
                    this.LastHTTPLog   = null;
                    this.LastStartDate = DateTime.Now;
                    this.LastEndDate   = this.LastStartDate;
                    result             = true;
                }
            }

            return(result);
        }
        /// <summary>
        /// Create protocol monitoring report
        /// </summary>
        /// <param name="level">The verbosity level.</param>
        /// <returns>
        /// string representation of report
        /// </returns>
        public string GetMonitoringStats(SMLoggerState level)
        {
            string result = string.Empty;

            // if we have zero saved result slots - just make totals
            if (this.savedStats.Count == 0)
            {
                // if HTTP log is avaialble, assume it is the last download operation
                if (this.LastHTTPLog != null)
                {
                    return(this.LastHTTPLog.ToString());
                }
                else
                {
                    // output S+M operation
                    if (level < SMLoggerState.VerboseLogging)
                    {
                        return(this.totals.GetShortLog());
                    }
                    else
                    {
                        return(this.totals.ToString());
                    }
                }
            }

            // if we have saved slots, we make new side-by-side format
            int maxLines = 0;

            foreach (KeyValuePair <int, StatisticsSnapshot> kvp in this.savedStats)
            {
                StatisticsSnapshot ss = kvp.Value;
                if (maxLines < ss.MaxTotalsLines)
                {
                    maxLines = ss.MaxTotalsLines;
                }

                ss.StartSxSOutput();
                result += string.Format("{0,-40}    ", ss.GetLogTitle());
            }

            result += "\r\n";

            for (int i = 0; i < maxLines; i++)
            {
                foreach (KeyValuePair <int, StatisticsSnapshot> kvp in this.savedStats)
                {
                    StatisticsSnapshot ss = kvp.Value;
                    result += string.Format("{0,-35}  ", ss.GetSxSLine());
                }

                result += "\r\n";
            }

            return(result);
        }
        /// <summary>
        ///  Saves current SM statistics into storage slot.
        /// </summary>
        /// <param name="slotId">The slot id.</param>
        /// <returns>True is operation succeeded.</returns>
        public bool SaveSlot(int slotId)
        {
            bool result = false;
            lock (this.exclusiveLock)
            {
                StatisticsSnapshot ss;
                if (!this.savedStats.TryGetValue(slotId, out ss))
                {
                    if (this.LastHTTPLog != null)
                    {
                        ss = new StatisticsSnapshot(this.LastHTTPLog);
                        this.LastHTTPLog = null;
                    }
                    else
                    {
                        ss = new StatisticsSnapshot(this.totals);
                    }

                    this.savedStats.Add(slotId, ss);
                    result = true;
                }
            }

            return result;
        }
        /// <summary>
        ///  Saves current SM statistics into storage slot.
        /// </summary>
        /// <param name="slotId">The slot id.</param>
        /// <returns>True is operation succeeded.</returns>
        public bool SaveSlot(int slotId)
        {
            bool result = false;
            lock (this.exclusiveLock)
            {
                StatisticsSnapshot ss;
                if (!this.savedStats.TryGetValue(slotId, out ss))
                {
                    TimeSpan currentDuration = this.LastEndDate - this.LastStartDate;
                    if (this.LastHTTPLog != null)
                    {
                        ss = new StatisticsSnapshot(this.LastHTTPLog, currentDuration);
                        this.LastHTTPLog = null;
                    }
                    else
                    {
                        ss = new StatisticsSnapshot(this.totals, currentDuration);
                    }

                    this.savedStats.Add(slotId, ss);
                    this.totals.Reset();
                    this.statsByStream.Reset();
                    this.LastHTTPLog = null;
                    this.LastStartDate = DateTime.Now;
                    this.LastEndDate = this.LastStartDate;
                    result = true;
                }
            }

            return result;
        }