class HtmlBuilder extends HtmlAppendableBase<HtmlBuilder> {
    public HtmlBuilder() {
        super(0, LineAppendable.F_PASS_THROUGH);
    }

    public HtmlBuilder(int indentSize, int formatOptions) {
        super(indentSize, formatOptions);
    }

    @SuppressWarnings({ "UnusedReturnValue", "WeakerAccess" })
    public HtmlBuilder closeAllTags() {
        while (!getOpenTags().isEmpty()) {
            CharSequence tag = getOpenTags().peek();
            closeTag(tag);
        }
        return this;
    }

    public String toFinalizedString() {
        //if (!openTags.isEmpty()) throw new IllegalStateException("Unclosed tags on toHtml call: " + tagStack());
        closeAllTags();
        return toString(0, 0);
    }

    @SuppressWarnings("WeakerAccess")
    public HtmlBuilder attr(Object... convertible) {
        for (Object convert : convertible) {
            if (convert instanceof Attribute) {
                super.attr((Attribute) convert);
                super.withAttr();
            } else {
                //noinspection rawtypes
                HtmlStyler styler = getHtmlStyler(convert);
                // NOTE: show not simple name but name of container class if any
                if (styler == null) throw new IllegalStateException("Don't know how to style " + convert.getClass().getName().substring(getClass().getPackage().getName().length() + 1));

                //noinspection unchecked
                String value = styler.getStyle(styler.getStyleable(convert));
                if (value != null && !value.isEmpty()) {
                    Attribute style = AttributeImpl.of(Attribute.STYLE_ATTR, value);
                    super.attr(style);
                    super.withAttr();
                }
            }
        }
        return this;
    }

    @NotNull
    @Override
    public HtmlBuilder attr(@NotNull CharSequence name, @Nullable CharSequence value) {
        super.withAttr();
        return super.attr(name, value);
    }

    public HtmlBuilder style(CharSequence value) {
        super.withAttr();
        return super.attr(Attribute.STYLE_ATTR, value);
    }

    @NotNull
    @Override
    public HtmlBuilder attr(@NotNull Attribute... attribute) {
        super.withAttr();
        return super.attr(attribute);
    }

    @NotNull
    @Override
    public HtmlBuilder attr(@NotNull Attributes attributes) {
        super.withAttr();
        return super.attr(attributes);
    }

    public HtmlBuilder span() {
        return tag("span", false);
    }

    public HtmlBuilder span(CharSequence text) {
        tag("span", false);
        text(text);
        return closeSpan();
    }

    public HtmlBuilder span(boolean withLine, Runnable runnable) {
        return tag("span", false, withLine, runnable);
    }

    public HtmlBuilder span(Runnable runnable) {
        return span(false, runnable);
    }

    public HtmlBuilder spanLine(Runnable runnable) {
        return span(true, runnable);
    }

    public HtmlBuilder closeSpan() {
        return closeTag("span");
    }

    // statics
    final public static HashMap<Class, HtmlStyler> stylerMap = new HashMap<>();
    static {
        ColorStyler colorStyler = new ColorStyler();
        stylerMap.put(BackgroundColor.class, colorStyler);
        stylerMap.put(Color.class, colorStyler);
        //stylerMap.put(JBColor.class, colorStyler);
        stylerMap.put(java.awt.Color.class, colorStyler);

        FontStyler fontStyler = new FontStyler();
        stylerMap.put(Font.class, fontStyler);
        stylerMap.put(FontUIResource.class, fontStyler);

        stylerMap.put(FontStyle.class, new FontStyleStyler());
    }
    public static void addColorStylerClass(Class clazz) {
        HtmlStyler styler = stylerMap.get(Color.class);
        stylerMap.put(clazz, styler);
    }

    public static HtmlStyler getHtmlStyler(Object item) {<FILL_FUNCTION_BODY>}

    public static Attribute getAttribute(Object item) {
        HtmlStyler styler = getHtmlStyler(item);
        if (styler != null) {
            //noinspection unchecked
            String value = styler.getStyle(styler.getStyleable(item));
            if (value != null && !value.isEmpty()) {
                return AttributeImpl.of(Attribute.STYLE_ATTR, value);
            }
        }
        return null;
    }

    // mimic string builder for comfort
    public HtmlBuilder append(Object obj) { return super.append(String.valueOf(obj)); }

