public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
        {
            var riakSessionItem = new RiakSessionItem
            {
                SessionContainer = ApplicationName,
                SessionId = id,
                Created = DateTime.Now,
                Timeout = timeout
            };

            _client.Async.Put(riakSessionItem.ToRiakObject(), result => { return; });
            return;
        }
        private void InvokeExpireCallbackAndDeleteSession()
        {
            // MR to get sessions to delete
            var query = new RiakMapReduceQuery();
            query.Inputs(ApplicationName)
                .MapJs(
                    m =>
                    m.Source(@"
function (value, keyData, arg) {
    var now = new Date(Date.parse(arg));
    var metadata = value.values[0].metadata;
    var expires = metadata['X-Riak-Meta']['X-Riak-Meta-Expires'];

    if (arg > expires) 
    {
        return [value.key, expires];
    }
    else
    {
        return [];
    }
}")
                        .Argument(DateTime.Now.ToString("R")));

            var results = _client.MapReduce(query);
            
            if (results.IsSuccess)
            {
                var keys = results.Value.PhaseResults.ElementAt(results.Value.PhaseResults.Count() - 1).Value.FromRiakString();
                var keyList = JsonConvert.DeserializeObject<string[]>(keys);

                var riakObjectIdList = keyList.Select(key => new RiakObjectId(ApplicationName, key)).ToList();

                // for some stupid reason, we have to retrieve all of the deleted keys, process them, and THEN delete them
                var riakSessionObjects = _client.Get(riakObjectIdList);
                foreach (var riakSessionObject in riakSessionObjects)
                {
                    var value = riakSessionObject.Value;
                    var session = new RiakSessionItem(value);
                    _expireCallBack.Invoke(value.Key, Deserialize(session.SessionStoreItems));
                }

                _client.Async.Delete(riakObjectIdList, deleteResults => { return; });
            }
        }
        private SessionStateStoreData GetSessionStoreItem(bool lockRecord,
          HttpContext context,
          string id,
          out bool locked,
          out TimeSpan lockAge,
          out object lockId,
          out SessionStateActions actions)
        {
            SessionStateStoreData result = null;

            locked = default(bool);
            lockAge = default(TimeSpan);
            lockId = null;
            actions = default(SessionStateActions);

            var riakResult = _client.Get(ApplicationName, id);

            if (riakResult.IsSuccess)
            {
                var riakObject = riakResult.Value;
                var riakSessionItem = new RiakSessionItem(riakObject);

                locked = riakSessionItem.Locked;
                lockAge = DateTime.Now.Subtract(riakSessionItem.LockDate);
                lockId = riakSessionItem.LockId;
                actions = (SessionStateActions) riakSessionItem.Flags;

                if (riakSessionItem.Expires < DateTime.Now || riakSessionItem.Locked)
                    return null;
                
                if (actions == SessionStateActions.InitializeItem)
                {
                    result = CreateNewStoreData(context, riakSessionItem.Timeout);
                }
                else
                {
                    result = Deserialize(riakSessionItem.SessionStoreItems);
                }

                if (lockRecord)
                {
                    riakSessionItem.Locked = true;
                    _client.Async.Put(riakSessionItem.ToRiakObject(), results => { return; });
                }
            }

            return result;
        }
        public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
        {
            if (newItem)
            {
                var riakSessionItem = new RiakSessionItem
                                          {
                                              SessionStoreItems = Serialize(item)
                                          };
                _client.Put(riakSessionItem.ToRiakObject());
            }
            else
            {
                var result = _client.Get(ApplicationName, id);
                var riakSessionItem = new RiakSessionItem();

                if (result.ResultCode != ResultCode.NotFound)
                {
                    riakSessionItem = new RiakSessionItem(result.Value) {Flags = 0};
                    riakSessionItem.Unlock();
                }
                else
                {
                    riakSessionItem.SessionId = id;
                    riakSessionItem.SessionContainer = ApplicationName;
                }

                riakSessionItem.Created = DateTime.Now;
                riakSessionItem.Timeout = item.Timeout;
                riakSessionItem.SessionStoreItems = Serialize(item);

                _client.Async.Put(riakSessionItem.ToRiakObject(), results => { return; });
            }
        }
        public override void ResetItemTimeout(HttpContext context, string id)
        {
            var result = _client.Get(ApplicationName, id);
            var riakSessionItem = new RiakSessionItem(result.Value) {Timeout = _config.Timeout.Minutes};
            riakSessionItem.ResetTimeout();

            _client.Async.Put(riakSessionItem.ToRiakObject(), results => { return; });
        }
        public override void ReleaseItemExclusive(HttpContext context, string id, object lockId)
        {
            var riakObject = _client.Get(ApplicationName, id).Value;
            var riakSessionItem = new RiakSessionItem(riakObject) {Timeout = _config.Timeout.Minutes};

            if (riakSessionItem.LockId == (int)lockId)
            {
                riakSessionItem.ResetTimeout();
                _client.Async.Put(riakSessionItem.ToRiakObject(), result => { return; });
            }
        }