/// <summary>Compare for equality</summary>
        /// <param name="o">the CompoundFileReference to compare to</param>
        public override bool Equals(object o)
        {
            if (o == null)
            {
                return(false);   // Standard behavior.
            }
            // support subclassing - our subclasses can call us and do any additive work themselves
            if (o.GetType() != GetType())
            {
                return(false);
            }

            // Note that because of the GetType() checking above, the casting must be valid.
            CompoundFileStorageReference r = (CompoundFileStorageReference)o;

            return(String.CompareOrdinal(_fullName.ToUpperInvariant(), r._fullName.ToUpperInvariant()) == 0);
        }
        /// <summary>
        /// Compares two CompoundFileReferences
        /// </summary>
        /// <param name="o">CompoundFileReference to compare to this one</param>
        /// <remarks>Supports the IComparable interface</remarks>
        /// <returns>less than zero if this instance is less than the given reference, zero if they are equal
        /// and greater than zero if this instance is greater than the given reference</returns>
        int IComparable.CompareTo(object o)
        {
            if (o == null)
            {
                return(1);   // Standard behavior.
            }
            // different type?
            if (o.GetType() != GetType())
            {
                throw new ArgumentException(
                          SR.Get(SRID.CanNotCompareDiffTypes));
            }

            // Note that because of the GetType() checking above, the casting must be valid.
            CompoundFileStorageReference r = (CompoundFileStorageReference)o;

            return(String.CompareOrdinal(_fullName.ToUpperInvariant(), r._fullName.ToUpperInvariant()));
        }
        /// <summary>
        /// Deserialize from the given stream
        /// </summary>
        /// <param name="reader">the BinaryReader to deserialize from with the seek pointer at the beginning of the container reference</param>
        /// <param name="bytesRead">bytes consumed from the stream</param>
        /// <remarks>
        /// Side effect of change the stream pointer
        /// </remarks>
        /// <exception cref="FileFormatException">Throws a FileFormatException if any formatting errors are encountered</exception>
        internal static CompoundFileReference Load(BinaryReader reader, out int bytesRead)
        {
            ContainerUtilities.CheckAgainstNull(reader, "reader");

            bytesRead = 0;  // running count of how much we've read - sanity check

            // create the TypeMap
            // reconstitute ourselves from the given BinaryReader

            // in this version, the next Int32 is the number of entries
            Int32 entryCount = reader.ReadInt32();

            bytesRead += ContainerUtilities.Int32Size;
            // EntryCount of zero indicates the root storage.
            if (entryCount < 0)
            {
                throw new FileFormatException(
                          SR.Get(SRID.CFRCorrupt));
            }

            // need a temp collection because we don't know what we're dealing with until a non-storage component
            // type is encountered
            StringCollection storageList = null;
            String           streamName  = null;

            // loop through the entries - accumulating strings until we know what kind of object
            // we ultimately need
            int byteLength;     // reusable

            while (entryCount > 0)
            {
                // first Int32 tells us what kind of component this entry represents
                RefComponentType refType = (RefComponentType)reader.ReadInt32();
                bytesRead += ContainerUtilities.Int32Size;

                switch (refType)
                {
                case RefComponentType.Storage:
                {
                    if (streamName != null)
                    {
                        throw new FileFormatException(
                                  SR.Get(SRID.CFRCorruptStgFollowStm));
                    }

                    if (storageList == null)
                    {
                        storageList = new StringCollection();
                    }

                    String str = ContainerUtilities.ReadByteLengthPrefixedDWordPaddedUnicodeString(reader, out byteLength);
                    bytesRead += byteLength;
                    storageList.Add(str);
                } break;

                case RefComponentType.Stream:
                {
                    if (streamName != null)
                    {
                        throw new FileFormatException(
                                  SR.Get(SRID.CFRCorruptMultiStream));
                    }

                    streamName = ContainerUtilities.ReadByteLengthPrefixedDWordPaddedUnicodeString(reader, out byteLength);
                    bytesRead += byteLength;
                } break;

                // we don't handle these types yet
                default:
                    throw new FileFormatException(
                              SR.Get(SRID.UnknownReferenceComponentType));
                }

                --entryCount;
            }

            CompoundFileReference newRef = null;

            // stream or storage?
            if (streamName == null)
            {
                newRef = new CompoundFileStorageReference(
                    ContainerUtilities.ConvertStringArrayPathToBackSlashPath(storageList));
            }
            else
            {
                newRef = new CompoundFileStreamReference(
                    ContainerUtilities.ConvertStringArrayPathToBackSlashPath(storageList, streamName));
            }

            return(newRef);
        }
        /// <summary> 
        /// Deserialize from the given stream
        /// </summary> 
        /// <param name="reader">the BinaryReader to deserialize from with the seek pointer at the beginning of the container reference</param> 
        /// <param name="bytesRead">bytes consumed from the stream</param>
        /// <remarks> 
        /// Side effect of change the stream pointer
        /// </remarks>
        /// <exception cref="FileFormatException">Throws a FileFormatException if any formatting errors are encountered</exception>
        internal static CompoundFileReference Load(BinaryReader reader, out int bytesRead) 
        {
            ContainerUtilities.CheckAgainstNull( reader, "reader" ); 
 
            bytesRead = 0;  // running count of how much we've read - sanity check
 
            // create the TypeMap
            // reconstitute ourselves from the given BinaryReader

            // in this version, the next Int32 is the number of entries 
            Int32 entryCount = reader.ReadInt32();
            bytesRead += ContainerUtilities.Int32Size; 
            // EntryCount of zero indicates the root storage. 
            if (entryCount < 0)
                throw new FileFormatException( 
                    SR.Get(SRID.CFRCorrupt));

            // need a temp collection because we don't know what we're dealing with until a non-storage component
            // type is encountered 
            StringCollection storageList = null;
            String streamName = null; 
 
            // loop through the entries - accumulating strings until we know what kind of object
            // we ultimately need 
            int byteLength;     // reusable
            while (entryCount > 0)
            {
                // first Int32 tells us what kind of component this entry represents 
                RefComponentType refType = (RefComponentType)reader.ReadInt32();
                bytesRead += ContainerUtilities.Int32Size; 
 
                switch (refType)
                { 
                    case RefComponentType.Storage:
                    {
                        if (streamName != null)
                            throw new FileFormatException( 
                                SR.Get(SRID.CFRCorruptStgFollowStm));
 
                        if (storageList == null) 
                            storageList = new StringCollection();
 
                        String str = ContainerUtilities.ReadByteLengthPrefixedDWordPaddedUnicodeString(reader, out byteLength);
                        bytesRead += byteLength;
                        storageList.Add(str);
 
                    } break;
                    case RefComponentType.Stream: 
                    { 
                        if (streamName != null)
                            throw new FileFormatException( 
                                SR.Get(SRID.CFRCorruptMultiStream));

                        streamName = ContainerUtilities.ReadByteLengthPrefixedDWordPaddedUnicodeString(reader, out byteLength);
                        bytesRead += byteLength; 
                    } break;
 
                    // we don't handle these types yet 
                    default:
                        throw new FileFormatException( 
                            SR.Get(SRID.UnknownReferenceComponentType));
                }

                --entryCount; 
            }
 
            CompoundFileReference newRef = null; 

            // stream or storage? 
            if (streamName == null)
            {
                newRef = new CompoundFileStorageReference(
                    ContainerUtilities.ConvertStringArrayPathToBackSlashPath(storageList)); 
            }
            else 
                newRef = new CompoundFileStreamReference( 
                    ContainerUtilities.ConvertStringArrayPathToBackSlashPath(storageList, streamName));
 
            return newRef;
        }