class CloseElementTag
            extends AbstractElementTag
            implements ICloseElementTag, IEngineTemplateEvent {


    final String trailingWhiteSpace; // can be null if there is none
    final boolean unmatched;




    CloseElementTag(
            final TemplateMode templateMode,
            final ElementDefinition elementDefinition,
            final String elementCompleteName,
            final String trailingWhiteSpace,
            final boolean synthetic,
            final boolean unmatched) {
        super(templateMode, elementDefinition, elementCompleteName, synthetic);
        this.trailingWhiteSpace = trailingWhiteSpace;
        this.unmatched = unmatched;
    }


    CloseElementTag(
            final TemplateMode templateMode,
            final ElementDefinition elementDefinition,
            final String elementCompleteName,
            final String trailingWhiteSpace,
            final boolean synthetic,
            final boolean unmatched,
            final String templateName,
            final int line,
            final int col) {
        super(templateMode, elementDefinition, elementCompleteName, synthetic, templateName, line, col);
        this.trailingWhiteSpace = trailingWhiteSpace;
        this.unmatched = unmatched;
    }




    public boolean isUnmatched() {
        return this.unmatched;
    }


    // ------------
    // NO GETTER for trailingWhiteSpace, as it is an internal-only property with no interest outside the engine
    // ------------




    public void accept(final IModelVisitor visitor) {
        visitor.visit(this);
    }


    public void write(final Writer writer) throws IOException {
        if (this.synthetic) {
            // Nothing to be written... synthetic elements were not present at the original template!
            return;
        }
        // NOTE that being unmatched or not doesn't have an influence in how the tag is represented in output
        if (this.templateMode.isText()) {
            writer.write("[/");
            writer.write(this.elementCompleteName);
            if (this.trailingWhiteSpace != null) {
                writer.write(this.trailingWhiteSpace);
            }
            writer.write("]");
            return;
        }
        writer.write("</");
        writer.write(this.elementCompleteName);
        if (this.trailingWhiteSpace != null) {
            writer.write(this.trailingWhiteSpace);
        }
        writer.write('>');
    }




    // Meant to be called only from within the engine
    static CloseElementTag asEngineCloseElementTag(final ICloseElementTag closeElementTag) {<FILL_FUNCTION_BODY>}




    @Override
    public void beHandled(final ITemplateHandler handler) {
        handler.handleCloseElement(this);
    }


}


        if (closeElementTag instanceof CloseElementTag) {
            return (CloseElementTag) closeElementTag;
        }

        return new CloseElementTag(
                closeElementTag.getTemplateMode(), closeElementTag.getElementDefinition(), closeElementTag.getElementCompleteName(),
                null, closeElementTag.isSynthetic(), closeElementTag.isUnmatched(),
                closeElementTag.getTemplateName(), closeElementTag.getLine(), closeElementTag.getCol());

    
<methods>public final java.lang.String getElementCompleteName() ,public final org.thymeleaf.engine.ElementDefinition getElementDefinition() ,public final org.thymeleaf.templatemode.TemplateMode getTemplateMode() ,public final boolean isSynthetic() ,public final java.lang.String toString() <variables>final non-sealed java.lang.String elementCompleteName,final non-sealed org.thymeleaf.engine.ElementDefinition elementDefinition,final non-sealed boolean synthetic,final non-sealed org.thymeleaf.templatemode.TemplateMode templateMode