protected virtual void CreateOpfDocument()
        {
            //m_ProgressPercentage = 90;
            //reportProgress(m_ProgressPercentage, UrakawaSDK_daisy_Lang.AllFilesCreated);
            if (RequestCancellation)
            {
                return;
            }
            XmlDocument opfDocument = CreateStub_OpfDocument();

            XmlNode manifestNode = XmlDocumentHelper.GetFirstChildElementOrSelfWithName(opfDocument, true, "manifest", null); //opfDocument.GetElementsByTagName("manifest")[0];


            m_AllowedInDcMetadata.Add(SupportedMetadata_Z39862005.DC_Title);
            m_AllowedInDcMetadata.Add(SupportedMetadata_Z39862005.DC_Creator);
            m_AllowedInDcMetadata.Add(SupportedMetadata_Z39862005.DC_Subject);
            m_AllowedInDcMetadata.Add(SupportedMetadata_Z39862005.DC_Description);
            m_AllowedInDcMetadata.Add(SupportedMetadata_Z39862005.DC_Identifier);
            m_AllowedInDcMetadata.Add(SupportedMetadata_Z39862005.DC_Publisher);
            m_AllowedInDcMetadata.Add(SupportedMetadata_Z39862005.DC_Contributor);
            m_AllowedInDcMetadata.Add(SupportedMetadata_Z39862005.DC_Date);
            m_AllowedInDcMetadata.Add(SupportedMetadata_Z39862005.DC_Type);
            m_AllowedInDcMetadata.Add(SupportedMetadata_Z39862005.DC_Format);
            m_AllowedInDcMetadata.Add(SupportedMetadata_Z39862005.D_Source);
            m_AllowedInDcMetadata.Add(SupportedMetadata_Z39862005.DC_Language);
            m_AllowedInDcMetadata.Add(SupportedMetadata_Z39862005.DC_Relation);
            m_AllowedInDcMetadata.Add(SupportedMetadata_Z39862005.DC_Coverage);
            m_AllowedInDcMetadata.Add(SupportedMetadata_Z39862005.DC_Rights);

            m_DtbAllowedInXMetadata.Add(SupportedMetadata_Z39862005.DTB_SOURCE_DATE);
            m_DtbAllowedInXMetadata.Add(SupportedMetadata_Z39862005.DTB_SOURCE_EDITION);
            m_DtbAllowedInXMetadata.Add(SupportedMetadata_Z39862005.DTB_SOURCE_PUBLISHER);
            m_DtbAllowedInXMetadata.Add(SupportedMetadata_Z39862005.DTB_SOURCE_RIGHTS);
            m_DtbAllowedInXMetadata.Add(SupportedMetadata_Z39862005.DTB_SOURCE_TITLE);
            m_DtbAllowedInXMetadata.Add(SupportedMetadata_Z39862005.DTB_MULTIMEDIA_TYPE);
            m_DtbAllowedInXMetadata.Add(SupportedMetadata_Z39862005.DTB_MULTIMEDIA_CONTENT);
            m_DtbAllowedInXMetadata.Add(SupportedMetadata_Z39862005.DTB_NARRATOR);
            m_DtbAllowedInXMetadata.Add(SupportedMetadata_Z39862005.DTB_PRODUCER);
            m_DtbAllowedInXMetadata.Add(SupportedMetadata_Z39862005.DTB_PRODUCED_DATE);
            m_DtbAllowedInXMetadata.Add(SupportedMetadata_Z39862005.DTB_REVISION);
            m_DtbAllowedInXMetadata.Add(SupportedMetadata_Z39862005.DTB_REVISION_DATE);
            m_DtbAllowedInXMetadata.Add(SupportedMetadata_Z39862005.DTB_REVISION_DESCRIPTION);
            m_DtbAllowedInXMetadata.Add(SupportedMetadata_Z39862005.DTB_TOTAL_TIME);
            m_DtbAllowedInXMetadata.Add(SupportedMetadata_Z39862005.DTB_AUDIO_FORMAT);

            AddFilenameToManifest(opfDocument, manifestNode, m_Filename_Ncx, "ncx", DataProviderFactory.NCX_MIME_TYPE);

            if (m_Filename_Content != null)
            {
                AddFilenameToManifest(opfDocument, manifestNode, m_Filename_Content, GetNextID(ID_OpfPrefix), DataProviderFactory.DTBOOK_MIME_TYPE);
            }

            AddFilenameToManifest(opfDocument, manifestNode, m_Filename_Opf, GetNextID(ID_OpfPrefix), DataProviderFactory.XML_MIME_TYPE);

            foreach (string externalFileName in m_FilesList_ExternalFiles)
            {
                // ALREADY escaped!
                //externalFileName = FileDataProvider.EliminateForbiddenFileNameCharacters(externalFileName);

                string strID = GetNextID(ID_OpfPrefix);

                string ext = Path.GetExtension(externalFileName);
                if (DataProviderFactory.CSS_EXTENSION.Equals(ext, StringComparison.OrdinalIgnoreCase))
                {
                    AddFilenameToManifest(opfDocument, manifestNode, externalFileName, strID, DataProviderFactory.CSS_MIME_TYPE);
                }
                else if (DataProviderFactory.XSLT_EXTENSION.Equals(ext, StringComparison.OrdinalIgnoreCase) ||
                         DataProviderFactory.XSL_EXTENSION.Equals(ext, StringComparison.OrdinalIgnoreCase))
                {
                    AddFilenameToManifest(opfDocument, manifestNode, externalFileName, strID, DataProviderFactory.XSLT_MIME_TYPE_);
                }
                else if (DataProviderFactory.DTD_EXTENSION.Equals(ext, StringComparison.OrdinalIgnoreCase))
                {
                    AddFilenameToManifest(opfDocument, manifestNode, externalFileName, strID, DataProviderFactory.DTD_MIME_TYPE);
                }
            }

            if (RequestCancellation)
            {
                return;
            }

            List <string> smilIDListInPlayOrder = new List <string>();

            foreach (string smilFileName in m_FilesList_Smil)
            {
                string strID = GetNextID(ID_OpfPrefix);

                AddFilenameToManifest(opfDocument, manifestNode, smilFileName, strID, DataProviderFactory.SMIL_MIME_TYPE_);
                smilIDListInPlayOrder.Add(strID);
            }

            if (RequestCancellation)
            {
                return;
            }

            foreach (string audioFileName in m_FilesList_SmilAudio)
            {
                string strID = GetNextID(ID_OpfPrefix);

                string ext  = Path.GetExtension(audioFileName);
                string mime = DataProviderFactory.GetMimeTypeFromExtension(ext);
                AddFilenameToManifest(opfDocument, manifestNode, audioFileName, strID, mime);
            }

            if (RequestCancellation)
            {
                return;
            }

            foreach (string imageFileName in m_FilesList_Image)
            {
                string strID = GetNextID(ID_OpfPrefix);

                string ext  = Path.GetExtension(imageFileName);
                string mime = DataProviderFactory.GetMimeTypeFromExtension(ext);
                AddFilenameToManifest(opfDocument, manifestNode, imageFileName, strID, mime);
            }


#if SUPPORT_AUDIO_VIDEO
            if (RequestCancellation)
            {
                return;
            }

            foreach (string videoFileName in m_FilesList_Video)
            {
                string strID = GetNextID(ID_OpfPrefix);

                string ext  = Path.GetExtension(videoFileName);
                string mime = DataProviderFactory.GetMimeTypeFromExtension(ext);
                AddFilenameToManifest(opfDocument, manifestNode, videoFileName, strID, mime);
            }

            foreach (string audioFileName in m_FilesList_Audio)
            {
                string strID = GetNextID(ID_OpfPrefix);

                string ext  = Path.GetExtension(audioFileName);
                string mime = DataProviderFactory.GetMimeTypeFromExtension(ext);
                AddFilenameToManifest(opfDocument, manifestNode, audioFileName, strID, mime);
            }
#endif

            if (RequestCancellation)
            {
                return;
            }

            bool textOnly = m_TotalTime == null || m_TotalTime.AsLocalUnits == 0;
            if (true || !textOnly)
            {
                // copy resource files and place entry in manifest
                string sourceDirectoryPath    = System.AppDomain.CurrentDomain.BaseDirectory;
                string ResourceRes_Filename   = "tpbnarrator.res";
                string resourceAudio_Filename = "tpbnarrator_res.mp3";

                string ResourceRes_Filename_fullPath   = Path.Combine(sourceDirectoryPath, ResourceRes_Filename);
                string resourceAudio_Filename_fullPath = Path.Combine(sourceDirectoryPath, resourceAudio_Filename);
                if (File.Exists(ResourceRes_Filename_fullPath) && File.Exists(resourceAudio_Filename_fullPath))
                {
                    if (RequestCancellation)
                    {
                        return;
                    }

                    string destRes = Path.Combine(m_OutputDirectory, ResourceRes_Filename);

                    if (!textOnly)
                    {
                        File.Copy(ResourceRes_Filename_fullPath, destRes, true);
                        try
                        {
                            File.SetAttributes(destRes, FileAttributes.Normal);
                        }
                        catch
                        {
                        }
                    }
                    else
                    {
                        string resXml = File.ReadAllText(ResourceRes_Filename_fullPath);

                        int i = -1;
                        int j = 0;
                        while ((i = resXml.IndexOf("<audio", j)) >= 0)
                        {
                            j = resXml.IndexOf("/>", i);
                            if (j > i)
                            {
                                int len = j - i + 2;
                                resXml = resXml.Remove(i, len);

                                string fill = "";
                                for (int k = 1; k <= len; k++)
                                {
                                    fill += ' '; //k.ToString();
                                }

                                resXml = resXml.Insert(i, fill);
                            }
                            else
                            {
#if DEBUG
                                Debugger.Break();
#endif
                                break;
                            }
                        }

                        StreamWriter streamWriter = File.CreateText(destRes);
                        try
                        {
                            streamWriter.Write(resXml);
                        }
                        finally
                        {
                            streamWriter.Close();
                        }
                    }

                    AddFilenameToManifest(opfDocument, manifestNode, ResourceRes_Filename, "resource", DataProviderFactory.DTB_RES_MIME_TYPE);

                    if (!textOnly)
                    {
                        string destFile = Path.Combine(m_OutputDirectory, resourceAudio_Filename);
                        File.Copy(resourceAudio_Filename_fullPath, destFile, true);
                        try
                        {
                            File.SetAttributes(destFile, FileAttributes.Normal);
                        }
                        catch
                        {
                        }

                        AddFilenameToManifest(opfDocument, manifestNode, resourceAudio_Filename, GetNextID(ID_OpfPrefix), DataProviderFactory.AUDIO_MP3_MIME_TYPE);
                    }
                }
            }

            // create spine
            XmlNode spineNode = XmlDocumentHelper.GetFirstChildElementOrSelfWithName(opfDocument, true, "spine", null); //opfDocument.GetElementsByTagName("spine")[0];

            foreach (string strSmilID in smilIDListInPlayOrder)
            {
                XmlNode itemRefNode = opfDocument.CreateElement(null, "itemref", spineNode.NamespaceURI);
                spineNode.AppendChild(itemRefNode);
                XmlDocumentHelper.CreateAppendXmlAttribute(opfDocument, itemRefNode, "idref", strSmilID);
            }

            if (RequestCancellation)
            {
                return;
            }

            AddMetadata_Opf(opfDocument);

            if (RequestCancellation)
            {
                opfDocument = null;
                return;
            }

            XmlReaderWriterHelper.WriteXmlDocument(opfDocument, OpfFilePath, null);
        }