BuildRandomLastWriteWinsElementSet(DateTime?start = null)
        {
            var elementSet = new LastWriteWinsElementSet <int>();

            start = start ?? DateTime.Parse("2018-10-02");

            const int operationCount = 1000;

            var random    = new Random();
            var timestamp = start.Value;

            for (int i = 0; i < operationCount; i++)
            {
                timestamp = timestamp.AddMilliseconds(random.Next(1, 10000));
                var element = random.Next(1, 100);
                if (elementSet.Lookup(element)) // Can be addition or removal
                {
                    if (random.Next(1, 10) % 2 == 0)
                    {
                        elementSet.Add(element, timestamp);
                    }
                    else
                    {
                        elementSet.Remove(element, timestamp);
                    }
                }
                else
                {
                    elementSet.Add(element, timestamp);
                }
            }

            return(elementSet, timestamp);
        }
        public void TestAdditionAndRemoval()
        {
            var elementSet = new LastWriteWinsElementSet <int>();
            var start      = DateTime.Parse("2018-10-02");

            // Initially, no element is in the set
            elementSet.Lookup(3).Should().BeFalse();

            // Adds element should show up in the set
            elementSet.Add(3, start);
            elementSet.Lookup(3).Should().BeTrue();

            // Adds the same element again should not give error
            elementSet.Add(3, start.AddSeconds(1));
            elementSet.Lookup(3).Should().BeTrue();

            // Removes the element should make the element disappear
            elementSet.Remove(3, start.AddSeconds(2));
            elementSet.Lookup(3).Should().BeFalse();

            // Re-adds the element should make the element show up again
            elementSet.Add(3, start.AddSeconds(4));
            elementSet.Lookup(3).Should().BeTrue();

            // Re-removes the element should make the element disappear again
            elementSet.Remove(3, start.AddSeconds(5));
            elementSet.Lookup(3).Should().BeFalse();

            // Removes an element that doesn't exist should throw error
            Assert.Throws <ArgumentException>(() => elementSet.Remove(4, start.AddSeconds(6)));
        }