/// <summary>
        /// Adds an uninitialized item to the session data store.
        /// </summary>
        /// <param name="context">The HttpContext instance for the current request</param>
        /// <param name="id">The session identifier.</param>
        /// <param name="timeout">The expiry timeout in minutes.</param>
        public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
        {
            using (var db = _store.OpenSession())
            {
                var expiry = DateTime.UtcNow.AddMinutes(timeout);

                var sessionState = new Session(id, ApplicationName)
                {
                    Expires = expiry
                };

                db.Store(sessionState);
                db.Advanced.GetMetadataFor(sessionState)["Raven-Expiration-Date"] = new RavenJValue(expiry);
                db.SaveChanges();
            }
        }
        /// <summary>
        /// Adds a new session-state item to the data store.
        /// </summary>
        /// 
        /// <param name="context">
        /// The <see cref="System.Web.HttpContext"/> for the current request.
        /// </param>
        /// 
        /// <param name="id">
        /// The session identifier for the current request.
        /// </param>
        /// 
        /// <param name="timeout">
        /// The timeout for the current request.
        /// </param>
        public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
        {
            var session = new Session
            {
                Id      = id,
                Expires = DateTime.UtcNow.AddMinutes(timeout)
            };

            _db.Store(session);
            _db.Advanced.GetMetadataFor(session)["Raven-Expiration-Date"] = new RavenJValue(session.Expires);
            _db.SaveChanges();
        }
        /// <summary>
        /// If the newItem parameter is true, the SetAndReleaseItemExclusive method inserts a new item into the data store with the supplied values. 
        /// Otherwise, the existing item in the data store is updated with the supplied values, and any lock on the data is released. 
        /// </summary>
        /// <param name="context">The HttpContext instance for the current request</param>
        /// <param name="id">The session identifier.</param>
        /// <param name="item">The current session values to be stored</param>
        /// <param name="lockId">The lock identifier for the current request.</param>
        /// <param name="newItem">If true, a new item is inserted into the store.  Otherwise, the existing item in 
        /// the data store is updated with the supplied values, and any lock on the data is released. </param>
        public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item,
                                                        object lockId, bool newItem)
        {
            var serializedItems = Serialize((SessionStateItemCollection)item.Items);

            using (var db = _store.OpenSession())
            {
                Session sessionState;

                if (newItem)
                {
                    sessionState = db.Query<Session>()
                                     .Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
                                     .SingleOrDefault(x => x.Id == id && x.ApplicationName == ApplicationName && x.Expires < DateTime.UtcNow);

                    if (sessionState != null)
                        throw new InvalidOperationException(String.Format("Item aleady exist with SessionId=\"{0}\" and ApplicationName=\"{1}\"", id, ApplicationName));

                    sessionState = new Session(id, ApplicationName);

                    db.Store(sessionState);
                }
                else
                {
                    var query = db.Query<Session>()
                                  .Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
                                  .Where(x => x.Id == id && x.ApplicationName == ApplicationName);

                    sessionState = _locking ? query.Single(x => x.LockId == (int)lockId) : query.Single();
                }

                var expiry = DateTime.UtcNow.AddMinutes(_config.Timeout.TotalMinutes);

                sessionState.Expires      = expiry;
                sessionState.SessionItems = serializedItems;
                sessionState.Locked       = false;

                db.Advanced.GetMetadataFor(sessionState)["Raven-Expiration-Date"] = new RavenJValue(expiry);
                db.SaveChanges();
            }
        }