/// <summary>
        /// An authentication response have been received from the web browser.
        /// Check if it's correct
        /// </summary>
        /// <param name="header">Contents from the Authorization header</param>
        /// <param name="realm">Realm that should be authenticated</param>
        /// <param name="httpVerb">GET/POST/PUT/DELETE etc.</param>
        /// <param name="options">First option: true if username/password is correct but not cnonce</param>
        /// <returns>
        /// Authentication object that is stored for the request. A user class or something like that.
        /// </returns>
        /// <exception cref="ArgumentException">if authenticationHeader is invalid</exception>
        /// <exception cref="ArgumentNullException">If any of the parameters is empty or null.</exception>
        public bool Authenticate(AuthorizationHeader header, string realm, string httpVerb, object[] options)
        {
            if (header == null)
            {
                throw new ArgumentNullException("header");
            }

            lock (_nonces)
            {
                if (_timer == null)
                {
                    _timer = new Timer(ManageNonces, null, 15000, 15000);
                }
            }

            if (!header.Scheme.Equals("digest", StringComparison.OrdinalIgnoreCase))
            {
                return(false);
            }

            var parameters = HeaderParameterCollection.Parse(new StringReader(header.Data));

            if (!IsValidNonce(parameters["nonce"]) && !DisableNonceCheck)
            {
                return(false);
            }

            // request authentication information
            string        username = parameters["username"];
            DigestContext context  = new DigestContext(realm, username);

            if (!_authenticator(context))
            {
                return(false);
            }


            // Encode authentication info
            string HA1;

            if (string.IsNullOrEmpty(context.HA1))
            {
                string A1 = String.Format("{0}:{1}:{2}", username, realm, context.Password);
                HA1 = GetMD5HashBinHex2(A1);
            }
            else
            {
                HA1 = context.HA1;
            }

            // encode challenge info
            string A2           = String.Format("{0}:{1}", httpVerb, parameters["uri"]);
            string HA2          = GetMD5HashBinHex2(A2);
            string hashedDigest = Encrypt(HA1, HA2, parameters["qop"],
                                          parameters["nonce"], parameters["nc"], parameters["cnonce"]);

            //validate
            return(parameters["response"] == hashedDigest);
        }
        /// <summary>
        /// An authentication response have been received from the web browser.
        /// Check if it's correct
        /// </summary>
        /// <param name="header">Contents from the Authorization header</param>
        /// <param name="realm">Realm that should be authenticated</param>
        /// <param name="httpVerb">GET/POST/PUT/DELETE etc.</param>
        /// <param name="options">First option: true if username/password is correct but not cnonce</param>
        /// <returns>
        /// Authentication object that is stored for the request. A user class or something like that.
        /// </returns>
        /// <exception cref="ArgumentException">if authenticationHeader is invalid</exception>
        /// <exception cref="ArgumentNullException">If any of the parameters is empty or null.</exception>
        public bool Authenticate(AuthorizationHeader header, string realm, string httpVerb, object[] options)
        {
            if (header == null)
                throw new ArgumentNullException("header");

            lock (_nonces)
            {
                if (_timer == null)
                    _timer = new Timer(ManageNonces, null, 15000, 15000);
            }

            if (!header.Scheme.Equals("digest", StringComparison.OrdinalIgnoreCase))
                return false;

            var parameters = HeaderParameterCollection.Parse(new StringReader(header.Data));
            if (!IsValidNonce(parameters["nonce"]) && !DisableNonceCheck)
                return false;

            // request authentication information
            string username = parameters["username"];
            DigestContext context = new DigestContext(realm, username);
            if (!_authenticator(context))
                return false;

            // Encode authentication info
            string HA1;
            if (string.IsNullOrEmpty(context.HA1))
            {
                string A1 = String.Format("{0}:{1}:{2}", username, realm, context.Password);
                HA1 = GetMD5HashBinHex2(A1);
            }
            else
                HA1 = context.HA1;

            // encode challenge info
            string A2 = String.Format("{0}:{1}", httpVerb, parameters["uri"]);
            string HA2 = GetMD5HashBinHex2(A2);
            string hashedDigest = Encrypt(HA1, HA2, parameters["qop"],
                                          parameters["nonce"], parameters["nc"], parameters["cnonce"]);

            //validate
            return parameters["response"] == hashedDigest;
        }