/// <summary>
 /// Read the version information that specifies the minimum versions of the 
 /// DataSpaceManager software that can read, write, or update the data space 
 /// information in this file.
 /// </summary>
 /// <param name="dataSpaceStorage"></param>
 /// <exception cref="FileFormatException">
 /// If the format version information in the stream is corrupt.
 /// </exception>
 private void ReadDataSpaceVersionInformation(StorageInfo dataSpaceStorage)
 {      
     if (_fileFormatVersion == null)
     {
         if (dataSpaceStorage.StreamExists( DataSpaceVersionName ))
         {
             StreamInfo versionStreamInfo = dataSpaceStorage.GetStreamInfo( DataSpaceVersionName );
             using (Stream versionStream = versionStreamInfo.GetStream(FileMode.Open))
             {
                 _fileFormatVersion = FormatVersion.LoadFromStream(versionStream);
                                     
                 // Transform Identifier: we preserve casing, but do case-insensitive comparison
                 //Case-insensitive comparison. As per recommendations, we convert both strings
                 //to Upper case and then compare with StringComparison.Ordinal
                 if (!((IEqualityComparer) CU.StringCaseInsensitiveComparer).Equals(_fileFormatVersion.FeatureIdentifier,
                                    DataSpaceVersionIdentifier))
                 {
                     throw new FileFormatException(
                                         SR.Get(SRID.InvalidTransformFeatureName,
                                         _fileFormatVersion.FeatureIdentifier,
                                         DataSpaceVersionIdentifier));                       
                 }
                 // If we ever write this version number out again, we will want to record
                 // the fact that it was done by the current version of the Dataspace software.
                 _fileFormatVersion.WriterVersion = DataSpaceCurrentWriterVersion;
             }
         }
     }        
 }
    /// <summary>
    /// Write the data space mapping table to underlying storage.
    /// </summary>
    void WriteDataSpaceMap()
    {
        ThrowIfIncorrectUpdaterVersion();

        StorageInfo dataSpaceStorage = 
            new StorageInfo( _associatedStorage, DataSpaceStorageName );
        StreamInfo dataSpaceMapStreamInfo = 
            new StreamInfo ( dataSpaceStorage, DataSpaceMapTableName );

        if( 0 < _dataSpaceMap.Count )
        {
            // Write versioning information
            StreamInfo versionStreamInfo = null;
            if (dataSpaceStorage.StreamExists( DataSpaceVersionName ) )
                versionStreamInfo = dataSpaceStorage.GetStreamInfo( DataSpaceVersionName );
            else
                versionStreamInfo = dataSpaceStorage.CreateStream( DataSpaceVersionName );
            Stream versionStream = versionStreamInfo.GetStream();
            _fileFormatVersion.SaveToStream(versionStream);
            versionStream.Close();

            // Create stream for write, overwrite any existing
            using(Stream dataSpaceMapStream = dataSpaceMapStreamInfo.GetStream(FileMode.Create))
            {
                using(BinaryWriter dataSpaceMapWriter =
                    new BinaryWriter( dataSpaceMapStream, System.Text.Encoding.Unicode ))
                {
                    // Write header 

                    // header length = our known size + preserved array size
                    dataSpaceMapWriter.Write( 
                        checked ((Int32) (KnownBytesInMapTableHeader + _mapTableHeaderPreservation.Length)));
                    // number of entries
                    dataSpaceMapWriter.Write(
                        _dataSpaceMap.Count );
                    // anything else we've preserved
                    dataSpaceMapWriter.Write(
                        _mapTableHeaderPreservation );

                    // Loop to write entries
                    foreach( CompoundFileReference o in _dataSpaceMap.Keys )
                    {
                        // determine the entry length
                        string label = (string)_dataSpaceMap[o];
                        int entryLength = CompoundFileReference.Save(o, null);

                        checked { entryLength += CU.WriteByteLengthPrefixedDWordPaddedUnicodeString(null, label); }

                        // length of entryLength itself
                        checked { entryLength += 4; }

                        // write out the entry length
                        dataSpaceMapWriter.Write((Int32) entryLength);

                        // Write out reference
                        CompoundFileReference.Save( o, dataSpaceMapWriter);

                        // Write out dataspace label
                        CU.WriteByteLengthPrefixedDWordPaddedUnicodeString(
                            dataSpaceMapWriter, label);
                    }
                }
            }
        }
        else
        {
            // data space map is empty, remove existing stream if there.
            if ( dataSpaceStorage.StreamExists( DataSpaceMapTableName ) )
                dataSpaceStorage.DeleteStream( DataSpaceMapTableName );
        }
    }