public void ThreadingTests()
        {
            var myObjectCreator = new InMemoryObjectDataRepository();
            var lazyRepo        = new LazyInMemoryRepository <InMemoryObject, string>(myObjectCreator);

            Task slowIterator = new Task(() =>
            {
                foreach (var item in lazyRepo.GetAll())
                {
                    // Let's iterate very slowly :)
                    Thread.Sleep(100);
                }
            });
            Task slowAdded = new Task(() =>
            {
                Thread.Sleep(50);
                lazyRepo.Add(new InMemoryObject("T", "Mwhuahua"));
                Thread.Sleep(100);
                lazyRepo.Store(new InMemoryObject("T", "Mwhuahua2"));
                Thread.Sleep(100);
                lazyRepo.Remove(new InMemoryObject("T", "Mwhuahua"));
            });

            slowIterator.Start();
            slowAdded.Start();

            slowIterator.Wait();
        }
        public void LazyInMemoryReadOnlyTest()
        {
            var myObjectCreator = new InMemoryObjectDataSource();
            var lazyRepo        = new LazyInMemoryRepository <InMemoryObject, string>(myObjectCreator);

            // Unitialized
            Assert.AreEqual(0, myObjectCreator.GetIdsCalls);
            Assert.AreEqual(0, myObjectCreator.AddObjectCalls);
            Assert.AreEqual(0, myObjectCreator.GetObjectCalls);
            Assert.AreEqual(0, myObjectCreator.RemoveObjectCalls);

            // Only peek what's out there:
            Assert.AreEqual(false, lazyRepo.Contains("A"));
            Assert.AreEqual(true, lazyRepo.Contains("B"));
            Assert.AreEqual(false, lazyRepo.Contains("C"));
            Assert.AreEqual(true, lazyRepo.Contains("1"));
            Assert.AreEqual(false, lazyRepo.Contains("2"));
            Assert.AreEqual(true, lazyRepo.Contains("!"));
            Assert.AreEqual(false, lazyRepo.Contains("@"));

            Assert.AreEqual(1, myObjectCreator.GetIdsCalls);
            Assert.AreEqual(0, myObjectCreator.AddObjectCalls);
            Assert.AreEqual(0, myObjectCreator.GetObjectCalls);
            Assert.AreEqual(0, myObjectCreator.StoreObjectCalls);
            Assert.AreEqual(0, myObjectCreator.RemoveObjectCalls);

            // Now let's get an object:
            var myObjectB = lazyRepo.GetById("B");

            Assert.AreEqual("B", myObjectB.ID);
            Assert.AreEqual("Test 2", myObjectB.Test);

            Assert.AreEqual(1, myObjectCreator.GetIdsCalls);
            Assert.AreEqual(0, myObjectCreator.AddObjectCalls);
            Assert.AreEqual(1, myObjectCreator.GetObjectCalls);
            Assert.AreEqual(0, myObjectCreator.StoreObjectCalls);
            Assert.AreEqual(0, myObjectCreator.RemoveObjectCalls);

            // Try to add an object.
            var myObjectA = new InMemoryObject("A", "Test A");

            Assert.AreEqual(false, lazyRepo.Add(myObjectA)); // read-only!
            Assert.AreEqual(1, myObjectCreator.GetIdsCalls);
            Assert.AreEqual(1, myObjectCreator.AddObjectCalls);
            Assert.AreEqual(1, myObjectCreator.GetObjectCalls);
            Assert.AreEqual(0, myObjectCreator.StoreObjectCalls);
            Assert.AreEqual(0, myObjectCreator.RemoveObjectCalls);

            // Try to remove an object.
            Assert.AreEqual(false, lazyRepo.Remove(myObjectB)); // read-only!
            Assert.AreEqual(1, myObjectCreator.GetIdsCalls);
            Assert.AreEqual(1, myObjectCreator.AddObjectCalls);
            Assert.AreEqual(1, myObjectCreator.GetObjectCalls);
            Assert.AreEqual(0, myObjectCreator.StoreObjectCalls);
            Assert.AreEqual(1, myObjectCreator.RemoveObjectCalls);

            // Try to remove an object (that doens't even exist).
            Assert.AreEqual(false, lazyRepo.Remove(myObjectA)); // read-only!
            Assert.AreEqual(1, myObjectCreator.GetIdsCalls);
            Assert.AreEqual(1, myObjectCreator.AddObjectCalls);
            Assert.AreEqual(1, myObjectCreator.GetObjectCalls);
            Assert.AreEqual(0, myObjectCreator.StoreObjectCalls);
            Assert.AreEqual(2, myObjectCreator.RemoveObjectCalls);

            // After trying to remove it, try to get object B again:
            var myObjectB_2 = lazyRepo.GetById("B");

            Assert.AreEqual(true, myObjectB_2.Equals(myObjectB));
            Assert.AreEqual(1, myObjectCreator.GetIdsCalls);
            Assert.AreEqual(1, myObjectCreator.AddObjectCalls);
            Assert.AreEqual(1, myObjectCreator.GetObjectCalls); // we already had this object in data list.
            Assert.AreEqual(0, myObjectCreator.StoreObjectCalls);
            Assert.AreEqual(2, myObjectCreator.RemoveObjectCalls);
            Assert.AreEqual(1, lazyRepo.GetDataCount());

            // Try to get object C (doesn't exist)
            var myObjectC = lazyRepo.GetById("C");

            Assert.AreEqual(null, myObjectC);
            Assert.AreEqual(1, myObjectCreator.GetIdsCalls);
            Assert.AreEqual(1, myObjectCreator.AddObjectCalls);
            Assert.AreEqual(1, myObjectCreator.GetObjectCalls); // tried to get C
            Assert.AreEqual(0, myObjectCreator.StoreObjectCalls);
            Assert.AreEqual(2, myObjectCreator.RemoveObjectCalls);
            Assert.AreEqual(1, lazyRepo.GetDataCount());

            // Have object '!' ready, and try to see if it contains it.
            var objectExclamationMark = new InMemoryObject("!", "Test 3");

            Assert.AreEqual(false, lazyRepo.Contains(objectExclamationMark)); // we haven't pulled the object out of the repo!
            Assert.AreEqual(1, myObjectCreator.GetIdsCalls);
            Assert.AreEqual(1, myObjectCreator.AddObjectCalls);
            Assert.AreEqual(1, myObjectCreator.GetObjectCalls);
            Assert.AreEqual(0, myObjectCreator.StoreObjectCalls);
            Assert.AreEqual(2, myObjectCreator.RemoveObjectCalls);
            Assert.AreEqual(1, lazyRepo.GetDataCount());

            // Try to store it:
            var objectDollarSign = new InMemoryObject("$", "Money");

            Assert.AreEqual(false, lazyRepo.Store(objectDollarSign));
            Assert.AreEqual(1, myObjectCreator.GetIdsCalls);
            Assert.AreEqual(1, myObjectCreator.AddObjectCalls);
            Assert.AreEqual(1, myObjectCreator.GetObjectCalls);
            Assert.AreEqual(0, myObjectCreator.StoreObjectCalls); // No DataSource::Store() is called because this object isn't in the ID list.
            Assert.AreEqual(2, myObjectCreator.RemoveObjectCalls);
            Assert.AreEqual(1, lazyRepo.GetDataCount());

            // Try to update/store existing object
            var myOwnObjectA = new InMemoryObject("B", "Test B");

            Assert.AreEqual(false, lazyRepo.Store(myOwnObjectA)); // read-only repo
            Assert.AreEqual(1, myObjectCreator.GetIdsCalls);
            Assert.AreEqual(1, myObjectCreator.AddObjectCalls);
            Assert.AreEqual(1, myObjectCreator.GetObjectCalls);
            Assert.AreEqual(1, myObjectCreator.StoreObjectCalls); // Now it does try to store it, because the ID exists.
            Assert.AreEqual(2, myObjectCreator.RemoveObjectCalls);
            Assert.AreEqual(1, lazyRepo.GetDataCount());

            // Get all:
            Assert.AreEqual(3, lazyRepo.GetAll().ToList().Count);
            Assert.AreEqual(1, myObjectCreator.GetIdsCalls);
            Assert.AreEqual(1, myObjectCreator.AddObjectCalls);
            Assert.AreEqual(3, myObjectCreator.GetObjectCalls);
            Assert.AreEqual(1, myObjectCreator.StoreObjectCalls);
            Assert.AreEqual(2, myObjectCreator.RemoveObjectCalls);
        }