/// <summary>
        /// Creates PDF document from given content. See https://github.com/CommunityHiQ/Frends.Community.PdfFromTemplate
        /// </summary>
        /// <param name="outputFile"></param>
        /// <param name="content"></param>
        /// <param name="options"></param>
        /// <returns>Object { bool Success, string FileName, byte[] ResultAsByteArray }</returns>
        public static Output CreatePdf([PropertyTab] FileProperties outputFile,
                                       [PropertyTab] DocumentContent content,
                                       [PropertyTab] Options options)
        {
            try
            {
                Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

                DocumentDefinition docContent = JsonConvert.DeserializeObject <DocumentDefinition>(content.ContentJson);

                var document = new Document();
                if (!string.IsNullOrWhiteSpace(docContent.Title))
                {
                    document.Info.Title = docContent.Title;
                }
                if (!string.IsNullOrWhiteSpace(docContent.Author))
                {
                    document.Info.Author = docContent.Author;
                }

                PageSetup.GetPageSize(docContent.PageSize.ConvertEnum <PageFormat>(), out Unit width, out Unit height);

                var section = document.AddSection();
                SetupPage(section.PageSetup, width, height, docContent);

                // index for stylename
                var elementNumber = 0;
                // add page elements

                foreach (var pageElement in docContent.DocumentElements)
                {
                    var styleName = $"style_{elementNumber}";
                    var style     = document.Styles.AddStyle(styleName, "Normal");
                    switch (pageElement.ElementType)
                    {
                    case ElementTypeEnum.Paragraph:
                        SetFont(style, ((ParagraphDefinition)pageElement).StyleSettings);
                        SetParagraphStyle(style, ((ParagraphDefinition)pageElement).StyleSettings, false);
                        AddTextContent(section, ((ParagraphDefinition)pageElement).Text, style);
                        break;

                    case ElementTypeEnum.Image:
                        AddImage(section, (ImageDefinition)pageElement, width);
                        break;

                    case ElementTypeEnum.Table:
                        SetFont(style, ((TableDefinition)pageElement).StyleSettings);
                        SetParagraphStyle(style, ((TableDefinition)pageElement).StyleSettings, true);
                        AddTable(section, (TableDefinition)pageElement, width, style);
                        break;

                    case ElementTypeEnum.PageBreak:
                        section = document.AddSection();
                        SetupPage(section.PageSetup, width, height, docContent);
                        break;

                    default:
                        break;
                    }

                    ++elementNumber;
                }

                string fileName      = Path.Combine(outputFile.Directory, outputFile.FileName);
                int    fileNameIndex = 1;
                while (File.Exists(fileName) && outputFile.FileExistsAction != FileExistsActionEnum.Overwrite)
                {
                    switch (outputFile.FileExistsAction)
                    {
                    case FileExistsActionEnum.Error:
                        throw new Exception($"File {fileName} already exists.");

                    case FileExistsActionEnum.Rename:
                        fileName = Path.Combine(outputFile.Directory, $"{Path.GetFileNameWithoutExtension(outputFile.FileName)}_({fileNameIndex}){Path.GetExtension(outputFile.FileName)}");
                        break;
                    }
                    fileNameIndex++;
                }
                // save document

                var pdfRenderer = new PdfDocumentRenderer(outputFile.Unicode)
                {
                    Document = document
                };


                pdfRenderer.RenderDocument();

                if (outputFile.SaveToDisk)
                {
                    if (!options.UseGivenCredentials)
                    {
                        pdfRenderer.PdfDocument.Save(fileName);
                    }
                    else
                    {
                        var domainAndUserName = GetDomainAndUserName(options.UserName);
                        using (Impersonation.LogonUser(domainAndUserName[0], domainAndUserName[1], options.Password, LogonType.NewCredentials))
                        {
                            pdfRenderer.PdfDocument.Save(fileName);
                        }
                    }
                }

                byte[] resultAsBytes = null;

                if (options.GetResultAsByteArray)
                {
                    using (MemoryStream stream = new MemoryStream())
                    {
                        pdfRenderer.PdfDocument.Save(stream, false);
                        resultAsBytes = stream.ToArray();
                    }
                }

                return(new Output {
                    Success = true, FileName = fileName, ResultAsByteArray = resultAsBytes
                });
            }
            catch (Exception ex)
            {
                if (options.ThrowErrorOnFailure)
                {
                    throw;
                }

                return(new Output {
                    Success = false, ErrorMessage = ex.Message
                });
            }
        }
 /// <summary>
 /// Define page parameters.
 /// </summary>
 /// <param name="setup"></param>
 /// <param name="pageWidth"></param>
 /// <param name="pageHeight"></param>
 /// <param name="docDefinition"></param>
 private static void SetupPage(PageSetup setup, Unit pageWidth, Unit pageHeight, DocumentDefinition docDefinition)
 {
     setup.Orientation  = docDefinition.PageOrientation.ConvertEnum <Orientation>();
     setup.PageHeight   = pageHeight;
     setup.PageWidth    = pageWidth;
     setup.LeftMargin   = new Unit(docDefinition.MarginLeftInCm, UnitType.Centimeter);
     setup.TopMargin    = new Unit(docDefinition.MarginTopInCm, UnitType.Centimeter);
     setup.RightMargin  = new Unit(docDefinition.MarginRightInCm, UnitType.Centimeter);
     setup.BottomMargin = new Unit(docDefinition.MarginBottomInCm, UnitType.Centimeter);
 }