// Path: core/modules/api/src/com/haulmont/yarg/formatters/factory/FormatterFactoryInput.java
// public class FormatterFactoryInput {
// 
//     protected final String templateExtension;
//     protected final BandData rootBand;
//     protected final ReportTemplate reportTemplate;
//     protected final OutputStream outputStream;
// 
//     protected ReportOutputType outputType = null;
// 
//     public FormatterFactoryInput(String templateExtension, BandData rootBand, ReportTemplate reportTemplate, OutputStream outputStream) {
//         if (templateExtension == null) {
//             throw new NullPointerException("templateExtension can not be null");
//         }
// 
//         if (rootBand == null) {
//             throw new NullPointerException("rootBand can not be null");
//         }
// 
//         this.templateExtension = templateExtension;
//         this.rootBand = rootBand;
//         this.reportTemplate = reportTemplate;
//         this.outputStream = outputStream;
//     }
// 
//     public FormatterFactoryInput(String templateExtension, BandData rootBand, ReportTemplate reportTemplate, ReportOutputType outputType, OutputStream outputStream) {
//         this(templateExtension, rootBand, reportTemplate, outputStream);
//         this.outputType = outputType;
//     }
// 
//     public String getTemplateExtension() {
//         return templateExtension;
//     }
// 
//     public BandData getRootBand() {
//         return rootBand;
//     }
// 
//     public ReportTemplate getReportTemplate() {
//         return reportTemplate;
//     }
// 
//     public OutputStream getOutputStream() {
//         return outputStream;
//     }
// 
//     public ReportOutputType getOutputType() {
//         return outputType;
//     }
// }
// 
// Path: core/modules/core/src/com/haulmont/yarg/formatters/impl/inline/ContentInliner.java
// public interface ContentInliner {
// 
//     /**
//      * Get Regexp Pattern for match format string
//      *
//      * @return Pattern
//      */
//     Pattern getTagPattern();
// 
//     /**
//      * Inline content to xlsx template
//      */
//     void inlineToXlsx(SpreadsheetMLPackage pkg, WorksheetPart worksheetPart, Cell newCell, Object paramValue, Matcher matcher);
// 
//     /**
//      * Inline content into doc template
//      */
//     void inlineToDoc(OfficeComponent officeComponent, XTextRange textRange, XText destination, Object paramValue, Matcher paramsMatcher)
//             throws Exception;
// 
//     /**
//      * Inline content into docx template
//      */
//     void inlineToDocx(WordprocessingMLPackage wordPackage, Text destination, Object paramValue, Matcher paramsMatcher);
// 
//     /**
//      * Inline content into xls template
//      */
//     void inlineToXls(HSSFPatriarch patriarch, HSSFCell destination, Object paramValue, Matcher paramsMatcher);
// }
// 
// Path: core/modules/api/src/com/haulmont/yarg/structure/ReportFieldFormat.java
// public interface ReportFieldFormat extends Serializable {
//     /**
//      * @return formatted field name. Should also contain all parent band names.
//      * Example: Band1.Band2.field1
//      */
//     String getName();
// 
//     /**
//      * @return format string
//      * Example: ##,# for decimals, dd-MM-yyyy for dates, etc.
//      */
//     String getFormat();
// 
//     /**
//      * @return boolean <code>true</code> if the groovy script, otherwise <code>false</code>
//      */
//     Boolean isGroovyScript();
// }


import com.haulmont.yarg.formatters.factory.FormatterFactoryInput;
import com.haulmont.yarg.formatters.impl.docx.*;
import com.haulmont.yarg.formatters.impl.inline.ContentInliner;
import com.haulmont.yarg.formatters.impl.xls.DocumentConverter;
import com.haulmont.yarg.structure.BandData;
import com.haulmont.yarg.structure.ReportFieldFormat;
import com.haulmont.yarg.structure.ReportOutputType;
import org.apache.commons.io.IOUtils;
import org.docx4j.Docx4J;
import org.docx4j.TraversalUtil;
import org.docx4j.convert.in.xhtml.XHTMLImporter;
import org.docx4j.convert.in.xhtml.XHTMLImporterImpl;
import org.docx4j.convert.out.HTMLSettings;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.io.SaveToZipFile;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.JaxbXmlPartAltChunkHost;
import org.docx4j.openpackaging.parts.WordprocessingML.AltChunkType;
import org.docx4j.openpackaging.parts.WordprocessingML.AlternativeFormatInputPart;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.toc.TocException;
import org.docx4j.toc.TocFinder;
import org.docx4j.toc.TocGenerator;
import org.docx4j.utils.AltChunkFinder;
import org.docx4j.wml.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;

        updateTableOfContents();

        saveAndClose();
    }

    protected void updateTableOfContents() {
        try {
            MainDocumentPart documentPart = wordprocessingMLPackage.getMainDocumentPart();
            Document wmlDocumentEl;
            try {
                wmlDocumentEl = documentPart.getContents();
            } catch (Docx4JException e) {
                throw new RuntimeException("Unable to get document content", e);
            }
            Body body = wmlDocumentEl.getBody();

            TocFinder finder = new TocFinder();
            new TraversalUtil(body.getContent(), finder);
            SdtBlock structuredDocumentPart = finder.getTocSDT();

            if (structuredDocumentPart != null) {
                TocGenerator tocGenerator = new TocGenerator(wordprocessingMLPackage);
                tocGenerator.updateToc(false);
            }
        } catch (TocException e) {
            log.error("An error occurred during updating the Table Of Contents", e);
        }
    }

