public void CaptureStream_Supports_Reading_A_File_For_Playback_Prior_To_The_Entire_File_Becoming_Available()
        {
            //base bytes to feed into the stream at random
            var bytes = VastPark.FrameworkBase.IO.EmbeddedResource.GetBytes("Continuum.Test.Samples.weather-simulation.continuum", Assembly.GetExecutingAssembly());
            var endOfHeader = 0L;

            using (var ms = new MemoryStream(bytes))
            {
                var reader = new CaptureReader(new ConcurrentStream(ms), new StateResolver());

                endOfHeader = reader.BaseStream.Position;
            }

            var stream = new MemoryStream();
            var baseStream = new ConcurrentStream(stream);
            var binaryWriter = new BinaryWriter(stream);
            var stateResolver = new StateResolver();
            stateResolver.Add(new Continuum.Test.Mock.WeatherStateController(new WeatherSimulator()));

            //push in some bytes to get it started, enough for the header so that the stream won't throw on construction
            binaryWriter.Write(bytes, 0, (int)endOfHeader);

            var offset = baseStream.Position;
            baseStream.Position = 0;

            var captureStream = new CaptureStream(baseStream, FileAccess.Read, stateResolver);

            Assert.Null(captureStream.Peek());

            //write some bytes in (not enough for a full state)
            binaryWriter.Seek((int)offset, SeekOrigin.Begin);
            binaryWriter.Write(bytes, (int)offset, 10);

            offset += 10;

            Assert.Null(captureStream.Peek());

            //write some more bytes so that there is now a full state that can be peeked at
            binaryWriter.Seek((int)offset, SeekOrigin.Begin);
            binaryWriter.Write(bytes, (int)offset, 200);

            Assert.NotNull(captureStream.Peek());
        }
        public void CaptureStream_Supports_Reading_A_File_While_It_Is_Being_Written_From_Another_Thread()
        {
            //base bytes to feed into the stream at random
            var bytes = VastPark.FrameworkBase.IO.EmbeddedResource.GetBytes("Continuum.Test.Samples.weather-simulation.continuum", Assembly.GetExecutingAssembly());
            var endOfHeader = 0L;

            using(var ms = new MemoryStream(bytes))
            {
                var reader = new CaptureReader(new ConcurrentStream(ms), new StateResolver());

                endOfHeader = reader.BaseStream.Position;
            }

            var stream = new MemoryStream();
            var baseStream = new ConcurrentStream(stream);
            var binaryWriter = new BinaryWriter(stream);
            var stateResolver = new StateResolver();
            stateResolver.Add(new Continuum.Test.Mock.WeatherStateController(new WeatherSimulator()));

            //push in some bytes to get it started, enough for the header so that the stream won't throw on construction
            binaryWriter.Write(bytes, 0, (int)endOfHeader);

            var offset = baseStream.Position;
            baseStream.Position = 0;

            var captureStream = new CaptureStream(baseStream, FileAccess.Read, stateResolver);

            //write in a little more so we don't have a full state yet
            binaryWriter.Seek((int)offset, SeekOrigin.Begin);
            //binaryWriter.Write(bytes, (int)offset, 5);

            //offset += 5;

            var readStates = 0;
            var lockObject = new object();

            //create a thread to randomly write chunks of bytes into the base stream
            ThreadPool.QueueUserWorkItem(w =>
            {
                while (offset < bytes.LongLength)
                {
                    var bytesToWrite = new Random().Next(1, 200);

                    if (bytesToWrite > bytes.Length - offset)
                    {
                        bytesToWrite = Convert.ToInt32(bytes.LongLength - offset);
                    }

                    lock (lockObject)
                    {
                        binaryWriter.Seek((int)offset, SeekOrigin.Begin);
                        binaryWriter.Write(bytes, (int)offset, bytesToWrite);
                        offset += bytesToWrite;
                    }

                    Thread.Sleep(200);
                }

                Assert.Equal(bytes.LongLength, baseStream.Length);

                lock (lockObject)
                {
                    binaryWriter.Seek(0, SeekOrigin.Begin);

                    for (int i = 0; i < bytes.LongLength; i++)
                    {
                        Assert.Equal(bytes[i], (byte)baseStream.ReadByte());
                    }
                }
            });

            while (captureStream.Position < captureStream.Count)
            {
                lock (lockObject)
                {
                    if (captureStream.Peek() != null)
                    {
                        captureStream.Read();
                        readStates++;
                    }
                }
            }

            Assert.Equal(captureStream.Count, readStates);
        }