/// <summary>
        /// Write sector data, including the CRC, to the stream.  The stream must be positioned at the first byte of the sector
        /// payload data.
        /// </summary>
        /// <param name="data">Sector data buffer.</param>
        /// <param name="offset">Offset of the first byte of sector data into the data buffer.</param>
        /// <param name="length">Size of the sector data.</param>
        private void WriteSectorData(byte[] data, int offset, int length)
        {
            Sync();
            var blockId = trackStream.ReadByte();

            if (blockId == -1)
            {
                throw new DiskImageFormatException("Sector data not found after sector address mark");
            }
            if (blockId != DataAddressMark)
            {
                throw new DiskImageFormatException(String.Format("Unexpected block type {0}", blockId));
            }

            var crc = new Crc16Ccitt();

            crc.Add(0xa1);
            crc.Add(0xa1);
            crc.Add(0xa1);
            crc.Add(DataAddressMark);
            for (int i = 0; i < length; i++)
            {
                crc.Add(data[offset + i]);
            }

            trackStream.Write(data, offset, length);
            trackStream.WriteByte((byte)((crc.Crc >> 8) & 0xff));
            trackStream.WriteByte((byte)(crc.Crc & 0xff));
        }
        /// <summary>
        /// Initialize (format) a track by writing headers and sectors to it.
        /// </summary>
        /// <param name="diskStream">Stream for writing the disk track.</param>
        /// <param name="trackOffset">Byte offset of the track data in the disk image.</param>
        /// <param name="headId">Side of disk for initializing the track.</param>
        /// <param name="sectors">Collection of sectors to be written to the track.</param>
        /// <returns>The track length in the disk image stream.</returns>
        static internal int InitializeTrack(Stream diskStream, int trackOffset, int headId, IEnumerable <HfeSector> sectors)
        {
            var rawStream   = new HfeRawTrack(diskStream, trackOffset, headId);
            var trackStream = new MfmStream(rawStream);

            trackStream.WriteBytes(0x4e, PreableLength);

            foreach (var sector in sectors)
            {
                // Write gap preceeding sector ID record
                trackStream.WriteBytes(0x4e, 24);
                trackStream.WriteBytes(0x00, 12);
                trackStream.WriteSync();
                trackStream.WriteSync();
                trackStream.WriteSync();

                // Write sector ID record
                var sectorInfo      = sector.GetSectorInfo();
                var encodedIdRecord = sectorInfo.Encode();
                trackStream.Write(encodedIdRecord, 0, encodedIdRecord.Length);

                // Write gap preceeding sector data record
                trackStream.WriteBytes(0x4e, 22);
                trackStream.WriteBytes(0x00, 12);
                trackStream.WriteSync();
                trackStream.WriteSync();
                trackStream.WriteSync();

                // Write sector data record
                var encodedDataRecord = sector.Encode();
                trackStream.Write(encodedDataRecord, 0, encodedDataRecord.Length);
            }

            trackStream.WriteBytes(0x4e, PostambleLength);
            trackStream.Flush();

            return(rawStream.TrackLength - trackOffset);
        }