    public HtmlBuilder append(String str) { return super.append(str); }

    public HtmlBuilder append(StringBuffer sb) { return super.append(sb.toString()); }

    @NotNull
    public HtmlBuilder append(@NotNull CharSequence s) { return super.append(s); }

    @NotNull
    public HtmlBuilder append(@NotNull CharSequence s, int start, int end) { return super.append(s, start, end); }

    public HtmlBuilder append(char[] str) { return super.append(String.valueOf(str)); }

    public HtmlBuilder append(char[] str, int offset, int len) { return super.append(String.valueOf(str, offset, len)); }

    public HtmlBuilder append(boolean b) { return super.append(b ? "true" : "false"); }

    @NotNull
    public HtmlBuilder append(char c) { return super.append(c); }

    public HtmlBuilder append(int i) { return super.append(String.valueOf(i)); }

    public HtmlBuilder append(long l) { return super.append(String.valueOf(l)); }

    public HtmlBuilder append(float f) { return super.append(String.valueOf(f)); }

    public HtmlBuilder append(double d) { return super.append(String.valueOf(d)); }
}

        HtmlStyler styler = stylerMap.get(item.getClass());
        if (styler != null) return styler;

        // see if we have one that can handle this
        for (Class value : stylerMap.keySet()) {
            //noinspection unchecked
            if (value.isAssignableFrom(item.getClass())) {
                styler = stylerMap.get(value);
                break;
            }
        }

        if (styler != null) {
            stylerMap.put(item.getClass(), styler);
        }
        return styler;
    
