/// <summary>
        /// This will cause the transaction to be written to the database.
        /// Also Calls Dispose()
        /// </summary>
        /// <remarks>Duplicate calls to this function, or subsequent calls to RollbackTransaction will throw an exception</remarks>
        public void CommitAndDispose()
        {
            if (m_disposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }

            foreach (SubFileStream file in m_openedFiles)
            {
                if (file != null && !file.IsDisposed)
                {
                    throw new Exception("Not all files have been properly disposed of.");
                }
            }
            try
            {
                //ToDo: First commit the data, then the file system.
                m_dataReader.CommitChanges(m_fileHeaderBlock);
                if (m_delHasBeenCommitted != null)
                {
                    m_delHasBeenCommitted.Invoke();
                }
            }
            finally
            {
                m_delHasBeenCommitted  = null;
                m_delHasBeenRolledBack = null;
                m_disposed             = true;
                GC.SuppressFinalize(this);
            }
        }
        private static void TestReadAndWritesWithCommit(DiskIo stream)
        {
            FileHeaderBlock header;
            SubFileHeader   node;
            SubFileStream   ds, ds1, ds2;

            //Open The File For Editing
            header = stream.LastCommittedHeader.CloneEditable();
            node   = header.Files[0];
            ds     = new SubFileStream(stream, node, header, false);
            TestSingleByteWrite(ds);
            stream.CommitChanges(header);

            header = stream.LastCommittedHeader;
            node   = header.Files[0];
            ds1    = ds = new SubFileStream(stream, node, header, true);
            TestSingleByteRead(ds);

            //Open The File For Editing
            header = stream.LastCommittedHeader.CloneEditable();
            node   = header.Files[0];
            ds     = new SubFileStream(stream, node, header, false);
            TestCustomSizeWrite(ds, 5);
            stream.CommitChanges(header);

            header = stream.LastCommittedHeader;
            node   = header.Files[0];
            ds2    = ds = new SubFileStream(stream, node, header, true);
            TestCustomSizeRead(ds, 5);

            //Open The File For Editing
            header = stream.LastCommittedHeader.CloneEditable();
            node   = header.Files[0];
            ds     = new SubFileStream(stream, node, header, false);
            TestCustomSizeWrite(ds, BlockDataLength + 20);
            stream.CommitChanges(header);

            header = stream.LastCommittedHeader;
            node   = header.Files[0];
            ds     = new SubFileStream(stream, node, header, true);
            TestCustomSizeRead(ds, BlockDataLength + 20);

            //check old versions of the file
            TestSingleByteRead(ds1);
            TestCustomSizeRead(ds2, 5);
        }
        private static void TestReadAndWrites(DiskIo stream)
        {
            FileHeaderBlock header = stream.LastCommittedHeader;

            header = header.CloneEditable();
            SubFileHeader node = header.CreateNewFile(SubFileName.CreateRandom());

            header.CreateNewFile(SubFileName.CreateRandom());
            header.CreateNewFile(SubFileName.CreateRandom());

            SubFileStream ds = new SubFileStream(stream, node, header, false);

            TestSingleByteWrite(ds);
            TestSingleByteRead(ds);

            TestCustomSizeWrite(ds, 5);
            TestCustomSizeRead(ds, 5);

            TestCustomSizeWrite(ds, BlockDataLength + 20);
            TestCustomSizeRead(ds, BlockDataLength + 20);
            stream.CommitChanges(header);
        }
        private static void TestReadAndWritesToDifferentFilesWithCommit(DiskIo stream)
        {
            FileHeaderBlock header;

            SubFileStream ds;

            //Open The File For Editing
            header = stream.LastCommittedHeader.CloneEditable();
            ds     = new SubFileStream(stream, header.Files[0], header, false);
            TestSingleByteWrite(ds);
            ds = new SubFileStream(stream, header.Files[1], header, false);
            TestCustomSizeWrite(ds, 5);
            ds = new SubFileStream(stream, header.Files[2], header, false);
            TestCustomSizeWrite(ds, BlockDataLength + 20);
            stream.CommitChanges(header);

            header = stream.LastCommittedHeader;
            ds     = new SubFileStream(stream, header.Files[0], header, true);
            TestSingleByteRead(ds);
            ds = new SubFileStream(stream, header.Files[1], header, true);
            TestCustomSizeRead(ds, 5);
            ds = new SubFileStream(stream, header.Files[2], header, true);
            TestCustomSizeRead(ds, BlockDataLength + 20);
        }