public void UpdateCache(IUpdateContextCodeFeature update)
        {
            // ignore updates that aren't for this cache instance
            if (update.ContextId != ContextMetadata <TContext> .Id)
            {
                return;
            }

            CodeFeatureId codeFeatureId = update.CodeFeatureId;

            ICachedContextFeatureState existingContext;

            if (_cache.TryGetContextFeatureState(update.ContextKey, out existingContext))
            {
                ICachedCodeFeatureState existingCode;
                if (existingContext.TryGetCodeFeatureState(codeFeatureId, out existingCode))
                {
                    if (existingCode.Enabled == update.Enabled)
                    {
                        return;
                    }

                    UpdateExistingCodeFeature(update, codeFeatureId, existingContext, existingCode);
                }
                else
                {
                    AddCodeFeatureState(update, codeFeatureId, existingContext);
                }
            }
            else
            {
                AddContextFeatureState(update, codeFeatureId);
            }
        }
        void NotifyUpdated(IUpdateContextCodeFeature update, ICachedCodeFeatureState updatedFeatureState)
        {
            var updatedEvent = new ContextCodeFeatureStateCacheUpdated(update.ContextId, update.ContextKey, updatedFeatureState.Id,
                                                                       updatedFeatureState.Enabled, update.CommandId);

            _cacheUpdated.ForEach(x => x.OnNext(updatedEvent));
        }
        void AddCodeFeatureState(IUpdateContextCodeFeature update, CodeFeatureId codeFeatureId, ICachedContextFeatureState existingContext)
        {
            var featureState = new CachedCodeFeatureState(codeFeatureId, update.Enabled);

            bool updated = existingContext.TryAdd(codeFeatureId, featureState);

            if (updated)
            {
                NotifyUpdated(update, featureState);
            }
        }
        void AddContextFeatureState(IUpdateContextCodeFeature update, CodeFeatureId codeFeatureId)
        {
            var featureState        = new CachedCodeFeatureState(codeFeatureId, update.Enabled);
            var contextFeatureState = new CachedContextFeatureState(Enumerable.Repeat(featureState, 1), update.ContextKey);

            bool updated = _cache.TryAdd(update.ContextKey, contextFeatureState);

            if (updated)
            {
                NotifyUpdated(update, featureState);
            }
        }