private HotDocs.Server.OutputOptions ConvertOutputOptions(OutputOptions sdkOpts)
        {
            HotDocs.Server.OutputOptions hdsOpts = null;
            if (sdkOpts is PdfOutputOptions)
            {
                PdfOutputOptions sdkPdfOpts = (PdfOutputOptions)sdkOpts;
                HotDocs.Server.PdfOutputOptions hdsPdfOpts = new HotDocs.Server.PdfOutputOptions();

                hdsPdfOpts.Author   = sdkPdfOpts.Author;
                hdsPdfOpts.Comments = sdkPdfOpts.Comments;
                hdsPdfOpts.Company  = sdkPdfOpts.Company;
                hdsPdfOpts.Keywords = sdkPdfOpts.Keywords;
                hdsPdfOpts.Subject  = sdkPdfOpts.Subject;
                hdsPdfOpts.Title    = sdkPdfOpts.Title;

                //Remember that these are PDF passwords which are not highly secure.
                hdsPdfOpts.OwnerPassword = sdkPdfOpts.OwnerPassword;
                hdsPdfOpts.UserPassword  = sdkPdfOpts.UserPassword;

                hdsi.PdfOutputFlags hdsFlags = 0;
                if (sdkPdfOpts.EmbedFonts)
                {
                    hdsFlags |= hdsi.PdfOutputFlags.pdfOut_EmbedFonts;
                }
                if (sdkPdfOpts.KeepFillablePdf)
                {
                    hdsFlags |= hdsi.PdfOutputFlags.pdfOut_KeepFillablePdf;
                }
                if (sdkPdfOpts.PdfA)
                {
                    hdsFlags |= hdsi.PdfOutputFlags.pdfOut_PdfA;
                }
                if (sdkPdfOpts.TaggedPdf)
                {
                    hdsFlags |= hdsi.PdfOutputFlags.pdfOut_TaggedPdf;
                }
                if (sdkPdfOpts.TruncateFields)
                {
                    hdsFlags |= hdsi.PdfOutputFlags.pdfOut_TruncateFields;
                }
                hdsPdfOpts.PdfOutputFlags = hdsFlags;

                hdsi.PdfPermissions hdsPerm = 0;
                if (sdkPdfOpts.Permissions.HasFlag(PdfPermissions.Copy))
                {
                    hdsPerm |= hdsi.PdfPermissions.COPY;
                }
                if (sdkPdfOpts.Permissions.HasFlag(PdfPermissions.Modify))
                {
                    hdsPerm |= hdsi.PdfPermissions.MOD;
                }
                if (sdkPdfOpts.Permissions.HasFlag(PdfPermissions.Print))
                {
                    hdsPerm |= hdsi.PdfPermissions.PRINT;
                }
                hdsPdfOpts.PdfPermissions = hdsPerm;

                hdsOpts = hdsPdfOpts;
            }
            else if (sdkOpts is HtmlOutputOptions)
            {
                HtmlOutputOptions sdkHtmOpts = (HtmlOutputOptions)sdkOpts;
                HotDocs.Server.HtmlOutputOptions hdsHtmOpts = new HotDocs.Server.HtmlOutputOptions();

                hdsHtmOpts.Author   = sdkHtmOpts.Author;
                hdsHtmOpts.Comments = sdkHtmOpts.Comments;
                hdsHtmOpts.Company  = sdkHtmOpts.Company;
                hdsHtmOpts.Keywords = sdkHtmOpts.Keywords;
                hdsHtmOpts.Subject  = sdkHtmOpts.Subject;
                hdsHtmOpts.Title    = sdkHtmOpts.Title;

                hdsHtmOpts.Encoding = sdkHtmOpts.Encoding;

                hdsOpts = hdsHtmOpts;
            }
            else if (sdkOpts is TextOutputOptions)
            {
                TextOutputOptions sdkTxtOpts = (TextOutputOptions)sdkOpts;
                HotDocs.Server.TextOutputOptions hdsTxtOpts = new HotDocs.Server.TextOutputOptions();
                hdsTxtOpts.Encoding = sdkTxtOpts.Encoding;
                hdsOpts             = hdsTxtOpts;
            }

            return(hdsOpts);
        }
        /// <summary>
        /// Assemble a document from the given template, answers and settings.
        /// </summary>
        /// <param name="template">An instance of the Template class.</param>
        /// <param name="answers">Either an XML answer string, or a string containing encoded
        /// interview answers as posted from a HotDocs browser interview.</param>
        /// <param name="settings">An instance of the AssembleDocumentResult class.</param>
        /// <include file="../Shared/Help.xml" path="Help/string/param[@name='logRef']"/>
        /// <returns>An AssemblyResult object containing all the files and data resulting from the request.</returns>
        public AssembleDocumentResult AssembleDocument(Template template, TextReader answers, AssembleDocumentSettings settings, string logRef)
        {
            // Validate input parameters, creating defaults as appropriate.
            string logStr = logRef == null ? string.Empty : logRef;

            if (template == null)
            {
                throw new ArgumentNullException("template", string.Format(@"Local.Services.AssembleDocument: the ""template"" parameter passed in was null, logRef: {0}", logStr));
            }

            if (settings == null)
            {
                settings = new AssembleDocumentSettings();
            }


            HotDocs.Server.AnswerCollection ansColl = new HotDocs.Server.AnswerCollection();
            ansColl.OverlayXMLAnswers(answers == null ? "" : answers.ReadToEnd());
            HotDocs.Server.OutputOptions outputOptions = ConvertOutputOptions(settings.OutputOptions);

            string docPath = CreateTempDocDirAndPath(template, settings.Format);

            _app.AssembleDocument(
                template.GetFullPath(),                //Template path
                hdsi.HDAssemblyOptions.asmOptMarkupView,
                ansColl,
                docPath,
                outputOptions);

            //Prepare the post-assembly answer set.
            HotDocs.Sdk.AnswerCollection resultAnsColl = new AnswerCollection();
            resultAnsColl.ReadXml(new StringReader(ansColl.XmlAnswers));
            if (!settings.RetainTransientAnswers && _app.PendingAssemblyCmdLineStrings.Count == 0)
            {
                // Create a list of all "transient" answers to remove.
                IEnumerable <Answer> transAnswers    = from a in resultAnsColl where !a.Save select a;
                List <string>        answersToRemove = new List <string>();
                foreach (Answer ans in transAnswers)
                {
                    answersToRemove.Add(ans.Name);
                }

                // Iterate through the list of answers to remove and remove them from the result answer collection.
                // This is done as a separate step so we are not modifying the collecion over which we are iterating.
                foreach (string s in answersToRemove)
                {
                    resultAnsColl.RemoveAnswer(s);
                }
            }

            //Build the list of pending assemblies.
            List <Template> pendingAssemblies = new List <Template>();

            for (int i = 0; i < _app.PendingAssemblyCmdLineStrings.Count; i++)
            {
                string cmdLine = _app.PendingAssemblyCmdLineStrings[i];
                string path, switches;
                Util.ParseHdAsmCmdLine(cmdLine, out path, out switches);
                pendingAssemblies.Add(new Template(Path.GetFileName(path), template.Location.Duplicate(), switches));
            }

            //Prepare the document stream and image information for the browser.
            DocumentType       docType         = settings.Format;
            List <NamedStream> supportingFiles = new List <NamedStream>();
            MemoryStream       docStream;

            if (docType == DocumentType.Native)
            {
                docType   = Document.GetDocumentType(docPath);
                docStream = LoadFileIntoMemStream(docPath);
            }
            else if (docType == DocumentType.HTMLwDataURIs)
            {
                //If the consumer requested both HTML and HTMLwDataURIs, they'll only get the latter.
                string content = Util.EmbedImagesInURIs(docPath);
                docStream = new MemoryStream(Encoding.UTF8.GetBytes(content));
            }
            else if (docType == DocumentType.MHTML)
            {
                string content = Util.HtmlToMultiPartMime(docPath);
                docStream = new MemoryStream(Encoding.UTF8.GetBytes(content));
            }
            else if (docType == DocumentType.HTML)
            {
                string targetFilenameNoExtention = Path.GetFileNameWithoutExtension(docPath);
                foreach (string img in Directory.EnumerateFiles(Path.GetDirectoryName(docPath)))
                {
                    string ext = Path.GetExtension(img).ToLower();
                    if (Path.GetFileName(img).StartsWith(targetFilenameNoExtention) && (ext == ".jpg" || ext == ".jpeg" || ext == ".gif" || ext == ".png" || ext == ".bmp"))
                    {
                        supportingFiles.Add(LoadFileIntoNamedStream(img));
                    }
                }

                docStream = LoadFileIntoMemStream(docPath);
            }
            else
            {
                docStream = LoadFileIntoMemStream(docPath);
            }

            //Now that we've loaded all of the assembly results into memory, remove the assembly files.
            FreeTempDocDir(docPath);

            //Return the results.
            Document document             = new Document(template, docStream, docType, supportingFiles.ToArray(), _app.UnansweredVariablesList.ToArray());
            AssembleDocumentResult result = new AssembleDocumentResult(document, resultAnsColl.XmlAnswers, pendingAssemblies.ToArray(), _app.UnansweredVariablesList.ToArray());

            return(result);
        }