/// <summary>
        ///     Create a new, blank, compound file.
        /// </summary>
        /// <param name="cfsVersion">Use a specific Compound File Version to set 512 or 4096 bytes sectors</param>
        /// <param name="sectorRecycle">If true, recycle unused sectors</param>
        /// <example>
        ///     <code>
        ///  
        ///      byte[] b = new byte[10000];
        ///      for (int i = 0; i &lt; 10000; i++)
        ///      {
        ///          b[i % 120] = (byte)i;
        ///      }
        /// 
        ///      CompoundFile cf = new CompoundFile(CFSVersion.Ver_4, true, true);
        ///      CFStream myStream = cf.RootStorage.AddStream("MyStream");
        /// 
        ///      Assert.IsNotNull(myStream);
        ///      myStream.SetData(b);
        ///      cf.Save("MyCompoundFile.cfs");
        ///      cf.Close();
        ///      
        ///  </code>
        /// </example>
        /// <remarks>
        ///     Sector recycling reduces data writing performances but avoids space wasting in scenarios with frequently
        ///     data manipulation of the same streams. The new compound file is open in Update mode.
        /// </remarks>
        public CompoundFile(CFSVersion cfsVersion, bool sectorRecycle)
        {
            _header = new Header((ushort) cfsVersion);
            _sectorRecycle = sectorRecycle;

            _difatSectorFATEntriesCount = (GetSectorSize()/4) - 1;
            _fatSectorEntriesCount = (GetSectorSize()/4);

            //Root --
            RootStorage = new CFStorage(this);

            RootStorage.DirEntry.SetEntryName("Root Entry");
            RootStorage.DirEntry.StgType = StgType.StgRoot;
        }
        /// <summary>
        ///     Load compound file from an existing stream.
        /// </summary>
        /// <param name="stream">Stream to load compound file from</param>
        private void Load(Stream stream)
        {
            try
            {
                _header = new Header();
                _directoryEntries = new List<IDirectoryEntry>();

                SourceStream = stream;

                _header.Read(stream);

                var numberOfSectors = Ceiling(((stream.Length - GetSectorSize())/(double) GetSectorSize()));

                if (stream.Length > 0x7FFFFF0)
                    TransactionLockAllocated = true;

                _sectors = new SectorCollection();
                for (var i = 0; i < numberOfSectors; i++)
                    _sectors.Add(null);

                LoadDirectories();

                RootStorage = new CFStorage(this, _directoryEntries[0]);
            }
            catch (Exception)
            {
                if (stream != null)
                    stream.Close();

                throw;
            }
        }
        /// <summary>
        ///     Create a blank, version 3 compound file.
        ///     Sector recycle is turned off to achieve the best reading/writing
        ///     performance in most common scenarios.
        /// </summary>
        /// <example>
        ///     <code>
        ///  
        ///      byte[] b = new byte[10000];
        ///      for (int i = 0; i &lt; 10000; i++)
        ///      {
        ///          b[i % 120] = (byte)i;
        ///      }
        /// 
        ///      CompoundFile cf = new CompoundFile();
        ///      CFStream myStream = cf.RootStorage.AddStream("MyStream");
        /// 
        ///      Assert.IsNotNull(myStream);
        ///      myStream.SetData(b);
        ///      cf.Save("MyCompoundFile.cfs");
        ///      cf.Close();
        ///      
        ///  </code>
        /// </example>
        public CompoundFile()
        {
            _header = new Header();
            _sectorRecycle = false;

            _difatSectorFATEntriesCount = (GetSectorSize()/4) - 1;
            _fatSectorEntriesCount = (GetSectorSize()/4);

            //Root --
            RootStorage = new CFStorage(this);

            RootStorage.DirEntry.SetEntryName("Root Entry");
            RootStorage.DirEntry.StgType = StgType.StgRoot;
        }
        /// <summary>
        ///     When called from user code, release all resources, otherwise, in the case runtime called it,
        ///     only unmanagd resources are released.
        /// </summary>
        /// <param name="disposing">If true, method has been called from User code, if false it's been called from .net runtime</param>
        protected virtual void Dispose(bool disposing)
        {
            try
            {
                if (!IsClosed)
                {
                    lock (_lockObject)
                    {
                        if (disposing)
                        {
                            // Call from user code...

                            if (_sectors != null)
                            {
                                _sectors.Clear();
                                _sectors = null;
                            }

                            RootStorage = null; // Some problem releasing resources...
                            _header = null;
                            _directoryEntries.Clear();
                            _directoryEntries = null;
                            _lockObject = null;
                            _buffer = null;
                        }

                        if (SourceStream != null)
                            SourceStream.Close();
                    }
                }
            }
            finally
            {
                IsClosed = true;
            }
        }