/// <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)
        {
            try
            {
                Logger.Debug("Beginning CreateUninitializedItem. id={0}, timeout={1}", id, timeout);

                var store = storeLocator();
                using (var documentSession = store.OpenSession())
                {
                    var expiry = DateTime.UtcNow.AddMinutes(timeout);

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

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

                Logger.Debug("Completed CreateUninitializedItem. id={0}, timeout={1}", id, timeout);
            }
            catch (Exception ex)
            {
                Logger.ErrorException("Error during CreateUninitializedItem", ex);
                throw;
            }
        }
        /// <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)
        {
            try
            {
                Logger.Debug(
                    " Beginning SetAndReleaseItemExclusive. SessionId={0}, LockId={1}, newItem={2}", id, lockId, newItem);

                var serializedItems = Serialize((SessionStateItemCollection)item.Items);

                var store = storeLocator();
                using (var documentSession = store.OpenSession())
                {
                    // if we get a concurrency conflict, then we want to know about it
                    documentSession.Advanced.UseOptimisticConcurrency = true;

                    SessionState sessionState;
                    if (newItem)
                    {
                        sessionState = documentSession.Query<SessionState>()
                            .Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
                            .SingleOrDefault(x => x.SessionId == 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, lockId));

                        sessionState = new SessionState(id, ApplicationName);
                        documentSession.Store(sessionState);
                    }
                    else
                    {
                        sessionState = documentSession.Query<SessionState>()
                            .Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
                            .Single(x => x.SessionId == id && x.ApplicationName == ApplicationName && x.LockId == (int)lockId);
                    }

                    var expiryDate = DateTime.UtcNow.AddMinutes(sessionStateConfig.Timeout.TotalMinutes);
                    var ravenJObject = documentSession.Advanced.GetMetadataFor(sessionState);
                    ravenJObject["Raven-Expiration-Date"] = new RavenJValue(expiryDate);
                    sessionState.Expires = expiryDate;
                    sessionState.SessionItems = serializedItems;
                    sessionState.Locked = false;

                    documentSession.SaveChanges();
                }

                Logger.Debug("Completed SetAndReleaseItemExclusive. SessionId={0}, LockId={1}, newItem={2}", id, lockId, newItem);
            }
            catch (Exception ex)
            {
                Logger.ErrorException(string.Format("Error during SetAndReleaseItemExclusive. SessionId={0}, LockId={1}, newItem={2}", id, lockId, newItem), ex);
                throw;
            }
        }