/// <summary>
        /// Logs a log object
        /// </summary>
        /// <typeparam name="T">The target type (must be serializable)</typeparam>
        /// <param name="log">The log to store</param>
        public override void Log <T>(Log <T> log)
        {
            string uniqueId      = Guid.NewGuid().ToString("N");
            string logName       = log.LogLevel + CacheItemNamePartSeparator + log.TimeStamp.ToFileTimeUtc() + CacheItemNamePartSeparator + uniqueId;
            string serializedLog = SerializationService.SerializeObject(log);

            CachingService.Cache(logName, log);
        }
        /// <summary>
        /// Adds the configuration to the defined cache
        /// </summary>
        /// <typeparam name="T">The configuration type</typeparam>
        /// <typeparam name="Tm">The configuration metadata type</typeparam>
        /// <param name="configuration">The configuration to add to cache</param>
        protected internal virtual void AddConfiguration <T, Tm>(T configuration)
            where T : IConfiguration <T, Tm>, new()
            where Tm : IConfigurationMetadata <T, Tm>, new()
        {
            DateTime cacheTime = DateTime.UtcNow;

            ClearConfiguration <T, Tm>(configuration.ConfigurationMetadata);
            CachingService.Cache(configuration.ConfigurationMetadata.ConfigurationName, configuration, cacheTime,
                                 (ConfigurationLifeSpan == null ? (DateTime?)null : cacheTime.Add(ConfigurationLifeSpan.Value)));
        }
        public string GetAnswer(RequestInfo info)
        {
            string answer = cachedAnswers.GetAnswer(info);

            if (answer == string.Empty)
            {
                var searchingResult = GetAnswer(info.Data);
                answer = new TextRange(searchingResult.ContentStart, searchingResult.ContentEnd).Text;
                cachedAnswers.Cache(info, answer);
            }

            return(answer);
        }
        /// <summary>
        /// Ensures that the request recognizes the correct time, and that it is not a repeat request (based on nonce recognition)
        /// </summary>
        /// <param name="contentStream">The stream of content to hash</param>
        /// <returns>If the request is a replay request</returns>
        protected virtual bool IsReplayRequest(string nonce, string requestTimeStamp)
        {
            if (string.IsNullOrWhiteSpace(nonce) || CachingService.ContainsKey(nonce))
            {
                return(true);
            }

            ulong serverTotalSeconds  = DateTime.UtcNow.UnixTimeStamp();
            ulong requestTotalSeconds = Convert.ToUInt64(requestTimeStamp);

            if ((serverTotalSeconds - requestTotalSeconds) > ServerClientMaxTimeDifference)
            {
                return(true);
            }

            DateTime cachedTime = requestTimeStamp?.GetDateTimeFromUnixTimestampString() ?? DateTime.MinValue;

            CachingService.Cache(nonce, nonce, cachedTime, cachedTime.AddSeconds(RequestMaxAgeInSeconds));

            return(false);
        }