package de.duehl.basics.text.html.generation;

/*
 * Copyright 2024 Christian Dühl. All rights reserved.
 *
 * This program is free software. You can redistribute it and/or
 * modify it under the same terms as perl:
 *
 * general:  http://dev.perl.org/licenses/
 * GPL:      http://dev.perl.org/licenses/gpl1.html
 * artistic: http://dev.perl.org/licenses/artistic.html
 */

import static org.junit.Assert.*;

import java.util.List;

import org.junit.Test;

import de.duehl.basics.collections.CollectionsHelper;
import de.duehl.basics.text.Text;

import static de.duehl.basics.text.html.generation.HtmlBuilder.*;

public class HtmlBuilderTest {

    @Test
    public void creation() {
        HtmlBuilder html = new HtmlBuilder();
        assertNotNull(html);
    }

    @Test
    public void appendSomethingClearAndGetEmptyResult() {
        HtmlBuilder html = new HtmlBuilder()
                .append("foo")
                .clear();

        String actual = html.toString();
        String expected = "";
        assertEquals(expected, actual);
    }

    @Test
    public void setIndentationLevelToZero() {
        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .increaseIndentationLevel()
                .setIndentationLevelToZero()
                .appendLn("foo bar baz");

        String actual = html.toString();
        String expected = "foo bar baz" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendLn() {
        HtmlBuilder html = new HtmlBuilder()
                .appendLn("foo bar baz");

        String actual = html.toString();
        String expected = "foo bar baz" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendLnEmpty() {
        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendLn("");

        String actual = html.toString();
        String expected = "" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendLnWithSpaces() {
        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendLn("foo bar baz");

        String actual = html.toString();
        String expected = "        foo bar baz" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendLink() {
        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendLink("http://www.heinsundpartner.de", "Heins + Partner GmbH")
                ;

        String actual = html.toString();
        String expected = "        "
                + "<a href=\"http://www.heinsundpartner.de\">Heins + Partner GmbH</a>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendLinkWithClass() {
        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendLinkWithClass("http://www.heinsundpartner.de", "Heins + Partner GmbH",
                        "Css-Klasse")
                ;

        String actual = html.toString();
        String expected = "        "
                + "<a class=\"Css-Klasse\" "
                + "href=\"http://www.heinsundpartner.de\">Heins + Partner GmbH</a>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendLinkWithClassAndScript() {
        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendLinkWithClassAndScript("http://www.heinsundpartner.de",
                        "Heins + Partner GmbH", "Css-Klasse", "ichWerdeAufgerufen()")
                ;

        String actual = html.toString();
        String expected = "        "
                + "<a class=\"Css-Klasse\" "
                + "href=\"http://www.heinsundpartner.de\""
                + " onclick=\"ichWerdeAufgerufen()\""
                + ">Heins + Partner GmbH</a>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendLinkWithoutUrlWithClassAndScript() {
        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendLinkWithoutUrlWithClassAndScript("Heins + Partner GmbH",
                        "Css-Klasse", "ichWerdeAufgerufen()")
                ;

        String actual = html.toString();
        String expected = "        "
                + "<a class=\"Css-Klasse\" "
                + "onclick=\"ichWerdeAufgerufen()\""
                + ">Heins + Partner GmbH</a>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendNumbers() {
        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendIndented(42)
                .append(" = ")
                .append(42)
                .appendLineBreak();

        String actual = html.toString();
        String expected = "        42 = 42" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHtml5HeadWithFormatCssInSameDirectory() {
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithFormatCssInSameDirectory("Sehr schöne Seite!")
                ;

        String actual = html.toString();
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Sehr schöne Seite!</title>" + n
                + "        <link href=\"format.css\" rel=\"stylesheet\" type=\"text/css\" />" + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHtml5HeadWithFormatCssInSameDirectoryUtf8() {
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithFormatCssInSameDirectoryUtf8("Sehr schöne Seite!")
                ;

        String actual = html.toString();
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Sehr schöne Seite!</title>" + n
                + "        <meta charset=\"utf-8\">" + n
                + "        <link href=\"format.css\" rel=\"stylesheet\" type=\"text/css\" />" + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHtml5HeadWithFormatCssInUpperDirectory() {
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithFormatCssInUpperDirectory("Sehr schöne Seite!")
                ;

        String actual = html.toString();
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Sehr schöne Seite!</title>" + n
                + "        <link href=\"../format.css\" rel=\"stylesheet\" type=\"text/css\" />" + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHtml5HeadWithFormatCssInUpperDirectoryUtf8() {
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithFormatCssInUpperDirectoryUtf8("Sehr schöne Seite!")
                ;

        String actual = html.toString();
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Sehr schöne Seite!</title>" + n
                + "        <meta charset=\"utf-8\">" + n
                + "        <link href=\"../format.css\" rel=\"stylesheet\" type=\"text/css\" />" + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendMultipleLinesString() {
        String linesAsString = ""
                + "public void foo() {\n"
                + "    System.out.println(\"foo\");\n"
                + "}";

        HtmlBuilder html = new HtmlBuilder()
                .appendMultipleLines(linesAsString)
                ;

        String actual = html.toString();
        String expected = ""
                + "public void foo() {" + n
                + "    System.out.println(\"foo\");" + n
                + "}" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendMultipleLinesStringIndented() {
        String linesAsString = ""
                + "public void foo() {\n"
                + "    System.out.println(\"foo\");\n"
                + "}";

        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendMultipleLines(linesAsString)
                ;

        String actual = html.toString();
        String expected = ""
                + "        public void foo() {" + n
                + "            System.out.println(\"foo\");" + n
                + "        }" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendMultipleLinesListOfString() {
        List<String> lines = CollectionsHelper.buildListFrom(
                "public void foo() {",
                "    System.out.println(\"foo\");",
                "}");

        HtmlBuilder html = new HtmlBuilder()
                .appendMultipleLines(lines)
                ;

        String actual = html.toString();
        String expected = ""
                + "public void foo() {" + n
                + "    System.out.println(\"foo\");" + n
                + "}" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendMultipleLinesEllipse() {
        HtmlBuilder html = new HtmlBuilder()
                .appendMultipleLines(
                        "public void foo() {",
                        "    System.out.println(\"foo\");",
                        "}");

        String actual = html.toString();
        String expected = ""
                + "public void foo() {" + n
                + "    System.out.println(\"foo\");" + n
                + "}" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHtml5HeadWithTitle() {
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithTitle("Toller Titel")
                ;

        String actual = html.toString();
        String expected = ""
                + "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Toller Titel</title>" + n
                + "    </head>" + n
                + "" + n
                + "" + n
                + "    <body>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHtml5HeadWithTitleAndCssFilename() {
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithTitleAndCssFilename("Toller Titel", "c:/temp/format.css")
                ;

        String actual = html.toString();
        String expected = ""
                + "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Toller Titel</title>" + n
                + "        <link href=\"c:/temp/format.css\" rel=\"stylesheet\" type=\"text/css\" />" + n
                + "    </head>" + n
                + "" + n
                + "" + n
                + "    <body>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHtml5HeadWithTitleCssFilenameAndJavaScript() {
        String script = ""
                + "<script>" + "\n"
                + "    var password1 = document.getElementById('field1');" + "\n"
                + "    var password2 = document.getElementById('field2');" + "\n"
                + "    var checkPasswordValidity = function () {" + "\n"
                + "        if (password1.value != password2.value) {" + "\n"
                + "            password2.setCustomValidity('Passwörter müssen übereinstimmen!');" + "\n"
                + "        } " + "\n"
                + "        else {" + "\n"
                + "            password2.setCustomValidity('');" + "\n"
                + "        }" + "\n"
                + "    };" + "\n"
                + "    password1.addEventListener('change', checkPasswordValidity);" + "\n"
                + "    password2.addEventListener('change', checkPasswordValidity);" + "\n"
                + "</script>";
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithTitleCssFilenameAndJavaScript("Toller Titel",
                        "c:/temp/format.css", script);

        String actual = html.toString();
        String expected = ""
                + "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Toller Titel</title>" + n
                + "        <link href=\"c:/temp/format.css\" rel=\"stylesheet\" type=\"text/css\" />" + n
                + "        <script>" + n
                + "            var password1 = document.getElementById('field1');" + n
                + "            var password2 = document.getElementById('field2');" + n
                + "            var checkPasswordValidity = function () {" + n
                + "                if (password1.value != password2.value) {" + n
                + "                    password2.setCustomValidity('Passwörter müssen "
                                                      + "übereinstimmen!');" + n
                + "                } " + n
                + "                else {" + n
                + "                    password2.setCustomValidity('');" + n
                + "                }" + n
                + "            };" + n
                + "            password1.addEventListener('change', checkPasswordValidity);" + n
                + "            password2.addEventListener('change', checkPasswordValidity);" + n
                + "        </script>" + n
                + "    </head>" + n
                + "" + n
                + "" + n
                + "    <body>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHtml5HeadWithTitleMultipleCssFilenameAndJavaScript() {
        String script = ""
                + "<script>" + "\n"
                + "    var password1 = document.getElementById('field1');" + "\n"
                + "    var password2 = document.getElementById('field2');" + "\n"
                + "    var checkPasswordValidity = function () {" + "\n"
                + "        if (password1.value != password2.value) {" + "\n"
                + "            password2.setCustomValidity('Passwörter müssen übereinstimmen!');" + "\n"
                + "        } " + "\n"
                + "        else {" + "\n"
                + "            password2.setCustomValidity('');" + "\n"
                + "        }" + "\n"
                + "    };" + "\n"
                + "    password1.addEventListener('change', checkPasswordValidity);" + "\n"
                + "    password2.addEventListener('change', checkPasswordValidity);" + "\n"
                + "</script>";
        List<String> cssFiles = CollectionsHelper.buildListFrom("c:/temp/format.css",
                "c:/temp/formatTable.css", "c:/temp/formatFoot.css");
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithTitleMultipleCssFilenameAndJavaScript("Toller Titel", cssFiles,
                        script);

        String actual = html.toString();
        String expected = ""
                + "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Toller Titel</title>" + n
                + "        <link href=\"c:/temp/format.css\" rel=\"stylesheet\" "
                                                               + "type=\"text/css\" />" + n
                + "        <link href=\"c:/temp/formatTable.css\" rel=\"stylesheet\" "
                                                               + "type=\"text/css\" />" + n
                + "        <link href=\"c:/temp/formatFoot.css\" rel=\"stylesheet\" "
                                                               + "type=\"text/css\" />" + n
                + "        <script>" + n
                + "            var password1 = document.getElementById('field1');" + n
                + "            var password2 = document.getElementById('field2');" + n
                + "            var checkPasswordValidity = function () {" + n
                + "                if (password1.value != password2.value) {" + n
                + "                    password2.setCustomValidity('Passwörter müssen "
                                                      + "übereinstimmen!');" + n
                + "                } " + n
                + "                else {" + n
                + "                    password2.setCustomValidity('');" + n
                + "                }" + n
                + "            };" + n
                + "            password1.addEventListener('change', checkPasswordValidity);" + n
                + "            password2.addEventListener('change', checkPasswordValidity);" + n
                + "        </script>" + n
                + "    </head>" + n
                + "" + n
                + "" + n
                + "    <body>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHtml5HeadWithTitleMultipleCssFilenameAndAdditionalLines() {
        List<String> additionalLines = CollectionsHelper.buildListFrom(
                "<script>",
                "    var password1 = document.getElementById('field1');",
                "    var password2 = document.getElementById('field2');",
                "    var checkPasswordValidity = function () {",
                "        if (password1.value != password2.value) {",
                "            password2.setCustomValidity('Passwörter müssen übereinstimmen!');",
                "        } ",
                "        else {",
                "            password2.setCustomValidity('');",
                "        }",
                "    };",
                "    password1.addEventListener('change', checkPasswordValidity);",
                "    password2.addEventListener('change', checkPasswordValidity);",
                "</script>");
        List<String> cssFiles = CollectionsHelper.buildListFrom("c:/temp/format.css",
                "c:/temp/formatTable.css", "c:/temp/formatFoot.css");
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithTitleMultipleCssFilenameAndAdditionalLines("Toller Titel",
                        cssFiles,
                        additionalLines);

        String actual = html.toString();
        String expected = ""
                + "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Toller Titel</title>" + n
                + "        <link href=\"c:/temp/format.css\" rel=\"stylesheet\" "
                                                               + "type=\"text/css\" />" + n
                + "        <link href=\"c:/temp/formatTable.css\" rel=\"stylesheet\" "
                                                               + "type=\"text/css\" />" + n
                + "        <link href=\"c:/temp/formatFoot.css\" rel=\"stylesheet\" "
                                                               + "type=\"text/css\" />" + n
                + "        <script>" + n
                + "            var password1 = document.getElementById('field1');" + n
                + "            var password2 = document.getElementById('field2');" + n
                + "            var checkPasswordValidity = function () {" + n
                + "                if (password1.value != password2.value) {" + n
                + "                    password2.setCustomValidity('Passwörter müssen "
                                                      + "übereinstimmen!');" + n
                + "                } " + n
                + "                else {" + n
                + "                    password2.setCustomValidity('');" + n
                + "                }" + n
                + "            };" + n
                + "            password1.addEventListener('change', checkPasswordValidity);" + n
                + "            password2.addEventListener('change', checkPasswordValidity);" + n
                + "        </script>" + n
                + "    </head>" + n
                + "" + n
                + "" + n
                + "    <body>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHtml5HeadWithTitleMultipleCssFilenameAndAdditionalLinesUtf8() {
        List<String> additionalLines = CollectionsHelper.buildListFrom(
                "<script>",
                "    var password1 = document.getElementById('field1');",
                "    var password2 = document.getElementById('field2');",
                "    var checkPasswordValidity = function () {",
                "        if (password1.value != password2.value) {",
                "            password2.setCustomValidity('Passwörter müssen übereinstimmen!');",
                "        } ",
                "        else {",
                "            password2.setCustomValidity('');",
                "        }",
                "    };",
                "    password1.addEventListener('change', checkPasswordValidity);",
                "    password2.addEventListener('change', checkPasswordValidity);",
                "</script>");
        List<String> cssFiles = CollectionsHelper.buildListFrom("c:/temp/format.css",
                "c:/temp/formatTable.css", "c:/temp/formatFoot.css");
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithTitleMultipleCssFilenameAndAdditionalLinesUtf8("Toller Titel",
                        cssFiles,
                        additionalLines);

        String actual = html.toString();
        String expected = ""
                + "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Toller Titel</title>" + n
                + "        <meta charset=\"utf-8\">" + n
                + "        <link href=\"c:/temp/format.css\" rel=\"stylesheet\" "
                                                               + "type=\"text/css\" />" + n
                + "        <link href=\"c:/temp/formatTable.css\" rel=\"stylesheet\" "
                                                               + "type=\"text/css\" />" + n
                + "        <link href=\"c:/temp/formatFoot.css\" rel=\"stylesheet\" "
                                                               + "type=\"text/css\" />" + n
                + "        <script>" + n
                + "            var password1 = document.getElementById('field1');" + n
                + "            var password2 = document.getElementById('field2');" + n
                + "            var checkPasswordValidity = function () {" + n
                + "                if (password1.value != password2.value) {" + n
                + "                    password2.setCustomValidity('Passwörter müssen "
                                                      + "übereinstimmen!');" + n
                + "                } " + n
                + "                else {" + n
                + "                    password2.setCustomValidity('');" + n
                + "                }" + n
                + "            };" + n
                + "            password1.addEventListener('change', checkPasswordValidity);" + n
                + "            password2.addEventListener('change', checkPasswordValidity);" + n
                + "        </script>" + n
                + "    </head>" + n
                + "" + n
                + "" + n
                + "    <body>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHtml5HeadWithTitleJavaScriptAndMultipleCssFilenames() {
        String script = ""
                + "<script>" + "\n"
                + "    var password1 = document.getElementById('field1');" + "\n"
                + "    var password2 = document.getElementById('field2');" + "\n"
                + "    var checkPasswordValidity = function () {" + "\n"
                + "        if (password1.value != password2.value) {" + "\n"
                + "            password2.setCustomValidity('Passwörter müssen übereinstimmen!');" + "\n"
                + "        } " + "\n"
                + "        else {" + "\n"
                + "            password2.setCustomValidity('');" + "\n"
                + "        }" + "\n"
                + "    };" + "\n"
                + "    password1.addEventListener('change', checkPasswordValidity);" + "\n"
                + "    password2.addEventListener('change', checkPasswordValidity);" + "\n"
                + "</script>";
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithTitleJavaScriptAndMultipleCssFilenames("Toller Titel", script,
                        "c:/temp/format.css", "c:/temp/formatTable.css", "c:/temp/formatFoot.css");

        String actual = html.toString();
        String expected = ""
                + "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Toller Titel</title>" + n
                + "        <link href=\"c:/temp/format.css\" rel=\"stylesheet\" "
                                                            + "type=\"text/css\" />" + n
                + "        <link href=\"c:/temp/formatTable.css\" rel=\"stylesheet\" "
                                                            + "type=\"text/css\" />" + n
                + "        <link href=\"c:/temp/formatFoot.css\" rel=\"stylesheet\" "
                                                            + "type=\"text/css\" />" + n
                + "        <script>" + n
                + "            var password1 = document.getElementById('field1');" + n
                + "            var password2 = document.getElementById('field2');" + n
                + "            var checkPasswordValidity = function () {" + n
                + "                if (password1.value != password2.value) {" + n
                + "                    password2.setCustomValidity('Passwörter müssen "
                                                      + "übereinstimmen!');" + n
                + "                } " + n
                + "                else {" + n
                + "                    password2.setCustomValidity('');" + n
                + "                }" + n
                + "            };" + n
                + "            password1.addEventListener('change', checkPasswordValidity);" + n
                + "            password2.addEventListener('change', checkPasswordValidity);" + n
                + "        </script>" + n
                + "    </head>" + n
                + "" + n
                + "" + n
                + "    <body>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void divs() {
        HtmlBuilder html = new HtmlBuilder()
                .appendOpeningDiv()
                .appendP("Absatz 1")
                .appendClosingDiv()
                .appendOpeningDivWithClass("Css-Klasse")
                .appendP("Absatz 2")
                .appendClosingDiv()
                .appendOpeningDivWithId("ID")
                .appendP("Absatz 3")
                .appendClosingDiv()
                .appendOpeningDivWithIdAndClass("ID", "Css-Klasse")
                .appendP("Absatz 4")
                .appendClosingDiv()
                ;

        String actual = html.toString();
        String expected = ""
                + "<div>" + n
                + "    <p>Absatz 1</p>" + n
                + "</div>" + n
                + "<div class=\"Css-Klasse\">" + n
                + "    <p>Absatz 2</p>" + n
                + "</div>" + n
                + "<div id=\"ID\">" + n
                + "    <p>Absatz 3</p>" + n
                + "</div>" + n
                + "<div id=\"ID\" class=\"Css-Klasse\">" + n
                + "    <p>Absatz 4</p>" + n
                + "</div>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendOpeningOl() {
        HtmlBuilder html = new HtmlBuilder()
                .increaseIndentationLevel()
                .appendOpeningOl()
                .appendLi("foo")
                .appendLi("bar")
                .appendLi("baz")
                .appendClosingOl()
                ;

        String actual = html.toString();
        String expected = ""
                + "    <ol>" + n
                + "        <li>foo</li>" + n
                + "        <li>bar</li>" + n
                + "        <li>baz</li>" + n
                + "    </ol>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendOpeningOlStart() {
        HtmlBuilder html = new HtmlBuilder()
                .appendOpeningOlStart(15)
                .appendLi("foo")
                .appendLi("bar")
                .appendLi("baz")
                .appendClosingOl()
                ;

        String actual = html.toString();
        String expected = ""
                + "<ol start=\"15\">" + n
                + "    <li>foo</li>" + n
                + "    <li>bar</li>" + n
                + "    <li>baz</li>" + n
                + "</ol>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendOpeningUl() {
        HtmlBuilder html = new HtmlBuilder()
                .increaseIndentationLevel()
                .appendOpeningUl()
                .appendLi("foo")
                .appendLi("bar")
                .appendLi("baz")
                .appendClosingUl();

        String actual = html.toString();
        String expected = ""
                + "    <ul>" + n
                + "        <li>foo</li>" + n
                + "        <li>bar</li>" + n
                + "        <li>baz</li>" + n
                + "    </ul>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendOpeningUlWithLongerLi() {
        HtmlBuilder html = new HtmlBuilder()
                .increaseIndentationLevel()
                .appendOpeningUl()
                .appendLi("foo")
                .appendLi("bar")
                .appendLi("baz")
                .appendOpeningLi()
                .appendLn("Außerdem:")
                .appendOpeningOl()
                .appendLi("foo 1")
                .appendLi("bar 2")
                .appendLi("baz 3")
                .appendClosingOl()
                .appendClosingLi()
                .appendClosingUl();

        String actual = html.toString();
        String expected = ""
                + "    <ul>" + n
                + "        <li>foo</li>" + n
                + "        <li>bar</li>" + n
                + "        <li>baz</li>" + n
                + "        <li>" + n
                + "            Außerdem:" + n
                + "            <ol>" + n
                + "                <li>foo 1</li>" + n
                + "                <li>bar 2</li>" + n
                + "                <li>baz 3</li>" + n
                + "            </ol>" + n
                + "        </li>" + n
                + "    </ul>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendOpeningUlWithNumberLis() {
        HtmlBuilder html = new HtmlBuilder()
                .increaseIndentationLevel()
                .appendOpeningUl()
                .appendLi(106541278)
                .appendLi(23231)
                .appendLi(262622444)
                .appendClosingUl();

        String actual = html.toString();
        String expected = ""
                + "    <ul>" + n
                + "        <li>106541278</li>" + n
                + "        <li>23231</li>" + n
                + "        <li>262622444</li>" + n
                + "    </ul>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void tableWithBorderWidth() {
        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendOpeningTableWithBorderWidth(5)
                .appendOpeningTr()
                .appendTh("Zeug")
                .appendClosingTr()
                .appendOpeningTr()
                .appendTd("foo")
                .appendClosingTr()
                .appendOpeningTr()
                .appendTd("foo 2")
                .appendClosingTr()
                .appendClosingTable();

        String actual = html.toString();
        String expected = ""
                + "        <table border=\"5\">" + n
                + "            <tr>" + n
                + "                <th>Zeug</th>" + n
                + "            </tr>" + n
                + "            <tr>" + n
                + "                <td>foo</td>" + n
                + "            </tr>" + n
                + "            <tr>" + n
                + "                <td>foo 2</td>" + n
                + "            </tr>" + n
                + "        </table>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendOpeningTableWithClass() {
        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendOpeningTableWithClass("CSS-Klasse-TABLE")
                .appendOpeningTr()
                .appendTh("Zeug")
                .appendClosingTr()
                .appendOpeningTr()
                .appendTd("foo")
                .appendClosingTr()
                .appendOpeningTrWithClass("CSS-Klasse-TR")
                .appendTd("bar")
                .appendClosingTr()
                .appendClosingTable()
                ;

        String actual = html.toString();
        String expected = ""
                + "        <table class=\"CSS-Klasse-TABLE\">" + n
                + "            <tr>" + n
                + "                <th>Zeug</th>" + n
                + "            </tr>" + n
                + "            <tr>" + n
                + "                <td>foo</td>" + n
                + "            </tr>" + n
                + "            <tr class=\"CSS-Klasse-TR\">" + n
                + "                <td>bar</td>" + n
                + "            </tr>" + n
                + "        </table>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendOpeningTableWithId() {
        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendOpeningTableWithId("CSS-ID")
                .appendOpeningTr()
                .appendTh("Zeug")
                .appendClosingTr()
                .appendOpeningTr()
                .appendTd("foo")
                .appendClosingTr()
                .appendOpeningTr()
                .appendTd("bar")
                .appendClosingTr()
                .appendClosingTable()
                ;

        String actual = html.toString();
        String expected = ""
                + "        <table id=\"CSS-ID\">" + n
                + "            <tr>" + n
                + "                <th>Zeug</th>" + n
                + "            </tr>" + n
                + "            <tr>" + n
                + "                <td>foo</td>" + n
                + "            </tr>" + n
                + "            <tr>" + n
                + "                <td>bar</td>" + n
                + "            </tr>" + n
                + "        </table>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void normalTable() {
        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendOpeningTable()
                .appendOpeningTr()
                .appendTh("Zeug")
                .appendLeftAlignedTh("Anderes Zeug")
                .appendRightAlignedTh("Noch mehr Zeug")
                .appendLeftAlignedThWithClass("Zeug mit Klasse", "CSS-KLASSE")
                .appendClosingTr()
                .appendOpeningTr()
                .appendTd("foo")
                .appendTd("bar")
                .appendRightAlignedTd("baz")
                .appendTd("blubb", "CSS-KLASSE")
                .appendClosingTr()
                .appendOpeningTr()
                .appendTd("foo 2")
                .appendTd("bar 2")
                .appendTd("baz 2")
                .appendTd("blubb 2")
                .appendClosingTr()
                .appendClosingTable()
                ;

        String actual = html.toString();
        String expected = ""
                + "        <table>" + n
                + "            <tr>" + n
                + "                <th>Zeug</th>" + n
                + "                <th align=\"left\">Anderes Zeug</th>" + n
                + "                <th align=\"right\">Noch mehr Zeug</th>" + n
                + "                <th class=\"CSS-KLASSE\" align=\"left\">Zeug mit Klasse</th>" + n
                + "            </tr>" + n
                + "            <tr>" + n
                + "                <td>foo</td>" + n
                + "                <td>bar</td>" + n
                + "                <td align=\"right\">baz</td>" + n
                + "                <td class=\"CSS-KLASSE\">blubb</td>" + n
                + "            </tr>" + n
                + "            <tr>" + n
                + "                <td>foo 2</td>" + n
                + "                <td>bar 2</td>" + n
                + "                <td>baz 2</td>" + n
                + "                <td>blubb 2</td>" + n
                + "            </tr>" + n
                + "        </table>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void tableWithTheadTbodyAndTfoot() {
        HtmlBuilder html = new HtmlBuilder()
            .appendOpeningTable()
            .appendOpeningThead()
            .appendOpeningTr()
            .appendTh("Zeug")
            .appendLeftAlignedTh("Anderes Zeug")
            .appendRightAlignedTh("Noch mehr Zeug")
            .appendLeftAlignedThWithClass("Zeug mit Klasse", "CSS-KLASSE")
            .appendClosingTr()
            .appendClosingThead()
            .appendOpeningTbody()
            .appendOpeningTr()
            .appendTd("foo")
            .appendTd("bar")
            .appendRightAlignedTd("baz")
            .appendTd("blubb", "CSS-KLASSE")
            .appendClosingTr()
            .appendOpeningTr()
            .appendTd("foo 2")
            .appendTd("bar 2")
            .appendTd("baz 2")
            .appendTd("blubb 2")
            .appendClosingTr()
            .appendClosingTbody()
            .appendOpeningTfoot()
            .appendP("Blubber")
            .appendClosingTfoot()
            .appendClosingTable();

        String actual = html.toString();
        String expected = ""
                + "<table>" + n
                + "    <thead>" + n
                + "        <tr>" + n
                + "            <th>Zeug</th>" + n
                + "            <th align=\"left\">Anderes Zeug</th>" + n
                + "            <th align=\"right\">Noch mehr Zeug</th>" + n
                + "            <th class=\"CSS-KLASSE\" align=\"left\">Zeug mit Klasse</th>" + n
                + "        </tr>" + n
                + "    </thead>" + n
                + "    <tbody>" + n
                + "        <tr>" + n
                + "            <td>foo</td>" + n
                + "            <td>bar</td>" + n
                + "            <td align=\"right\">baz</td>" + n
                + "            <td class=\"CSS-KLASSE\">blubb</td>" + n
                + "        </tr>" + n
                + "        <tr>" + n
                + "            <td>foo 2</td>" + n
                + "            <td>bar 2</td>" + n
                + "            <td>baz 2</td>" + n
                + "            <td>blubb 2</td>" + n
                + "        </tr>" + n
                + "    </tbody>" + n
                + "    <tfoot>" + n
                + "        <p>Blubber</p>" + n
                + "    </tfoot>" + n
                + "</table>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void tableWithTheadTbodyWithCssStyleAndTfoot() {
        HtmlBuilder html = new HtmlBuilder()
                .appendOpeningTable()
                .appendOpeningThead()
                .appendOpeningTr()
                .appendTh("Zeug", "CSS-KLASSE")
                .appendLeftAlignedTh("Anderes Zeug")
                .appendRightAlignedTh("Noch mehr Zeug")
                .appendLeftAlignedThWithClass("Zeug mit Klasse", "CSS-KLASSE")
                .appendClosingTr()
                .appendClosingThead()
                .appendOpeningTbody()
                .appendOpeningTr()
                .appendTd("foo")
                .appendTd("bar")
                .appendRightAlignedTd("baz")
                .appendTd("blubb", "CSS-KLASSE")
                .appendClosingTr()
                .appendOpeningTr()
                .appendTd(1)
                .appendTd(2)
                .appendTd(3)
                .appendTd(4)
                .appendClosingTr()
                .appendClosingTbody()
                .appendOpeningTfoot()
                .appendP("Blubber")
                .appendClosingTfoot()
                .appendClosingTable()
                ;

        String actual = html.toString();
        String expected = ""
                + "<table>" + n
                + "    <thead>" + n
                + "        <tr>" + n
                + "            <th class=\"CSS-KLASSE\">Zeug</th>" + n
                + "            <th align=\"left\">Anderes Zeug</th>" + n
                + "            <th align=\"right\">Noch mehr Zeug</th>" + n
                + "            <th class=\"CSS-KLASSE\" align=\"left\">Zeug mit Klasse</th>" + n
                + "        </tr>" + n
                + "    </thead>" + n
                + "    <tbody>" + n
                + "        <tr>" + n
                + "            <td>foo</td>" + n
                + "            <td>bar</td>" + n
                + "            <td align=\"right\">baz</td>" + n
                + "            <td class=\"CSS-KLASSE\">blubb</td>" + n
                + "        </tr>" + n
                + "        <tr>" + n
                + "            <td>1</td>" + n
                + "            <td>2</td>" + n
                + "            <td>3</td>" + n
                + "            <td>4</td>" + n
                + "        </tr>" + n
                + "    </tbody>" + n
                + "    <tfoot>" + n
                + "        <p>Blubber</p>" + n
                + "    </tfoot>" + n
                + "</table>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHeaderRowAndAppendDataRow() {
        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendOpeningTable()
                .appendHeaderRow("Zeug", "anderes Zeug", "noch mehr Zeug")
                .appendDataRow("foo", "bar", "baz")
                .appendDataRow("eins", "zwei", "drei")
                .appendDataRow("Apfel", "Birne", "Clementine")
                .appendClosingTable();

        String actual = html.toString();
        String expected = ""
                + "        <table>" + n
                + "            <tr>" + n
                + "                <th>Zeug</th>" + n
                + "                <th>anderes Zeug</th>" + n
                + "                <th>noch mehr Zeug</th>" + n
                + "            </tr>" + n
                + "            <tr>" + n
                + "                <td>foo</td>" + n
                + "                <td>bar</td>" + n
                + "                <td>baz</td>" + n
                + "            </tr>" + n
                + "            <tr>" + n
                + "                <td>eins</td>" + n
                + "                <td>zwei</td>" + n
                + "                <td>drei</td>" + n
                + "            </tr>" + n
                + "            <tr>" + n
                + "                <td>Apfel</td>" + n
                + "                <td>Birne</td>" + n
                + "                <td>Clementine</td>" + n
                + "            </tr>" + n
                + "        </table>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendLeftAlignedHeaderRowAndAppendDataRow() {
        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendOpeningTable()
                .appendLeftAlignedHeaderRow("Zeug", "anderes Zeug", "noch mehr Zeug")
                .appendDataRow("foo", "bar", "baz")
                .appendDataRow("eins", "zwei", "drei")
                .appendDataRow("Apfel", "Birne", "Clementine")
                .appendClosingTable()
                ;

        String actual = html.toString();
        String expected = ""
                + "        <table>" + n
                + "            <tr>" + n
                + "                <th align=\"left\">Zeug</th>" + n
                + "                <th align=\"left\">anderes Zeug</th>" + n
                + "                <th align=\"left\">noch mehr Zeug</th>" + n
                + "            </tr>" + n
                + "            <tr>" + n
                + "                <td>foo</td>" + n
                + "                <td>bar</td>" + n
                + "                <td>baz</td>" + n
                + "            </tr>" + n
                + "            <tr>" + n
                + "                <td>eins</td>" + n
                + "                <td>zwei</td>" + n
                + "                <td>drei</td>" + n
                + "            </tr>" + n
                + "            <tr>" + n
                + "                <td>Apfel</td>" + n
                + "                <td>Birne</td>" + n
                + "                <td>Clementine</td>" + n
                + "            </tr>" + n
                + "        </table>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void withoutContent() {
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithTitle("Ein tolles HTML-Dokument")
                .appendH1("Überschrift 1")
                .appendH2("Unterpunkt 1.1")
                .appendH2("Unterpunkt 1.2")
                .appendH1("Überschrift 2")
                .appendH2("Unterpunkt 2.1")
                .appendH3("Unterpunkt 2.1.1")
                .appendH1("Überschrift 3")
                .appendH2("Unterpunkt 3.1")
                .appendH3("Unterpunkt 3.1.1")
                .appendH4("Unterpunkt 3.1.1.1")
                .appendH3("Unterpunkt 3.1.2")
                .appendH4("Unterpunkt 3.1.2.1")
                .appendH5("Unterpunkt 3.1.2.1.1")
                .appendH6("Unterpunkt 3.1.2.1.1.1")
                .appendFoot();

        String actual = html.toString();
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Ein tolles HTML-Dokument</title>" + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                + "        <h1 id=\"id1\">Überschrift 1</h1>" + n + n
                + "        <h2 id=\"id1_1\">Unterpunkt 1.1</h2>" + n + n
                + "        <h2 id=\"id1_2\">Unterpunkt 1.2</h2>" + n
                + "        <a href=\"#top\">Zum Seitenanfang</a>" + n + n
                + "        <h1 id=\"id2\">Überschrift 2</h1>" + n + n
                + "        <h2 id=\"id2_3\">Unterpunkt 2.1</h2>" + n + n
                + "        <h3 id=\"id2_3_1\">Unterpunkt 2.1.1</h3>" + n
                + "        <a href=\"#top\">Zum Seitenanfang</a>" + n + n
                + "        <h1 id=\"id3\">Überschrift 3</h1>" + n + n
                + "        <h2 id=\"id3_4\">Unterpunkt 3.1</h2>" + n + n
                + "        <h3 id=\"id3_4_2\">Unterpunkt 3.1.1</h3>" + n + n
                + "        <h4 id=\"id3_4_2_1\">Unterpunkt 3.1.1.1</h4>" + n + n
                + "        <h3 id=\"id3_4_3\">Unterpunkt 3.1.2</h3>" + n + n
                + "        <h4 id=\"id3_4_3_2\">Unterpunkt 3.1.2.1</h4>" + n + n
                + "        <h5 id=\"id3_4_3_2_1\">Unterpunkt 3.1.2.1.1</h5>" + n + n
                + "        <h6 id=\"id3_4_3_2_1_1\">Unterpunkt 3.1.2.1.1.1</h6>" + n + n
                //+ "    <a href=\"#top\">Zum Seitenanfang</a>" + n
                + "    </body>" + n
                + "</html>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void withoutContentAndToplinks() {
        HtmlBuilder html = new HtmlBuilder()
                .hideTopLinks()
                .appendHtml5HeadWithTitle("Ein tolles HTML-Dokument")
                .appendH1("Überschrift 1")
                .appendH2("Unterpunkt 1.1")
                .appendH2("Unterpunkt 1.2")
                .appendH1("Überschrift 2")
                .appendH2("Unterpunkt 2.1")
                .appendH3("Unterpunkt 2.1.1")
                .appendH1("Überschrift 3")
                .appendH2("Unterpunkt 3.1")
                .appendH3("Unterpunkt 3.1.1")
                .appendH4("Unterpunkt 3.1.1.1")
                .appendH3("Unterpunkt 3.1.2")
                .appendH4("Unterpunkt 3.1.2.1")
                .appendH5("Unterpunkt 3.1.2.1.1")
                .appendH6("Unterpunkt 3.1.2.1.1.1")
                .appendFoot();

        String actual = html.toString();
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Ein tolles HTML-Dokument</title>" + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                + "        <h1 id=\"id1\">Überschrift 1</h1>" + n + n
                + "        <h2 id=\"id1_1\">Unterpunkt 1.1</h2>" + n + n
                + "        <h2 id=\"id1_2\">Unterpunkt 1.2</h2>" + n + n
                + "        <h1 id=\"id2\">Überschrift 2</h1>" + n + n
                + "        <h2 id=\"id2_3\">Unterpunkt 2.1</h2>" + n + n
                + "        <h3 id=\"id2_3_1\">Unterpunkt 2.1.1</h3>" + n + n
                + "        <h1 id=\"id3\">Überschrift 3</h1>" + n + n
                + "        <h2 id=\"id3_4\">Unterpunkt 3.1</h2>" + n + n
                + "        <h3 id=\"id3_4_2\">Unterpunkt 3.1.1</h3>" + n + n
                + "        <h4 id=\"id3_4_2_1\">Unterpunkt 3.1.1.1</h4>" + n + n
                + "        <h3 id=\"id3_4_3\">Unterpunkt 3.1.2</h3>" + n + n
                + "        <h4 id=\"id3_4_3_2\">Unterpunkt 3.1.2.1</h4>" + n + n
                + "        <h5 id=\"id3_4_3_2_1\">Unterpunkt 3.1.2.1.1</h5>" + n + n
                + "        <h6 id=\"id3_4_3_2_1_1\">Unterpunkt 3.1.2.1.1.1</h6>" + n + n
                + "    </body>" + n
                + "</html>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void content() {
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithTitle("Ein tolles HTML-Dokument")
                .appendH1("Überschrift 1")
                .appendH2("Unterpunkt 1.1")
                .appendH2("Unterpunkt 1.2")
                .appendH1("Überschrift 2")
                .appendH2("Unterpunkt 2.1")
                .appendH3("Unterpunkt 2.1.1")
                .appendH1("Überschrift 3")
                .appendH2("Unterpunkt 3.1")
                .appendH3("Unterpunkt 3.1.1")
                .appendH4("Unterpunkt 3.1.1.1")
                .appendH3("Unterpunkt 3.1.2")
                .appendH4("Unterpunkt 3.1.2.1")
                .appendH5("Unterpunkt 3.1.2.1.1")
                .appendH6("Unterpunkt 3.1.2.1.1.1")
                .appendFoot()
                .insertContent()
                ;

        String actual = html.toString();
        String s = "&nbsp;&nbsp;&nbsp;&nbsp;";
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Ein tolles HTML-Dokument</title>" + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                + "        <h1>Inhaltsverzeichnis</h1>" + n
                + "        <a href=\"#id1\">Überschrift 1</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id1_1\">Unterpunkt 1.1</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id1_2\">Unterpunkt 1.2</a>" + n
                + "        <br />" + n
                + "        <a href=\"#id2\">Überschrift 2</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id2_3\">Unterpunkt 2.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + "<a href=\"#id2_3_1\">Unterpunkt 2.1.1</a>" + n
                + "        <br />" + n
                + "        <a href=\"#id3\">Überschrift 3</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id3_4\">Unterpunkt 3.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + "<a href=\"#id3_4_2\">Unterpunkt 3.1.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + "<a href=\"#id3_4_2_1\">Unterpunkt 3.1.1.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + "<a href=\"#id3_4_3\">Unterpunkt 3.1.2</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + "<a href=\"#id3_4_3_2\">Unterpunkt 3.1.2.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + s + "<a href=\"#id3_4_3_2_1\">Unterpunkt 3.1.2.1.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + s + s + "<a href=\"#id3_4_3_2_1_1\">"
                        + "Unterpunkt 3.1.2.1.1.1</a>" + n
                + "        <br />" + n + n
                + "        <h1 id=\"id1\">Überschrift 1</h1>" + n + n
                + "        <h2 id=\"id1_1\">Unterpunkt 1.1</h2>" + n + n
                + "        <h2 id=\"id1_2\">Unterpunkt 1.2</h2>" + n
                + "        <a href=\"#top\">Zum Seitenanfang</a>" + n + n
                + "        <h1 id=\"id2\">Überschrift 2</h1>" + n + n
                + "        <h2 id=\"id2_3\">Unterpunkt 2.1</h2>" + n + n
                + "        <h3 id=\"id2_3_1\">Unterpunkt 2.1.1</h3>" + n
                + "        <a href=\"#top\">Zum Seitenanfang</a>" + n + n
                + "        <h1 id=\"id3\">Überschrift 3</h1>" + n + n
                + "        <h2 id=\"id3_4\">Unterpunkt 3.1</h2>" + n + n
                + "        <h3 id=\"id3_4_2\">Unterpunkt 3.1.1</h3>" + n + n
                + "        <h4 id=\"id3_4_2_1\">Unterpunkt 3.1.1.1</h4>" + n + n
                + "        <h3 id=\"id3_4_3\">Unterpunkt 3.1.2</h3>" + n + n
                + "        <h4 id=\"id3_4_3_2\">Unterpunkt 3.1.2.1</h4>" + n + n
                + "        <h5 id=\"id3_4_3_2_1\">Unterpunkt 3.1.2.1.1</h5>" + n + n
                + "        <h6 id=\"id3_4_3_2_1_1\">Unterpunkt 3.1.2.1.1.1</h6>" + n + n
                + "    </body>" + n
                + "</html>" + n;
        assertEquals(expected, actual);
    }

    @Test (expected = RuntimeException.class)
    public void contentWithoutBodyTagException() {
        new HtmlBuilder()
                .appendH1("Überschrift 1")
                .appendH2("Unterpunkt 1.1")
                .appendH2("Unterpunkt 1.2")
                .appendH1("Überschrift 2")
                .appendH2("Unterpunkt 2.1")
                .appendH3("Unterpunkt 2.1.1")
                .appendH1("Überschrift 3")
                .appendH2("Unterpunkt 3.1")
                .appendH3("Unterpunkt 3.1.1")
                .appendH4("Unterpunkt 3.1.1.1")
                .appendH3("Unterpunkt 3.1.2")
                .appendH4("Unterpunkt 3.1.2.1")
                .appendH5("Unterpunkt 3.1.2.1.1")
                .appendH6("Unterpunkt 3.1.2.1.1.1")
                .insertContent()
                ;
    }

    @Test
    public void contentBeforeFoot() {
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithTitle("Ein tolles HTML-Dokument")
                .appendH1("Überschrift 1")
                .appendH2("Unterpunkt 1.1")
                .appendH2("Unterpunkt 1.2")
                .appendH1("Überschrift 2")
                .appendH2("Unterpunkt 2.1")
                .appendH3("Unterpunkt 2.1.1")
                .appendH1("Überschrift 3")
                .appendH2("Unterpunkt 3.1")
                .appendH3("Unterpunkt 3.1.1")
                .appendH4("Unterpunkt 3.1.1.1")
                .appendH3("Unterpunkt 3.1.2")
                .appendH4("Unterpunkt 3.1.2.1")
                .appendH5("Unterpunkt 3.1.2.1.1")
                .appendH6("Unterpunkt 3.1.2.1.1.1")
                .insertContent()
                .appendFoot()
                ;

        String actual = html.toString();
        String s = "&nbsp;&nbsp;&nbsp;&nbsp;";
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Ein tolles HTML-Dokument</title>" + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                + "        <h1>Inhaltsverzeichnis</h1>" + n
                + "        <a href=\"#id1\">Überschrift 1</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id1_1\">Unterpunkt 1.1</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id1_2\">Unterpunkt 1.2</a>" + n
                + "        <br />" + n
                + "        <a href=\"#id2\">Überschrift 2</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id2_3\">Unterpunkt 2.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + "<a href=\"#id2_3_1\">Unterpunkt 2.1.1</a>" + n
                + "        <br />" + n
                + "        <a href=\"#id3\">Überschrift 3</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id3_4\">Unterpunkt 3.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + "<a href=\"#id3_4_2\">Unterpunkt 3.1.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + "<a href=\"#id3_4_2_1\">Unterpunkt 3.1.1.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + "<a href=\"#id3_4_3\">Unterpunkt 3.1.2</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + "<a href=\"#id3_4_3_2\">Unterpunkt 3.1.2.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + s + "<a href=\"#id3_4_3_2_1\">Unterpunkt 3.1.2.1.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + s + s + "<a href=\"#id3_4_3_2_1_1\">"
                        + "Unterpunkt 3.1.2.1.1.1</a>" + n
                + "        <br />" + n + n
                + "        <h1 id=\"id1\">Überschrift 1</h1>" + n + n
                + "        <h2 id=\"id1_1\">Unterpunkt 1.1</h2>" + n + n
                + "        <h2 id=\"id1_2\">Unterpunkt 1.2</h2>" + n
                + "        <a href=\"#top\">Zum Seitenanfang</a>" + n + n
                + "        <h1 id=\"id2\">Überschrift 2</h1>" + n + n
                + "        <h2 id=\"id2_3\">Unterpunkt 2.1</h2>" + n + n
                + "        <h3 id=\"id2_3_1\">Unterpunkt 2.1.1</h3>" + n
                + "        <a href=\"#top\">Zum Seitenanfang</a>" + n + n
                + "        <h1 id=\"id3\">Überschrift 3</h1>" + n + n
                + "        <h2 id=\"id3_4\">Unterpunkt 3.1</h2>" + n + n
                + "        <h3 id=\"id3_4_2\">Unterpunkt 3.1.1</h3>" + n + n
                + "        <h4 id=\"id3_4_2_1\">Unterpunkt 3.1.1.1</h4>" + n + n
                + "        <h3 id=\"id3_4_3\">Unterpunkt 3.1.2</h3>" + n + n
                + "        <h4 id=\"id3_4_3_2\">Unterpunkt 3.1.2.1</h4>" + n + n
                + "        <h5 id=\"id3_4_3_2_1\">Unterpunkt 3.1.2.1.1</h5>" + n + n
                + "        <h6 id=\"id3_4_3_2_1_1\">Unterpunkt 3.1.2.1.1.1</h6>" + n + n
                + "        <a href=\"#top\">Zum Seitenanfang</a>" + n
                + "    </body>" + n
                + "</html>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void contentAtEnd() {
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithTitleUtf8("Ein tolles HTML-Dokument")
                .appendH1("Überschrift 1")
                .appendH2("Unterpunkt 1.1")
                .appendH2("Unterpunkt 1.2")
                .appendH1("Überschrift 2")
                .appendH2("Unterpunkt 2.1")
                .appendH3("Unterpunkt 2.1.1")
                .appendH1("Überschrift 3")
                .appendH2("Unterpunkt 3.1")
                .appendH3("Unterpunkt 3.1.1")
                .appendH4("Unterpunkt 3.1.1.1")
                .appendH3("Unterpunkt 3.1.2")
                .appendH4("Unterpunkt 3.1.2.1")
                .appendH5("Unterpunkt 3.1.2.1.1")
                .appendH6("Unterpunkt 3.1.2.1.1.1")
                .appendFoot()
                .insertContentAtEnd();

        String actual = html.toString();
        String s = "&nbsp;&nbsp;&nbsp;&nbsp;";
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Ein tolles HTML-Dokument</title>" + n
                + "        <meta charset=\"utf-8\">" + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                + "        <h1 id=\"id1\">Überschrift 1</h1>" + n + n
                + "        <h2 id=\"id1_1\">Unterpunkt 1.1</h2>" + n + n
                + "        <h2 id=\"id1_2\">Unterpunkt 1.2</h2>" + n
                + "        <a href=\"#top\">Zum Seitenanfang</a>" + n + n
                + "        <h1 id=\"id2\">Überschrift 2</h1>" + n + n
                + "        <h2 id=\"id2_3\">Unterpunkt 2.1</h2>" + n + n
                + "        <h3 id=\"id2_3_1\">Unterpunkt 2.1.1</h3>" + n
                + "        <a href=\"#top\">Zum Seitenanfang</a>" + n + n
                + "        <h1 id=\"id3\">Überschrift 3</h1>" + n + n
                + "        <h2 id=\"id3_4\">Unterpunkt 3.1</h2>" + n + n
                + "        <h3 id=\"id3_4_2\">Unterpunkt 3.1.1</h3>" + n + n
                + "        <h4 id=\"id3_4_2_1\">Unterpunkt 3.1.1.1</h4>" + n + n
                + "        <h3 id=\"id3_4_3\">Unterpunkt 3.1.2</h3>" + n + n
                + "        <h4 id=\"id3_4_3_2\">Unterpunkt 3.1.2.1</h4>" + n + n
                + "        <h5 id=\"id3_4_3_2_1\">Unterpunkt 3.1.2.1.1</h5>" + n + n
                + "        <h6 id=\"id3_4_3_2_1_1\">Unterpunkt 3.1.2.1.1.1</h6>" + n + n
                + "    " + n
                + "        <h1>Inhaltsverzeichnis</h1>" + n
                + "        <a href=\"#id1\">Überschrift 1</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id1_1\">Unterpunkt 1.1</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id1_2\">Unterpunkt 1.2</a>" + n
                + "        <br />" + n
                + "        <a href=\"#id2\">Überschrift 2</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id2_3\">Unterpunkt 2.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + "<a href=\"#id2_3_1\">Unterpunkt 2.1.1</a>" + n
                + "        <br />" + n
                + "        <a href=\"#id3\">Überschrift 3</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id3_4\">Unterpunkt 3.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + "<a href=\"#id3_4_2\">Unterpunkt 3.1.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + "<a href=\"#id3_4_2_1\">Unterpunkt 3.1.1.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + "<a href=\"#id3_4_3\">Unterpunkt 3.1.2</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + "<a href=\"#id3_4_3_2\">Unterpunkt 3.1.2.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + s + "<a href=\"#id3_4_3_2_1\">Unterpunkt 3.1.2.1.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + s + s + "<a href=\"#id3_4_3_2_1_1\">"
                        + "Unterpunkt 3.1.2.1.1.1</a>" + n
                + "        <br />" + n
                + "    </body>" + n
                + "</html>" + n;
        assertEquals(expected, actual);
    }

    @Test  (expected = RuntimeException.class)
    public void contentAtEndBeforeFoot() {
        new HtmlBuilder()
                .appendHtml5HeadWithTitleUtf8("Ein tolles HTML-Dokument")
                .appendH1("Überschrift 1")
                .appendH2("Unterpunkt 1.1")
                .appendH2("Unterpunkt 1.2")
                .appendH1("Überschrift 2")
                .appendH2("Unterpunkt 2.1")
                .appendH3("Unterpunkt 2.1.1")
                .appendH1("Überschrift 3")
                .appendH2("Unterpunkt 3.1")
                .appendH3("Unterpunkt 3.1.1")
                .appendH4("Unterpunkt 3.1.1.1")
                .appendH3("Unterpunkt 3.1.2")
                .appendH4("Unterpunkt 3.1.2.1")
                .appendH5("Unterpunkt 3.1.2.1.1")
                .appendH6("Unterpunkt 3.1.2.1.1.1")
                .insertContentAtEnd()
                .appendFoot()
                ;
    }

    @Test (expected = RuntimeException.class)
    public void contentAtEndWithoutBodyTagException() {
        new HtmlBuilder()
                .appendH1("Überschrift 1")
                .appendH2("Unterpunkt 1.1")
                .appendH2("Unterpunkt 1.2")
                .appendH1("Überschrift 2")
                .appendH2("Unterpunkt 2.1")
                .appendH3("Unterpunkt 2.1.1")
                .appendH1("Überschrift 3")
                .appendH2("Unterpunkt 3.1")
                .appendH3("Unterpunkt 3.1.1")
                .appendH4("Unterpunkt 3.1.1.1")
                .appendH3("Unterpunkt 3.1.2")
                .appendH4("Unterpunkt 3.1.2.1")
                .appendH5("Unterpunkt 3.1.2.1.1")
                .appendH6("Unterpunkt 3.1.2.1.1.1")
                .insertContentAtEnd()
                ;
    }

    @Test
    public void quote() {
        HtmlBuilder html = new HtmlBuilder()
                .appendOpeningQuote()
                .appendP("Inhalt des Zitates.")
                .appendClosingQuote()
                ;

        String actual = html.toString();
        String expected = ""
                + "<blockquote>" + n
                + "    <p>Inhalt des Zitates.</p>" + n
                + "</blockquote>" + n
                ;
            assertEquals(expected, actual);
    }

    @Test
    public void quote2() {
        HtmlBuilder html = new HtmlBuilder()
                .appendOpeningQuote()
                .appendP("Absatz 1")
                .appendP("Absatz 2")
                .appendClosingQuote()
                ;

        String actual = html.toString();
        String expected = ""
                + "<blockquote>" + n
                + "    <p>Absatz 1</p>" + n
                + "    <p>Absatz 2</p>" + n
                + "</blockquote>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void blockquote() {
        HtmlBuilder html = new HtmlBuilder()
                .appendOpeningBlockquote()
                .appendP("Inhalt des Zitates.")
                .appendClosingBlockquote()
                ;

        String actual = html.toString();
        String expected = ""
                + "<blockquote>" + n
                + "    <p>Inhalt des Zitates.</p>" + n
                + "</blockquote>" + n
                ;
            assertEquals(expected, actual);
    }

    @Test
    public void appendPTT() {
        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendPTT("Absatz")
                ;

        String actual = html.toString();
        String expected = ""
                + "        <p class=\"monospace\">Absatz</p>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendSeparatoringLine() {
        HtmlBuilder html = new HtmlBuilder()
                .appendSeparatoringLine()
                ;

        String actual = html.toString();
        String expected = ""
                + "<p></p>" + n
                + "<p></p>" + n
                + "<hr />" + n
                + "<p></p>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendLine() {
        HtmlBuilder html = new HtmlBuilder()
                .appendLine()
                ;

        String actual = html.toString();
        String expected = ""
                + "<hr />" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendStringBuilder() {
        StringBuilder builder = new StringBuilder()
                .append("Huhu");

        HtmlBuilder html = new HtmlBuilder()
                .append(builder)
                ;

        String actual = html.toString();
        String expected = ""
                + "Huhu"
                + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendStringBuilderIndented() {
        StringBuilder builder = new StringBuilder()
                .append("Huhu");

        HtmlBuilder html = new HtmlBuilder()
                .appendOpeningDiv()
                .append(builder)
                .appendClosingDiv()
                ;

        String actual = html.toString();
        String expected = ""
                + "<div>" + n
                + "    Huhu" + n
                + "</div>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHtmlBuilder() {
        HtmlBuilder otherHtmlBuilder = new HtmlBuilder()
                .appendSeparatoringLine()
                ;
        HtmlBuilder html = new HtmlBuilder()
                .append(otherHtmlBuilder)
                ;

        String actual = html.toString();
        String expected = ""
                + "<p></p>" + n
                + "<p></p>" + n
                + "<hr />" + n
                + "<p></p>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHtmlBuilderIndented() {
        HtmlBuilder otherHtmlBuilder = new HtmlBuilder()
                .appendSeparatoringLine()
                ;
        HtmlBuilder html = new HtmlBuilder()
                .appendOpeningDiv()
                .append(otherHtmlBuilder)
                .appendClosingDiv()
                ;

        String actual = html.toString();
        String expected = ""
                + "<div>" + n
                + "    <p></p>" + n
                + "    <p></p>" + n
                + "    <hr />" + n
                + "    <p></p>" + n
                + "</div>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void length() {
        HtmlBuilder html = new HtmlBuilder()
                .appendSeparatoringLine()
                ;

        int actual = html.length();
        int expected = 35;
        assertEquals(expected, actual);
    }

    @Test
    public void appendPre() {
        HtmlBuilder html = new HtmlBuilder()
                .appendPre("pre pre pre")
                ;

        String actual = html.toString();
        String expected = ""
                + "<pre>pre pre pre</pre>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendOpeningClosingPre() {
        HtmlBuilder html = new HtmlBuilder()
                .appendOpeningPre()
                .append("pre pre pre")
                .appendLineBreak()
                .appendClosingPre()
                ;

        String actual = html.toString();
        String expected = ""
                + "<pre>" + n
                + "pre pre pre" + n
                + "</pre>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendPreWithMultipleLines() {
        String text = "komisches <b>ausgezeichnetes</b>\n"
                + "Zeug mit\n"
                + "     <i>eingerücktem</i> und\n"
                + "Umbrüchen";
        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendPre(text)
                ;

        String actual = html.toString();
        String expected = ""
                + "        <pre>" + text + "</pre>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendVerticalSpace() {
        HtmlBuilder html = new HtmlBuilder()
                .appendVerticalSpace()
                ;

        String actual = html.toString();
        String expected = ""
                + "<p>&nbsp;</p>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendFieldset() {
        HtmlBuilder html = new HtmlBuilder()
                .appendOpeningFieldset("Bereich Blubb")
                .appendLn("Fasel")
                .appendClosingFieldset()
                ;

        String actual = html.toString();
        String expected = ""
                + "<fieldset>" + n
                + "    <legend>Bereich Blubb</legend>" + n
                + "    Fasel" + n
                + "</fieldset>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void multiLineP() {
        HtmlBuilder html = new HtmlBuilder()
                .appendOpeningP()
                .appendLn("Zeile 1")
                .appendLn("Zeile 2")
                .appendClosingP()
                ;

        String actual = html.toString();
        String expected = ""
                + "<p>" + n
                + "    Zeile 1" + n
                + "    Zeile 2" + n
                + "</p>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void multiLinePWithClass() {
        HtmlBuilder html = new HtmlBuilder()
                .appendOpeningP("Css-Klasse")
                .appendLn("Zeile 1")
                .appendLn("Zeile 2")
                .appendClosingP()
                ;

        String actual = html.toString();
        String expected = ""
                + "<p class=\"Css-Klasse\">" + n
                + "    Zeile 1" + n
                + "    Zeile 2" + n
                + "</p>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendButtonWithType() {
        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .increaseIndentationLevel()
                .appendOpeningP()
                .appendButtonWithType("reset", "Eingaben zurücksetzen")
                .appendButtonWithType("submit", "Absenden")
                .appendClosingP()
                ;

        String actual = html.toString();
        String expected = ""
                + "            <p>" + n
                + "                <button type=\"reset\">Eingaben zurücksetzen</button>" + n
                + "                <button type=\"submit\">Absenden</button>" + n
                + "            </p>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendButtonWithTypeAndAdditionalParams() {
        String buttonName = "BUTTON_NAME";
        String nameOfTheForm = "NAME_OF_THE_FORM";

        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .increaseIndentationLevel()
                .appendOpeningP()
                .appendButtonWithType("reset", "Eingaben zurücksetzen")
                .appendButtonWithTypeAndAdditionalParams("button", "Felder leeren",
                        "name=\"" + buttonName + "\"",
                        "onClick=\"clearAllFieldsInFirstForm(" + nameOfTheForm + ")\""
                        )
                .appendButtonWithType("submit", "Absenden")
                .appendClosingP()
                ;

        String actual = html.toString();
        String expected = ""
                + "            <p>" + n
                + "                <button type=\"reset\">Eingaben zurücksetzen</button>" + n
                + "                <button type=\"button\" "
                +                         "name=\"" + buttonName + "\" "
                +                         "onClick=\"clearAllFieldsInFirstForm(" + nameOfTheForm
                +                         ")\">Felder leeren</button>" + n
                + "                <button type=\"submit\">Absenden</button>" + n
                + "            </p>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void form() {
        String buttonName = "BUTTON_NAME";
        String nameOfTheForm = "NAME_OF_THE_FORM";
        String url = "http://www.example.org";

        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .increaseIndentationLevel()
                .appendOpeningForm(nameOfTheForm, "http://www.example.org")
                .appendOpeningP()
                .appendButtonWithType("reset", "Eingaben zurücksetzen")
                .appendButtonWithTypeAndAdditionalParams("button", "Felder leeren",
                        "name=\"" + buttonName + "\"",
                        "onClick=\"clearAllFieldsInFirstForm(" + nameOfTheForm + ")\""
                        )
                .appendButtonWithType("submit", "Absenden")
                .appendClosingP()
                .appendClosingForm()
                ;

        String actual = html.toString();
        String expected = ""
                + "            <form name=\"" + nameOfTheForm + "\" action=\"" + url + "\" "
                                                  + "accept-charset=\"UTF-8\" method=\"post\">" + n
                + "                <p>" + n
                + "                    <button type=\"reset\">Eingaben zurücksetzen</button>" + n
                + "                    <button type=\"button\" "
                +                         "name=\"" + buttonName + "\" "
                +                         "onClick=\"clearAllFieldsInFirstForm(" + nameOfTheForm
                +                         ")\">Felder leeren</button>" + n
                + "                    <button type=\"submit\">Absenden</button>" + n
                + "                </p>" + n
                + "            </form>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void formInNewTab() {
        String nameOfTheForm = "NAME_OF_THE_FORM";
        String buttonName = "BUTTON_NAME";
        String url = "http://www.example.org";

        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .increaseIndentationLevel()
                .appendOpeningFormOpeningInNewTab(nameOfTheForm, url)
                .appendOpeningP()
                .appendButtonWithType("reset", "Eingaben zurücksetzen")
                .appendButtonWithTypeAndAdditionalParams("button", "Felder leeren",
                        "name=\"" + buttonName + "\"",
                        "onClick=\"clearAllFieldsInFirstForm(" + nameOfTheForm + ")\""
                        )
                .appendButtonWithType("submit", "Absenden")
                .appendClosingP()
                .appendClosingForm()
                ;

        String actual = html.toString();
        String expected = ""
                + "            <form name=\"" + nameOfTheForm + "\" action=\"" + url + "\" "
                                + "accept-charset=\"UTF-8\" method=\"post\" target=\"_blank\">" + n
                + "                <p>" + n
                + "                    <button type=\"reset\">Eingaben zurücksetzen</button>" + n
                + "                    <button type=\"button\" "
                +                         "name=\"" + buttonName + "\" "
                +                         "onClick=\"clearAllFieldsInFirstForm(" + nameOfTheForm
                +                         ")\">Felder leeren</button>" + n
                + "                    <button type=\"submit\">Absenden</button>" + n
                + "                </p>" + n
                + "            </form>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void nameLessForm() {
        String cssClass = "CSS-KLASSE";
        String url = "http://www.example.org";

        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .increaseIndentationLevel()
                .appendOpenNamelessForm(url, cssClass)
                .appendClosingForm()
                ;

        String actual = html.toString();
        String expected = ""
                + "            <form class=\"" + cssClass + "\" action=\"" + url + "\" "
                                                  + "accept-charset=\"UTF-8\" method=\"post\">" + n
                + "            </form>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendOpenUpdateForm() {
        String cssClass = "CSS-KLASSE";
        String url = "http://www.example.org";

        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .increaseIndentationLevel()
                .appendOpenUpdateForm(url, cssClass)
                .appendClosingForm()
                ;

        String actual = html.toString();
        String expected = ""
                + "            <form class=\"" + cssClass + "\" action=\"" + url + "\" "
                                                  + "accept-charset=\"UTF-8\" method=\"post\" "
                                                  + "enctype=\"multipart/form-data\">" + n
                + "            </form>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendLabel() {
        String field = "field";
        String text = "Beschriftung des Labels";

        HtmlBuilder html = new HtmlBuilder()
                .appendLabel(field, text)
                ;

        String actual = html.toString();
        String expected = ""
                + "<label for=\"" + field + "\">" + text + "</label>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendLabelWithClass() {
        String field = "field";
        String text = "Beschriftung des Labels";
        String cssClass = "Css-Klasse";

        HtmlBuilder html = new HtmlBuilder()
                .appendLabelWithClass(field, text, cssClass)
                ;

        String actual = html.toString();
        String expected = ""
                + "<label class=\"" + cssClass  + "\" for=\"" + field + "\">" + text + "</label>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendInput() {
        String field = "field";

        HtmlBuilder html = new HtmlBuilder()
                .appendInput(field)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input id=\"" + field + "\" name=\"" + field + "\"/>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendInputWithClass() {
        String field = "field";
        String cssClass = "Css-Klasse";

        HtmlBuilder html = new HtmlBuilder()
                .appendInputWithClass(field, cssClass)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input class=\"" + cssClass + "\" "
                + "id=\"" + field + "\" name=\"" + field + "\"/>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendInputWithValue() {
        String field = "field";
        String value = "VALUE";

        HtmlBuilder html = new HtmlBuilder()
                .appendInputWithValue(field, value)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input "
                + "id=\"" + field + "\" "
                + "name=\"" + field + "\" "
                + "value=\"" + value + "\"/>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendInputWithClassAndValue() {
        String field = "field";
        String cssClass = "Css-Klasse";
        String value = "VALUE";

        HtmlBuilder html = new HtmlBuilder()
                .appendInputWithClassAndValue(field, cssClass, value)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input class=\"" + cssClass + "\" "
                + "id=\"" + field + "\" name=\"" + field + "\" "
                + "value=\"" + value + "\"/>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendRequiredInputWithClassAndValue() {
        String field = "field";
        String cssClass = "Css-Klasse";
        String value = "VALUE";

        HtmlBuilder html = new HtmlBuilder()
                .appendRequiredInputWithClassAndValue(field, cssClass, value)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input class=\"" + cssClass + "\" "
                + "id=\"" + field + "\" name=\"" + field + "\" "
                + "value=\"" + value + "\" required/>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendInputWithClassAndPlaceholder() {
        String field = "field";
        String cssClass = "Css-Klasse";
        String placeholder = "PLACEHOLDER";

        HtmlBuilder html = new HtmlBuilder()
                .appendInputWithClassAndPlaceholder(field, cssClass, placeholder)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input class=\"" + cssClass + "\" "
                + "id=\"" + field + "\" name=\"" + field + "\" "
                + "placeholder=\"" + placeholder + "\"/>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendRequiredInputWithClassAndPlaceholder() {
        String field = "field";
        String cssClass = "Css-Klasse";
        String placeholder = "PLACEHOLDER";

        HtmlBuilder html = new HtmlBuilder()
                .appendRequiredInputWithClassAndPlaceholder(field, cssClass, placeholder)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input class=\"" + cssClass + "\" "
                + "id=\"" + field + "\" name=\"" + field + "\" "
                + "placeholder=\"" + placeholder + "\" required/>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendRequiredInputWithClassPlaceholderAndPattern() {
        String field = "field";
        String cssClass = "Css-Klasse";
        String placeholder = "PLACEHOLDER";
        String pattern = "PATTERN";

        HtmlBuilder html = new HtmlBuilder()
                .appendRequiredInputWithClassPlaceholderAndPattern(field, cssClass, placeholder,
                        pattern)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input class=\"" + cssClass + "\" "
                + "id=\"" + field + "\" "
                + "name=\"" + field + "\" "
                + "placeholder=\"" + placeholder + "\" "
                + "pattern=\"" + pattern + "\" "
                + "required"
                + "/>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendPasswordInputWithClassPlaceholderAndMinLength() {
        String field = "field";
        String cssClass = "Css-Klasse";
        String placeholder = "PLACEHOLDER";
        int minLength = 8;

        HtmlBuilder html = new HtmlBuilder()
                .appendPasswordInputWithClassPlaceholderAndMinLength(field, cssClass,
                        placeholder, minLength)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input class=\"" + cssClass + "\" "
                + "id=\"" + field + "\" "
                + "name=\"" + field + "\" "
                + "type=\"password\" "
                + "placeholder=\"" + placeholder + "\" "
                + "minlength=\"" + minLength + "\""
                + "/>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendRequiredPasswordInputWithClassPlaceholderAndMinLength() {
        String field = "field";
        String cssClass = "Css-Klasse";
        String placeholder = "PLACEHOLDER";
        int minLength = 8;

        HtmlBuilder html = new HtmlBuilder()
                .appendRequiredPasswordInputWithClassPlaceholderAndMinLength(field, cssClass,
                        placeholder, minLength)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input class=\"" + cssClass + "\" "
                + "id=\"" + field + "\" "
                + "name=\"" + field + "\" "
                + "type=\"password\" "
                + "placeholder=\"" + placeholder + "\" "
                + "minlength=\"" + minLength + "\" "
                + "required"
                + "/>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendEmailInputWithClassPlaceholder() {
        String field = "field";
        String cssClass = "Css-Klasse";
        String placeholder = "PLACEHOLDER";

        HtmlBuilder html = new HtmlBuilder()
                .appendEmailInputWithClassPlaceholder(field, cssClass, placeholder)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input class=\"" + cssClass + "\" "
                + "id=\"" + field + "\" "
                + "name=\"" + field + "\" "
                + "type=\"email\" "
                + "placeholder=\"" + placeholder + "\""
                + "/>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendRequiredEmailInputWithClassAndPlaceholder() {
        String field = "field";
        String cssClass = "Css-Klasse";
        String placeholder = "PLACEHOLDER";

        HtmlBuilder html = new HtmlBuilder()
                .appendRequiredEmailInputWithClassAndPlaceholder(field, cssClass, placeholder)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input class=\"" + cssClass + "\" "
                + "id=\"" + field + "\" "
                + "name=\"" + field + "\" "
                + "type=\"email\" "
                + "placeholder=\"" + placeholder + "\" "
                + "required"
                + "/>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendRequiredEmailInputWithClassAndValue() {
        String field = "field";
        String cssClass = "Css-Klasse";
        String value = "VALUE";

        HtmlBuilder html = new HtmlBuilder()
                .appendRequiredEmailInputWithClassAndValue(field, cssClass, value)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input class=\"" + cssClass + "\" "
                + "id=\"" + field + "\" "
                + "name=\"" + field + "\" "
                + "type=\"email\" "
                + "value=\"" + value + "\" "
                + "required"
                + "/>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendInputCheckbox() {
        String field = "field";
        boolean selected = false;

        HtmlBuilder html = new HtmlBuilder()
                .appendInputCheckbox(field, selected)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input id=\"" + field + "\" "
                + "type=\"checkbox\" "
                + "name=\"" + field + "\""
                + "/>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendSelectedInputCheckbox() {
        String field = "field";
        boolean selected = true;

        HtmlBuilder html = new HtmlBuilder()
                .appendInputCheckbox(field, selected)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input id=\"" + field + "\" "
                + "type=\"checkbox\" "
                + "name=\"" + field + "\""
                + " checked" + "/>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendInputRadioButton() {
        String field = "field";
        String buttonGroupName = "GRUPPE";
        boolean selected = false;

        HtmlBuilder html = new HtmlBuilder()
                .appendInputRadioButton(field, buttonGroupName, selected)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input id=\"" + field + "\" "
                + "type=\"radio\" "
                + "name=\"" + buttonGroupName + "\" "
                + "value=\"" + field + "\""
                + "/>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendSelectedInputRadioButton() {
        String field = "field";
        String buttonGroupName = "GRUPPE";
        boolean selected = true;

        HtmlBuilder html = new HtmlBuilder()
                .appendInputRadioButton(field, buttonGroupName, selected)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input id=\"" + field + "\" "
                + "type=\"radio\" "
                + "name=\"" + buttonGroupName + "\" "
                + "value=\"" + field + "\""
                + " checked" + "/>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHiddenField() {
        String name = "NAME";
        String value = "VALUE";

        HtmlBuilder html = new HtmlBuilder()
                .appendHiddenField(name, value)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input type=\"hidden\" name=\"" + name + "\" value=\"" + value + "\"/>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendReallyClearFieldsOfFormButton() {
        String buttonName = "BUTTON_NAME";
        String formName = "FORM_NAME";

        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendReallyClearFieldsOfFormButton(buttonName, formName)
                ;

        String actual = html.toString();
        String expected = ""
                + "        <script>" + n
                + "            function clearAllFieldsInFirstForm(form) {" + n
                + "                for (i = 0; i < form.elements.length; ++i) {" + n
                + "                    if (form.elements[i].type == 'text'" + n
                + "                            || form.elements[i].type == 'textarea') {" + n
                + "                        form.elements[i].value = '';" + n
                + "                    }" + n
                + "                }" + n
                + "            }" + n
                + "        </script>" + n
                + "        <button type=\"button\" name=\"" + buttonName + "\" "
                        + "onClick=\"clearAllFieldsInFirstForm(" + formName
                        + ")\">Felder leeren</button>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendReallyClearFieldsOfFormButtonWithEllipse() {
        String buttonName = "BUTTON_NAME";
        String formName = "FORM_NAME";

        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendReallyClearFieldsOfFormButton(buttonName, formName, "IGNORE_1", "IGNORE_2",
                        "IGNORE_3", "IGNORE_4")
                ;

        String actual = html.toString();
        String expected = ""
                + "        <script>" + n
                + "            function clearAllFieldsInFirstForm(form) {" + n
                + "                for (i = 0; i < form.elements.length; ++i) {" + n
                + "                    if (form.elements[i].type == 'text'" + n
                + "                            || form.elements[i].type == 'textarea') {" + n
                + "                        if (form.elements[i].id != 'IGNORE_1'" + n
                + "                                && form.elements[i].id != 'IGNORE_2'" + n
                + "                                && form.elements[i].id != 'IGNORE_3'" + n
                + "                                && form.elements[i].id != 'IGNORE_4') {" + n
                + "                            form.elements[i].value = '';" + n
                + "                        }" + n
                + "                    }" + n
                + "                }" + n
                + "            }" + n
                + "        </script>" + n
                + "        <button type=\"button\" name=\"" + buttonName + "\" "
                        + "onClick=\"clearAllFieldsInFirstForm(" + formName
                        + ")\">Felder leeren</button>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendReallyClearFieldsOfFormButtonWithList() {
        String buttonName = "BUTTON_NAME";
        String formName = "FORM_NAME";

        String idToIgnore1 = "IGNORE_1";
        String idToIgnore2 = "IGNORE_2";
        List<String> idsToIgnore = CollectionsHelper.buildListFrom(idToIgnore1, idToIgnore2);

        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendReallyClearFieldsOfFormButton(buttonName, formName, idsToIgnore)
                ;

        String actual = html.toString();
        String expected = ""
                + "        <script>" + n
                + "            function clearAllFieldsInFirstForm(form) {" + n
                + "                for (i = 0; i < form.elements.length; ++i) {" + n
                + "                    if (form.elements[i].type == 'text'" + n
                + "                            || form.elements[i].type == 'textarea') {" + n
                + "                        if (form.elements[i].id != '" + idToIgnore1 + "'" + n
                + "                                && form.elements[i].id != '" + idToIgnore2 + "') {" + n
                + "                            form.elements[i].value = '';" + n
                + "                        }" + n
                + "                    }" + n
                + "                }" + n
                + "            }" + n
                + "        </script>" + n
                + "        <button type=\"button\" name=\"" + buttonName + "\" "
                        + "onClick=\"clearAllFieldsInFirstForm(" + formName
                        + ")\">Felder leeren</button>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendReallyClearFieldsAndCheckbuttonsOfFormButton() {
        String buttonName = "BUTTON_NAME";
        String formName = "FORM_NAME";

        String ignore1 = "IGNORE_1";
        String ignore2 = "IGNORE_2";
        String ignore3 = "IGNORE_3";
        String ignore4 = "IGNORE_4";
        List<String> idsToIgnore = CollectionsHelper.buildListFrom(ignore1, ignore2, ignore3,
                ignore4);

        String check1 = "CHECKBOX_ID_1";
        String check2 = "CHECKBOX_ID_2";
        String check3 = "CHECKBOX_ID_3";
        List<String> checkboxIdsToClear = CollectionsHelper.buildListFrom(check1, check2, check3);

        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendReallyClearFieldsAndCheckbuttonsOfFormButton(buttonName, formName,
                        checkboxIdsToClear, idsToIgnore)
                ;

        String actual = html.toString();
        String expected = ""
                + "        <script>" + n
                + "            function clearAllFieldsInFirstForm(form) {" + n
                + "                for (i = 0; i < form.elements.length; ++i) {" + n
                + "                    if (form.elements[i].type == 'text'" + n
                + "                            || form.elements[i].type == 'textarea') {" + n
                + "                        if (form.elements[i].id != '" + ignore1 + "'" + n
                + "                                && form.elements[i].id != '" + ignore2 + "'" + n
                + "                                && form.elements[i].id != '" + ignore3 + "'" + n
                + "                                && form.elements[i].id != '" + ignore4 + "') {" + n
                + "                            form.elements[i].value = '';" + n
                + "                        }" + n
                + "                    }" + n
                + "                    if (form.elements[i].type == 'checkbox') {" + n
                + "                        if (form.elements[i].id == '" + check1 + "'" + n
                + "                                || form.elements[i].id == '" + check2 + "'" + n
                + "                                || form.elements[i].id == '" + check3 + "') {" + n
                + "                            form.elements[i].checked = false;" + n
                + "                        }" + n
                + "                    }" + n
                + "                }" + n
                + "            }" + n
                + "        </script>" + n
                + "        <button type=\"button\" name=\"" + buttonName + "\" "
                        + "onClick=\"clearAllFieldsInFirstForm(" + formName
                        + ")\">Felder leeren</button>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendReallyClearFieldsAndCheckbuttonsOfFormButtonWithNothingToIgnore() {
        String buttonName = "BUTTON_NAME";
        String formName = "FORM_NAME";

        String ignore1 = "IGNORE_1";
        String ignore2 = "IGNORE_2";
        String ignore3 = "IGNORE_3";
        String ignore4 = "IGNORE_4";
        List<String> idsToIgnore = CollectionsHelper.buildListFrom(ignore1, ignore2, ignore3,
                ignore4);

        List<String> checkboxIdsToClear = CollectionsHelper.buildListFrom();

        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendReallyClearFieldsAndCheckbuttonsOfFormButton(buttonName, formName,
                        checkboxIdsToClear, idsToIgnore)
                ;

        String actual = html.toString();
        String expected = ""
                + "        <script>" + n
                + "            function clearAllFieldsInFirstForm(form) {" + n
                + "                for (i = 0; i < form.elements.length; ++i) {" + n
                + "                    if (form.elements[i].type == 'text'" + n
                + "                            || form.elements[i].type == 'textarea') {" + n
                + "                        if (form.elements[i].id != '" + ignore1 + "'" + n
                + "                                && form.elements[i].id != '" + ignore2 + "'" + n
                + "                                && form.elements[i].id != '" + ignore3 + "'" + n
                + "                                && form.elements[i].id != '" + ignore4 + "') {" + n
                + "                            form.elements[i].value = '';" + n
                + "                        }" + n
                + "                    }" + n
                + "                }" + n
                + "            }" + n
                + "        </script>" + n
                + "        <button type=\"button\" name=\"" + buttonName + "\" "
                        + "onClick=\"clearAllFieldsInFirstForm(" + formName
                        + ")\">Felder leeren</button>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendLabelAndInput() {
        String field = "FIELD";
        String fieldTitle = "FIELD_TITLE";

        HtmlBuilder html = new HtmlBuilder()
                .appendLabelAndInput(field, fieldTitle)
                ;

        String actual = html.toString();
        String expected = ""
                + "<p>" + n
                + "    <label for=\"" + field + "\">" + fieldTitle + "</label>" + n
                + "    <input id=\"" + field + "\" name=\"" + field + "\"/>" + n
                + "</p>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendLabelAndInputWithValue() {
        String field = "FIELD";
        String fieldTitle = "FIELD_TITLE";
        String value = "VALUE";

        HtmlBuilder html = new HtmlBuilder()
                .appendLabelAndInputWithValue(field, fieldTitle, value)
                ;

        String actual = html.toString();
        String expected = ""
                + "<p>" + n
                + "    <label for=\"" + field + "\">" + fieldTitle + "</label>" + n
                + "    <input id=\"" + field + "\" name=\"" + field + "\" "
                        + "value=\"" + value + "\"/>" + n
                + "</p>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendLabelAndCheckBox() {
        String field = "FIELD";
        String fieldTitle = "FIELD_TITLE";
        boolean selected = false;
        String cssLabelClass = "CSS-KLASSE";

        HtmlBuilder html = new HtmlBuilder()
                .appendLabelAndCheckBox(field, fieldTitle, selected, cssLabelClass)
                ;

        String actual = html.toString();
        String expected = ""
                + "<p>" + n
                + "    <label class=\"" + cssLabelClass + "\" for=\"" + field+ "\">" + fieldTitle
                        + "</label>" + n
                + "    <input id=\"" + field+ "\" type=\"checkbox\" name=\"" + field+ "\"/>" + n
                + "</p>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendLabelAndRadioButton() {
        String field = "FIELD";
        String buttonGroup = "GRUPPE";
        String fieldTitle = "FIELD_TITLE";
        boolean selected = false;
        String cssLabelClass = "CSS-KLASSE";

        HtmlBuilder html = new HtmlBuilder()
                .appendLabelAndRadioButton(field, buttonGroup , fieldTitle, selected, cssLabelClass)
                ;

        String actual = html.toString();
        String expected = ""
                + "<p>" + n
                + "    <label class=\"" + cssLabelClass
                        + "\" for=\"" + field + "\">" + fieldTitle + "</label>" + n
                + "    <input id=\"" + field + "\" "
                        + "type=\"radio\" "
                        + "name=\"" + buttonGroup + "\" "
                        + "value=\"" + field + "\""
                        + "/>" + n
                + "</p>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendSelectedLabelAndRadioButton() {
        String field = "FIELD";
        String buttonGroup = "GRUPPE";
        String fieldTitle = "FIELD_TITLE";
        boolean selected = true;
        String cssLabelClass = "CSS-KLASSE";

        HtmlBuilder html = new HtmlBuilder()
                .appendLabelAndRadioButton(field, buttonGroup , fieldTitle, selected, cssLabelClass)
                ;

        String actual = html.toString();
        String expected = ""
                + "<p>" + n
                + "    <label class=\"" + cssLabelClass
                        + "\" for=\"" + field + "\">" + fieldTitle + "</label>" + n
                + "    <input id=\"" + field + "\" "
                        + "type=\"radio\" "
                        + "name=\"" + buttonGroup + "\" "
                        + "value=\"" + field + "\" "
                        + "checked"
                        + "/>" + n
                + "</p>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendFormButtons() {
        String submitTitle = "SUBMIT_TITLE";

        HtmlBuilder html = new HtmlBuilder()
                .createHtmlPartInBody()
                .appendFormButtons(submitTitle)
                ;

        String actual = html.toString();
        String expected = ""
                + "        <p>" + n
                + "            <button type=\"reset\">Eingaben zurücksetzen</button>" + n
                + "            <button type=\"submit\">SUBMIT_TITLE</button>" + n
                + "        </p>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendFocusSettingJavaScript() {
        String field = "FELDNAME";

        HtmlBuilder html = new HtmlBuilder()
                .appendFocusSettingJavaScript(field)
                ;

        String actual = html.toString();
        String expected = ""
                + "<script>" + n
                + "    document.getElementById(\"" + field + "\").focus();" + n
                + "</script>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendPasswordVerificationJavaScript() {
        String field1 = "FELDNAME_1";
        String field2 = "FELDNAME_2";

        HtmlBuilder html = new HtmlBuilder()
                .appendPasswordVerificationJavaScript(field1, field2)
                ;

        String actual = html.toString();
        String expected = ""
                + "<script>" + n
                + "    var password1 = document.getElementById('" + field1 + "');" + n
                + "    var password2 = document.getElementById('" + field2 + "');" + n
                + "    var checkPasswordValidity = function () {" + n
                + "        if (password1.value != password2.value) {" + n
                + "            password2.setCustomValidity('Passwörter müssen übereinstimmen!');" + n
                + "        }" + n
                + "        else {" + n
                + "            password2.setCustomValidity('');" + n
                + "        }" + n
                + "    };" + n
                + "    password1.addEventListener('change', checkPasswordValidity);" + n
                + "    password2.addEventListener('change', checkPasswordValidity);" + n
                + "</script>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendSendPostJavaScript() {
        HtmlBuilder html = new HtmlBuilder()
                .appendSendPostJavaScript()
                ;

        String actual = html.toString();
        String expected = ""
                + "<script>" + n
                + "    function post(path, params, method) {" + n
                + "        method = method || \"POST\"; // Set method to post by default if not specified." + n
                + "" + n
                + "        var form = document.createElement(\"form\");" + n
                + "        form.setAttribute(\"method\", method);" + n
                + "        form.setAttribute(\"action\", path);" + n
                + "        /*" + n
                + "         * Es geht hier auch" + n
                + "         *     form.setAttribute(\"target\", \"_blank\");" + n
                + "         * um die neue Seite in einem eigenen Tab anzuzeigen." + n
                + "         */" + n
                + "" + n
                + "        for (var key in params) {" + n
                + "            if (params.hasOwnProperty(key)) {" + n
                + "                var hiddenField = document.createElement(\"input\");" + n
                + "                hiddenField.setAttribute(\"type\", \"hidden\");" + n
                + "                hiddenField.setAttribute(\"name\", key);" + n
                + "                hiddenField.setAttribute(\"value\", params[key]);" + n
                + "" + n
                + "                form.appendChild(hiddenField);" + n
                + "            }" + n
                + "        }" + n
                + "" + n
                + "        document.body.appendChild(form);" + n
                + "        form.submit();" + n
                + "    }" + n
                + "</script>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendTableSortingJavaScript() {
        String tableId = "TABLE_ID";

        HtmlBuilder html = new HtmlBuilder()
                .appendTableSortingJavaScript(tableId)
                ;

        String actual = html.toString();
        String expected = ""
                + "<script>" + n
                + "    \"use strict\";" + n
                + "    var tableSort = function (tab) {" + n
                + "            var titel = tab.getElementsByTagName(\"thead\")[0]" + n
                + "                    .getElementsByTagName(\"tr\")[0]."
                        +                      "getElementsByTagName(\"th\");" + n
                + "            var tbdy = tab.getElementsByTagName(\"tbody\")[0];" + n
                + "            var tz = tbdy.rows;" + n
                + "            var nzeilen = tz.length;" + n
                + "            if (nzeilen == 0) {" + n
                + "                return;" + n
                + "            }" + n
                + "            var nspalten = tz[0].cells.length;" + n
                + "            var arr = new Array(nzeilen);" + n
                + "            var sortiert = -1;" + n
                + "            var sorttype = new Array(nspalten);" + n
                + "            var sortbuttonStyle = document.createElement('style'); "
                        +                                          "// Stylesheet für Button im TH" + n
                + "            sortbuttonStyle.innerText =" + n
                + "                '.sortbutton { width:100%; height:100%; border: none; "
                        +            "background-color: transparent; font: inherit; "
                        +            "color: inherit; text-align: inherit; padding: 0; "
                        +            "cursor: pointer; } "
                        +        ".sortbutton::-moz-focus-inner { margin: -1px; "
                        +            "border-width: 1px; padding: 0; }';" + n
                + "            document.head.appendChild(sortbuttonStyle);" + n
                + "            var initTableHead = function (sp) { // Kopfzeile vorbereiten" + n
                + "                var b = document.createElement(\"button\");" + n
                + "                b.type = \"button\";" + n
                + "                b.className = \"sortbutton\";" + n
                + "                b.innerHTML = titel[sp].innerHTML;" + n
                + "                b.addEventListener(\"click\", function () {" + n
                + "                    tsort(sp);" + n
                + "                }, false);" + n
                + "                titel[sp].innerHTML = \"\";" + n
                + "                titel[sp].appendChild(b);" + n
                + "            }" + n
                + "            var getData = function (ele, s) {" + n
                + "                    var val = ele.textContent; // Nicht im IE8" + n
                + "                    if (!isNaN(val) && val.search(/[0-9]/) != -1) return val;" + n
                + "                    var n = val.replace(\",\", \".\");" + n
                + "                    if (!isNaN(n) && n.search(/[0-9]/) != -1) return n;" + n
                + "                    sorttype[s] = \"s\"; // String" + n
                + "                    return val;" + n
                + "                } // getData" + n
                + "            var vglFkt_s = function (a, b) {" + n
                + "                    var as = a[sortiert]," + n
                + "                        bs = b[sortiert];" + n
                + "                    if (as > bs) {" + n
                + "                        return 1;" + n
                + "                    }" + n
                + "                    else {" + n
                + "                        return -1;" + n
                + "                    }" + n
                + "                } // vglFkt_s" + n
                + "            var vglFkt_n = function (a, b) {" + n
                + "                    return parseFloat(a[sortiert]) - parseFloat(b[sortiert]);" + n
                + "                } // vglFkt_n" + n
                + "            var tsort = function (sp) {" + n
                + "                    if (sp == sortiert) {" + n
                + "                        // Tabelle ist schon nach dieser Spalte sortiert, also" + n
                + "                        // nur Reihenfolge umdrehen:" + n
                + "                        arr.reverse();" + n
                + "                    }" + n
                + "                    else { // Sortieren" + n
                + "                        sortiert = sp;" + n
                + "                        if (sorttype[sp] == \"n\") {" + n
                + "                            arr.sort(vglFkt_n);" + n
                + "                        }" + n
                + "                        else {" + n
                + "                            arr.sort(vglFkt_s);" + n
                + "                        }" + n
                + "                    }" + n
                + "                    for (var z = 0; z < nzeilen; z++) {" + n
                + "                        tbdy.appendChild(arr[z][nspalten]); "
                        +                              "// Sortierte Daten zurückschreiben" + n
                + "                    }" + n
                + "                } // tsort" + n
                + "            // Kopfzeile vorbereiten" + n
                + "            for (var i = 0; i < titel.length; i++) {" + n
                + "                initTableHead(i);" + n
                + "            }" + n
                + "            // Array mit Info, wie Spalte zu sortieren ist, vorbelegen" + n
                + "            for (var s = 0; s < nspalten; s++) {" + n
                + "                sorttype[s] = \"n\";" + n
                + "            }" + n
                + "            // Tabelleninhalt in ein Array kopieren" + n
                + "            for (var z = 0; z < nzeilen; z++) {" + n
                + "                var zelle = tz[z].getElementsByTagName(\"td\"); // cells;" + n
                + "                arr[z] = new Array(nspalten + 1);" + n
                + "                arr[z][nspalten] = tz[z];" + n
                + "                for (var s = 0; s < nspalten; s++) {" + n
                + "                    var zi = getData(zelle[s], s);" + n
                + "                    arr[z][s] = zi;" + n
                + "                    // zelle[s].innerHTML += \"<br>\"+zi+\"<br>\"+sorttype[s]; "
                        +                     "// zum Debuggen" + n
                + "                }" + n
                + "            }" + n
                + "        } // tableSort" + n
                + "    var initTableSort = function () {" + n
                + "            var sort_Table = document.querySelectorAll(\"table#" + tableId
                        + "\");" + n
                + "            for (var i = 0; i < sort_Table.length; i++) {" + n
                + "                new tableSort(sort_Table[i]);" + n
                + "            }" + n
                + "        } // initTable" + n
                + "    if (window.addEventListener) {" + n
                + "        window.addEventListener(\"DOMContentLoaded\", initTableSort, false); "
                        +              "// nicht im IE8" + n
                + "    }" + n
                + "</script>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendTableSortingJavaScriptWithRowBackgroundColorAdjustment() {
        String tableId = "TABLE_ID";
        String titleForSameRowColor = "HUP";
        String cssClassForOddRows = "evenPrepageTableRow";
        String cssClassForEvenRows = "oddPrepageTableRow";

        HtmlBuilder html = new HtmlBuilder()
                .appendTableSortingJavaScriptWithRowBackgroundColorAdjustment(tableId,
                        titleForSameRowColor, cssClassForOddRows, cssClassForEvenRows)
                ;

        String actual = html.toString();
        String expected = ""
                + "<script>" + n
                + "    \"use strict\";" + n
                + "    var tableSort = function (tab) {" + n
                + "            var titel = tab.getElementsByTagName(\"thead\")[0]" + n
                + "                    .getElementsByTagName(\"tr\")[0]."
                        +                      "getElementsByTagName(\"th\");" + n
                + "" + n
                + "            var hupIndex = -1;" + n
                + "            for (var t = 0; t < titel.length; t++) {" + n
                + "                var tinner = titel[t];" + n
                + "                var tinnerX = tinner.innerHTML;" + n
                + "                if (0 == tinnerX.localeCompare(\"" + titleForSameRowColor + "\")) {" + n
                + "                    hupIndex = t;" + n
                + "                }" + n
                + "            }" + n
                + "" + n
                + "            var tbdy = tab.getElementsByTagName(\"tbody\")[0];" + n
                + "            var tz = tbdy.rows;" + n
                + "            var nzeilen = tz.length;" + n
                + "            if (nzeilen == 0) {" + n
                + "                return;" + n
                + "            }" + n
                + "            var nspalten = tz[0].cells.length;" + n
                + "            var arr = new Array(nzeilen);" + n
                + "            var sortiert = -1;" + n
                + "            var sorttype = new Array(nspalten);" + n
                + "            var sortbuttonStyle = document.createElement('style'); "
                        +                                          "// Stylesheet für Button im TH" + n
                + "            sortbuttonStyle.innerText =" + n
                + "                '.sortbutton { width:100%; height:100%; border: none; "
                        +            "background-color: transparent; font: inherit; "
                        +            "color: inherit; text-align: inherit; padding: 0; "
                        +            "cursor: pointer; } "
                        +        ".sortbutton::-moz-focus-inner { margin: -1px; "
                        +            "border-width: 1px; padding: 0; }';" + n
                + "            document.head.appendChild(sortbuttonStyle);" + n
                + "            var initTableHead = function (sp) { // Kopfzeile vorbereiten" + n
                + "                var b = document.createElement(\"button\");" + n
                + "                b.type = \"button\";" + n
                + "                b.className = \"sortbutton\";" + n
                + "                b.innerHTML = titel[sp].innerHTML;" + n
                + "                b.addEventListener(\"click\", function () {" + n
                + "                    tsort(sp);" + n
                + "                }, false);" + n
                + "                titel[sp].innerHTML = \"\";" + n
                + "                titel[sp].appendChild(b);" + n
                + "            }" + n
                + "            var getData = function (ele, s) {" + n
                + "                    var val = ele.textContent; // Nicht im IE8" + n
                + "                    if (!isNaN(val) && val.search(/[0-9]/) != -1) return val;" + n
                + "                    var n = val.replace(\",\", \".\");" + n
                + "                    if (!isNaN(n) && n.search(/[0-9]/) != -1) return n;" + n
                + "                    sorttype[s] = \"s\"; // String" + n
                + "                    return val;" + n
                + "                } // getData" + n
                + "            var vglFkt_s = function (a, b) {" + n
                + "                    var as = a[sortiert]," + n
                + "                        bs = b[sortiert];" + n
                + "                    if (as > bs) {" + n
                + "                        return 1;" + n
                + "                    }" + n
                + "                    else {" + n
                + "                        return -1;" + n
                + "                    }" + n
                + "                } // vglFkt_s" + n
                + "            var vglFkt_n = function (a, b) {" + n
                + "                    return parseFloat(a[sortiert]) - parseFloat(b[sortiert]);" + n
                + "                } // vglFkt_n" + n
                + "            var tsort = function (sp) {" + n
                + "                    if (sp == sortiert) {" + n
                + "                        // Tabelle ist schon nach dieser Spalte sortiert, also" + n
                + "                        // nur Reihenfolge umdrehen:" + n
                + "                        arr.reverse();" + n
                + "                    }" + n
                + "                    else { // Sortieren" + n
                + "                        sortiert = sp;" + n
                + "                        if (sorttype[sp] == \"n\") {" + n
                + "                            arr.sort(vglFkt_n);" + n
                + "                        }" + n
                + "                        else {" + n
                + "                            arr.sort(vglFkt_s);" + n
                + "                        }" + n
                + "                    }" + n
                + "                    for (var z = 0; z < nzeilen; z++) {" + n
                + "                        tbdy.appendChild(arr[z][nspalten]); "
                        +                              "// Sortierte Daten zurückschreiben" + n
                + "                    }" + n
                + "" + n
                + "                    if (-1 < hupIndex) {" + n
                + "                        var oldHup = \"\";" + n
                + "                        var rowClass = \"" + cssClassForOddRows + "\";" + n
                + "                        for (var z = 0; z < nzeilen; z++) {" + n
                + "                            var row = tz[z];" + n
                + "                            var hupCell = row.cells[hupIndex];" + n
                + "                            var hup = hupCell.innerHTML;" + n
                + "" + n
                + "                            var classList = row.classList;" + n
                + "                            if (classList.contains(\"" + cssClassForEvenRows
                        + "\")) {" + n
                + "                                classList.remove(\"" + cssClassForEvenRows
                        + "\");" + n
                + "                            }" + n
                + "                            if (classList.contains(\"" + cssClassForOddRows
                        + "\")) {" + n
                + "                                classList.remove(\"" + cssClassForOddRows
                        + "\");" + n
                + "                            }" + n
                + "" + n
                + "                            //console.log(\"z=\", z, \", hup=\", hup, \", "
                            + "oldHup=\", oldHup, \", diff=\", hup.localeCompare(oldHup));" + n
                + "                            if (0 != hup.localeCompare(oldHup)) {" + n
                + "                                if (0 == rowClass.localeCompare(\""
                            + cssClassForOddRows + "\")) {" + n
                + "                                    rowClass = \"" + cssClassForEvenRows
                        + "\";" + n
                + "                                }" + n
                + "                                else {" + n
                + "                                    rowClass = \"" + cssClassForOddRows
                    + "\";" + n
                + "                                }" + n
                + "                            }" + n
                + "                            classList.add(rowClass);" + n
                + "                            oldHup = hup;" + n
                + "                        }" + n
                + "                    }" + n
                + "" + n
                + "                } // tsort" + n
                + "            // Kopfzeile vorbereiten" + n
                + "            for (var i = 0; i < titel.length; i++) {" + n
                + "                initTableHead(i);" + n
                + "            }" + n
                + "            // Array mit Info, wie Spalte zu sortieren ist, vorbelegen" + n
                + "            for (var s = 0; s < nspalten; s++) {" + n
                + "                sorttype[s] = \"n\";" + n
                + "            }" + n
                + "            // Tabelleninhalt in ein Array kopieren" + n
                + "            for (var z = 0; z < nzeilen; z++) {" + n
                + "                var zelle = tz[z].getElementsByTagName(\"td\"); // cells;" + n
                + "                arr[z] = new Array(nspalten + 1);" + n
                + "                arr[z][nspalten] = tz[z];" + n
                + "                for (var s = 0; s < nspalten; s++) {" + n
                + "                    var zi = getData(zelle[s], s);" + n
                + "                    arr[z][s] = zi;" + n
                + "                    // zelle[s].innerHTML += \"<br>\"+zi+\"<br>\"+sorttype[s]; "
                        +                     "// zum Debuggen" + n
                + "                }" + n
                + "            }" + n
                + "        } // tableSort" + n
                + "    var initTableSort = function () {" + n
                + "            var sort_Table = document.querySelectorAll(\"table#" + tableId
                        + "\");" + n
                + "            for (var i = 0; i < sort_Table.length; i++) {" + n
                + "                new tableSort(sort_Table[i]);" + n
                + "            }" + n
                + "        } // initTable" + n
                + "    if (window.addEventListener) {" + n
                + "        window.addEventListener(\"DOMContentLoaded\", initTableSort, false); "
                        +              "// nicht im IE8" + n
                + "    }" + n
                + "</script>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendOpeningAndClosingTag() {
        String tag = "TAG";

        HtmlBuilder html = new HtmlBuilder()
                .appendLn("vorher")
                .appendOpeningTag(tag)
                .appendLn("im Tag")
                .appendClosingTag(tag)
                .appendLn("nachher")
                ;

        String actual = html.toString();
        String expected = ""
                + "vorher" + n
                + "<" + tag + ">" + n
                + "    im Tag" + n
                + "</" + tag + ">" + n
                + "nachher" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendOpeningAndClosingTagWithClass() {
        String tag = "TAG";
        String cssClass = "CSS-KLASSE";

        HtmlBuilder html = new HtmlBuilder()
                .appendLn("vorher")
                .appendOpeningTagWithClass(tag, cssClass)
                .appendLn("im Tag")
                .appendClosingTag(tag)
                .appendLn("nachher")
                ;

        String actual = html.toString();
        String expected = ""
                + "vorher" + n
                + "<" + tag + " class=\"" + cssClass + "\">" + n
                + "    im Tag" + n
                + "</" + tag + ">" + n
                + "nachher" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendOpeningAndClosingTagWithId() {
        String tag = "TAG";
        String id = "ID";

        HtmlBuilder html = new HtmlBuilder()
                .appendLn("vorher")
                .appendOpeningTagWithId(tag, id)
                .appendLn("im Tag")
                .appendClosingTag(tag)
                .appendLn("nachher")
                ;

        String actual = html.toString();
        String expected = ""
                + "vorher" + n
                + "<" + tag + " id=\"" + id + "\">" + n
                + "    im Tag" + n
                + "</" + tag + ">" + n
                + "nachher" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendPWithClass() {
        String text = "TEXT";
        String cssClass = "CSS-KLASSE";

        HtmlBuilder html = new HtmlBuilder()
                .appendPWithClass(text, cssClass)
                ;

        String actual = html.toString();
        String expected = ""
                + "<p class=\"" + cssClass + "\">" + text  + "</p>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendInSpanWithClass() {
        String text = "TEXT";
        String cssClass = "CSS-KLASSE";

        HtmlBuilder html = new HtmlBuilder()
                .appendSpanWithClass(text, cssClass)
                ;

        String actual = html.toString();
        String expected = ""
                + "<span class=\"" + cssClass + "\">" + text  + "</span>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendInSpanWithId() {
        String text = "TEXT";
        String id = "ID";

        HtmlBuilder html = new HtmlBuilder()
                .appendSpanWithId(text, id)
                ;

        String actual = html.toString();
        String expected = ""
                + "<span id=\"" + id + "\">" + text  + "</span>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void spans() {
        HtmlBuilder html = new HtmlBuilder()
                .appendOpeningSpan()
                .appendLn("Inhalt 1")
                .appendClosingSpan()
                .appendOpeningSpanWithClass("Css-Klasse")
                .appendLn("Inhalt 2")
                .appendClosingSpan()
                .appendOpeningSpanWithId("ID")
                .appendLn("Inhalt 3")
                .appendClosingSpan()
                .appendOpeningSpanWithIdAndClass("ID", "Css-Klasse")
                .appendLn("Inhalt 4")
                .appendClosingSpan()
                ;

        String actual = html.toString();
        String expected = ""
                + "<span>" + n
                + "    Inhalt 1" + n
                + "</span>" + n
                + "<span class=\"Css-Klasse\">" + n
                + "    Inhalt 2" + n
                + "</span>" + n
                + "<span id=\"ID\">" + n
                + "    Inhalt 3" + n
                + "</span>" + n
                + "<span id=\"ID\" class=\"Css-Klasse\">" + n
                + "    Inhalt 4" + n
                + "</span>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void headerMainFooter() {
        HtmlBuilder html = new HtmlBuilder()
                .appendOpeningHeader()
                .appendP("In Header")
                .appendClosingHeader()
                .appendOpeningMain()
                .appendP("In Main")
                .appendClosingMain()
                .appendOpeningFooter()
                .appendP("In Footer")
                .appendClosingFooter()
                ;

        String actual = html.toString();
        String expected = ""
                + "<header>" + n
                + "    <p>In Header</p>" + n
                + "</header>" + n
                + "<main>" + n
                + "    <p>In Main</p>" + n
                + "</main>" + n
                + "<footer>" + n
                + "    <p>In Footer</p>" + n
                + "</footer>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void h1AtStartWithoutNewLine() {
        HtmlBuilder html = new HtmlBuilder()
                .appendH1("Dies")
                ;

        String actual = html.toString();
        String expected = ""
                + "<h1 id=\"id1\">Dies</h1>" + n
                ;
            assertEquals(expected, actual);
    }

    @Test
    public void h1AfterOpeningTagWithoutNewLine() {
        HtmlBuilder html = new HtmlBuilder()
                .appendOpeningDiv()
                .appendH1("Dies")
                .appendClosingDiv()
                ;

        String actual = html.toString();
        String expected = ""
                + "<div>" + n
                + "    <h1 id=\"id1\">Dies</h1>" + n
                + "</div>" + n
                ;
            assertEquals(expected, actual);
    }

    @Test
    public void openingAndClosingThAndTds() {
        HtmlBuilder html = new HtmlBuilder()
                .appendOpeningTable()
                .appendOpeningTr()
                .appendOpeningTh()
                .appendLn("Überschrift")
                .appendClosingTh()
                .appendClosingTr()
                .appendOpeningTr()
                .appendOpeningTd()
                .appendLn("Eintrag 1")
                .appendClosingTd()
                .appendClosingTr()
                .appendOpeningTr()
                .appendOpeningTd()
                .appendLn("Eintrag 2")
                .appendClosingTd()
                .appendClosingTr()
                .appendClosingTable()
                ;

        String actual = html.toString();
        String expected = ""
                + "<table>" + n
                + "    <tr>" + n
                + "        <th>" + n
                + "            Überschrift" + n
                + "        </th>" + n
                + "    </tr>" + n
                + "    <tr>" + n
                + "        <td>" + n
                + "            Eintrag 1" + n
                + "        </td>" + n
                + "    </tr>" + n
                + "    <tr>" + n
                + "        <td>" + n
                + "            Eintrag 2" + n
                + "        </td>" + n
                + "    </tr>" + n
                + "</table>" + n
                ;
            assertEquals(expected, actual);
    }

    @Test
    public void openingAndClosingLeftAlignedThAndTds() {
        HtmlBuilder html = new HtmlBuilder()
                .appendOpeningTable()
                .appendOpeningTr()
                .appendOpeningLeftAlignedTh()
                .appendLn("Überschrift")
                .appendClosingTh()
                .appendClosingTr()
                .appendOpeningTr()
                .appendOpeningTd()
                .appendLn("Eintrag 1")
                .appendClosingTd()
                .appendClosingTr()
                .appendOpeningTr()
                .appendOpeningTd()
                .appendLn("Eintrag 2")
                .appendClosingTd()
                .appendClosingTr()
                .appendClosingTable()
                ;

        String actual = html.toString();
        String expected = ""
                + "<table>" + n
                + "    <tr>" + n
                + "        <th align=\"left\">" + n
                + "            Überschrift" + n
                + "        </th>" + n
                + "    </tr>" + n
                + "    <tr>" + n
                + "        <td>" + n
                + "            Eintrag 1" + n
                + "        </td>" + n
                + "    </tr>" + n
                + "    <tr>" + n
                + "        <td>" + n
                + "            Eintrag 2" + n
                + "        </td>" + n
                + "    </tr>" + n
                + "</table>" + n
                ;
            assertEquals(expected, actual);
    }

    @Test
    public void appendFrameWithSource() {
        String sourceCode = ""
                + "<!DOCTYPE html>" + n
                + "<html>" + n
                + "    <head>" + n
                + "        <title>Multitest 1</title>" + n
                + "    </head>" + n
                + "" + n
                + "" + n
                + "    <body>" + n
                + "        <div class=\"css-class-main\">" + n
                + "            <h1 id=\"id1\">Dies</h1>" + n
                + "" + n
                + "            <h2 id=\"id1_1\">Unterpunkt 1</h2>" + n
                + "            <ol>" + n
                + "                <li>foo</li>" + n
                + "                <li>bar</li>" + n
                + "                <li>baz</li>" + n
                + "            </ol>" + n
                + "" + n
                + "            <h2 id=\"id1_2\">Unterpunkt 2</h2>" + n
                + "            <ol start=\"4\">" + n
                + "                <li>foo</li>" + n
                + "                <li>bar</li>" + n
                + "                <li>baz</li>" + n
                + "            </ol>" + n
                + "            <a href=\"#top\">Zum Seitenanfang</a>" + n
                + "" + n
                + "            <h1 id=\"id2\">Das</h1>" + n
                + "            <pre>pre pre pre</pre>" + n
                + "        </div>" + n
                + "" + n
                + "    </body>" + n
                + "</html>" + n
                ;
        HtmlBuilder html = new HtmlBuilder()
                .appendP("Absatz davor")
                .appendFrameWithSource(sourceCode)
                .appendP("Absatz danach")
                ;

        String actual = html.toString();
        String expected = ""
                + "<p>Absatz davor</p>" + n
                + "<iframe srcdoc='" + n
                + "        <!DOCTYPE html>" + n
                + "        <html>" + n
                + "            <head>" + n
                + "                <title>Multitest 1</title>" + n
                + "            </head>" + n
                + "" + n
                + "" + n
                + "            <body>" + n
                + "                <div class=\"css-class-main\">" + n
                + "                    <h1 id=\"id1\">Dies</h1>" + n
                + "" + n
                + "                    <h2 id=\"id1_1\">Unterpunkt 1</h2>" + n
                + "                    <ol>" + n
                + "                        <li>foo</li>" + n
                + "                        <li>bar</li>" + n
                + "                        <li>baz</li>" + n
                + "                    </ol>" + n
                + "" + n
                + "                    <h2 id=\"id1_2\">Unterpunkt 2</h2>" + n
                + "                    <ol start=\"4\">" + n
                + "                        <li>foo</li>" + n
                + "                        <li>bar</li>" + n
                + "                        <li>baz</li>" + n
                + "                    </ol>" + n
                + "                    <a href=\"#top\">Zum Seitenanfang</a>" + n
                + "" + n
                + "                    <h1 id=\"id2\">Das</h1>" + n
                + "                    <pre>pre pre pre</pre>" + n
                + "                </div>" + n
                + "" + n
                + "            </body>" + n
                + "        </html>" + n
                + "    ' sandbox=\"\">" + n
                + "</iframe>" + n
                + "<p>Absatz danach</p>" + n
                ;
            assertEquals(expected, actual);
    }

    @Test
    public void appendFrameWithSourceAndClass() {
        String cssClass = "CSS-KLASSE";

        String sourceCode = ""
                + "<!DOCTYPE html>" + n
                + "<html>" + n
                + "    <head>" + n
                + "        <title>Multitest 1</title>" + n
                + "    </head>" + n
                + "" + n
                + "" + n
                + "    <body>" + n
                + "        <div class=\"css-class-main\">" + n
                + "            <h1 id=\"id1\">Dies</h1>" + n
                + "" + n
                + "            <h2 id=\"id1_1\">Unterpunkt 1</h2>" + n
                + "            <ol>" + n
                + "                <li>foo</li>" + n
                + "                <li>bar</li>" + n
                + "                <li>baz</li>" + n
                + "            </ol>" + n
                + "" + n
                + "            <h2 id=\"id1_2\">Unterpunkt 2</h2>" + n
                + "            <ol start=\"4\">" + n
                + "                <li>foo</li>" + n
                + "                <li>bar</li>" + n
                + "                <li>baz</li>" + n
                + "            </ol>" + n
                + "            <a href=\"#top\">Zum Seitenanfang</a>" + n
                + "" + n
                + "            <h1 id=\"id2\">Das</h1>" + n
                + "            <pre>pre pre pre</pre>" + n
                + "        </div>" + n
                + "" + n
                + "    </body>" + n
                + "</html>" + n
                ;
        HtmlBuilder html = new HtmlBuilder()
                .appendP("Absatz davor")
                .appendFrameWithSource(cssClass, sourceCode)
                .appendP("Absatz danach")
                ;

        String actual = html.toString();
        String expected = ""
                + "<p>Absatz davor</p>" + n
                + "<iframe class=\"" + cssClass + "\" srcdoc='" + n
                + "        <!DOCTYPE html>" + n
                + "        <html>" + n
                + "            <head>" + n
                + "                <title>Multitest 1</title>" + n
                + "            </head>" + n
                + "" + n
                + "" + n
                + "            <body>" + n
                + "                <div class=\"css-class-main\">" + n
                + "                    <h1 id=\"id1\">Dies</h1>" + n
                + "" + n
                + "                    <h2 id=\"id1_1\">Unterpunkt 1</h2>" + n
                + "                    <ol>" + n
                + "                        <li>foo</li>" + n
                + "                        <li>bar</li>" + n
                + "                        <li>baz</li>" + n
                + "                    </ol>" + n
                + "" + n
                + "                    <h2 id=\"id1_2\">Unterpunkt 2</h2>" + n
                + "                    <ol start=\"4\">" + n
                + "                        <li>foo</li>" + n
                + "                        <li>bar</li>" + n
                + "                        <li>baz</li>" + n
                + "                    </ol>" + n
                + "                    <a href=\"#top\">Zum Seitenanfang</a>" + n
                + "" + n
                + "                    <h1 id=\"id2\">Das</h1>" + n
                + "                    <pre>pre pre pre</pre>" + n
                + "                </div>" + n
                + "" + n
                + "            </body>" + n
                + "        </html>" + n
                + "    ' sandbox=\"\">" + n
                + "</iframe>" + n
                + "<p>Absatz danach</p>" + n
                ;
            assertEquals(expected, actual);
    }

    @Test
    public void multitest1() {
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithTitle("Multitest 1")
                .appendOpeningDivWithClass("css-class-main")
                .appendH1("Dies")
                .appendH2("Unterpunkt 1")
                .appendOpeningOl()
                .appendLi("foo")
                .appendLi("bar")
                .appendLi("baz")
                .appendClosingOl()
                .appendH2("Unterpunkt 2")
                .appendOpeningOlStart(4)
                .appendLi("foo")
                .appendLi("bar")
                .appendLi("baz")
                .appendClosingOl()
                .appendH1("Das")
                .appendPre("pre pre pre")
                .appendClosingDiv()
                .appendFoot()
                ;

        String actual = html.toString();
        String expected = ""
                + "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Multitest 1</title>" + n
                + "    </head>" + n
                + "" + n
                + "" + n
                + "    <body>" + n
                + "        <div class=\"css-class-main\">" + n
                + "            <h1 id=\"id1\">Dies</h1>" + n
                + "" + n
                + "            <h2 id=\"id1_1\">Unterpunkt 1</h2>" + n
                + "            <ol>" + n
                + "                <li>foo</li>" + n
                + "                <li>bar</li>" + n
                + "                <li>baz</li>" + n
                + "            </ol>" + n
                + "" + n
                + "            <h2 id=\"id1_2\">Unterpunkt 2</h2>" + n
                + "            <ol start=\"4\">" + n
                + "                <li>foo</li>" + n
                + "                <li>bar</li>" + n
                + "                <li>baz</li>" + n
                + "            </ol>" + n
                + "            <a href=\"#top\">Zum Seitenanfang</a>" + n
                + "" + n
                + "            <h1 id=\"id2\">Das</h1>" + n
                + "            <pre>pre pre pre</pre>" + n
                + "        </div>" + n
                + "" + n
                + "    </body>" + n
                + "</html>" + n
                ;
            assertEquals(expected, actual);
    }

    @Test
    public void appendOnRowClickJavaScript() {
        HtmlBuilder html = new HtmlBuilder()
                .appendOnRowClickJavaScript()
                ;

        String actual = html.toString();
        String expected = ""
                + "<script>" + n
                + "    function onRowClick(tableId, callback) {" + n
                + "        var table = document.getElementById(tableId);" + n
                + "        var rows = table.getElementsByTagName(\"tr\");" + n
                + "        for (var index = 0; index < rows.length; index++) {" + n
                + "            var rowTable = function (row) {" + n
                + "                return function () {" + n
                + "                    callback(row);" + n
                + "                };" + n
                + "            };" + n
                + "            table.rows[index].onclick = rowTable(table.rows[index]);" + n
                + "        }" + n
                + "    };" + n
                + "</script>" + n
                ;
            assertEquals(expected, actual);
    }

    @Test
    public void appendLabelAndSpinner() {
        String field = "matchingIdColumn";
        String fieldTitle = "ID";
        int min = 1;
        int max = 100;
        int step = 1;
        String value = "1";

        String cssLabelClass = "twoColumnSpinnerLabel";
        String cssSpinnerClass = "twoColumnSpinner";

        HtmlBuilder html = new HtmlBuilder()
                .appendLabelAndSpinner(field, fieldTitle, min, max, step, value, cssLabelClass,
                        cssSpinnerClass)
                ;

        String actual = html.toString();
        String expected = ""
                + "<p>" + n
                + "    <label class=\"" + cssLabelClass + "\" for=\"" + field + "\">"
                        + fieldTitle + "</label>" + n
                + "    <input id=\"" + field + "\" "
                        + "type=\"number\" "
                        + "name=\"" + field + "\" "
                        + "min=\"" + min + "\" "
                        + "max=\"" + max + "\" "
                        + "step=\"" + step + "\" "
                        + "value=\"" + value + "\" "
                        + "class=\"" + cssSpinnerClass + "\""
                        + "/>" + n
                + "</p>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendSpinner() {
        String field = "matchingIdColumn";
        int min = 1;
        int max = 100;
        int step = 1;
        String value = "1";

        String cssClass = "twoColumnSpinner";

        HtmlBuilder html = new HtmlBuilder()
                .appendSpinner(field, min, max, step, value, cssClass)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input id=\"" + field + "\" "
                + "type=\"number\" "
                + "name=\"" + field + "\" "
                + "min=\"" + min + "\" "
                + "max=\"" + max + "\" "
                + "step=\"" + step + "\" "
                + "value=\"" + value + "\" "
                + "class=\"" + cssClass + "\""
                + "/>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendInputCheckboxWithOnClickScript() {
        String field = "FIELD";
        boolean selected = false;
        String jsCall = "JS-CALL";

        HtmlBuilder html = new HtmlBuilder()
                .appendInputCheckboxWithOnClickScript(field, selected, jsCall)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input id=\"" + field + "\" "
                + "type=\"checkbox\" "
                + "name=\"" + field + "\" "
                + "onclick=\"" + "javascript: JS-CALL" + "\""
                + "/>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendSelectedInputCheckboxWithOnClickScript() {
        String field = "FIELD";
        boolean selected = true;
        String jsCall = "JS-CALL";

        HtmlBuilder html = new HtmlBuilder()
                .appendInputCheckboxWithOnClickScript(field, selected, jsCall)
                ;

        String actual = html.toString();
        String expected = ""
                + "<input id=\"" + field + "\" "
                + "type=\"checkbox\" "
                + "name=\"" + field + "\" "
                + "onclick=\"" + "javascript: JS-CALL" + "\""
                + " checked"
                + "/>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendLabelAndCheckBoxWithOnClickScript() {
        String field = "FIELD";
        String fieldTitle = "FIELD-TITLE";
        boolean selected = false;
        String jsCall = "JS-CALL";
        String cssLabelClass = "CSS-CLASS";

        HtmlBuilder html = new HtmlBuilder()
                .appendLabelAndCheckBoxWithOnClickScript(field, fieldTitle, selected, jsCall,
                        cssLabelClass)
                ;

        String actual = html.toString();
        String expected = "<p>" + n
                + "    <label class=\"" + cssLabelClass + "\" "
                            + "for=\"" + field + "\">"
                            + fieldTitle
                            + "</label>" + n
                + "    <input id=\"" + field + "\" "
                            + "type=\"checkbox\" "
                            + "name=\"" + field + "\" "
                            + "onclick=\"" + "javascript: JS-CALL" + "\""
                            + "/>" + n
                + "</p>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendSelectedLabelAndCheckBoxWithOnClickScript() {
        String field = "FIELD";
        String fieldTitle = "FIELD-TITLE";
        boolean selected = true;
        String jsCall = "JS-CALL";
        String cssLabelClass = "CSS-CLASS";

        HtmlBuilder html = new HtmlBuilder()
                .appendLabelAndCheckBoxWithOnClickScript(field, fieldTitle, selected, jsCall,
                        cssLabelClass)
                ;

        String actual = html.toString();
        String expected = "<p>" + n
                + "    <label class=\"" + cssLabelClass + "\" "
                            + "for=\"" + field + "\">"
                            + fieldTitle
                            + "</label>" + n
                + "    <input id=\"" + field + "\" "
                            + "type=\"checkbox\" "
                            + "name=\"" + field + "\" "
                            + "onclick=\"" + "javascript: JS-CALL" + "\""
                            + " checked"
                            + "/>" + n
                + "</p>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendSwitchMaximumHitsFieldJavaScript() {
        HtmlBuilder html = new HtmlBuilder()
                .appendSwitchMaximumHitsFieldJavaScript()
                ;

        String actual = html.toString();
        String expected = "<script>" + n
                + "    function switch_maximum_hits_field(idMaxHits, idCheckBox) {" + n
                + "        inputField = document.getElementById(idMaxHits);" + n
                + "        checkbox = document.getElementById(idCheckBox);" + n
                + "        if (checkbox.checked) {" + n
                + "            inputField.disabled = true;" + n
                + "        }" + n
                + "        else {" + n
                + "            inputField.disabled = false;" + n
                + "        }" + n
                + "    }" + n
                + "</script>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void createAnchor() {
        String anchor = "ANCHOR";

        HtmlBuilder html = new HtmlBuilder()
                .createAnchor(anchor)
                ;

        String actual = html.toString();
        String expected = "<a name=\"" + anchor + "\"/>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHtml5HeadWithOwnCss() {
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithOwnCss("Sehr schöne Seite!")
                ;

        String actual = html.toString();
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Sehr schöne Seite!</title>" + n
                + Text.indent(CSS, 2) + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void withoutContentWithOwnCss() {
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithOwnCssUtf8("Ein tolles HTML-Dokument")
                .appendH1("Überschrift 1")
                .appendH2("Unterpunkt 1.1")
                .appendH2("Unterpunkt 1.2")
                .appendH1("Überschrift 2")
                .appendH2("Unterpunkt 2.1")
                .appendH3("Unterpunkt 2.1.1")
                .appendH1("Überschrift 3")
                .appendH2("Unterpunkt 3.1")
                .appendH3("Unterpunkt 3.1.1")
                .appendH4("Unterpunkt 3.1.1.1")
                .appendH3("Unterpunkt 3.1.2")
                .appendH4("Unterpunkt 3.1.2.1")
                .appendH5("Unterpunkt 3.1.2.1.1")
                .appendH6("Unterpunkt 3.1.2.1.1.1")
                .appendFoot()
                ;

        String actual = html.toString();
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Ein tolles HTML-Dokument</title>" + n
                + "        <meta charset=\"utf-8\">" + n
                + Text.indent(CSS, 2) + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                + "        <h1 id=\"id1\">Überschrift 1</h1>" + n + n
                + "        <h2 id=\"id1_1\">Unterpunkt 1.1</h2>" + n + n
                + "        <h2 id=\"id1_2\">Unterpunkt 1.2</h2>" + n
                + "        <a href=\"#top\">Zum Seitenanfang</a>" + n + n
                + "        <h1 id=\"id2\">Überschrift 2</h1>" + n + n
                + "        <h2 id=\"id2_3\">Unterpunkt 2.1</h2>" + n + n
                + "        <h3 id=\"id2_3_1\">Unterpunkt 2.1.1</h3>" + n
                + "        <a href=\"#top\">Zum Seitenanfang</a>" + n + n
                + "        <h1 id=\"id3\">Überschrift 3</h1>" + n + n
                + "        <h2 id=\"id3_4\">Unterpunkt 3.1</h2>" + n + n
                + "        <h3 id=\"id3_4_2\">Unterpunkt 3.1.1</h3>" + n + n
                + "        <h4 id=\"id3_4_2_1\">Unterpunkt 3.1.1.1</h4>" + n + n
                + "        <h3 id=\"id3_4_3\">Unterpunkt 3.1.2</h3>" + n + n
                + "        <h4 id=\"id3_4_3_2\">Unterpunkt 3.1.2.1</h4>" + n + n
                + "        <h5 id=\"id3_4_3_2_1\">Unterpunkt 3.1.2.1.1</h5>" + n + n
                + "        <h6 id=\"id3_4_3_2_1_1\">Unterpunkt 3.1.2.1.1.1</h6>" + n + n
                //+ "    <a href=\"#top\">Zum Seitenanfang</a>" + n
                + "    </body>" + n
                + "</html>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void withoutContentAndToplinksWithOwnCss() {
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithOwnCssUtf8("Ein tolles HTML-Dokument")
                .hideTopLinks()
                .appendH1("Überschrift 1")
                .appendH2("Unterpunkt 1.1")
                .appendH2("Unterpunkt 1.2")
                .appendH1("Überschrift 2")
                .appendH2("Unterpunkt 2.1")
                .appendH3("Unterpunkt 2.1.1")
                .appendH1("Überschrift 3")
                .appendH2("Unterpunkt 3.1")
                .appendH3("Unterpunkt 3.1.1")
                .appendH4("Unterpunkt 3.1.1.1")
                .appendH3("Unterpunkt 3.1.2")
                .appendH4("Unterpunkt 3.1.2.1")
                .appendH5("Unterpunkt 3.1.2.1.1")
                .appendH6("Unterpunkt 3.1.2.1.1.1")
                .appendFoot()
                ;

        String actual = html.toString();
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Ein tolles HTML-Dokument</title>" + n
                + "        <meta charset=\"utf-8\">" + n
                + Text.indent(CSS, 2) + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                + "        <h1 id=\"id1\">Überschrift 1</h1>" + n + n
                + "        <h2 id=\"id1_1\">Unterpunkt 1.1</h2>" + n + n
                + "        <h2 id=\"id1_2\">Unterpunkt 1.2</h2>" + n + n
                + "        <h1 id=\"id2\">Überschrift 2</h1>" + n + n
                + "        <h2 id=\"id2_3\">Unterpunkt 2.1</h2>" + n + n
                + "        <h3 id=\"id2_3_1\">Unterpunkt 2.1.1</h3>" + n + n
                + "        <h1 id=\"id3\">Überschrift 3</h1>" + n + n
                + "        <h2 id=\"id3_4\">Unterpunkt 3.1</h2>" + n + n
                + "        <h3 id=\"id3_4_2\">Unterpunkt 3.1.1</h3>" + n + n
                + "        <h4 id=\"id3_4_2_1\">Unterpunkt 3.1.1.1</h4>" + n + n
                + "        <h3 id=\"id3_4_3\">Unterpunkt 3.1.2</h3>" + n + n
                + "        <h4 id=\"id3_4_3_2\">Unterpunkt 3.1.2.1</h4>" + n + n
                + "        <h5 id=\"id3_4_3_2_1\">Unterpunkt 3.1.2.1.1</h5>" + n + n
                + "        <h6 id=\"id3_4_3_2_1_1\">Unterpunkt 3.1.2.1.1.1</h6>" + n + n
                + "    </body>" + n
                + "</html>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void contentWithOwnCss() {
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithOwnCssUtf8("Ein tolles HTML-Dokument")
                .appendH1("Überschrift 1")
                .appendH2("Unterpunkt 1.1")
                .appendH2("Unterpunkt 1.2")
                .appendH1("Überschrift 2")
                .appendH2("Unterpunkt 2.1")
                .appendH3("Unterpunkt 2.1.1")
                .appendH1("Überschrift 3")
                .appendH2("Unterpunkt 3.1")
                .appendH3("Unterpunkt 3.1.1")
                .appendH4("Unterpunkt 3.1.1.1")
                .appendH3("Unterpunkt 3.1.2")
                .appendH4("Unterpunkt 3.1.2.1")
                .appendH5("Unterpunkt 3.1.2.1.1")
                .appendH6("Unterpunkt 3.1.2.1.1.1")
                .appendFoot()
                .insertContent()
                ;

        String actual = html.toString();
        String s = "&nbsp;&nbsp;&nbsp;&nbsp;";
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Ein tolles HTML-Dokument</title>" + n
                + "        <meta charset=\"utf-8\">" + n
                + Text.indent(CSS, 2) + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                + "        <h1>Inhaltsverzeichnis</h1>" + n
                + "        <a href=\"#id1\">Überschrift 1</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id1_1\">Unterpunkt 1.1</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id1_2\">Unterpunkt 1.2</a>" + n
                + "        <br />" + n
                + "        <a href=\"#id2\">Überschrift 2</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id2_3\">Unterpunkt 2.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + "<a href=\"#id2_3_1\">Unterpunkt 2.1.1</a>" + n
                + "        <br />" + n
                + "        <a href=\"#id3\">Überschrift 3</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id3_4\">Unterpunkt 3.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + "<a href=\"#id3_4_2\">Unterpunkt 3.1.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + "<a href=\"#id3_4_2_1\">Unterpunkt 3.1.1.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + "<a href=\"#id3_4_3\">Unterpunkt 3.1.2</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + "<a href=\"#id3_4_3_2\">Unterpunkt 3.1.2.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + s + "<a href=\"#id3_4_3_2_1\">Unterpunkt 3.1.2.1.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + s + s + "<a href=\"#id3_4_3_2_1_1\">"
                        + "Unterpunkt 3.1.2.1.1.1</a>" + n
                + "        <br />" + n + n
                + "        <h1 id=\"id1\">Überschrift 1</h1>" + n + n
                + "        <h2 id=\"id1_1\">Unterpunkt 1.1</h2>" + n + n
                + "        <h2 id=\"id1_2\">Unterpunkt 1.2</h2>" + n
                + "        <a href=\"#top\">Zum Seitenanfang</a>" + n + n
                + "        <h1 id=\"id2\">Überschrift 2</h1>" + n + n
                + "        <h2 id=\"id2_3\">Unterpunkt 2.1</h2>" + n + n
                + "        <h3 id=\"id2_3_1\">Unterpunkt 2.1.1</h3>" + n
                + "        <a href=\"#top\">Zum Seitenanfang</a>" + n + n
                + "        <h1 id=\"id3\">Überschrift 3</h1>" + n + n
                + "        <h2 id=\"id3_4\">Unterpunkt 3.1</h2>" + n + n
                + "        <h3 id=\"id3_4_2\">Unterpunkt 3.1.1</h3>" + n + n
                + "        <h4 id=\"id3_4_2_1\">Unterpunkt 3.1.1.1</h4>" + n + n
                + "        <h3 id=\"id3_4_3\">Unterpunkt 3.1.2</h3>" + n + n
                + "        <h4 id=\"id3_4_3_2\">Unterpunkt 3.1.2.1</h4>" + n + n
                + "        <h5 id=\"id3_4_3_2_1\">Unterpunkt 3.1.2.1.1</h5>" + n + n
                + "        <h6 id=\"id3_4_3_2_1_1\">Unterpunkt 3.1.2.1.1.1</h6>" + n + n
                + "    </body>" + n
                + "</html>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void contentBeforeFootWithOwnCss() {
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithOwnCssUtf8("Ein tolles HTML-Dokument")
                .appendH1("Überschrift 1")
                .appendH2("Unterpunkt 1.1")
                .appendH2("Unterpunkt 1.2")
                .appendH1("Überschrift 2")
                .appendH2("Unterpunkt 2.1")
                .appendH3("Unterpunkt 2.1.1")
                .appendH1("Überschrift 3")
                .appendH2("Unterpunkt 3.1")
                .appendH3("Unterpunkt 3.1.1")
                .appendH4("Unterpunkt 3.1.1.1")
                .appendH3("Unterpunkt 3.1.2")
                .appendH4("Unterpunkt 3.1.2.1")
                .appendH5("Unterpunkt 3.1.2.1.1")
                .appendH6("Unterpunkt 3.1.2.1.1.1")
                .insertContent()
                .appendFoot()
                ;

        String actual = html.toString();
        String s = "&nbsp;&nbsp;&nbsp;&nbsp;";
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Ein tolles HTML-Dokument</title>" + n
                + "        <meta charset=\"utf-8\">" + n
                + Text.indent(CSS, 2) + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                + "        <h1>Inhaltsverzeichnis</h1>" + n
                + "        <a href=\"#id1\">Überschrift 1</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id1_1\">Unterpunkt 1.1</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id1_2\">Unterpunkt 1.2</a>" + n
                + "        <br />" + n
                + "        <a href=\"#id2\">Überschrift 2</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id2_3\">Unterpunkt 2.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + "<a href=\"#id2_3_1\">Unterpunkt 2.1.1</a>" + n
                + "        <br />" + n
                + "        <a href=\"#id3\">Überschrift 3</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id3_4\">Unterpunkt 3.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + "<a href=\"#id3_4_2\">Unterpunkt 3.1.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + "<a href=\"#id3_4_2_1\">Unterpunkt 3.1.1.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + "<a href=\"#id3_4_3\">Unterpunkt 3.1.2</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + "<a href=\"#id3_4_3_2\">Unterpunkt 3.1.2.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + s + "<a href=\"#id3_4_3_2_1\">Unterpunkt 3.1.2.1.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + s + s + "<a href=\"#id3_4_3_2_1_1\">"
                        + "Unterpunkt 3.1.2.1.1.1</a>" + n
                + "        <br />" + n + n
                + "        <h1 id=\"id1\">Überschrift 1</h1>" + n + n
                + "        <h2 id=\"id1_1\">Unterpunkt 1.1</h2>" + n + n
                + "        <h2 id=\"id1_2\">Unterpunkt 1.2</h2>" + n
                + "        <a href=\"#top\">Zum Seitenanfang</a>" + n + n
                + "        <h1 id=\"id2\">Überschrift 2</h1>" + n + n
                + "        <h2 id=\"id2_3\">Unterpunkt 2.1</h2>" + n + n
                + "        <h3 id=\"id2_3_1\">Unterpunkt 2.1.1</h3>" + n
                + "        <a href=\"#top\">Zum Seitenanfang</a>" + n + n
                + "        <h1 id=\"id3\">Überschrift 3</h1>" + n + n
                + "        <h2 id=\"id3_4\">Unterpunkt 3.1</h2>" + n + n
                + "        <h3 id=\"id3_4_2\">Unterpunkt 3.1.1</h3>" + n + n
                + "        <h4 id=\"id3_4_2_1\">Unterpunkt 3.1.1.1</h4>" + n + n
                + "        <h3 id=\"id3_4_3\">Unterpunkt 3.1.2</h3>" + n + n
                + "        <h4 id=\"id3_4_3_2\">Unterpunkt 3.1.2.1</h4>" + n + n
                + "        <h5 id=\"id3_4_3_2_1\">Unterpunkt 3.1.2.1.1</h5>" + n + n
                + "        <h6 id=\"id3_4_3_2_1_1\">Unterpunkt 3.1.2.1.1.1</h6>" + n + n
                + "        <a href=\"#top\">Zum Seitenanfang</a>" + n
                + "    </body>" + n
                + "</html>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void contentAtEndWithOwnCss() {
        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithOwnCssUtf8("Ein tolles HTML-Dokument")
                .appendH1("Überschrift 1")
                .appendH2("Unterpunkt 1.1")
                .appendH2("Unterpunkt 1.2")
                .appendH1("Überschrift 2")
                .appendH2("Unterpunkt 2.1")
                .appendH3("Unterpunkt 2.1.1")
                .appendH1("Überschrift 3")
                .appendH2("Unterpunkt 3.1")
                .appendH3("Unterpunkt 3.1.1")
                .appendH4("Unterpunkt 3.1.1.1")
                .appendH3("Unterpunkt 3.1.2")
                .appendH4("Unterpunkt 3.1.2.1")
                .appendH5("Unterpunkt 3.1.2.1.1")
                .appendH6("Unterpunkt 3.1.2.1.1.1")
                .appendFoot()
                .insertContentAtEnd()
                ;

        String actual = html.toString();
        String s = "&nbsp;&nbsp;&nbsp;&nbsp;";
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>Ein tolles HTML-Dokument</title>" + n
                + "        <meta charset=\"utf-8\">" + n
                + Text.indent(CSS, 2) + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                + "        <h1 id=\"id1\">Überschrift 1</h1>" + n + n
                + "        <h2 id=\"id1_1\">Unterpunkt 1.1</h2>" + n + n
                + "        <h2 id=\"id1_2\">Unterpunkt 1.2</h2>" + n
                + "        <a href=\"#top\">Zum Seitenanfang</a>" + n + n
                + "        <h1 id=\"id2\">Überschrift 2</h1>" + n + n
                + "        <h2 id=\"id2_3\">Unterpunkt 2.1</h2>" + n + n
                + "        <h3 id=\"id2_3_1\">Unterpunkt 2.1.1</h3>" + n
                + "        <a href=\"#top\">Zum Seitenanfang</a>" + n + n
                + "        <h1 id=\"id3\">Überschrift 3</h1>" + n + n
                + "        <h2 id=\"id3_4\">Unterpunkt 3.1</h2>" + n + n
                + "        <h3 id=\"id3_4_2\">Unterpunkt 3.1.1</h3>" + n + n
                + "        <h4 id=\"id3_4_2_1\">Unterpunkt 3.1.1.1</h4>" + n + n
                + "        <h3 id=\"id3_4_3\">Unterpunkt 3.1.2</h3>" + n + n
                + "        <h4 id=\"id3_4_3_2\">Unterpunkt 3.1.2.1</h4>" + n + n
                + "        <h5 id=\"id3_4_3_2_1\">Unterpunkt 3.1.2.1.1</h5>" + n + n
                + "        <h6 id=\"id3_4_3_2_1_1\">Unterpunkt 3.1.2.1.1.1</h6>" + n + n
                + "    " + n
                + "        <h1>Inhaltsverzeichnis</h1>" + n
                + "        <a href=\"#id1\">Überschrift 1</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id1_1\">Unterpunkt 1.1</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id1_2\">Unterpunkt 1.2</a>" + n
                + "        <br />" + n
                + "        <a href=\"#id2\">Überschrift 2</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id2_3\">Unterpunkt 2.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + "<a href=\"#id2_3_1\">Unterpunkt 2.1.1</a>" + n
                + "        <br />" + n
                + "        <a href=\"#id3\">Überschrift 3</a>" + n
                + "        <br />" + n
                + "        " + s + "<a href=\"#id3_4\">Unterpunkt 3.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + "<a href=\"#id3_4_2\">Unterpunkt 3.1.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + "<a href=\"#id3_4_2_1\">Unterpunkt 3.1.1.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + "<a href=\"#id3_4_3\">Unterpunkt 3.1.2</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + "<a href=\"#id3_4_3_2\">Unterpunkt 3.1.2.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + s + "<a href=\"#id3_4_3_2_1\">Unterpunkt 3.1.2.1.1</a>" + n
                + "        <br />" + n
                + "        " + s + s + s + s + s + "<a href=\"#id3_4_3_2_1_1\">"
                        + "Unterpunkt 3.1.2.1.1.1</a>" + n
                + "        <br />" + n
                + "    </body>" + n
                + "</html>" + n;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHtml5HeadWithOwnCss2() {
        String title = "PAGE-TITLE";

        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithOwnCss(title)
                ;

        String actual = html.toString();
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>" + title + "</title>" + n
                + Text.indent(CSS, 2) + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHtml5HeadWithOwnCssUtf8() {
        String title = "PAGE-TITLE";

        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithOwnCssUtf8(title)
                ;

        String actual = html.toString();
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>" + title + "</title>" + n
                + "        <meta charset=\"utf-8\">" + n
                + Text.indent(CSS, 2) + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void extendStandardCss() {
        int point = 16;
        String extendedCss = HtmlBuilder.createBodyFontSizeInPointCssExtension(point);
        String actual = HtmlBuilder.extendStandardCss(extendedCss);
        String expected = ""
                + "<style>" + n
                + "    body {" + n
                + "        background-color:#E6E6FF;" + n
                + "        color:#000096;" + n
                + "        font-family:Verdana, sans-serif;" + n
                + "        font-size:14pt;" + n
                + "        margin-left:3%;" + n
                + "        margin-right:3%;" + n
                + "        color:#000096;" + n
                + "    }" + n
                + "    p {" + n
                + "        font-size:1em;" + n
                + "        font-family:Verdana, sans-serif;" + n
                + "        color:#000096;" + n
                + "    }" + n
                + "    h1 {" + n
                + "        text-align: left;" + n
                + "        font-size: 36pt;" + n
                + "        font-weight: bold;" + n
                + "        color:#000096;" + n
                + "        margin-top:25;" + n
                + "    }" + n
                + "    h1#id1 {" + n
                + "        margin-top:0;" + n
                + "    }" + n
                + "    h2 {" + n
                + "        text-align: left;" + n
                + "        font-size: 24pt;" + n
                + "        font-weight: bold;" + n
                + "        color:#000096;" + n
                + "        margin-bottom:8;" + n
                + "        margin-top:15;" + n
                + "    }" + n
                + "    h3 {" + n
                + "        font-size: 20pt;" + n
                + "        color:#000096;" + n
                + "        margin-bottom:0;" + n
                + "    }" + n
                + "    h4 {" + n
                + "        font-size: 18pt;" + n
                + "        color:#000096;" + n
                + "        margin-bottom:0;" + n
                + "    }" + n
                + "    h5 {" + n
                + "        font-size: 16pt;" + n
                + "        color:#000096;" + n
                + "        margin-bottom:0;" + n
                + "    }" + n
                + "    h6 {" + n
                + "        font-size: 15pt;" + n
                + "        color:#000096;" + n
                + "        margin-bottom:0;" + n
                + "    }" + n
                + "    .monospace {" + n
                + "        font-family: monospace;" + n
                + "    }" + n
                + "    body {" + n
                + "        font-size:" + point + "pt;" + n
                + "    }" + n
                + "</style>"
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHtml5HeadWithOwnExtendedCss() {
        String title = "PAGE-TITLE";

        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithOwnExtendedCss(title,
                        HtmlBuilder.createBodyFontSizeInPointCssExtension(16))
                ;

        String css = HtmlBuilder.extendStandardCss(
                HtmlBuilder.createBodyFontSizeInPointCssExtension(16));
        css = Text.indent(css, 2);

        String actual = html.toString();
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>" + title + "</title>" + n
                + css + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                ;
        assertEquals(expected, actual);
    }

    @Test
    public void appendHtml5HeadWithOwnExtendedCssUtf8() {
        String title = "PAGE-TITLE";

        HtmlBuilder html = new HtmlBuilder()
                .appendHtml5HeadWithOwnExtendedCssUtf8(title,
                        HtmlBuilder.createBodyFontSizeInPointCssExtension(16))
                ;

        String css = HtmlBuilder
                .extendStandardCss(HtmlBuilder.createBodyFontSizeInPointCssExtension(16));
        css = Text.indent(css, 2);

        String actual = html.toString();
        String expected = "<!DOCTYPE html>" + n
                + "<html lang=\"de\">" + n
                + "    <head>" + n
                + "        <title>" + title + "</title>" + n
                + "        <meta charset=\"utf-8\">" + n
                + css + n
                + "    </head>" + n + n + n
                + "    <body>" + n
                ;
        assertEquals(expected, actual);
    }

}
