private DateTime?GetTokenValue(ControllerBase controller, string value)
        {
            switch (StorageType)
            {
            case StorageType.TempData:
                if (controller.TempData.ContainsKey(value))
                {
                    var result = (DateTime)controller.TempData[value];
                    controller.TempData.Remove(value);
                    return(result);
                }
                return(null);

            case StorageType.Session:
                var      dictionary = CaptchaUtils.GetFromSession(SessionKey, () => new ConcurrentDictionary <KeyTimeEntry <string>, DateTime>());
                DateTime time;
                if (dictionary.TryRemove(value, out time))
                {
                    return(time);
                }
                return(null);

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        private bool RemoveTokenValue(ControllerBase controller, string value)
        {
            switch (StorageType)
            {
            case StorageType.TempData:
                return(controller.TempData.Remove(value));

            case StorageType.Session:
                var hashSet = CaptchaUtils.GetFromSession(SessionKey, () => new HashSet <KeyTimeEntry <string> >());
                return(hashSet.Remove(value));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        private void SaveTokenValue(ICaptcha captcha)
        {
            switch (StorageType)
            {
            case StorageType.TempData:
                captcha.BuildInfo.HtmlHelper.ViewContext.TempData[captcha.BuildInfo.TokenValue] = DateTime.UtcNow;
                break;

            case StorageType.Session:
                var dictionary = CaptchaUtils.GetFromSession(SessionKey, () => new ConcurrentDictionary <KeyTimeEntry <string>, DateTime>());
                dictionary.ClearIfNeed(SessionValuesMaxCount);
                dictionary.TryAdd(captcha.BuildInfo.TokenValue, DateTime.UtcNow);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        private void SaveTokenValue(ICaptcha captcha)
        {
            switch (StorageType)
            {
            case StorageType.TempData:
                captcha.BuildInfo.HtmlHelper.ViewContext.TempData[captcha.BuildInfo.TokenValue] = true;
                break;

            case StorageType.Session:
                var hashSet = CaptchaUtils.GetFromSession(SessionKey, () => new HashSet <KeyTimeEntry <string> >());
                hashSet.ClearIfNeed(SessionValuesMaxCount);
                hashSet.Add(captcha.BuildInfo.TokenValue);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }