private void CreateHelpersSubscription()
        {
            var existingHelpers = UnderlingConfiguration.Helpers.ToDictionary(
                o => _pathInfoStore.GetOrAdd($"[{o.Key}]"),
                o => new StrongBox <HelperDescriptorBase>(o.Value)
                );

            Helpers = new ObservableDictionary <PathInfo, StrongBox <HelperDescriptorBase> >(existingHelpers, Compatibility.RelaxedHelperNaming ? PathInfo.PlainPathComparer : PathInfo.PlainPathWithPartsCountComparer);

            var helpersObserver = new ObserverBuilder <ObservableEvent <HelperDescriptorBase> >()
                                  .OnEvent <ObservableDictionary <string, HelperDescriptorBase> .ReplacedObservableEvent>(
                @event => Helpers[_pathInfoStore.GetOrAdd($"[{@event.Key}]")].Value = @event.Value
                )
                                  .OnEvent <ObservableDictionary <string, HelperDescriptorBase> .AddedObservableEvent>(
                @event =>
            {
                Helpers.AddOrUpdate(_pathInfoStore.GetOrAdd($"[{@event.Key}]"),
                                    h => new StrongBox <HelperDescriptorBase>(h),
                                    (h, o) => o.Value = h,
                                    @event.Value);
            })
                                  .OnEvent <ObservableDictionary <string, HelperDescriptorBase> .RemovedObservableEvent>(@event =>
            {
                if (Helpers.TryGetValue(_pathInfoStore.GetOrAdd($"[{@event.Key}]"), out var helperToRemove))
                {
                    helperToRemove.Value = new LateBindHelperDescriptor(@event.Key, this);
                }
            })
                                  .Build();

            UnderlingConfiguration.Helpers
            .As <ObservableDictionary <string, HelperDescriptorBase> >()
            .Subscribe(helpersObserver);
        }
        public void AddOrUpdateAddsNewItem()
        {
            // given
            var key = 1;
            var value = "One";

            using (var observableDictionary = new ObservableDictionary<int, string>())
            {
                // when
                observableDictionary.AddOrUpdate(key, value);

                // then check whether all items have been accounted for
                observableDictionary.Count.Should().Be(1);
                observableDictionary.Should().Contain(1, "One");
            }
        }
        public void AddOrUpdateAllowsUpdateForExistingKeyWithSameValue()
        {
            // given
            var initialKvPs = new List<KeyValuePair<int, string>>()
            {
                new KeyValuePair<int, string>(1, "One")
            };

            using (var observableDictionary = new ObservableDictionary<int, string>(initialKvPs))
            {
                // when
                observableDictionary.AddOrUpdate(1, "One");

                // then check whether all items have been accounted for
                observableDictionary.Count.Should().Be(1);
                observableDictionary.Should().Contain(1, "One");
            }
        }
        public void AddOrUpdateShouldAllowUpdateWithDefaultValue()
        {
            // given
            var initialKvPs = new List<KeyValuePair<string, string>>()
            {
                new KeyValuePair<string, string>("1", "One Value")
            };

            using (var observableDictionary = new ObservableDictionary<string, string>(initialKvPs))
            {
                // when
                Action action = () => observableDictionary.AddOrUpdate("1", default(string));

                // then
                action.ShouldNotThrow<ArgumentNullException>();

                observableDictionary.Count.Should().Be(1);
                observableDictionary.Should().Contain("1", default(string));
            }
        }
        public void AddOrUpdateThrowsOnNullKey()
        {
            // given
            using (var observableDictionary = new ObservableDictionary<string, string>())
            {
                // when
                Action action = () => observableDictionary.AddOrUpdate(null, null);

                // then
                action
                    .ShouldThrow<ArgumentNullException>()
                    .WithMessage("Value cannot be null.\r\nParameter name: key");

                observableDictionary.Count.Should().Be(0);
            }
        }
        public void AddOrUpdateShouldAllowAddWithDefaultValue()
        {
            // given
            using (var observableDictionary = new ObservableDictionary<string, string>())
            {
                // when
                Action action = () => observableDictionary.AddOrUpdate("1", default(string));

                // then
                action.ShouldNotThrow<ArgumentNullException>();

                observableDictionary.Count.Should().Be(1);
                observableDictionary.Should().Contain("1", default(string));
            }
        }