<methods>public void <init>(com.vladsch.flexmark.util.sequence.LineAppendable, boolean) ,public void <init>(int, int) ,public void <init>(@Nullable Appendable, int, int) ,public @NotNull HtmlBuilder addIndentOnFirstEOL(@NotNull Runnable) ,public @NotNull HtmlBuilder addPrefix(@NotNull CharSequence) ,public @NotNull HtmlBuilder addPrefix(@NotNull CharSequence, boolean) ,public @NotNull HtmlBuilder append(char) ,public @NotNull HtmlBuilder append(@NotNull CharSequence) ,public @NotNull HtmlBuilder append(@NotNull CharSequence, int, int) ,public @NotNull HtmlBuilder append(@NotNull LineAppendable, int, int, boolean) ,public @NotNull HtmlBuilder append(char, int) ,public T appendTo(@NotNull T, boolean, int, int, int, int) throws java.io.IOException,public @NotNull HtmlBuilder attr(@NotNull CharSequence, @NotNull CharSequence) ,public transient @NotNull HtmlBuilder attr(@NotNull Attribute []) ,public @NotNull HtmlBuilder attr(@NotNull Attributes) ,public @NotNull HtmlBuilder blankLine() ,public @NotNull HtmlBuilder blankLine(int) ,public @NotNull HtmlBuilder blankLineIf(boolean) ,public @NotNull HtmlBuilder changeOptions(int, int) ,public @NotNull HtmlBuilder closePre() ,public @NotNull HtmlBuilder closePreFormatted() ,public @NotNull HtmlBuilder closeTag(@NotNull CharSequence) ,public int column() ,public boolean endsWithEOL() ,public int getAfterEolPrefixDelta() ,public com.vladsch.flexmark.util.html.Attributes getAttributes() ,public @NotNull BasedSequence getBeforeEolPrefix() ,public @NotNull ISequenceBuilder<?,?> getBuilder() ,public @NotNull HtmlAppendable getEmptyAppendable() ,public @NotNull BasedSequence getIndentPrefix() ,public @NotNull BasedSequence getLine(int) ,public int getLineCount() ,public int getLineCountWithPending() ,public @NotNull LineInfo getLineInfo(int) ,public @NotNull Iterable<BasedSequence> getLines(int, int, int, boolean) ,public @NotNull Iterable<LineInfo> getLinesInfo(int, int, int) ,public @NotNull Stack<String> getOpenTags() ,public @NotNull List<String> getOpenTagsAfterLast(@NotNull CharSequence) ,public @NotNull BitFieldSet<LineAppendable.Options> getOptionSet() ,public int getOptions() ,public int getPendingEOL() ,public int getPendingSpace() ,public @NotNull BasedSequence getPrefix() ,public int getTrailingBlankLines(int) ,public boolean inPre() ,public @NotNull HtmlBuilder indent() ,public void insertLine(int, @NotNull CharSequence, @NotNull CharSequence) ,public boolean isPendingSpace() ,public boolean isPreFormatted() ,public boolean isSuppressCloseTagLine() ,public boolean isSuppressOpenTagLine() ,public @NotNull Iterator<LineInfo> iterator() ,public @NotNull HtmlBuilder line() ,public @NotNull HtmlBuilder lineIf(boolean) ,public @NotNull HtmlBuilder lineOnFirstText(boolean) ,public @NotNull HtmlBuilder lineWithTrailingSpaces(int) ,public int offset() ,public int offsetWithPending() ,public @NotNull HtmlBuilder openPre() ,public @NotNull HtmlBuilder openPreFormatted(boolean) ,public @NotNull HtmlBuilder popOptions() ,public @NotNull HtmlBuilder popPrefix() ,public @NotNull HtmlBuilder popPrefix(boolean) ,public @NotNull HtmlBuilder pushOptions() ,public @NotNull HtmlBuilder pushPrefix() ,public @NotNull HtmlBuilder raw(@NotNull CharSequence) ,public @NotNull HtmlBuilder raw(@NotNull CharSequence, int) ,public @NotNull HtmlBuilder rawIndentedPre(@NotNull CharSequence) ,public @NotNull HtmlBuilder rawPre(@NotNull CharSequence) ,public @NotNull HtmlBuilder removeExtraBlankLines(int, int, int, int) ,public @NotNull HtmlBuilder removeIndentOnFirstEOL(@NotNull Runnable) ,public @NotNull HtmlBuilder removeLines(int, int) ,public @NotNull HtmlBuilder setAttributes(@NotNull Attributes) ,public @NotNull HtmlBuilder setIndentPrefix(@Nullable CharSequence) ,public void setLine(int, @NotNull CharSequence, @NotNull CharSequence) ,public @NotNull HtmlBuilder setOptions(int) ,public @NotNull HtmlBuilder setPrefix(@NotNull CharSequence) ,public @NotNull HtmlBuilder setPrefix(@Nullable CharSequence, boolean) ,public void setPrefixLength(int, int) ,public @NotNull HtmlBuilder setSuppressCloseTagLine(boolean) ,public void setSuppressOpenTagLine(boolean) ,public @NotNull HtmlBuilder tag(@NotNull CharSequence) ,public @NotNull HtmlBuilder tag(@NotNull CharSequence, @NotNull Runnable) ,public @NotNull HtmlBuilder tag(@NotNull CharSequence, boolean) ,public @NotNull HtmlBuilder tag(@NotNull CharSequence, boolean, boolean, @NotNull Runnable) ,public @NotNull HtmlBuilder tagIndent(@NotNull CharSequence, @NotNull Runnable) ,public @NotNull HtmlBuilder tagLine(@NotNull CharSequence) ,public @NotNull HtmlBuilder tagLine(@NotNull CharSequence, boolean) ,public @NotNull HtmlBuilder tagLine(@NotNull CharSequence, @NotNull Runnable) ,public @NotNull HtmlBuilder tagLineIndent(@NotNull CharSequence, @NotNull Runnable) ,public @NotNull HtmlBuilder tagVoid(@NotNull CharSequence) ,public @NotNull HtmlBuilder tagVoidLine(@NotNull CharSequence) ,public @NotNull HtmlBuilder text(@NotNull CharSequence) ,public @NotNull CharSequence toSequence(int, int, boolean) ,public @NotNull String toString() ,public @NotNull String toString(int, int, boolean) ,public @NotNull HtmlBuilder unIndent() ,public @NotNull HtmlBuilder unIndentNoEol() ,public @NotNull HtmlBuilder withAttr() ,public @NotNull HtmlBuilder withCondIndent() ,public @NotNull HtmlBuilder withCondLineOnChildText() <variables>private final non-sealed com.vladsch.flexmark.util.sequence.LineAppendable appendable,private @Nullable MutableAttributes currentAttributes,private boolean indentOnFirstEol,private boolean lineOnChildText,private final @NotNull Stack<String> openTags,private boolean suppressCloseTagLine,private boolean suppressOpenTagLine,private boolean withAttributes