// Path: core/modules/api/src/com/haulmont/yarg/formatters/factory/FormatterFactoryInput.java
// public class FormatterFactoryInput {
// 
//     protected final String templateExtension;
//     protected final BandData rootBand;
//     protected final ReportTemplate reportTemplate;
//     protected final OutputStream outputStream;
// 
//     protected ReportOutputType outputType = null;
// 
//     public FormatterFactoryInput(String templateExtension, BandData rootBand, ReportTemplate reportTemplate, OutputStream outputStream) {
//         if (templateExtension == null) {
//             throw new NullPointerException("templateExtension can not be null");
//         }
// 
//         if (rootBand == null) {
//             throw new NullPointerException("rootBand can not be null");
//         }
// 
//         this.templateExtension = templateExtension;
//         this.rootBand = rootBand;
//         this.reportTemplate = reportTemplate;
//         this.outputStream = outputStream;
//     }
// 
//     public FormatterFactoryInput(String templateExtension, BandData rootBand, ReportTemplate reportTemplate, ReportOutputType outputType, OutputStream outputStream) {
//         this(templateExtension, rootBand, reportTemplate, outputStream);
//         this.outputType = outputType;
//     }
// 
//     public String getTemplateExtension() {
//         return templateExtension;
//     }
// 
//     public BandData getRootBand() {
//         return rootBand;
//     }
// 
//     public ReportTemplate getReportTemplate() {
//         return reportTemplate;
//     }
// 
//     public OutputStream getOutputStream() {
//         return outputStream;
//     }
// 
//     public ReportOutputType getOutputType() {
//         return outputType;
//     }
// }
// 
// Path: core/modules/core/src/com/haulmont/yarg/formatters/impl/inline/ContentInliner.java
// public interface ContentInliner {
// 
//     /**
//      * Get Regexp Pattern for match format string
//      *
//      * @return Pattern
//      */
//     Pattern getTagPattern();
// 
//     /**
//      * Inline content to xlsx template
//      */
//     void inlineToXlsx(SpreadsheetMLPackage pkg, WorksheetPart worksheetPart, Cell newCell, Object paramValue, Matcher matcher);
// 
//     /**
//      * Inline content into doc template
//      */
//     void inlineToDoc(OfficeComponent officeComponent, XTextRange textRange, XText destination, Object paramValue, Matcher paramsMatcher)
//             throws Exception;
// 
//     /**
//      * Inline content into docx template
//      */
//     void inlineToDocx(WordprocessingMLPackage wordPackage, Text destination, Object paramValue, Matcher paramsMatcher);
// 
//     /**
//      * Inline content into xls template
//      */
//     void inlineToXls(HSSFPatriarch patriarch, HSSFCell destination, Object paramValue, Matcher paramsMatcher);
// }
// 
// Path: core/modules/api/src/com/haulmont/yarg/structure/ReportFieldFormat.java
// public interface ReportFieldFormat extends Serializable {
//     /**
//      * @return formatted field name. Should also contain all parent band names.
//      * Example: Band1.Band2.field1
//      */
//     String getName();
// 
//     /**
//      * @return format string
//      * Example: ##,# for decimals, dd-MM-yyyy for dates, etc.
//      */
//     String getFormat();
// 
//     /**
//      * @return boolean <code>true</code> if the groovy script, otherwise <code>false</code>
//      */
//     Boolean isGroovyScript();
// }


// Path: core/modules/core/src/com/haulmont/yarg/formatters/impl/DocxFormatter.java
import com.haulmont.yarg.formatters.factory.FormatterFactoryInput;
import com.haulmont.yarg.formatters.impl.docx.*;
import com.haulmont.yarg.formatters.impl.inline.ContentInliner;
import com.haulmont.yarg.formatters.impl.xls.DocumentConverter;
import com.haulmont.yarg.structure.BandData;
import com.haulmont.yarg.structure.ReportFieldFormat;
import com.haulmont.yarg.structure.ReportOutputType;
import org.apache.commons.io.IOUtils;
import org.docx4j.Docx4J;
import org.docx4j.TraversalUtil;
import org.docx4j.convert.in.xhtml.XHTMLImporter;
import org.docx4j.convert.in.xhtml.XHTMLImporterImpl;
import org.docx4j.convert.out.HTMLSettings;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.io.SaveToZipFile;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.JaxbXmlPartAltChunkHost;
import org.docx4j.openpackaging.parts.WordprocessingML.AltChunkType;
import org.docx4j.openpackaging.parts.WordprocessingML.AlternativeFormatInputPart;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.toc.TocException;
import org.docx4j.toc.TocFinder;
import org.docx4j.toc.TocGenerator;
import org.docx4j.utils.AltChunkFinder;
import org.docx4j.wml.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;


        updateTableOfContents();

        saveAndClose();
    }

    protected void updateTableOfContents() {
        try {
            MainDocumentPart documentPart = wordprocessingMLPackage.getMainDocumentPart();
            Document wmlDocumentEl;
            try {
                wmlDocumentEl = documentPart.getContents();
            } catch (Docx4JException e) {
                throw new RuntimeException("Unable to get document content", e);
            }
            Body body = wmlDocumentEl.getBody();

            TocFinder finder = new TocFinder();
            new TraversalUtil(body.getContent(), finder);
            SdtBlock structuredDocumentPart = finder.getTocSDT();

            if (structuredDocumentPart != null) {
                TocGenerator tocGenerator = new TocGenerator(wordprocessingMLPackage);
                tocGenerator.updateToc(false);
            }
        } catch (TocException e) {
            log.error("An error occurred during updating the Table Of Contents", e);
        }
    }

    protected void handleUrls() {