/// <summary>
        /// Adds the given configuration section using given section key.
        /// </summary>
        /// <param name="reply">The reply to receive the section settings.</param>
        /// <param name="sectionKey">The status output key to use for the section values.</param>
        private void AddConfiguration(ServerStatusReply reply, string sectionKey)
        {
            ConfigurationInfo configuration = new ConfigurationInfo();

            foreach (var item in this.configuration.GetSection(sectionKey).GetChildren())
            {
                string valueToAdd = item.Value;
                if (CompletlyHideKeyRegex.IsMatch(item.Key))
                {
                    valueToAdd = PasswordReplacementString;
                }
                else if (item.Key.Contains("connection", StringComparison.InvariantCultureIgnoreCase))
                {
                    valueToAdd = PasswordReplaceRegex.Replace(valueToAdd, $"$1{PasswordReplacementString};");
                }

                configuration.Add(item.Key, valueToAdd);
            }

            reply.Add(sectionKey, configuration);
        }
        /// <summary>
        /// Collects and returns the version information.
        /// </summary>
        /// <returns>The collected version information.</returns>
        private ActionResult <IServerStatusReply> GetVersionInformation()
        {
            var myProcess = Process.GetCurrentProcess();
            var reply     = new ServerStatusReply
            {
                MaximumSupportedApiVersion = 1, // change this when creating new API version
                ServerVersion     = Program.LibraryInformationalVersion,
                ProcessUptime     = DateTime.UtcNow - myProcess.StartTime,
                ProcessCpuTime    = myProcess.TotalProcessorTime,
                ProcessWorkingSet = myProcess.WorkingSet64,
                ProcessPrivateSet = myProcess.PrivateMemorySize64,
                ProcessThreads    = myProcess.Threads.Count,
                ProcessStartTime  = myProcess.StartTime,
            };

            reply.Add("WebRequests", new Statistic(StatsProperties.Select(sp => new KeyValuePair <string, string>(sp.Name, sp.GetValue(Program.RequestStatistics)?.ToString()))));

            this.AddConfiguration(reply, Program.RssiAquisitionServiceSectionKey);
            this.AddConfiguration(reply, MaintenanceService.MaintenanceServiceSectionKey);
            this.AddConfiguration(reply, Program.InfluxSectionKey);
            this.AddConfiguration(reply, QueryResultDatabaseProvider.ResultDatabaseSectionName);
            this.AddConfiguration(reply, HamnetDbProvider.HamnetDbSectionName);
            this.AddConfiguration(reply, "CacheDatabase");
            this.AddConfiguration(reply, "DeviceDatabase");
            this.AddConfiguration(reply, Program.MonitoringAccountsSectionKey, Program.BgpAccountSectionKey);
            this.AddConfiguration(reply, Program.PenaltySystemSectionKey);

            var statusTableRow = this.dbContext.MonitoringStatus.First();

            var rssiQueryResultStats = new Statistic()
            {
                { "UniqueValues", this.dbContext.RssiValues.Count().ToString() },
                { "TotalFailures", this.dbContext.RssiFailingQueries.Count().ToString() },
                { "TimeoutFailures", this.dbContext.RssiFailingQueries.Where(q => q.ErrorInfo.Contains("Timeout") || q.ErrorInfo.Contains("Request has reached maximum retries")).Count().ToString() },
                { "NonTimeoutFailures", this.dbContext.RssiFailingQueries.Where(q => !q.ErrorInfo.Contains("Timeout") && !q.ErrorInfo.Contains("Request has reached maximum retries")).Count().ToString() },
                { "LastAquisitionStart", statusTableRow.LastRssiQueryStart.ToString("yyyy-MM-ddTHH\\:mm\\:sszzz") },
                { "LastAquisitionEnd", statusTableRow.LastRssiQueryEnd.ToString("yyyy-MM-ddTHH\\:mm\\:sszzz") },
            };

            reply.Add("RssiResultDatabase", rssiQueryResultStats);

            var bgpQueryResultStats = new Statistic()
            {
                { "UniqueValues", this.dbContext.BgpPeers.Count().ToString() },
                { "TotalFailures", this.dbContext.BgpFailingQueries.Count().ToString() },
                { "TimeoutFailures", this.dbContext.BgpFailingQueries.Where(q => q.ErrorInfo.Contains("Timeout") || q.ErrorInfo.Contains("timed out")).Count().ToString() },
                { "NonTimeoutFailures", this.dbContext.BgpFailingQueries.Where(q => !q.ErrorInfo.Contains("Timeout") && !q.ErrorInfo.Contains("timed out")).Count().ToString() },
                { "LastAquisitionStart", statusTableRow.LastBgpQueryStart.ToString("yyyy-MM-ddTHH\\:mm\\:sszzz") },
                { "LastAquisitionEnd", statusTableRow.LastBgpQueryEnd.ToString("yyyy-MM-ddTHH\\:mm\\:sszzz") },
            };

            reply.Add("BgpResultDatabase", bgpQueryResultStats);

            var maintenanceResultStats = new Statistic()
            {
                { "LastMaintenanceStart", statusTableRow.LastMaintenanceStart.ToString("yyyy-MM-ddTHH\\:mm\\:sszzz") },
                { "LastMaintenanceEnd", statusTableRow.LastMaintenanceEnd.ToString("yyyy-MM-ddTHH\\:mm\\:sszzz") },
            };

            reply.Add("MaintenanceDatabase", maintenanceResultStats);

            var cacheMaintenance = new CacheMaintenance(true /* we don't want to modify anything - so set dry-run to be sure */);

            reply.Add("CacheDatabase", new Statistic(cacheMaintenance.CacheStatistics()));

            var devDbMaintenance = new DeviceDatabaseMaintenance(true /* we don't want to modify anything - so set dry-run to be sure */);

            reply.Add("DeviceDatabase", new Statistic(devDbMaintenance.CacheStatistics()));

            return(reply);
        }