public void StatefulObserver_Basics()
        {
            {
                var mo = new MyObserver();

                mo.Start();
                Assert.IsTrue(mo.Started);
                //Assert.IsFalse(mo.StateChanged); // TODO: Hmm, can we do this?

                mo.OnNext(42);
                mo.OnNext(43);
                mo.OnCompleted();

                Assert.IsTrue(new[] { 42, 43 }.SequenceEqual(mo.Values));
                Assert.IsTrue(mo.Done);

                mo.Dispose();
                Assert.IsTrue(mo.Disposed);

                mo.Dispose();
                Assert.IsTrue(mo.Disposed);
            }

            {
                var mo = new MyObserver();

                mo.Start();
                Assert.IsTrue(mo.Started);
                //Assert.IsFalse(mo.StateChanged); // TODO: Hmm, can we do this?

                var ex = new Exception();

                mo.OnNext(42);
                mo.OnNext(43);
                mo.OnError(ex);

                Assert.IsTrue(new[] { 42, 43 }.SequenceEqual(mo.Values));
                Assert.AreSame(ex, mo.Error);

                mo.Dispose();
                Assert.IsTrue(mo.Disposed);

                mo.Dispose();
                Assert.IsTrue(mo.Disposed);
            }
        }
        public void StatefulObserver_State()
        {
            var state         = new MockOperatorStateContainer();
            var writerFactory = state.CreateWriter();
            var readerFactory = state.CreateReader();

            var mo = new MyObserver()
            {
                State = 42
            };

            mo.Start();
            Assert.IsTrue(mo.Started);
            Assert.IsTrue(mo.StateChanged);

            Assert.ThrowsException <ArgumentNullException>(() => mo.SaveState(null, mo.Version));

            var writer = writerFactory.Create(mo);

            mo.SaveState(writer, mo.Version);

            Assert.IsTrue(mo.StateChanged);
            mo.OnStateSaved();
            Assert.IsFalse(mo.StateChanged);

            var mor = new MyObserver();

            var reader = readerFactory.Create(mor);

            Assert.ThrowsException <ArgumentNullException>(() => mor.LoadState(null, mor.Version));

            mor.LoadState(reader, mor.Version);

            mor.Start();
            Assert.IsTrue(mor.Started);

            Assert.AreEqual(42, mor.State);

            mo.State = 43;
            Assert.IsTrue(mo.StateChanged);

            writer = writerFactory.Create(mo);
            mo.SaveState(writer, mo.Version);
            mo.OnStateSaved();
            Assert.IsFalse(mo.StateChanged);

            var moq = new MyObserver();

            reader = readerFactory.Create(moq);
            moq.LoadState(reader, moq.Version);

            moq.Start();
            Assert.IsTrue(moq.Started);

            Assert.AreEqual(43, moq.State);

            mo.Dispose();

            Assert.IsTrue(mo.Disposed);

            writer = writerFactory.Create(mo);
            mo.SaveState(writer, mo.Version);
            mo.OnStateSaved();

            var mop = new MyObserver();

            reader = readerFactory.Create(mop);
            mop.LoadState(reader, mop.Version);
            mop.Start();

            Assert.IsTrue(mop.Disposed);
            Assert.IsFalse(mop.Started);
        }