/// <summary>
        /// <see cref="MS.Internal.Documents.Application.IDocumentController"/>
        /// </summary>
        bool IDocumentController.Rebind(Document document)
        {
            RightsDocument doc      = (RightsDocument)document; // see class remarks on why this is ok
            Stream         ciphered = doc.Dependency.Source;
            Stream         clear    = ciphered;

            if (doc.IsRebindNeeded)
            {
                if (doc.SourcePackage != null)
                {
                    CloseEnvelope(doc.SourcePackage);
                    doc.SourcePackage = null;
                }

                EncryptedPackageEnvelope envelope   = null;
                PackageProperties        properties = null;
                bool isSourceProtected = doc.IsSourceProtected();

                if (isSourceProtected)
                {
                    envelope          = OpenEnvelopeOnStream(ciphered);
                    doc.SourcePackage = envelope;

                    properties = new SuppressedProperties(envelope);
                }

                DocumentProperties.Current.SetRightsManagedProperties(properties);
                DocumentRightsManagementManager.Current.SetEncryptedPackage(envelope);

                if (isSourceProtected)
                {
                    clear = DocumentRightsManagementManager.Current.DecryptPackage();

                    if (clear != null)
                    {
                        clear = new RightsManagementSuppressedStream(
                            clear,
                            DocumentRightsManagementManager.Current.HasPermissionToEdit);

                        // Reset the position of the stream since GetPackageStream will
                        // create a package and move the stream pointer somewhere else
                        clear.Position = 0;
                    }
                    else
                    {
                        Trace.SafeWrite(
                            Trace.Rights,
                            "You do not have rights for the current document.");

                        return(false);
                    }
                }

                doc.SourceProxy.Target = clear;
            }

            return(true);
        }
        /// <summary>
        /// Retrieves and creates a rights management suppressed stream around the
        /// decrypted stream from a given encrypted package envelope. The stream
        /// returned should not be handed out to untrusted code.
        /// </summary>
        /// <param name="envelope">The envelope to decrypt and suppress</param>
        /// <param name="allowWrite">True if editing the suppressed stream should
        /// be allowed</param>
        /// <returns>The new demand-suppressed stream</returns>
        /// <remarks>
        /// This function exists to centralize the asserts needed to use encrypted
        /// package envelopes.
        /// </remarks>
        private static Stream DecryptEnvelopeAndSuppressStream(
            EncryptedPackageEnvelope envelope,
            bool allowWrite)
        {
            Stream clear = null;

            clear = envelope.GetPackageStream();

            clear = new RightsManagementSuppressedStream(clear, allowWrite);

            // Reset the position of the stream since GetPackageStream will
            // create a package and move the stream pointer somewhere else
            clear.Position = 0;

            return(clear);
        }
        /// <summary>
        /// <see cref="MS.Internal.Documents.Application.IDocumentController"/>
        /// </summary>
        bool IDocumentController.Open(Document document)
        {
            RightsDocument doc               = (RightsDocument)document; // see class remarks on why this is ok
            Stream         ciphered          = doc.Dependency.Source;
            Stream         clear             = ciphered;
            bool           isSourceProtected = doc.IsSourceProtected();

            if (isSourceProtected)
            {
                // Do not catch exceptions here - there can be no mitigation
                EncryptedPackageEnvelope envelope   = OpenEnvelopeOnStream(ciphered);
                PackageProperties        properties = new SuppressedProperties(envelope);

                doc.SourcePackage = envelope;
                DocumentProperties.Current.SetRightsManagedProperties(properties);
            }

            RightsManagementProvider provider =
                new RightsManagementProvider(doc.SourcePackage);

            _provider.Value = provider;

            try
            {
                DocumentRightsManagementManager.Initialize(provider);

                DocumentRightsManagementManager.Current.PublishLicenseChange +=
                    new EventHandler(delegate(object sender, EventArgs args)
                {
                    Trace.SafeWrite(
                        Trace.Rights,
                        "Disabling file copy for current document.");
                    doc.IsFileCopySafe = false;

                    DocumentManager.CreateDefault().EnableEdit(null);
                });

                if (isSourceProtected)
                {
                    clear = DocumentRightsManagementManager.Current.DecryptPackage();

                    if (clear != null)
                    {
                        clear = new RightsManagementSuppressedStream(
                            clear,
                            DocumentRightsManagementManager.Current.HasPermissionToEdit);

                        // Reset the position of the stream since GetPackageStream will
                        // create a package and move the stream pointer somewhere else
                        clear.Position = 0;
                    }
                    else
                    {
                        Trace.SafeWrite(
                            Trace.Rights,
                            "You do not have rights for the current document.");

                        return(false);
                    }
                }
            }
            catch
            {
                // If anything failed here, we cannot use the provider any longer,
                // so we can dispose it
                provider.Dispose();
                _provider.Value = null;
                throw;
            }

            if (clear != null)
            {
                doc.SourceProxy = new StreamProxy(clear);
            }
            else
            {
                // If decryption failed, we can no longer do anything with the
                // provider instance or the current RM manager
                provider.Dispose();
                _provider.Value = null;
            }

            return(true);
        }