/// <summary>
        /// Build a carrier cluster stream with the given keysequence and ordered streams
        /// </summary>
        /// <typeparam name="TCarrierClusterStream">Type of carrier cluster stream to generate</typeparam>
        /// <param name="keySequence">IKeySequence instance</param>
        /// <param name="orderedStreams">Ordered list of streams, used to generate stream segements</param>
        /// <returns>New TCarrierClusterStream</returns>
        public BaseCarrierClusterStream BuildClusterStream(string name, IKeySequence keySequence, IList <Stream> orderedStreams)
        {
            if (keySequence == null)
            {
                throw new ArgumentNullException("keySequence");
            }

            if (orderedStreams == null)
            {
                throw new ArgumentNullException("orderedStreams");
            }

            if (orderedStreams.Count == 0)
            {
                throw new ArgumentOutOfRangeException("orderedStreams", "orderedStreams cannot be empty");
            }

            if (!_carrierClusterStreamTypes.ContainsKey(name))
            {
                throw new InvalidOperationException(string.Format("CarrierClusterStream not found for Name {0}", name));
            }

            ExportFactory <BaseCarrierClusterStream, ICarrierClusterStreamMetadata> factory =
                _carrierClusterStreamTypes[name];

            BaseCarrierClusterStream result = factory.CreateExport().Value;

            result.Initialize(keySequence, orderedStreams.Select(s => BuildCarrierStream(s)));

            return(result);
        }
        /// <summary>
        /// Initialize the cluster stream
        /// </summary>
        /// <param name="keySequence">Key sequence instance</param>
        /// <param name="carrierStreams">Carrier streams to initialized with</param>
        /// <remarks>
        /// Key Step Lengths(KSL)
        ///	Key Step Length Size(KSLS)
        ///	Writable Carrier Stream Length(WCSL)
        /// WCSL / Sum(KSL) * KSLS + WCSL % Sum(KSL) = Length
        /// </remarks>
        public override void Initialize(IKeySequence keySequence, IEnumerable <ICarrierStream> carrierStreams)
        {
            _keySequence = keySequence;

            long currentStart = 0;

            _carrierStreams = new ConcurrentBag <StreamSegment>(
                carrierStreams.Select(cs =>
            {
                long closureCurrentStart = currentStart;
                long end     = closureCurrentStart + cs.Length - 1;
                currentStart = end + 1;
                return(new StreamSegment
                {
                    Start = closureCurrentStart,
                    End = end,
                    CarrierStream = cs
                });
            }));

            _canRead  = _carrierStreams.All(s => s.CarrierStream.CanRead);
            _canSeek  = _carrierStreams.All(s => s.CarrierStream.CanSeek);
            _canWrite = _carrierStreams.All(s => s.CarrierStream.CanWrite);

            long carrierSumLength = _carrierStreams.Sum(s => s.CarrierStream.Length);

            _maxLength = carrierSumLength / _keySequence.TotalStepSum * _keySequence.Length
                         + carrierSumLength % _keySequence.TotalStepSum;

            _length = _maxLength;

            _logger.Info(h => h("Initialize: KeySequence Length: {0}, Stream Lengh = {1}",
                                _keySequence.Length, _length));
        }
        protected void GetSequenceTest(IKeySequence keySequence, int startAt, int count, IEnumerable <byte> expected)
        {
            IEnumerable <byte> results = keySequence.GetSequence(startAt, count);

            Assert.IsNotNull(results);
            Assert.AreEqual(count, results.Count());
            Assert.AreEqual(expected, results);
        }
        protected void GetSequenceTest(IKeySequence keySequence, int startAt, int count, IEnumerable<byte> expected)
        {
            IEnumerable<byte> results = keySequence.GetSequence(startAt, count);

            Assert.IsNotNull(results);
            Assert.AreEqual(count, results.Count());
            Assert.AreEqual(expected, results);
        }
 /// <summary>
 /// Initialize the cluster stream with key sequence instance and carrierStream list
 /// </summary>
 /// <param name="keySequence">Key sequence instance</param>
 /// <param name="carrierStreams">Carrier streams to initialized with</param>
 public abstract void Initialize(IKeySequence keySequence, System.Collections.Generic.IEnumerable <ICarrierStream> carrierStreams);
        /// <summary>
        /// Build a carrier cluster stream with the given keysequence and ordered streams
        /// </summary>
        /// <typeparam name="TCarrierClusterStream">Type of carrier cluster stream to generate</typeparam>
        /// <param name="keySequence">IKeySequence instance</param>
        /// <param name="orderedStreams">Ordered list of streams, used to generate stream segements</param>
        /// <returns>New TCarrierClusterStream</returns>
        public BaseCarrierClusterStream BuildClusterStream(string name, IKeySequence keySequence, IList<Stream> orderedStreams)
        {
            if (keySequence == null)
                throw new ArgumentNullException("keySequence");

            if (orderedStreams == null)
                throw new ArgumentNullException("orderedStreams");

            if (orderedStreams.Count == 0)
                throw new ArgumentOutOfRangeException("orderedStreams", "orderedStreams cannot be empty");

            if (!_carrierClusterStreamTypes.ContainsKey(name))
                throw new InvalidOperationException(string.Format("CarrierClusterStream not found for Name {0}", name));

            ExportFactory<BaseCarrierClusterStream, ICarrierClusterStreamMetadata> factory =
                _carrierClusterStreamTypes[name];

            BaseCarrierClusterStream result = factory.CreateExport().Value;
            result.Initialize(keySequence, orderedStreams.Select(s => BuildCarrierStream(s)));

            return result;
        }