// Make sure there is a part to write to and that it contains 
        // the expected start markup. 
        private void EnsureXmlWriter()
        { 
            // It does not make sense to reuse a writer outside of streaming creation.
            if (!_package.InStreamingCreation)
                Invariant.Assert(_xmlWriter == null);
 
            if (_xmlWriter != null)
                return; 
 
            EnsurePropertyPart(); // Should succeed or throw an exception.
 
            Stream writerStream;

            if(_package.InStreamingCreation)
                writerStream = _propertyPart.GetStream(FileMode.Create, FileAccess.Write); 
            else
                writerStream = new IgnoreFlushAndCloseStream(_propertyPart.GetStream(FileMode.Create, FileAccess.Write)); 
 
            _xmlWriter = new XmlTextWriter(writerStream, System.Text.Encoding.UTF8);
 
            WriteXmlStartTagsForPackageProperties();
        }
        internal static String GenerateDigestValue(
            Stream s, 
            List<String> transforms, 
            HashAlgorithm hashAlgorithm)
        {
            s.Seek(0, SeekOrigin.Begin);

            // We need to be able to dispose streams generated by the
            // Transform object but we don't want to dispose the stream
            // passed to us so we insert this to block any propagated Dispose() calls.
            Stream transformStream = new IgnoreFlushAndCloseStream(s);

            List<Stream> transformStreams = null;
            
            // canonicalize the part content if asked
            if (transforms != null)
            {
                transformStreams = new List<Stream>(transforms.Count);
                transformStreams.Add(transformStream);
                foreach (String transformName in transforms)
                {
                    // ignore empty strings at this point (as well as Relationship Transforms) - these are legal
                    if ((transformName.Length == 0)
                        || (String.CompareOrdinal(transformName, XTable.Get(XTable.ID.RelationshipsTransformName)) == 0))
                    {
                        continue;
                    }
                    
                    // convert the transform names into objects (if defined)
                    Transform transform = StringToTransform(transformName);

                    if (transform == null)
                    {
                        // throw XmlException so the outer loop knows the signature is invalid
                        throw new XmlException(SR.Get(SRID.UnsupportedTransformAlgorithm));
                    }

                    transformStream = TransformXml(transform, transformStream);
                    transformStreams.Add(transformStream);
                }
            }

            // hash it and encode to Base64
            String hashValueString = System.Convert.ToBase64String(HashStream(hashAlgorithm, transformStream));

            // dispose of any generated streams
            if (transformStreams != null)
            {
                foreach (Stream stream in transformStreams)
                    stream.Close();
            }

            return hashValueString;
        }