Bug 476005 - Add property to define HTML capable components

https://bugs.eclipse.org/bugs/show_bug.cgi?id=476005

* Backport HTML builder from Scout 6.0
* Add property getConfiguredHtmlEnabled
* Encode HTML properly in RAP and Swing
* Extract cell text rendering in RAP to separate helper class
* Add validation in RWT UI and Swing UI layer
* Add IHtmlCapable to IMessageBox
* Add same behaviour in Swing and RAP for messagebox
* Extend CellTest

Change-Id: Ia62b39d1a0a851cf3dcf678ae92d069fbebea0d3
Reviewed-on: https://git.eclipse.org/r/66518
Tested-by: Hudson CI
Reviewed-by: Ken Lee <kle@bsiag.com>
diff --git a/.gitreview b/.gitreview
index 72cbe55..d04858a 100644
--- a/.gitreview
+++ b/.gitreview
@@ -2,6 +2,6 @@
 host=git.eclipse.org
 port=29418
 project=scout/org.eclipse.scout.rt.git
-defaultbranch=develop
+defaultbranch=releases/4.2.x
 defaultremote=origin
 defaultrebase=0
diff --git a/org.eclipse.scout.commons.test/src/org/eclipse/scout/commons/html/HTMLTest.java b/org.eclipse.scout.commons.test/src/org/eclipse/scout/commons/html/HTMLTest.java
new file mode 100644
index 0000000..b01cf31
--- /dev/null
+++ b/org.eclipse.scout.commons.test/src/org/eclipse/scout/commons/html/HTMLTest.java
@@ -0,0 +1,304 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html;
+
+import static org.eclipse.scout.commons.html.HTML.bold;
+import static org.eclipse.scout.commons.html.HTML.div;
+import static org.eclipse.scout.commons.html.HTML.italic;
+import static org.eclipse.scout.commons.html.HTML.link;
+import static org.eclipse.scout.commons.html.HTML.td;
+import static org.eclipse.scout.commons.html.HTML.tr;
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.scout.commons.CollectionUtility;
+import org.junit.Test;
+
+/**
+ * Tests for {@link HTML}
+ *
+ * @since 6.0 (backported)
+ */
+public class HTMLTest {
+  private static final String HTML_TEXT = "Test Last Name&";
+  private static final String ESCAPED_HTML_TEXT = "Test Last Name&amp;";
+  private static final String TEST_URL = "http://SCOUTBLABLA.com\"";
+
+  private static final String sampleCSS = "p {" +
+      "    text-align: center;" +
+      "    color: red;" +
+      "}";
+
+  @Test
+  public void testHtmlNoBinds() {
+    assertEncodedText("h1", HTML.h1(HTML_TEXT).toHtml());
+    assertEncodedText("h2", HTML.h2(HTML_TEXT).toHtml());
+    assertEncodedText("h3", HTML.h3(HTML_TEXT).toHtml());
+    assertEncodedText("h4", HTML.h4(HTML_TEXT).toHtml());
+    assertEncodedText("h5", HTML.h5(HTML_TEXT).toHtml());
+    assertEncodedText("h6", HTML.h6(HTML_TEXT).toHtml());
+    assertEncodedText("b", bold(HTML_TEXT).toHtml());
+    assertEncodedText("i", italic(HTML_TEXT).toHtml());
+    assertEncodedText("td", td(HTML_TEXT).toHtml());
+    assertEncodedText("div", div(HTML_TEXT).toHtml());
+    assertEncodedText("p", HTML.p(HTML_TEXT).toHtml());
+    assertEncodedText("span", HTML.span(HTML_TEXT).toHtml());
+    assertEncodedText("li", HTML.li(HTML_TEXT).toHtml());
+    assertEncodedText("head", HTML.head(HTML_TEXT).toHtml());
+    assertEncodedText("body", HTML.body(HTML_TEXT).toHtml());
+  }
+
+  /**
+   * Tests a link with URL and encoded text.
+   */
+  @Test
+  public void testLinkNoBinds() {
+    String html = HTML.link(TEST_URL, HTML_TEXT).toHtml();
+    assertEquals("<a href=\"" + TEST_URL.replace("\"", "&quot;") + "\">" + escape(HTML_TEXT) + "</a>", html);
+  }
+
+  /**
+   * Tests an image encoded source.
+   */
+  @Test
+  public void testImageNoBinds() {
+    String html = HTML.img("logo.png").toHtml();
+    assertEquals("<img src=\"logo.png\">", html);
+  }
+
+  @Test
+  public void testNullAttribute() {
+    assertEquals("<a href=\"\"></a>", HTML.link(null, null).toHtml());
+    assertEquals("<a href=\"\">&lt;a&gt;badlink&lt;&#47;a&gt;</a>", HTML.link(null, "<a>badlink</a>").toHtml());
+  }
+
+  /**
+   * Tests for {@link HTML#br()}
+   */
+  @Test
+  public void testBr() {
+    IHtmlElement br = HTML.br();
+    assertEquals("<br>", br.toHtml());
+  }
+
+  @Test
+  public void testAddAttribute() {
+    IHtmlElement span = HTML.span("text").addAttribute("name", "value");
+    assertEquals("<span name=\"value\">text</span>", span.toHtml());
+  }
+
+  /**
+   * Test for {@link IHtmlElement#appLink(CharSequence)}
+   */
+  @Test
+  public void testAppLinkNoBinds() {
+    final IHtmlElement html = HTML.appLink("domain=123&text=456", "Link Text&");
+    assertEquals("<span class=\"app-link\" data-ref=\"domain=123&text=456\">Link Text&amp;</span>", html.toHtml());
+  }
+
+  @Test
+  public void testAppLinkWithQuote() {
+    final IHtmlElement html = HTML.appLink("domain=123\"text=456", "Link Text<a href=\"javascript:window.alert('bad');\">test</a>");
+    assertEquals("<span class=\"app-link\" data-ref=\"domain=123&quot;text=456\">Link Text&lt;a href=&quot;javascript:window.alert(&#39;bad&#39;);&quot;&gt;test&lt;&#47;a&gt;</span>", html.toHtml());
+  }
+
+  @Test
+  public void testBoldAppLink() {
+    final IHtmlElement html = HTML.bold("asdf", HTML.appLink("domain=123&text=456", "Link Text&"));
+    assertEquals("<b>asdf<span class=\"app-link\" data-ref=\"domain=123&text=456\">Link Text&amp;</span></b>", html.toHtml());
+  }
+
+  @Test
+  public void testTableNoBinds() {
+    String html = HTML.table(tr(td(HTML_TEXT))).toHtml();
+    assertEquals("<table><tr><td>" + escape(HTML_TEXT) + "</td></tr></table>", html);
+  }
+
+  @Test
+  public void testTableAttributesNoBinds() {
+    final IHtmlTable table = HTML.table(tr(td(HTML_TEXT)));
+    assertEquals("<table><tr><td>" + escape(HTML_TEXT) + "</td></tr></table>", table.toHtml());
+  }
+
+  @Test
+  public void testLinkWithBoldNoBinds() {
+    final IHtmlElement html = HTML.bold(HTML_TEXT, link(TEST_URL, HTML_TEXT));
+    assertEquals("<b>Test Last Name&amp;<a href=\"http://SCOUTBLABLA.com&quot;\">Test Last Name&amp;</a></b>", html.toHtml());
+  }
+
+  private String escape(String text) {
+    return HtmlHelper.escape(text);
+  }
+
+  private void assertEncodedText(String tagName, String actualText) {
+    assertEquals("<" + tagName + ">" + ESCAPED_HTML_TEXT + "</" + tagName + ">", actualText);
+  }
+
+  @Test
+  public void testFragment() {
+    assertEquals("", HTML.fragment((CharSequence) null).toHtml());
+
+    final IHtmlContent fragment = HTML.fragment(HTML.div(HTML_TEXT), HTML_TEXT);
+    assertEquals("<div>" + ESCAPED_HTML_TEXT + "</div>" + ESCAPED_HTML_TEXT, fragment.toHtml());
+  }
+
+  @Test
+  public void testMultipleFragments() {
+    final IHtmlContent fragment = HTML.fragment(HTML.div("1"), HTML.div("2"));
+    assertEquals("<div>1</div><div>2</div>", fragment.toHtml());
+  }
+
+  @Test
+  public void testRowWithMultipleBinds() {
+    IHtmlTableRow row = HTML.tr(HTML.td("p1"), HTML.td("p2"), HTML.td("p4"));
+    assertEquals("<tr><td>p1</td><td>p2</td><td>p4</td></tr>", row.toHtml());
+    assertEquals("<tr><td>p1</td><td>p2</td><td>p4</td></tr>", row.toString());
+  }
+
+  @Test
+  public void testMultipleCellsNoBinds() {
+    IHtmlTableRow row1 = HTML.tr(HTML.td("p1"), HTML.td("p2"));
+    assertEquals("<tr><td>p1</td><td>p2</td></tr>", row1.toString());
+  }
+
+  @Test
+  public void testCellWithColspan() {
+    IHtmlTableRow row = HTML.tr(HTML.td("1").colspan(2), HTML.td("2"));
+    assertEquals("<tr><td colspan=\"2\">1</td><td>2</td></tr>", row.toHtml());
+  }
+
+  @Test
+  public void testMultipleRowsNoBinds() {
+    IHtmlTableRow row1 = HTML.tr(HTML.td("p1"), HTML.td("p2"));
+    IHtmlTableRow row2 = HTML.tr(HTML.td("p3"), HTML.td("p4"));
+    String row1String = "<tr><td>p1</td><td>p2</td></tr>";
+    String row2String = "<tr><td>p3</td><td>p4</td></tr>";
+
+    String res = HTML.table(row1, row2).toHtml();
+    assertEquals("<table>" + row1String + row2String + "</table>", res);
+  }
+
+  @Test
+  public void testComplexHtml() {
+    final IHtmlElement html = HTML.div(link(TEST_URL, HTML_TEXT), HTML.table(tr(td(HTML_TEXT), td(HTML_TEXT), td(HTML_TEXT))));
+    String expected = "<div><a href=\"http://SCOUTBLABLA.com&quot;\">Test Last Name&amp;</a><table><tr><td>Test Last Name&amp;</td><td>Test Last Name&amp;</td><td>Test Last Name&amp;</td></tr></table></div>";
+    assertEquals(expected, html.toHtml());
+  }
+
+  @Test
+  public void testUl() {
+    String html = HTML.ul(HTML.li(HTML_TEXT)).toHtml();
+    assertEquals("<ul><li>" + ESCAPED_HTML_TEXT + "</li></ul>", html);
+  }
+
+  @Test
+  public void testMultipleUl() {
+    String html = HTML.ul(HTML.li(HTML_TEXT), HTML.li("2")).toHtml();
+    assertEquals("<ul><li>" + ESCAPED_HTML_TEXT + "</li><li>2</li></ul>", html);
+  }
+
+  @Test
+  public void testMultipleOl() {
+    String html = HTML.ol(HTML.li(HTML_TEXT), HTML.li("2")).toHtml();
+    assertEquals("<ol><li>" + ESCAPED_HTML_TEXT + "</li><li>2</li></ol>", html);
+  }
+
+  @Test
+  public void testHtmlCssStyle() {
+    IHtmlContent head = HTML.head(HTML.cssStyle(sampleCSS));
+    assertEquals("<head><style type=\"text/css\">" + sampleCSS + "</style></head>", head.toHtml());
+  }
+
+  @Test
+  public void testFullHtml() {
+    IHtmlDocument html = HTML.html(HTML.cssStyle(sampleCSS), HTML_TEXT);
+    String expected = "<html><head><style type=\"text/css\">" + sampleCSS + "</style>" + "</head><body>" + ESCAPED_HTML_TEXT + "</body></html>";
+    assertEquals(expected, html.toHtml());
+  }
+
+  @Test
+  public void testFullHtmlDocType() {
+    IHtmlDocument html = HTML.html5(HTML.cssStyle(sampleCSS), HTML_TEXT);
+    String expected = "<!DOCTYPE html><html><head><style type=\"text/css\">" + sampleCSS + "</style>" + "</head><body>" + ESCAPED_HTML_TEXT + "</body></html>";
+    assertEquals(expected, html.toHtml());
+  }
+
+  @Test
+  public void testPlain() {
+    assertEquals("", HTML.raw((CharSequence) null).toHtml());
+    assertEquals(HTML_TEXT, HTML.raw(HTML_TEXT).toHtml());
+    IHtmlContent plainLink = HTML.raw(HTML_TEXT, HTML.appLink("REF", HTML_TEXT));
+    String plainLinkString = String.format("%s<span class=\"app-link\" data-ref=\"REF\">%s</span>", HTML_TEXT, ESCAPED_HTML_TEXT);
+    assertEquals(String.format(plainLinkString, HTML_TEXT, ESCAPED_HTML_TEXT), plainLink.toHtml());
+    assertEquals(String.format("<b>%s</b>", plainLinkString), HTML.bold(plainLink).toHtml());
+    assertEquals(String.format("<i>%s</i>", plainLinkString), HTML.italic(plainLink).toHtml());
+  }
+
+  @Test
+  public void testManyBinds() throws Exception {
+    IHtmlElement h2 = HTML.h2("h2");
+    IHtmlTable table = createTable("0");
+
+    IHtmlElement html = HTML.div(h2, table);
+
+    String exp = "<div><h2>h2</h2>" + createTableString("0") + "</div>";
+    assertEquals(exp, html.toHtml());
+  }
+
+  @Test
+  public void testNullValues() {
+    String encodedNullDiv = HTML.div((String) null).toHtml();
+    assertEquals("<div></div>", encodedNullDiv);
+  }
+
+  @Test
+  public void testInput() {
+    String expected = "<input id='lastName' name='Last name' class='person-data' maxlength='30' value='' type='text'>";
+    expected = expected.replace("'", "\"");
+
+    IHtmlInput htmlInput = HTML.input().id("lastName").name("Last name").cssClass("person-data").maxlength(30).value("").type("text");
+    assertEquals(expected, htmlInput.toHtml());
+  }
+
+  @Test
+  public void testSpecialCharacters() {
+    assertEquals("<p>Test$Class</p>", HTML.p("Test$Class").toHtml());
+    assertEquals("<p>C:\\Temp\\config.properties</p>", HTML.p("C:\\Temp\\config.properties").toHtml());
+  }
+
+  private String createTableString(String prefix) {
+    List<String> rows = new ArrayList<String>();
+    for (int i = 0; i < 1; i++) {
+      rows.add(createRowString(prefix, i));
+    }
+    return "<table>" + CollectionUtility.format(rows, "") + "</table>";
+
+  }
+
+  private String createRowString(String prefix, int i) {
+    return HTML.tr(HTML.td("A" + prefix + i), HTML.td("B" + prefix + i)).toHtml();
+  }
+
+  private IHtmlTable createTable(String prefix) {
+    List<IHtmlTableRow> rows = new ArrayList<IHtmlTableRow>();
+    for (int i = 0; i < 1; i++) {
+      rows.add(createRow(prefix, i));
+    }
+    return HTML.table(rows);
+  }
+
+  private IHtmlTableRow createRow(String prefix, int i) {
+    return HTML.tr(HTML.td("A" + prefix + i), HTML.td("B" + prefix + i));
+  }
+
+}
diff --git a/org.eclipse.scout.commons.test/src/org/eclipse/scout/commons/html/HtmlContentBuilderTest.java b/org.eclipse.scout.commons.test/src/org/eclipse/scout/commons/html/HtmlContentBuilderTest.java
new file mode 100644
index 0000000..8b1326d
--- /dev/null
+++ b/org.eclipse.scout.commons.test/src/org/eclipse/scout/commons/html/HtmlContentBuilderTest.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.scout.commons.CollectionUtility;
+import org.eclipse.scout.commons.html.internal.HtmlContentBuilder;
+import org.junit.Test;
+
+/**
+ * Tests for {@link HtmlContentBuilder}
+ *
+ * @since 6.0 (backported)
+ */
+public class HtmlContentBuilderTest {
+
+  @Test
+  public void testManyBinds() throws Exception {
+    IHtmlElement h2 = HTML.h2("h2");
+    IHtmlTable table = createTable("0");
+
+    IHtmlElement html = HTML.div(
+        h2,
+        table);
+
+    String exp = "<div><h2>h2</h2>" + createTableString("0") + "</div>";
+    assertEquals(exp, html.toHtml());
+  }
+
+  private String createTableString(String prefix) {
+    List<String> rows = new ArrayList<String>();
+    for (int i = 0; i < 1; i++) {
+      rows.add(createRowString(prefix, i));
+    }
+    return "<table>" + CollectionUtility.format(rows, "") + "</table>";
+
+  }
+
+  private String createRowString(String prefix, int i) {
+    return HTML.tr(HTML.td("A" + prefix + i), HTML.td("B" + prefix + i)).toHtml();
+  }
+
+  private IHtmlTable createTable(String prefix) {
+    List<IHtmlTableRow> rows = new ArrayList<IHtmlTableRow>();
+    for (int i = 0; i < 1; i++) {
+      rows.add(createRow(prefix, i));
+    }
+    return HTML.table(rows);
+  }
+
+  private IHtmlTableRow createRow(String prefix, int i) {
+    return HTML.tr(HTML.td("A" + prefix + i), HTML.td("B" + prefix + i));
+  }
+
+}
diff --git a/org.eclipse.scout.commons.test/src/org/eclipse/scout/commons/html/HtmlHelperTest.java b/org.eclipse.scout.commons.test/src/org/eclipse/scout/commons/html/HtmlHelperTest.java
new file mode 100644
index 0000000..a1af862
--- /dev/null
+++ b/org.eclipse.scout.commons.test/src/org/eclipse/scout/commons/html/HtmlHelperTest.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2016 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.scout.commons.StringUtility;
+import org.junit.Test;
+
+/**
+ * @since 6.0 (backported)
+ */
+public class HtmlHelperTest {
+  @Test
+  public void testToPlainText() {
+    // Note: Some of the expected results are not really what the user would expect,
+    // but what the toPlainText() method currently returns. They are marked with "[?]"
+    // below. Sometimes in the future, it should be considered to change them.
+
+    assertEquals(null, HtmlHelper.toPlainText(null));
+    assertEquals("", HtmlHelper.toPlainText(""));
+
+    // Text only
+    assertEquals("hello", HtmlHelper.toPlainText("hello"));
+    assertEquals("one two", HtmlHelper.toPlainText("one\ntwo"));
+    assertEquals("one two", HtmlHelper.toPlainText("one\r\ntwo"));
+    assertEquals("onetwo", HtmlHelper.toPlainText("one\rtwo"));
+    assertEquals("hell<", HtmlHelper.toPlainText("hell&lt;"));
+    assertEquals("one   two", HtmlHelper.toPlainText("one&nbsp;&nbsp; two"));
+    assertEquals("hell&ouml;", HtmlHelper.toPlainText("hell&ouml;")); // [?] not all entities are replaced
+    assertEquals("one\ttwo", HtmlHelper.toPlainText("one&#9;two"));
+    assertEquals("one \t two", HtmlHelper.toPlainText("one &#9; two"));
+    assertEquals("one\ttwo", HtmlHelper.toPlainText("one" + StringUtility.HTML_ENCODED_TAB + "two"));
+
+    // Simple documents
+    assertEquals("", HtmlHelper.toPlainText("<html>"));
+    assertEquals("", HtmlHelper.toPlainText("<html></html>"));
+    assertEquals("", HtmlHelper.toPlainText("<html><head></html>"));
+    assertEquals("one", HtmlHelper.toPlainText("<html><head>one</html>"));
+    assertEquals("one & two", HtmlHelper.toPlainText("<html><head>one & two</html>"));
+    assertEquals("one & two", HtmlHelper.toPlainText("<html><head>one &amp; two</html>"));
+    assertEquals("one & two three", HtmlHelper.toPlainText("<html><head>one &amp; two</head><body>three</html>")); // [?] invalid <body>, has no end tag
+    assertEquals("three", HtmlHelper.toPlainText("<html><head>one &amp; two</head><body>three</body></html>"));
+
+    // Line breaks
+    assertEquals("a\nb", HtmlHelper.toPlainText("a<br>b"));
+    assertEquals("a\nb", HtmlHelper.toPlainText("a <br/> b"));
+    assertEquals("a\nb", HtmlHelper.toPlainText("a    <br/> b"));
+    assertEquals("a \nb", HtmlHelper.toPlainText("a&nbsp;<br/> b"));
+    assertEquals("line", HtmlHelper.toPlainText("<br/>line")); // [?]
+    assertEquals("line1\nx\nline2", HtmlHelper.toPlainText("<p>line1<br>\nx</p><p>line2</p>"));
+    assertEquals("line1 x\nline2", HtmlHelper.toPlainText("<div>line1\nx</div><div>line2</div>")); // [?]
+    assertEquals("line1\nline2", HtmlHelper.toPlainText("<div>line1<br/></div><div>line2<br/></div>"));
+
+    // Tables
+    assertEquals("one two\nthree four", HtmlHelper.toPlainText("<table><tr><td>one</td><td>two</td></tr><tr><td>three</td><td>four</td></tr></table>"));
+  }
+
+  @Test
+  public void testEscape() {
+    assertEquals(null, HtmlHelper.escape(null));
+    assertEquals("", HtmlHelper.escape(""));
+    assertEquals(" ", HtmlHelper.escape(" "));
+    assertEquals("hello", HtmlHelper.escape("hello"));
+
+    assertEquals("one &amp; two", HtmlHelper.escape("one & two"));
+    assertEquals("one &lt; two", HtmlHelper.escape("one < two"));
+    assertEquals("&gt;&lt;script&gt;alert(&#39;hacker attack&#39;);&lt;&#47;script&gt;&lt;", HtmlHelper.escape("><script>alert('hacker attack');</script><"));
+    assertEquals("one&amp;nbsp;&amp;nbsp; two", HtmlHelper.escape("one&nbsp;&nbsp; two"));
+    assertEquals("this is &quot;good&quot;", HtmlHelper.escape("this is \"good\""));
+    assertEquals("http:&#47;&#47;www.example.com&#47;~myapp&#47;script?q=search%20query&amp;time=now&amp;x=17263.23", HtmlHelper.escape("http://www.example.com/~myapp/script?q=search%20query&time=now&x=17263.23"));
+    assertEquals("&lt;div&gt;&lt;span style=&quot;color: red; content: &#39;\\u39&#39;;&quot;&gt;Alert!&lt;&#47;span&gt;&lt;br&#47;&gt;Line2&lt;&#47;div&gt;",
+        HtmlHelper.escape("<div><span style=\"color: red; content: '\\u39';\">Alert!</span><br/>Line2</div>"));
+    assertEquals("hell&amp;ouml;", HtmlHelper.escape("hell&ouml;"));
+    assertEquals("one&#47;two&#47;end", HtmlHelper.escape("one/two/end"));
+
+    // Things that should NOT be escaped
+    assertEquals("one\ntwo  end", HtmlHelper.escape("one\ntwo  end"));
+    assertEquals("key:\tvalue\r\nline2", HtmlHelper.escape("key:\tvalue\r\nline2"));
+  }
+
+  @Test
+  public void testUnescape() {
+    assertEquals(null, HtmlHelper.unescape(null));
+    assertEquals("", HtmlHelper.unescape(""));
+    assertEquals(" ", HtmlHelper.unescape(" "));
+    assertEquals("hello", HtmlHelper.unescape("hello"));
+
+    assertEquals("one & two", HtmlHelper.unescape("one &amp; two"));
+    assertEquals("one < two", HtmlHelper.unescape("one &lt; two"));
+    assertEquals("><script>alert('hacker attack');</script><", HtmlHelper.unescape("&gt;&lt;script&gt;alert(&#39;hacker attack&#39;);&lt;/script&gt;&lt;"));
+    assertEquals("one&nbsp;&nbsp; two", HtmlHelper.unescape("one&amp;nbsp;&amp;nbsp; two"));
+    assertEquals("this is \"good\"", HtmlHelper.unescape("this is &quot;good&quot;"));
+    assertEquals("http://www.example.com/~myapp/script?q=search%20query&time=now&x=17263.23", HtmlHelper.unescape("http://www.example.com/~myapp/script?q=search%20query&amp;time=now&amp;x=17263.23"));
+    assertEquals("<div><span style=\"color: red; content: '\\u39';\">Alert!</span><br/>Line2</div>",
+        HtmlHelper.unescape("&lt;div&gt;&lt;span style=&quot;color: red; content: &#39;\\u39&#39;;&quot;&gt;Alert!&lt;/span&gt;&lt;br/&gt;Line2&lt;/div&gt;"));
+    assertEquals("hell&ouml;", HtmlHelper.unescape("hell&amp;ouml;"));
+    assertEquals("one/two/end", HtmlHelper.unescape("one&#47;two&#47;end"));
+
+    // Things that should NOT be unescaped
+    assertEquals("one\ntwo  end", HtmlHelper.unescape("one\ntwo  end"));
+    assertEquals("key:\tvalue\r\nline2", HtmlHelper.unescape("key:\tvalue\r\nline2"));
+    assertEquals("hell&ouml;", HtmlHelper.unescape("hell&ouml;"));
+  }
+}
diff --git a/org.eclipse.scout.commons/META-INF/MANIFEST.MF b/org.eclipse.scout.commons/META-INF/MANIFEST.MF
index 9781d61..f0230e0 100644
--- a/org.eclipse.scout.commons/META-INF/MANIFEST.MF
+++ b/org.eclipse.scout.commons/META-INF/MANIFEST.MF
@@ -17,6 +17,8 @@
  org.eclipse.scout.commons.eventlistprofiler,
  org.eclipse.scout.commons.exception,
  org.eclipse.scout.commons.holders,
+ org.eclipse.scout.commons.html,
+ org.eclipse.scout.commons.html.internal,
  org.eclipse.scout.commons.internal.runtime;x-internal:=true,
  org.eclipse.scout.commons.job,
  org.eclipse.scout.commons.logger,
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/HTMLUtility.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/HTMLUtility.java
index 0aebe6d..58d783b 100644
--- a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/HTMLUtility.java
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/HTMLUtility.java
@@ -555,12 +555,20 @@
    *         |</tr>|</table> create newlines </xmp></pre>
    */
   public static String getPlainText(String s) {
-    s = StringUtility.getTag(s, "body");
+    return getPlainText(s, true, true);
+  }
+
+  public static String getPlainText(String s, boolean fetchInsideBodyTag, boolean replaceNewLine) {
+    if (fetchInsideBodyTag) {
+      s = StringUtility.getTag(s, "body");
+    }
     if (s == null || s.length() == 0) {
       return s;
     }
     //newlines
-    s = s.replaceAll("\n", " ");
+    if (replaceNewLine) {
+      s = s.replaceAll("\n", " ");
+    }
     s = s.replaceAll("<br>|<br/>|</p>|<p/>|</tr>|</table>", "\n");
     //remove tags
     s = Pattern.compile("<[^>]+>", Pattern.DOTALL).matcher(s).replaceAll(" ");
@@ -641,7 +649,7 @@
 
   /**
    * @return encoded text, ready to be included in a html text
-   *         <xmp>replaces &, ", ', <, > and all whitespace</xmp>
+   *         <xmp>replaces &, ", ', <, >, / and all whitespace</xmp>
    */
   public static String encodeText(String s) {
     return StringUtility.htmlEncode(s, true);
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/StringUtility.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/StringUtility.java
index 62b49d8..2512fa8 100644
--- a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/StringUtility.java
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/StringUtility.java
@@ -37,6 +37,11 @@
 public final class StringUtility {
   private static final IScoutLogger LOG = ScoutLogManager.getLogger(StringUtility.class);
   public static final Pattern PATTERN_TRIM_NEWLINES = Pattern.compile("^[\r\n]*(.*?)[\r\n]*$", Pattern.DOTALL);
+  /**
+   * Special constant used by {@link #htmlEncode(String)} to preserve a tab character (<code>\t</code>) in the resulting
+   * HTML. {@link #htmlDecode(String)} can convert it back to <code>\t</code>, but only if the tag was not altered.
+   */
+  public static final String HTML_ENCODED_TAB = "<span style=\"white-space:pre\">&#9;</span>";
 
   private static final String[] EMPTY_ARRAY = new String[0];
 
@@ -399,11 +404,18 @@
   /**
    * @return a start tag (ignores single tags) <foo> (not <foo/>)
    */
-  private static TagBounds getStartTag(String text, String tagName, int pos) {
+  private static TagBounds getStartTag(String text, String tagName, boolean ignoreCase, int pos) {
     if (text == null) {
       return TAG_BOUNDS_NOT_FOUND;
     }
-    Pattern pat = Pattern.compile("<" + tagName + "(\\s[^<>]*[^/])?>", Pattern.DOTALL);
+    int flags;
+    if (ignoreCase) {
+      flags = Pattern.CASE_INSENSITIVE | Pattern.DOTALL;
+    }
+    else {
+      flags = Pattern.DOTALL;
+    }
+    Pattern pat = Pattern.compile("<" + tagName + "(\\s[^<>]*[^/])?>", flags);
     Matcher m = pat.matcher(text);
     if (m.find(pos)) {
       return new TagBounds(m.start(), m.end());
@@ -414,11 +426,18 @@
   /**
    * @return an end tag </foo>
    */
-  private static TagBounds getEndTag(String text, String tagName, int pos) {
+  private static TagBounds getEndTag(String text, String tagName, boolean ignoreCase, int pos) {
     if (text == null) {
       return TAG_BOUNDS_NOT_FOUND;
     }
-    Pattern pat = Pattern.compile("</" + tagName + ">");
+    int flags;
+    if (ignoreCase) {
+      flags = Pattern.CASE_INSENSITIVE;
+    }
+    else {
+      flags = 0;
+    }
+    Pattern pat = Pattern.compile("</" + tagName + ">", flags);
     Matcher m = pat.matcher(text);
     if (m.find(pos)) {
       return new TagBounds(m.start(), m.end());
@@ -431,12 +450,16 @@
    *         when the tag is not found in the text.
    */
   public static String getTag(String text, String tagName) {
+    return getTag(text, tagName, false);
+  }
+
+  public static String getTag(String text, String tagName, boolean ignoreCase) {
     if (text == null) {
       return null;
     }
     TagBounds a;
     TagBounds b;
-    if ((a = getStartTag(text, tagName, 0)).begin >= 0 && (b = getEndTag(text, tagName, a.end)).begin >= 0) {
+    if ((a = getStartTag(text, tagName, ignoreCase, 0)).begin >= 0 && (b = getEndTag(text, tagName, ignoreCase, a.end)).begin >= 0) {
       return text.substring(a.end, b.begin).trim();
     }
     if ((a = getSingleTag(text, tagName, 0)).begin >= 0) {
@@ -462,6 +485,10 @@
    * be careful to not replace the tag again with the tag, this will result in an endless loop
    */
   public static String replaceTags(String text, String tagName, ITagProcessor processor) {
+    return replaceTags(text, tagName, false, processor);
+  }
+
+  public static String replaceTags(String text, String tagName, boolean ignoreCase, ITagProcessor processor) {
     if (text == null) {
       return null;
     }
@@ -472,7 +499,7 @@
       String replacement = processor.processTag(tagName, tagContent);
       text = text.substring(0, a.begin) + replacement + text.substring(a.end);
     }
-    while ((a = getStartTag(text, tagName, 0)).begin >= 0 && (b = getEndTag(text, tagName, a.end)).begin >= 0) {
+    while ((a = getStartTag(text, tagName, ignoreCase, 0)).begin >= 0 && (b = getEndTag(text, tagName, ignoreCase, a.end)).begin >= 0) {
       String tagContent = text.substring(a.end, b.begin);
       String replacement = processor.processTag(tagName, tagContent);
       text = text.substring(0, a.begin) + replacement + text.substring(b.end);
@@ -490,6 +517,10 @@
    * <code>removeTag(text, "b")</code> will return '&lt;html>some text&lt;/html&gt;'</code>
    */
   public static String removeTag(String text, String tagName) {
+    return removeTag(text, tagName, false);
+  }
+
+  public static String removeTag(String text, String tagName, boolean ignoreCase) {
     if (text == null) {
       return null;
     }
@@ -501,7 +532,7 @@
     while ((a = getSingleTag(text, tagName, 0)).begin >= 0) {
       text = text.substring(0, a.begin) + text.substring(a.end);
     }
-    while ((a = getStartTag(text, tagName, 0)).begin >= 0 && (b = getEndTag(text, tagName, a.end)).begin >= 0) {
+    while ((a = getStartTag(text, tagName, ignoreCase, 0)).begin >= 0 && (b = getEndTag(text, tagName, ignoreCase, a.end)).begin >= 0) {
       text = text.substring(0, a.begin) + text.substring(b.end);
     }
     return text;
@@ -529,6 +560,10 @@
   }
 
   public static String removeTagBounds(String text, String tagName) {
+    return removeTagBounds(text, tagName, false);
+  }
+
+  public static String removeTagBounds(String text, String tagName, boolean ignoreCase) {
     if (text == null) {
       return null;
     }
@@ -537,26 +572,30 @@
     while ((a = getSingleTag(text, tagName, 0)).begin >= 0) {
       text = text.substring(0, a.begin) + text.substring(a.end);
     }
-    while ((a = getStartTag(text, tagName, 0)).begin >= 0 && (b = getEndTag(text, tagName, a.end)).begin >= 0) {
+    while ((a = getStartTag(text, tagName, ignoreCase, 0)).begin >= 0 && (b = getEndTag(text, tagName, ignoreCase, a.end)).begin >= 0) {
       text = text.substring(0, a.begin) + text.substring(a.end, b.begin) + text.substring(b.end);
     }
     return text;
   }
 
   public static String replaceTagBounds(String text, String tagName, String start, String end) {
+    return replaceTagBounds(text, tagName, false, start, end);
+  }
+
+  public static String replaceTagBounds(String text, String tagName, boolean ignoreCase, String start, String end) {
     if (text == null) {
       return null;
     }
     TagBounds a;
     int b;
     int startPos = 0;
-    while (startPos < text.length() && (a = getStartTag(text, tagName, startPos)).begin >= 0 && (b = text.indexOf("</" + tagName + ">", a.end)) > 0) {
+    while (startPos < text.length() && (a = getStartTag(text, tagName, ignoreCase, startPos)).begin >= 0 && (b = text.indexOf("</" + tagName + ">", a.end)) > 0) {
       text =
           text.substring(0, a.begin) +
-              start +
-              text.substring(a.end, b) +
-              end +
-              text.substring(b + tagName.length() + 3);
+          start +
+          text.substring(a.end, b) +
+          end +
+          text.substring(b + tagName.length() + 3);
       //next
       startPos = a.begin + start.length();
     }
@@ -913,7 +952,8 @@
     if (replaceSpace) {
       s = s.replaceAll("\\s", "&nbsp;");
     }
-    s = s.replace(tabIdentifier, "<span style=\"white-space:pre\">&#9;</span>");
+    s = s.replace(tabIdentifier, HTML_ENCODED_TAB);
+
     return s;
   }
 
@@ -1819,4 +1859,19 @@
     }
     return true;
   }
+
+  public static String convertPlainTextNewLinesToHtml(String text, boolean replaceBreakableChars) {
+    if (isNullOrEmpty(text)) {
+      return text;
+    }
+
+    text = replaceNewLines(text, "<br/>");
+
+    if (replaceBreakableChars) {
+      text = text.replace("\\s", "&nbsp;");
+      text = text.replace("-", "&#8209;");
+    }
+
+    return text;
+  }
 }
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/AppLink.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/AppLink.java
new file mode 100644
index 0000000..c6cac8e7
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/AppLink.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html;
+
+import java.io.Serializable;
+
+/**
+ * Bean representing an app link.
+ *
+ * @since 6.0 (backported)
+ */
+public class AppLink implements Serializable {
+
+  private static final long serialVersionUID = 1L;
+
+  private String m_ref;
+  private String m_name;
+
+  public AppLink() {
+  }
+
+  /**
+   * Creates an app link bean
+   *
+   * @param ref
+   *          Reference
+   * @param name
+   *          Name of the app link
+   */
+  public AppLink(String ref, String name) {
+    m_ref = ref;
+    m_name = name;
+  }
+
+  public String getRef() {
+    return m_ref;
+  }
+
+  public void setRef(String ref) {
+    m_ref = ref;
+  }
+
+  public String getName() {
+    return m_name;
+  }
+
+  public void setName(String name) {
+    m_name = name;
+  }
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/HTML.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/HTML.java
new file mode 100644
index 0000000..667d263
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/HTML.java
@@ -0,0 +1,526 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.scout.commons.html.internal.EmptyHtmlNodeBuilder;
+import org.eclipse.scout.commons.html.internal.HtmlContentBuilder;
+import org.eclipse.scout.commons.html.internal.HtmlDocumentBuilder;
+import org.eclipse.scout.commons.html.internal.HtmlImageBuilder;
+import org.eclipse.scout.commons.html.internal.HtmlInputBuilder;
+import org.eclipse.scout.commons.html.internal.HtmlLinkBuilder;
+import org.eclipse.scout.commons.html.internal.HtmlListElement;
+import org.eclipse.scout.commons.html.internal.HtmlNodeBuilder;
+import org.eclipse.scout.commons.html.internal.HtmlPlainBuilder;
+import org.eclipse.scout.commons.html.internal.HtmlTableBuilder;
+import org.eclipse.scout.commons.html.internal.HtmlTableDataBuilder;
+import org.eclipse.scout.commons.html.internal.HtmlTableRowBuilder;
+import org.eclipse.scout.commons.html.internal.StyleElementBuilder;
+
+/**
+ * Convenience for building a html document or parts of it with encoded binds. <br>
+ * Only the most common cases are supported, not intended to be complete.
+ *
+ * @since 6.0 (backported)
+ */
+public final class HTML {
+
+  /**
+   * Utility class
+   */
+  private HTML() {
+  }
+
+  /**
+   * Create a html element with encoded text for &lt;head&gt;text&lt;/head&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.head("text").toHtml(); <br>
+   * </p>
+   *
+   * @param elements
+   *          text as bind
+   */
+  public static IHtmlContent head(CharSequence... elements) {
+    return new HtmlNodeBuilder("head", elements);
+  }
+
+  /**
+   * Create a html element with encoded text for &lt;body&gt;text&lt;/body&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.body("text").toHtml(); <br>
+   * </p>
+   *
+   * @param elements
+   *          text as bind
+   */
+  public static IHtmlContent body(CharSequence... elements) {
+    return new HtmlNodeBuilder("body", elements);
+  }
+
+  /**
+   * Create a html element with encoded text for &lt;b&gt;text&lt;/b&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.bold("text").toHtml(); <br>
+   * </p>
+   *
+   * @param text
+   *          text as bind
+   */
+  public static IHtmlElement bold(CharSequence... text) {
+    return new HtmlNodeBuilder("b", text);
+  }
+
+  /**
+   * Create a html element with encoded text for &lt;i&gt;text&lt;/i&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.italic("text").toHtml(); <br>
+   * </p>
+   *
+   * @param text
+   *          text as bind
+   */
+  public static IHtmlElement italic(CharSequence... text) {
+    return new HtmlNodeBuilder("i", text);
+  }
+
+  /**
+   * Create a html element with encoded text for &lt;p&gt;text&lt;/p&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.p("text").toHtml(); <br>
+   * </p>
+   *
+   * @param text
+   *          text as bind
+   */
+  public static IHtmlElement p(CharSequence... text) {
+    return new HtmlNodeBuilder("p", text);
+  }
+
+  /**
+   * Create a html element for &lt;br&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.br().toHtml(); <br>
+   * </p>
+   */
+  public static IHtmlElement br() {
+    return new EmptyHtmlNodeBuilder("br");
+  }
+
+  /**
+   * Create a html element for &lt;hr&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.hr().toHtml(); <br>
+   * </p>
+   */
+  public static IHtmlElement hr() {
+    return new EmptyHtmlNodeBuilder("hr");
+  }
+
+  /**
+   * Create a html element with encoded text for &lt;h1&gt;text&lt;/h1&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.h1("text").toHtml(); <br>
+   * </p>
+   *
+   * @param text
+   *          text as bind
+   */
+  public static IHtmlElement h1(CharSequence... text) {
+    return new HtmlNodeBuilder("h1", text);
+  }
+
+  /**
+   * Create a html element with encoded text for &lt;h2&gt;text&lt;/h2&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.h2("text").toHtml(); <br>
+   * </p>
+   *
+   * @param text
+   *          text as bind
+   */
+  public static IHtmlElement h2(CharSequence... text) {
+    return new HtmlNodeBuilder("h2", text);
+  }
+
+  /**
+   * Create a html element with encoded text for &lt;h3&gt;text&lt;/h3&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.h3("text").toHtml(); <br>
+   * </p>
+   *
+   * @param text
+   *          text as bind
+   */
+  public static IHtmlElement h3(CharSequence... text) {
+    return new HtmlNodeBuilder("h3", text);
+  }
+
+  /**
+   * Create a html element with encoded text for &lt;h4&gt;text&lt;/h4&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.h4("text").toHtml(); <br>
+   * </p>
+   *
+   * @param text
+   *          text as bind
+   */
+  public static IHtmlElement h4(CharSequence... text) {
+    return new HtmlNodeBuilder("h4", text);
+  }
+
+  /**
+   * Create a html element with encoded text for &lt;h5&gt;text&lt;/h5&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.h5("text").toHtml(); <br>
+   * </p>
+   *
+   * @param text
+   *          text as bind
+   */
+  public static IHtmlElement h5(CharSequence... text) {
+    return new HtmlNodeBuilder("h5", text);
+  }
+
+  /**
+   * Create a html element with encoded text for &lt;h6&gt;text&lt;/h6&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.h6("text").toHtml(); <br>
+   * </p>
+   *
+   * @param text
+   *          text as bind
+   */
+  public static IHtmlElement h6(CharSequence... text) {
+    return new HtmlNodeBuilder("h6", text);
+  }
+
+  /**
+   * Create a html element with encoded text for &lt;div&gt;content&lt;/div&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.div("text").toHtml(); <br>
+   * </p>
+   *
+   * @param content
+   *          content as bind
+   */
+  public static IHtmlElement div(CharSequence... content) {
+    return div(Arrays.asList(content));
+  }
+
+  /**
+   * Create a html element with encoded text for &lt;div&gt;content&lt;/div&gt;.
+   *
+   * @param contents
+   *          content as bind
+   */
+  public static IHtmlElement div(List<CharSequence> contents) {
+    return new HtmlNodeBuilder("div", contents);
+  }
+
+  /**
+   * Create a html element with encoded text for &lt;span&gt;content&lt;/span&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.span("text").toHtml(); <br>
+   * </p>
+   *
+   * @param text
+   *          text as bind
+   */
+  public static IHtmlElement span(CharSequence... text) {
+    return new HtmlNodeBuilder("span", text);
+  }
+
+  /**
+   * Create a html element with encoded text for a link &lt;a href="url"&gt;text&lt;/a&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.link("http://xyz.com","text").toHtml(); <br>
+   * </p>
+   *
+   * @param text
+   *          text as bind
+   */
+  public static IHtmlElement link(CharSequence url, CharSequence text) {
+    return new HtmlLinkBuilder(url, text);
+  }
+
+  /**
+   * Create a html element for an image: &lt;img src="path"&gt;&lt;/img&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.img("image.png").toHtml(); <br>
+   * </p>
+   *
+   * @param src
+   *          image source path as bind
+   */
+  public static IHtmlElement img(CharSequence src) {
+    return new HtmlImageBuilder(src);
+  }
+
+  /**
+   * Create a html element for an image: &lt;img src="binaryResource:resourceName"&gt;&lt;/img&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.imgByBinaryResource("resourceName").toHtml(); <br>
+   * </p>
+   *
+   * @param binaryResource
+   *          image source path as bind
+   */
+  public static IHtmlElement imgByBinaryResource(CharSequence binaryResource) {
+    return new HtmlImageBuilder("binaryResource:" + binaryResource);
+  }
+
+  /**
+   * Create a html element for an image: &lt;img src="iconid:icon_name"&gt;&lt;/img&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.imgByIconId("icon_name").toHtml(); <br>
+   * </p>
+   *
+   * @param iconId
+   *          image source path as bind
+   */
+  public static IHtmlElement imgByIconId(CharSequence iconId) {
+    return new HtmlImageBuilder("iconId:" + iconId);
+  }
+
+  /**
+   * Create a html list element with encoded text: &lt;li&gt;text&lt;/li&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.li("text").toHtml(); <br>
+   * </p>
+   */
+  public static IHtmlListElement li(CharSequence text) {
+    return new HtmlListElement(text);
+  }
+
+  /**
+   * Create an unordered html list element with encoded text: &lt;ul&gt;...&lt;/ul&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.ul(HTML.li("text"),...).toHtml(); <br>
+   * </p>
+   */
+  public static IHtmlElement ul(IHtmlListElement... li) {
+    return ul(Arrays.asList(li));
+  }
+
+  /**
+   * Create an unordered html list element with encoded text: &lt;ul&gt;...&lt;/ul&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.ul(HTML.li("text"),...).toHtml(); <br>
+   * </p>
+   */
+  public static IHtmlElement ul(List<IHtmlListElement> li) {
+    return new HtmlNodeBuilder("ul", li);
+  }
+
+  /**
+   * Create an ordered html list element with encoded text: &lt;ul&gt;...&lt;/ul&gt;.
+   * <p>
+   * Example:<br>
+   * String encodedHtml = HTML.ol(HTML.li("text"),...).toHtml(); <br>
+   * </p>
+   */
+  public static IHtmlContent ol(IHtmlListElement... li) {
+    return new HtmlNodeBuilder("ol", li);
+  }
+
+  /**
+   * Create a html element with encoded text for table data: &lt;td&gt;text&lt;/td&gt;.
+   * <p>
+   * Example:<br>
+   * <code>
+   * HTML.table(<br>
+   *     &nbsp;HTML.tr(<br>
+   *     &nbsp;&nbsp;HTML.td("cell1"),<br>
+   *     &nbsp;&nbsp;HTML.td("cell2")<br>
+   *     &nbsp;),<br>
+   *     &nbsp;HTML.tr(<br>
+   *     &nbsp;&nbsp;HTML.td("cell3"),<br>
+   *     &nbsp;&nbsp;HTML.td("cell4")<br>
+   *     )<br>
+   *     ).cellspacing(1).cellpadding(2)<br>
+   * </code>
+   * </p>
+   *
+   * @param text
+   *          text with binds
+   */
+  public static IHtmlTableCell td(CharSequence... text) {
+    return new HtmlTableDataBuilder(Arrays.asList(text));
+  }
+
+  /**
+   * Create a html element with encoded text for a table row: &lt;tr&gt;...&lt;/tr&gt;. Example:<br>
+   * <code>
+   * HTML.table(<br>
+   *     &nbsp;HTML.tr(<br>
+   *     &nbsp;&nbsp;HTML.td("cell1"),<br>
+   *     &nbsp;&nbsp;HTML.td("cell2")<br>
+   *     &nbsp;),<br>
+   *     &nbsp;HTML.tr(<br>
+   *     &nbsp;&nbsp;HTML.td("cell3"),<br>
+   *     &nbsp;&nbsp;HTML.td("cell4")<br>
+   *     )<br>
+   *     ).cellspacing(1).cellpadding(2)<br>
+   * </code>
+   *
+   * @param td
+   *          table data within row
+   */
+  public static IHtmlTableRow tr(IHtmlTableCell... td) {
+    return tr(Arrays.asList(td));
+  }
+
+  /**
+   * Create a html element with encoded text for a table row: &lt;tr&gt;...&lt;/tr&gt;. Example:<br>
+   * <code>
+   * HTML.table(<br>
+   *     &nbsp;HTML.tr(<br>
+   *     &nbsp;&nbsp;HTML.td("cell1"),<br>
+   *     &nbsp;&nbsp;HTML.td("cell2")<br>
+   *     &nbsp;),<br>
+   *     &nbsp;HTML.tr(<br>
+   *     &nbsp;&nbsp;HTML.td("cell3"),<br>
+   *     &nbsp;&nbsp;HTML.td("cell4")<br>
+   *     )<br>
+   *     ).cellspacing(1).cellpadding(2)<br>
+   * </code>
+   *
+   * @param td
+   *          table data within row
+   */
+  public static IHtmlTableRow tr(List<IHtmlTableCell> td) {
+    return new HtmlTableRowBuilder(td);
+  }
+
+  /**
+   * Create a html element with encoded text for a table. Example:<br>
+   * <code>
+   * HTML.table(<br>
+   *     &nbsp;HTML.tr(<br>
+   *     &nbsp;&nbsp;HTML.td("cell1"),<br>
+   *     &nbsp;&nbsp;HTML.td("cell2")<br>
+   *     &nbsp;),<br>
+   *     &nbsp;HTML.tr(<br>
+   *     &nbsp;&nbsp;HTML.td("cell3"),<br>
+   *     &nbsp;&nbsp;HTML.td("cell4")<br>
+   *     )<br>
+   *     ).cellspacing(1).cellpadding(2)<br>
+   * </code>
+   */
+  public static IHtmlTable table(IHtmlTableRow... rows) {
+    return new HtmlTableBuilder(Arrays.asList(rows));
+  }
+
+  /**
+   * Create a html element with encoded text for a table. Example:<br>
+   * <code>
+   * HTML.table(<br>
+   *     &nbsp;HTML.tr(<br>
+   *     &nbsp;&nbsp;HTML.td("cell1"),<br>
+   *     &nbsp;&nbsp;HTML.td("cell2")<br>
+   *     &nbsp;),<br>
+   *     &nbsp;HTML.tr(<br>
+   *     &nbsp;&nbsp;HTML.td("cell3"),<br>
+   *     &nbsp;&nbsp;HTML.td("cell4")<br>
+   *     )<br>
+   *     ).cellspacing(1).cellpadding(2)<br>
+   * </code>
+   */
+  public static IHtmlTable table(List<IHtmlTableRow> rows) {
+    return new HtmlTableBuilder(rows);
+  }
+
+  /**
+   * Creates an application local link String encodedHtml = HTML.appLink("path","text").toHtml(); <br>
+   *
+   * @param ref
+   *          what the link is referring to
+   * @param text
+   *          the link text
+   */
+  public static IHtmlElement appLink(CharSequence ref, CharSequence text) {
+    return span(text).appLink(ref);
+  }
+
+  /**
+   * Creates HTML content from multiple elements. e.g. <b>Bold Text</b> Text <b> More bold text </b>
+   */
+  public static IHtmlContent fragment(CharSequence... elements) {
+    return new HtmlContentBuilder(elements);
+  }
+
+  /**
+   * Creates HTML content from multiple elements. e.g. <b>Bold Text</b> Text <b> More bold text </b>
+   */
+  public static IHtmlContent fragment(List<? extends CharSequence> elements) {
+    return new HtmlContentBuilder(elements);
+  }
+
+  /**
+   * Creates HTML content with &lt;style type="text/css"&gt; cssStype &lt;style&gt;
+   */
+  public static IHtmlElement cssStyle(CharSequence... cssContent) {
+    return new StyleElementBuilder(cssContent).type("text/css");
+  }
+
+  /**
+   * Creates HTML content with HTML 5 doctype: &lt;!DOCTYPE
+   * html&gt;&lt;html&gt;&lt;head&gt;...&lt;/head&gt;body&gt;...&lt;/body&gt;&lt;html&gt;.
+   */
+  public static IHtmlDocument html5(CharSequence head, CharSequence body) {
+    return new HtmlDocumentBuilder(head(head), body(body)).doctype();
+  }
+
+  /**
+   * Creates HTML content with binds: &lt;html&gt;&lt;head&gt;...&lt;/head&gt;body&gt;...&lt;/body&gt;&lt;/html&gt;.
+   */
+  public static IHtmlDocument html(CharSequence head, CharSequence body) {
+    return new HtmlDocumentBuilder(head(head), body(body));
+  }
+
+  /**
+   * Creates HTML content that will not be encoded with {@link IHtmlContent#toHtml()}. <b>Use with caution!</b>
+   */
+  public static IHtmlContent raw(CharSequence... text) {
+    return new HtmlPlainBuilder(text);
+  }
+
+  /**
+   * Creates a html input field.
+   */
+  public static IHtmlInput input() {
+    return new HtmlInputBuilder();
+  }
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/HtmlHelper.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/HtmlHelper.java
new file mode 100644
index 0000000..9217526
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/HtmlHelper.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2016 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.scout.commons.StringUtility;
+
+/**
+ * @since 6.0 (backported)
+ */
+public final class HtmlHelper {
+
+  private static final Pattern HTML_PARAGRAPH_END_TAGS = Pattern.compile("<br/?></div>|</div>|<br/?>|</p>|<p/>|</tr>|</table>", Pattern.CASE_INSENSITIVE);
+
+  /**
+   * Very basic HTML to plain text conversion, without parsing and building a model.
+   * <p>
+   * The following rules are applied:
+   * <ul>
+   * <li>If the string contains a valid body tag (something between <code>&lt;body&gt;</code> and
+   * <code>&lt;/body&gt;</code>), only plain text of the body's content is returned. Otherwise, the plain text of the
+   * entire string is returned.
+   * <li><code>null</code> is only returned if the input is <code>null</code>. If no plain text is contained, the empty
+   * string (<code>""</code>) is returned.
+   * <li>The following tags are considered "end of paragraph" and are converted to <code>\n</code>:
+   * <ul>
+   * <li><code>&lt;br&gt;&lt;/div&gt;</code>
+   * <li><code>&lt;br/&gt;&lt;/div&gt;</code>
+   * <li><code>&lt;/div&gt;</code>
+   * <li><code>&lt;br&gt;</code>
+   * <li><code>&lt;br/&gt;</code>
+   * <li><code>&lt;/p&gt;</code>
+   * <li><code>&lt;p/&gt;</code>
+   * <li><code>&lt;/tr&gt;</code>
+   * <li><code>&lt;/table&gt;</code>
+   * </ul>
+   * <li>All other tags are replaced by a space.
+   * <li>Multiple consecutive spaces are merged to one space.
+   * <li>Leading and trailing whitespace line is removed from each line.
+   * </ul>
+   * <p>
+   */
+  public static String toPlainText(String html) {
+    if (html == null || html.length() == 0) {
+      return html;
+    }
+    String s = StringUtility.getTag(html, "body", true);
+    if (s == null) {
+      // <body> not found, use entire input
+      s = html;
+    }
+    //newlines
+    s = StringUtility.replace(s, "\r", "");
+    s = StringUtility.replace(s, "\n", " ");
+    Matcher matcher = HTML_PARAGRAPH_END_TAGS.matcher(s);
+    s = matcher.replaceAll("\n");
+    //tabs
+    s = StringUtility.replace(s, StringUtility.HTML_ENCODED_TAB, "\t");
+    //remove tags
+    s = Pattern.compile("<[^>]+>", Pattern.DOTALL).matcher(s).replaceAll(" ");
+    //remove multiple spaces
+    s = s.replaceAll("[ ]+", " ");
+    //remove spaces at the beginning and end of each line
+    s = s.replaceAll("[ ]+\n", "\n");
+    s = s.replaceAll("\n[ ]+", "\n");
+    s = unescape(s);
+
+    // space
+    s = StringUtility.replace(s, "&nbsp;", " ");
+    s = StringUtility.replace(s, "&#160;", " ");
+    s = StringUtility.replace(s, "&#xa0;", " ");
+
+    // tab
+    s = StringUtility.replace(s, "&#9;", "\t");
+    s = StringUtility.replace(s, "&#x9;", "\t");
+
+    s = s.trim();
+    return s;
+  }
+
+  /**
+   * Escapes the given string for use in HTML code. Useful when inserting data from an untrusted source directly inside
+   * HTML. Unlike {@link StringUtility#htmlEncode(String)}, this method does not alter whitespace.
+   * <p>
+   * According to <a href=
+   * "https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet#RULE_.231_-_HTML_Escape_Before_Inserting_Untrusted_Data_into_HTML_Element_Content"
+   * > OWASP recommendations</a>, the following characters are replaced:
+   * <ul>
+   * <li><code>&amp;</code> --> <code>&amp;amp;</code>
+   * <li><code>&lt;</code> --> <code>&amp;lt;</code>
+   * <li><code>&gt;</code> --> <code>&amp;gt;</code>
+   * <li><code>&quot;</code> --> <code>&amp;quot;</code>
+   * <li><code>&#39;</code> --> <code>&amp;#39;</code>
+   * <li><code>&#47;</code> --> <code>&amp;#47;</code>
+   * </ul>
+   *
+   * @see https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet
+   */
+  public static String escape(String text) {
+    if (text == null || text.length() == 0) {
+      return text;
+    }
+    text = StringUtility.replace(text, "&", "&amp;");
+    text = StringUtility.replace(text, "<", "&lt;");
+    text = StringUtility.replace(text, ">", "&gt;");
+    text = StringUtility.replace(text, "\"", "&quot;");
+    text = StringUtility.replace(text, "/", "&#47;");
+    text = StringUtility.replace(text, "'", "&#39;");
+    return text;
+  }
+
+  /**
+   * Reverse operation of {@link #escape(String)}. Unlike {@link StringUtility#htmlDecode(String)}, this method does not
+   * alter whitespace.
+   */
+  public static String unescape(String html) {
+    if (html == null || html.length() == 0) {
+      return html;
+    }
+
+    String decoded = StringUtility.replace(html, "&amp;", "&");
+    decoded = StringUtility.replace(decoded, "&#38;", "&");
+    decoded = StringUtility.replace(decoded, "&#x26;", "&");
+
+    decoded = StringUtility.replace(decoded, "&lt;", "<");
+    decoded = StringUtility.replace(decoded, "&#60;", "<");
+    decoded = StringUtility.replace(decoded, "&#x3c;", "<");
+
+    decoded = StringUtility.replace(decoded, "&gt;", ">");
+    decoded = StringUtility.replace(decoded, "&#62;", ">");
+    decoded = StringUtility.replace(decoded, "&#x3e;", ">");
+
+    decoded = StringUtility.replace(decoded, "&quot;", "\"");
+    decoded = StringUtility.replace(decoded, "&#34;", "\"");
+    decoded = StringUtility.replace(decoded, "&#x22;", "\"");
+
+    decoded = StringUtility.replace(decoded, "&#47;", "/"); // no named entity for the slash
+    decoded = StringUtility.replace(decoded, "&#x2f;", "/");
+
+    decoded = StringUtility.replace(decoded, "&apos;", "'");
+    decoded = StringUtility.replace(decoded, "&#39;", "'");
+    decoded = StringUtility.replace(decoded, "&#x27;", "'");
+    return decoded;
+  }
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlContent.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlContent.java
new file mode 100644
index 0000000..1663467
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlContent.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html;
+
+/**
+ * Marker Interface for any Html Content that may contain bind variables.
+ *
+ * @since 6.0 (backported)
+ */
+public interface IHtmlContent extends CharSequence {
+
+  String toHtml();
+
+  String toPlainText();
+
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlDocument.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlDocument.java
new file mode 100644
index 0000000..313a6bd
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlDocument.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html;
+
+/**
+ * @since 6.0 (backported)
+ */
+public interface IHtmlDocument extends IHtmlElement {
+
+  String HTML5_DOCTYPE = "<!DOCTYPE html>";
+
+  IHtmlDocument doctype(CharSequence type);
+
+  /**
+   * @return HTML document with HTML5 doctype {@value IHtmlDocument#HTML5_DOCTYPE}
+   */
+  IHtmlDocument doctype();
+
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlElement.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlElement.java
new file mode 100644
index 0000000..d7fc42e
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlElement.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html;
+
+/**
+ * A html element
+ *
+ * @since 6.0 (backported)
+ */
+public interface IHtmlElement extends CharSequence, IHtmlContent {
+
+  /**
+   * Add a css class
+   */
+  IHtmlElement cssClass(CharSequence cssClass);
+
+  /**
+   * Add a css style
+   */
+  IHtmlElement style(CharSequence style);
+
+  /**
+   * Add an application local link
+   *
+   * @param path
+   *          path to identify what is the link referring to.
+   */
+  IHtmlElement appLink(CharSequence path);
+
+  /**
+   * Add a html attribute to the element.
+   *
+   * @param name
+   *          of the attribute
+   * @param value
+   *          of the attribute
+   */
+  IHtmlElement addAttribute(String name, CharSequence value);
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlInput.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlInput.java
new file mode 100644
index 0000000..03ea789
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlInput.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html;
+
+/**
+ * @since 6.0 (backported)
+ */
+public interface IHtmlInput extends IHtmlElement {
+
+  String TYPE_TEXT = "text";
+  String TYPE_PASSWORD = "password";
+  String TYPE_CHECKBOX = "checkbox";
+  String TYPE_RADIO = "radio";
+  String TYPE_BUTTON = "button";
+  String TYPE_HIDDEN = "hidden";
+
+  String TYPE_SUBMIT = "submit";
+  String TYPE_RESET = "reset";
+
+  IHtmlInput id(String id);
+
+  IHtmlInput name(String name);
+
+  IHtmlInput type(String type);
+
+  IHtmlInput value(Object value);
+
+  IHtmlInput maxlength(int maxlength);
+
+  /**
+   * Only to be used with input fields of type {@value #TYPE_CHECKBOX} and {@value #TYPE_RADIO}.
+   */
+  IHtmlInput checked();
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  IHtmlInput cssClass(CharSequence cssClass);
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  IHtmlInput style(CharSequence style);
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  IHtmlInput appLink(CharSequence path);
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  IHtmlInput addAttribute(String name, CharSequence value);
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlListElement.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlListElement.java
new file mode 100644
index 0000000..754d0b2
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlListElement.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html;
+
+/**
+ * Marker Interface for list element &lt;li&gt;text&lt;/li&gt
+ *
+ * @since 6.0 (backported)
+ */
+public interface IHtmlListElement extends IHtmlElement {
+
+  /**
+   * Add a css class
+   */
+  @Override
+  IHtmlListElement cssClass(CharSequence cssClass);
+
+  /**
+   * Add a css style
+   */
+  @Override
+  IHtmlListElement style(CharSequence style);
+
+  /**
+   * Add an application local link
+   *
+   * @param path
+   *          path to identify what is the link referring to.
+   */
+  @Override
+  IHtmlListElement appLink(CharSequence path);
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  IHtmlListElement addAttribute(String name, CharSequence value);
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlTable.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlTable.java
new file mode 100644
index 0000000..76227f7
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlTable.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html;
+
+/**
+ * Marker Interface for html table
+ *
+ * @since 6.0 (backported)
+ */
+public interface IHtmlTable extends IHtmlElement {
+
+  /**
+   * Add a css class
+   */
+  @Override
+  IHtmlTable cssClass(CharSequence cssClass);
+
+  /**
+   * Add a css style
+   */
+  @Override
+  IHtmlTable style(CharSequence style);
+
+  /**
+   * Add an application local link
+   *
+   * @param path
+   *          path to identify what is the link referring to.
+   */
+  @Override
+  IHtmlTable appLink(CharSequence path);
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  IHtmlTable addAttribute(String name, CharSequence value);
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlTableCell.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlTableCell.java
new file mode 100644
index 0000000..7f136ea
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlTableCell.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html;
+
+/**
+ * Marker Interface for table cell
+ *
+ * @since 6.0 (backported)
+ */
+public interface IHtmlTableCell extends IHtmlElement {
+
+  /**
+   * Set the colspan.
+   */
+  IHtmlTableCell colspan(int colspan);
+
+  /**
+   * Add a css class
+   */
+  @Override
+  IHtmlTableCell cssClass(CharSequence cssClass);
+
+  /**
+   * Add a css style
+   */
+  @Override
+  IHtmlTableCell style(CharSequence style);
+
+  /**
+   * Add an application local link
+   *
+   * @param path
+   *          path to identify what is the link referring to.
+   */
+  @Override
+  IHtmlTableCell appLink(CharSequence path);
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  IHtmlTableCell addAttribute(String name, CharSequence value);
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlTableRow.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlTableRow.java
new file mode 100644
index 0000000..9e68161
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IHtmlTableRow.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html;
+
+/**
+ * Marker Interface for table row
+ *
+ * @since 6.0 (backported)
+ */
+public interface IHtmlTableRow extends IHtmlElement {
+
+  /**
+   * Add a css class
+   */
+  @Override
+  IHtmlTableRow cssClass(CharSequence cssClass);
+
+  /**
+   * Add a css style
+   */
+  @Override
+  IHtmlTableRow style(CharSequence style);
+
+  /**
+   * Add an application local link
+   *
+   * @param path
+   *          path to identify what is the link referring to.
+   */
+  @Override
+  IHtmlTableRow appLink(CharSequence path);
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  IHtmlTableRow addAttribute(String name, CharSequence value);
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IStyleElement.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IStyleElement.java
new file mode 100644
index 0000000..ca196bc
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/IStyleElement.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html;
+
+/**
+ * Marker Interface for style element
+ *
+ * @since 6.0 (backported)
+ */
+public interface IStyleElement extends IHtmlElement {
+
+  IStyleElement type(String typeName);
+
+  /**
+   * Add a css class
+   */
+  @Override
+  IStyleElement cssClass(CharSequence cssClass);
+
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/AbstractExpressionBuilder.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/AbstractExpressionBuilder.java
new file mode 100644
index 0000000..0e16996
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/AbstractExpressionBuilder.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html.internal;
+
+import org.eclipse.scout.commons.html.HtmlHelper;
+import org.eclipse.scout.commons.html.IHtmlContent;
+
+/**
+ * Buffer for expressions</br>
+ * (not thread safe)
+ *
+ * @since 6.0 (backported)
+ */
+public abstract class AbstractExpressionBuilder implements CharSequence, IHtmlContent {
+
+  private StringBuilder m_buf;
+
+  protected StringBuilder validate() {
+    if (m_buf == null) {
+      m_buf = new StringBuilder();
+      build();
+    }
+    return m_buf;
+  }
+
+  protected void invalidate() {
+    m_buf = null;
+  }
+
+  protected abstract void build();
+
+  @Override
+  public int length() {
+    return validate().length();
+  }
+
+  @Override
+  public char charAt(int index) {
+    return validate().charAt(index);
+  }
+
+  @Override
+  public CharSequence subSequence(int start, int end) {
+    return validate().subSequence(start, end);
+  }
+
+  @Override
+  public String toString() {
+    return validate().toString();
+  }
+
+  protected void append(CharSequence arg, boolean escape) {
+    String toAppend = null;
+    if (arg == null) {
+      toAppend = "";
+    }
+    else if (escape) {
+      toAppend = escape(arg);
+    }
+    else {
+      toAppend = arg.toString();
+    }
+    m_buf.append(toAppend);
+  }
+
+  @Override
+  public String toHtml() {
+    return toString();
+  }
+
+  @Override
+  public String toPlainText() {
+    return HtmlHelper.toPlainText(toHtml());
+  }
+
+  /**
+   * @return the escaped value.
+   */
+  protected String escape(Object value) {
+    return HtmlHelper.escape(value.toString());
+  }
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/EmptyHtmlNodeBuilder.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/EmptyHtmlNodeBuilder.java
new file mode 100644
index 0000000..126127e
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/EmptyHtmlNodeBuilder.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html.internal;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * An empty HTML tag without a closing tag (e.g. br)
+ *
+ * @since 6.0 (backported)
+ */
+public class EmptyHtmlNodeBuilder extends HtmlNodeBuilder {
+
+  public EmptyHtmlNodeBuilder(String tag, CharSequence... texts) {
+    this(tag, Arrays.asList(texts));
+  }
+
+  public EmptyHtmlNodeBuilder(String tag) {
+    this(tag, new ArrayList<String>());
+  }
+
+  public EmptyHtmlNodeBuilder(String tag, List<? extends CharSequence> texts) {
+    super(tag, texts);
+  }
+
+  @Override
+  public void build() {
+    appendStartTag();
+    if (getTexts().size() > 0) {
+      appendText();
+    }
+  }
+
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlContentBuilder.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlContentBuilder.java
new file mode 100644
index 0000000..9b6d34c
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlContentBuilder.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html.internal;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.scout.commons.html.IHtmlContent;
+
+/**
+ * Empty node for HTML fragments: Creates a node that may contain other html content, but does not have a tag name.
+ *
+ * @since 6.0 (backported)
+ */
+public class HtmlContentBuilder extends AbstractExpressionBuilder implements IHtmlContent {
+  private final List<? extends CharSequence> m_texts;
+
+  public HtmlContentBuilder(CharSequence... texts) {
+    this(Arrays.asList(texts));
+  }
+
+  public HtmlContentBuilder(List<? extends CharSequence> texts) {
+    m_texts = new ArrayList<CharSequence>(texts);
+  }
+
+  @Override
+  public void build() {
+    if (m_texts.size() > 0) {
+      appendText();
+    }
+  }
+
+  protected void appendText() {
+    for (CharSequence t : m_texts) {
+      append(t, !(t instanceof IHtmlContent));
+    }
+  }
+
+  protected List<? extends CharSequence> getTexts() {
+    return m_texts;
+  }
+
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlDocumentBuilder.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlDocumentBuilder.java
new file mode 100644
index 0000000..b5ef1dd
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlDocumentBuilder.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html.internal;
+
+import org.eclipse.scout.commons.html.IHtmlDocument;
+
+/**
+ * @since 6.0 (backported)
+ */
+public class HtmlDocumentBuilder extends HtmlNodeBuilder implements IHtmlDocument {
+  private CharSequence m_docType;
+
+  public HtmlDocumentBuilder(CharSequence... texts) {
+    super("html", texts);
+  }
+
+  @Override
+  public void build() {
+    if (m_docType != null) {
+      append(m_docType, false);
+    }
+    super.build();
+  }
+
+  @Override
+  public IHtmlDocument doctype(CharSequence doctype) {
+    m_docType = doctype;
+    return this;
+  }
+
+  @Override
+  public IHtmlDocument doctype() {
+    return doctype(IHtmlDocument.HTML5_DOCTYPE);
+  }
+
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlImageBuilder.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlImageBuilder.java
new file mode 100644
index 0000000..718a906
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlImageBuilder.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html.internal;
+
+import org.eclipse.scout.commons.html.IHtmlElement;
+
+/**
+ * Builder for a html image.
+ *
+ * @since 6.0 (backported)
+ */
+public class HtmlImageBuilder extends EmptyHtmlNodeBuilder implements IHtmlElement {
+
+  public HtmlImageBuilder(CharSequence path) {
+    super("img");
+    addAttribute("src", path);
+  }
+
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlInputBuilder.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlInputBuilder.java
new file mode 100644
index 0000000..9bb473d
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlInputBuilder.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html.internal;
+
+import org.eclipse.scout.commons.StringUtility;
+import org.eclipse.scout.commons.html.IHtmlInput;
+
+/**
+ * @since 6.0 (backported)
+ */
+public class HtmlInputBuilder extends EmptyHtmlNodeBuilder implements IHtmlInput {
+
+  public HtmlInputBuilder() {
+    super("input");
+  }
+
+  @Override
+  public IHtmlInput id(String id) {
+    addAttribute("id", id);
+    return this;
+  }
+
+  @Override
+  public IHtmlInput name(String name) {
+    addAttribute("name", name);
+    return this;
+  }
+
+  @Override
+  public IHtmlInput type(String type) {
+    addAttribute("type", type);
+    return this;
+  }
+
+  @Override
+  public IHtmlInput value(Object value) {
+    addAttribute("value", StringUtility.nvl(value, ""));
+    return this;
+  }
+
+  @Override
+  public IHtmlInput maxlength(int maxlength) {
+    addAttribute("maxlength", maxlength);
+    return this;
+  }
+
+  @Override
+  public IHtmlInput checked() {
+    addAttribute("checked", "checked");
+    return this;
+  }
+
+  @Override
+  public IHtmlInput cssClass(CharSequence cssClass) {
+    return (IHtmlInput) super.cssClass(cssClass);
+  }
+
+  @Override
+  public IHtmlInput style(CharSequence style) {
+    return (IHtmlInput) super.style(style);
+  }
+
+  @Override
+  public IHtmlInput appLink(CharSequence ref) {
+    return (IHtmlInput) super.appLink(ref);
+  }
+
+  @Override
+  public IHtmlInput addAttribute(String name, CharSequence value) {
+    return (IHtmlInput) super.addAttribute(name, value);
+  }
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlLinkBuilder.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlLinkBuilder.java
new file mode 100644
index 0000000..dd5b523
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlLinkBuilder.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html.internal;
+
+import org.eclipse.scout.commons.html.IHtmlElement;
+
+/**
+ * Builder for a html link.
+ *
+ * @since 6.0 (backported)
+ */
+public class HtmlLinkBuilder extends HtmlNodeBuilder implements IHtmlElement {
+
+  public HtmlLinkBuilder(CharSequence url, CharSequence text) {
+    super("a", text);
+    addAttribute("href", url);
+  }
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlListElement.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlListElement.java
new file mode 100644
index 0000000..146405e
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlListElement.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html.internal;
+
+import org.eclipse.scout.commons.html.IHtmlListElement;
+
+/**
+ * @since 6.0 (backported)
+ */
+public class HtmlListElement extends HtmlNodeBuilder implements IHtmlListElement {
+
+  public HtmlListElement(CharSequence text) {
+    super("li", text);
+  }
+
+  /**
+   * Add a css class
+   */
+  @Override
+  public IHtmlListElement cssClass(CharSequence cssClass) {
+    return (IHtmlListElement) super.cssClass(cssClass);
+  }
+
+  /**
+   * Add a css style
+   */
+  @Override
+  public IHtmlListElement style(CharSequence style) {
+    return (IHtmlListElement) super.style(style);
+  }
+
+  /**
+   * Add an application local link
+   *
+   * @param ref
+   *          path to identify what is the link referring to.
+   */
+  @Override
+  public IHtmlListElement appLink(CharSequence ref) {
+    return (IHtmlListElement) super.appLink(ref);
+  }
+
+  @Override
+  public IHtmlListElement addAttribute(String name, CharSequence value) {
+    return (IHtmlListElement) super.addAttribute(name, value);
+  }
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlNodeBuilder.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlNodeBuilder.java
new file mode 100644
index 0000000..e68239d
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlNodeBuilder.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html.internal;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.scout.commons.CollectionUtility;
+import org.eclipse.scout.commons.StringUtility;
+import org.eclipse.scout.commons.html.IHtmlElement;
+
+/**
+ * Builder for a html node with start tag, end tag and attributes.
+ *
+ * @since 6.0 (backported)
+ */
+public class HtmlNodeBuilder extends HtmlContentBuilder implements IHtmlElement {
+
+  private final List<CharSequence> m_attributes = new ArrayList<CharSequence>();
+  private String m_tag;
+
+  protected String getTag() {
+    return m_tag;
+  }
+
+  public HtmlNodeBuilder(String tag, CharSequence... texts) {
+    this(tag, Arrays.asList(texts));
+  }
+
+  public HtmlNodeBuilder(String tag) {
+    this(tag, new ArrayList<String>());
+  }
+
+  public HtmlNodeBuilder(String tag, List<? extends CharSequence> texts) {
+    super(texts);
+    m_tag = tag;
+  }
+
+  @Override
+  public void build() {
+    appendStartTag();
+    if (getTexts().size() > 0) {
+      appendText();
+    }
+    appendEndTag();
+  }
+
+  protected void appendStartTag() {
+    append("<", false);
+    append(getTag(), true);
+    appendAttributes();
+    append(">", false);
+  }
+
+  protected void appendEndTag() {
+    append("</", false);
+    append(getTag(), true);
+    append(">", false);
+  }
+
+  private void appendAttributes() {
+    if (m_attributes.size() > 0) {
+      append(" ", false);
+      append(CollectionUtility.format(m_attributes, " "), false);
+    }
+  }
+
+  protected void addAttribute(String name, int value) {
+    addAttribute(name, Integer.toString(value));
+  }
+
+  @Override
+  public IHtmlElement addAttribute(String name, CharSequence value) {
+    String attribValue = null;
+    final String doubleQuote = "\"";
+    if (value == null) {
+      attribValue = "";
+    }
+    else {
+      attribValue = StringUtility.replace(value.toString(), doubleQuote, "&quot;");
+    }
+
+    HtmlContentBuilder content = new HtmlContentBuilder(
+        new HtmlPlainBuilder(escape(name)),
+        new HtmlPlainBuilder("=" + doubleQuote),
+        new HtmlPlainBuilder(attribValue),
+        new HtmlPlainBuilder(doubleQuote));
+    m_attributes.add(content);
+    return this;
+  }
+
+/// GLOBAL ATTRIBUTES
+  @Override
+  public IHtmlElement style(CharSequence value) {
+    addAttribute("style", value);
+    return this;
+  }
+
+  @Override
+  public IHtmlElement cssClass(CharSequence cssClass) {
+    addAttribute("class", cssClass);
+    return this;
+  }
+
+  @Override
+  public IHtmlElement appLink(CharSequence ref) {
+    cssClass("app-link");
+    addAttribute("data-ref", ref);
+    return this;
+  }
+
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlPlainBuilder.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlPlainBuilder.java
new file mode 100644
index 0000000..9f5410c
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlPlainBuilder.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html.internal;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @since 6.0 (backported)
+ */
+public class HtmlPlainBuilder extends AbstractExpressionBuilder {
+  private final List<? extends CharSequence> m_texts;
+
+  public HtmlPlainBuilder(CharSequence... texts) {
+    this(Arrays.asList(texts));
+  }
+
+  public HtmlPlainBuilder(List<? extends CharSequence> texts) {
+    m_texts = new ArrayList<CharSequence>(texts);
+  }
+
+  @Override
+  public void build() {
+    if (m_texts.size() > 0) {
+      appendText();
+    }
+  }
+
+  protected void appendText() {
+    for (CharSequence t : m_texts) {
+      append(t, false);
+    }
+  }
+
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlTableBuilder.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlTableBuilder.java
new file mode 100644
index 0000000..33696b4
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlTableBuilder.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html.internal;
+
+import java.util.List;
+
+import org.eclipse.scout.commons.html.IHtmlTable;
+import org.eclipse.scout.commons.html.IHtmlTableRow;
+
+/**
+ * Builder for a html table.
+ *
+ * @since 6.0 (backported)
+ */
+public class HtmlTableBuilder extends HtmlNodeBuilder implements IHtmlTable {
+
+  public HtmlTableBuilder(List<IHtmlTableRow> rows) {
+    super("table", rows);
+  }
+
+  /**
+   * Add a css class
+   */
+  @Override
+  public IHtmlTable cssClass(CharSequence cssClass) {
+    return (IHtmlTable) super.cssClass(cssClass);
+  }
+
+  /**
+   * Add a css style
+   */
+  @Override
+  public IHtmlTable style(CharSequence style) {
+    return (IHtmlTable) super.style(style);
+  }
+
+  /**
+   * Add an application local link
+   *
+   * @param ref
+   *          path to identify what is the link referring to.
+   */
+  @Override
+  public IHtmlTable appLink(CharSequence ref) {
+    return (IHtmlTable) super.appLink(ref);
+  }
+
+  @Override
+  public IHtmlTable addAttribute(String name, CharSequence value) {
+    return (IHtmlTable) super.addAttribute(name, value);
+  }
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlTableDataBuilder.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlTableDataBuilder.java
new file mode 100644
index 0000000..9a5a667
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlTableDataBuilder.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html.internal;
+
+import java.util.List;
+
+import org.eclipse.scout.commons.html.IHtmlTableCell;
+
+/**
+ * Builder for a html table data
+ *
+ * @since 6.0 (backported)
+ */
+public class HtmlTableDataBuilder extends HtmlNodeBuilder implements IHtmlTableCell {
+
+  public HtmlTableDataBuilder(List<? extends CharSequence> text) {
+    super("td", text);
+  }
+
+  @Override
+  public IHtmlTableCell colspan(int colspan) {
+    addAttribute("colspan", colspan);
+    return this;
+  }
+
+  /**
+   * Add a css class
+   */
+  @Override
+  public IHtmlTableCell cssClass(CharSequence cssClass) {
+    return (IHtmlTableCell) super.cssClass(cssClass);
+  }
+
+  /**
+   * Add a css style
+   */
+  @Override
+  public IHtmlTableCell style(CharSequence style) {
+    return (IHtmlTableCell) super.style(style);
+  }
+
+  /**
+   * Add an application local link
+   *
+   * @param ref
+   *          path to identify what is the link referring to.
+   */
+  @Override
+  public IHtmlTableCell appLink(CharSequence ref) {
+    return (IHtmlTableCell) super.appLink(ref);
+  }
+
+  @Override
+  public IHtmlTableCell addAttribute(String name, CharSequence value) {
+    return (IHtmlTableCell) super.addAttribute(name, value);
+  }
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlTableRowBuilder.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlTableRowBuilder.java
new file mode 100644
index 0000000..8993f0d
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/HtmlTableRowBuilder.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html.internal;
+
+import java.util.List;
+
+import org.eclipse.scout.commons.html.IHtmlTableCell;
+import org.eclipse.scout.commons.html.IHtmlTableRow;
+
+/**
+ * Builder for a html table row.
+ *
+ * @since 6.0 (backported)
+ */
+public class HtmlTableRowBuilder extends HtmlNodeBuilder implements IHtmlTableRow {
+
+  public HtmlTableRowBuilder(List<? extends IHtmlTableCell> text) {
+    super("tr", text);
+  }
+
+  /**
+   * Add a css class
+   */
+  @Override
+  public IHtmlTableRow cssClass(CharSequence cssClass) {
+    return (IHtmlTableRow) super.cssClass(cssClass);
+  }
+
+  /**
+   * Add a css style
+   */
+  @Override
+  public IHtmlTableRow style(CharSequence style) {
+    return (IHtmlTableRow) super.style(style);
+  }
+
+  /**
+   * Add an application local link
+   *
+   * @param ref
+   *          path to identify what is the link referring to.
+   */
+  @Override
+  public IHtmlTableRow appLink(CharSequence ref) {
+    return (IHtmlTableRow) super.appLink(ref);
+  }
+
+  @Override
+  public IHtmlTableRow addAttribute(String name, CharSequence value) {
+    return (IHtmlTableRow) super.addAttribute(name, value);
+  }
+}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/StyleElementBuilder.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/StyleElementBuilder.java
new file mode 100644
index 0000000..1a4728b
--- /dev/null
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/html/internal/StyleElementBuilder.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.commons.html.internal;
+
+import org.eclipse.scout.commons.html.IStyleElement;
+
+/**
+ * @since 6.0 (backported)
+ */
+public class StyleElementBuilder extends HtmlNodeBuilder implements IStyleElement {
+
+  public StyleElementBuilder(CharSequence... elements) {
+    super("style", elements);
+  }
+
+  @Override
+  public IStyleElement type(String typeName) {
+    addAttribute("type", typeName);
+    return this;
+  }
+
+  /**
+   * Add a css class
+   */
+  @Override
+  public IStyleElement cssClass(CharSequence cssClass) {
+    return (IStyleElement) super.cssClass(cssClass);
+  }
+
+  /**
+   * Add a css style
+   */
+  @Override
+  public IStyleElement style(CharSequence style) {
+    return (IStyleElement) super.style(style);
+  }
+
+  /**
+   * Add an application local link
+   *
+   * @param ref
+   *          path to identify what is the link referring to.
+   */
+  @Override
+  public IStyleElement appLink(CharSequence ref) {
+    return (IStyleElement) super.appLink(ref);
+  }
+
+}
diff --git a/org.eclipse.scout.rt.client.mobile/src/org/eclipse/scout/rt/client/mobile/ui/basic/table/PagingTableRow.java b/org.eclipse.scout.rt.client.mobile/src/org/eclipse/scout/rt/client/mobile/ui/basic/table/PagingTableRow.java
index 12f2ca8..98f30ff 100644
--- a/org.eclipse.scout.rt.client.mobile/src/org/eclipse/scout/rt/client/mobile/ui/basic/table/PagingTableRow.java
+++ b/org.eclipse.scout.rt.client.mobile/src/org/eclipse/scout/rt/client/mobile/ui/basic/table/PagingTableRow.java
@@ -12,6 +12,7 @@
 
 import org.eclipse.scout.commons.CollectionUtility;
 import org.eclipse.scout.commons.IOUtility;
+import org.eclipse.scout.commons.html.HTML;
 import org.eclipse.scout.commons.logger.IScoutLogger;
 import org.eclipse.scout.commons.logger.ScoutLogManager;
 import org.eclipse.scout.rt.client.mobile.Activator;
@@ -51,8 +52,8 @@
       else {
         content = TEXTS.get("MobilePagingShowNext");
       }
-      content = "<b>" + content + "</b>";
-      String output = s_htmlCellTemplate.replace("#CONTENT#", content);
+
+      String output = s_htmlCellTemplate.replace("#CONTENT#", HTML.bold(content).toHtml());
       getCellForUpdate(column).setText(output);
     }
   }
diff --git a/org.eclipse.scout.rt.client.mobile/src/org/eclipse/scout/rt/client/mobile/ui/basic/table/columns/AbstractRowSummaryColumn.java b/org.eclipse.scout.rt.client.mobile/src/org/eclipse/scout/rt/client/mobile/ui/basic/table/columns/AbstractRowSummaryColumn.java
index e2e7fdd..1449c5a 100644
--- a/org.eclipse.scout.rt.client.mobile/src/org/eclipse/scout/rt/client/mobile/ui/basic/table/columns/AbstractRowSummaryColumn.java
+++ b/org.eclipse.scout.rt.client.mobile/src/org/eclipse/scout/rt/client/mobile/ui/basic/table/columns/AbstractRowSummaryColumn.java
@@ -22,9 +22,11 @@
 import org.eclipse.scout.commons.StringUtility;
 import org.eclipse.scout.commons.annotations.ClassId;
 import org.eclipse.scout.commons.exception.ProcessingException;
+import org.eclipse.scout.commons.html.HtmlHelper;
 import org.eclipse.scout.rt.client.mobile.Activator;
 import org.eclipse.scout.rt.client.mobile.Icons;
 import org.eclipse.scout.rt.client.mobile.ui.basic.table.DrillDownStyleMap;
+import org.eclipse.scout.rt.client.ui.basic.cell.ICell;
 import org.eclipse.scout.rt.client.ui.basic.table.ITable;
 import org.eclipse.scout.rt.client.ui.basic.table.ITableRow;
 import org.eclipse.scout.rt.client.ui.basic.table.columns.AbstractStringColumn;
@@ -95,6 +97,11 @@
   }
 
   @Override
+  protected boolean getConfiguredHtmlEnabled() {
+    return true;
+  }
+
+  @Override
   public String getDefaultDrillDownStyle() {
     return propertySupport.getPropertyString(PROP_DEFAULT_DRILL_DOWN_STYLE);
   }
@@ -203,9 +210,7 @@
         if (cellHeaderText != null && cellHeaderText.contains(columnDisplayText)) {
           return false;
         }
-
       }
-
     }
 
     if (columnEmpty) {
@@ -215,6 +220,13 @@
     return true;
   }
 
+  private ICell getHeaderCell(ITableRow row) {
+    if (m_cellHeaderColumn != null) {
+      return row.getCell(m_cellHeaderColumn);
+    }
+    return row.getTable().getSummaryCell(row);
+  }
+
   private String getCellHeaderText(ITableRow row) {
     if (m_cellHeaderColumn != null) {
       return m_cellHeaderColumn.getDisplayText(row);
@@ -282,13 +294,14 @@
       return null;
     }
 
+    ICell headerCell = getHeaderCell(row);
     String cellHeaderText = getCellHeaderText(row);
     if (cellHeaderText == null) {
       cellHeaderText = "";
     }
     //Don't generate cell content if the only column contains html.
     //It is assumed that such a column is already optimized for mobile devices.
-    if (m_cellDetailColumns.size() == 0 && containsHtml(cellHeaderText)) {
+    if (m_cellDetailColumns.size() == 0 && headerCell.isHtmlEnabled()) {
       cellHeaderText = adaptExistingHtmlInCellHeader(cellHeaderText);
 
       //Make sure drill down style is set to none
@@ -301,7 +314,7 @@
     String content = "";
     boolean cellHasHeader = false;
     if (StringUtility.hasText(cellHeaderText)) {
-      content = createCellHeader(cellHeaderText);
+      content = createCellHeader(cellHeaderText, headerCell);
       content += "<br/>";
       cellHasHeader = true;
     }
@@ -349,7 +362,7 @@
       return "";
     }
     else {
-      return "<img width=\"16\" height=\"16\" src=\"cid:" + iconId + "\"/>";
+      return "<img width=\"16\" height=\"16\" src=\"cid:" + StringUtility.htmlEncode(iconId) + "\"/>";
     }
   }
 
@@ -411,13 +424,9 @@
     }
   }
 
-  private String createCellHeader(String cellHeaderText) {
-    String content = "";
-
-    content = cleanupText(cellHeaderText);
-    content = "<b>" + content + "</b>";
-
-    return content;
+  private String createCellHeader(String cellHeaderText, ICell headerCell) {
+    String content = cleanupText(cellHeaderText, headerCell);
+    return "<b>" + content + "</b>";
   }
 
   private String createCellDetail(ITableRow row, boolean cellHasHeader) {
@@ -453,28 +462,38 @@
     return content;
   }
 
-  private String cleanupText(String text) {
+  private String cleanupText(String text, ICell cell) {
+    return cleanupText(text, cell.isHtmlEnabled());
+  }
+
+  private String cleanupText(String text, boolean containsHtml) {
     if (text == null) {
       return null;
     }
 
-    boolean containsHtml = text.contains("<html>");
     if (containsHtml) {
+      String textWithoutHtml = null;
       //Ignore every html code by removing all the tags to make sure it does not destroy the layout
-      String textWithoutHtml = HTMLUtility.getPlainText(text);
+      if (StringUtility.hasText(StringUtility.getTag(text, "body"))) {
+        textWithoutHtml = HTMLUtility.getPlainText(text);
+      }
+      else {
+        textWithoutHtml = HTMLUtility.getPlainText(text, false, false);
+      }
+
       if (textWithoutHtml != null) {
         text = textWithoutHtml;
       }
     }
+
     text = StringUtility.removeNewLines(text);
     text = StringUtility.trim(text);
+
     if (!containsHtml) {
       //If the text is not surrounded by <html> the html must not be interpreted but displayed as it is including all the html tags.
-      text = StringUtility.htmlEncode(text);
+      text = HtmlHelper.escape(text);
     }
-    text = replaceSpaces(text);
-
-    return text;
+    return replaceSpaces(text);
   }
 
   /**
@@ -486,19 +505,13 @@
   }
 
   private String extractCellDisplayText(IColumn<?> column, ITableRow row) {
-    String displayText = column.getDisplayText(row);
-
-    displayText = cleanupText(displayText);
-
-    return displayText;
+    ICell cell = row.getCell(column);
+    return cleanupText(cell.getText(), cell);
   }
 
   private String extractColumnHeader(IColumn<?> column) {
     String header = column.getHeaderCell().getText();
-
-    header = cleanupText(header);
-
-    return header;
+    return cleanupText(header, containsHtml(header));
   }
 
   /**
diff --git a/org.eclipse.scout.rt.client.test/src/org/eclipse/scout/rt/client/ui/basic/cell/CellTest.java b/org.eclipse.scout.rt.client.test/src/org/eclipse/scout/rt/client/ui/basic/cell/CellTest.java
index ad424f2..1efe612 100644
--- a/org.eclipse.scout.rt.client.test/src/org/eclipse/scout/rt/client/ui/basic/cell/CellTest.java
+++ b/org.eclipse.scout.rt.client.test/src/org/eclipse/scout/rt/client/ui/basic/cell/CellTest.java
@@ -43,6 +43,7 @@
     assertNull(c.getFont());
     assertTrue(c.isEnabled());
     assertNull(c.getObserver());
+    assertFalse(c.isHtmlEnabled());
   }
 
   @Test
@@ -66,6 +67,7 @@
     c.setForegroundColor(fgColor);
     c.setFont(font);
     c.setEnabled(true);
+    c.setHtmlEnabled(true);
     c.setObserver(observer);
 
     Cell copy = new Cell(c);
@@ -78,6 +80,7 @@
     assertEquals(fgColor, c.getForegroundColor());
     assertEquals(font.toPattern(), c.getFont().toPattern());
     assertTrue(c.isEnabled());
+    assertTrue(copy.isHtmlEnabled());
     assertSame(observer, c.getObserver());
     Mockito.verifyZeroInteractions(observer);
   }
@@ -96,6 +99,7 @@
     assertNull(c.getForegroundColor());
     assertNull(c.getFont());
     assertTrue(c.isEnabled());
+    assertFalse(c.isHtmlEnabled());
     assertSame(observer, c.getObserver());
     Mockito.verifyZeroInteractions(observer);
   }
@@ -262,6 +266,16 @@
   }
 
   @Test
+  public void testSetHtmlEnabled() {
+    Cell c = new Cell();
+    ICellObserver observer = Mockito.mock(ICellObserver.class);
+    c.setObserver(observer);
+    c.setHtmlEnabled(true);
+    assertTrue(c.isHtmlEnabled());
+    Mockito.verify(observer).cellChanged(c, ICell.HTML_ENABLED_BIT);
+  }
+
+  @Test
   public void testSetObserver() {
     Cell c = new Cell();
     ICellObserver observer = Mockito.mock(ICellObserver.class);
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/IHtmlCapable.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/IHtmlCapable.java
new file mode 100644
index 0000000..06ed937
--- /dev/null
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/IHtmlCapable.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.rt.client.ui;
+
+/**
+ * Specifies, if it is possible to use HTML that is rendered in the UI.
+ * <p>
+ * If HTML is enabled, the user needs to make sure that any user input (or other insecure input) is encoded (security).
+ *
+ * @since 5.2 (backported)
+ */
+public interface IHtmlCapable {
+  String PROP_HTML_ENABLED = "htmlEnabled";
+
+  /**
+   * Enable or disable the rendering of HTML.<br>
+   * Make sure that any user input (or other insecure input) is encoded (security)
+   */
+  void setHtmlEnabled(boolean enabled);
+
+  /**
+   * @return true, if the cell may contain html that needs to be rendered. false otherwise.
+   */
+  boolean isHtmlEnabled();
+
+}
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/Cell.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/Cell.java
index b70afe3..b78760c 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/Cell.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/Cell.java
@@ -19,6 +19,7 @@
 import org.eclipse.scout.commons.exception.ProcessingException;
 import org.eclipse.scout.commons.logger.IScoutLogger;
 import org.eclipse.scout.commons.logger.ScoutLogManager;
+import org.eclipse.scout.rt.client.ui.IHtmlCapable;
 import org.eclipse.scout.rt.client.ui.basic.table.columns.AbstractColumn;
 import org.eclipse.scout.rt.shared.data.basic.FontSpec;
 
@@ -29,7 +30,7 @@
  * rarely used properties.
  * </p>
  */
-public class Cell implements ICell {
+public class Cell implements ICell, IHtmlCapable {
 
   private static final IScoutLogger LOG = ScoutLogManager.getLogger(Cell.class);
 
@@ -87,6 +88,7 @@
       setValue(c.getValue());
       setEnabled(c.isEnabled());
       setErrorStatus(c.getErrorStatus());
+      setHtmlEnabled(c.isHtmlEnabled());
       //do not reset observer
     }
   }
@@ -313,4 +315,25 @@
     }
     return s;
   }
+
+  @Override
+  public void setHtmlEnabled(boolean b) {
+    if (m_cellSpecialization instanceof CellStyle) {
+      if (b) {
+        ICellSpecialization newStyle = new CellExtension(m_cellSpecialization);
+        newStyle.setHtmlEnabled(b);
+        setValueInternal(HTML_ENABLED_BIT, newStyle);
+      }
+    }
+    else if (m_cellSpecialization.isHtmlEnabled() != b) {
+      ICellSpecialization newStyle = m_cellSpecialization.copy();
+      newStyle.setHtmlEnabled(b);
+      setValueInternal(HTML_ENABLED_BIT, newStyle);
+    }
+  }
+
+  @Override
+  public boolean isHtmlEnabled() {
+    return m_cellSpecialization.isHtmlEnabled();
+  }
 }
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/CellExtension.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/CellExtension.java
index 3512423..535c54d 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/CellExtension.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/CellExtension.java
@@ -24,6 +24,7 @@
   private boolean m_enabled;
   private boolean m_editable;
   private CellStyle m_cellStyle;
+  private boolean m_htmlEnabled;
 
   public CellExtension(ICellSpecialization specialization) {
     m_enabled = true;
@@ -130,4 +131,14 @@
   public void setIconId(String iconId) {
     m_cellStyle.setIconId(iconId);
   }
+
+  @Override
+  public void setHtmlEnabled(boolean enabled) {
+    m_htmlEnabled = enabled;
+  }
+
+  @Override
+  public boolean isHtmlEnabled() {
+    return m_htmlEnabled;
+  }
 }
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/CellStyle.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/CellStyle.java
index bbf8e9b..74d728f 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/CellStyle.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/CellStyle.java
@@ -57,6 +57,11 @@
   }
 
   @Override
+  public void setHtmlEnabled(boolean enabled) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
   public String getTooltipText() {
     return null;
   }
@@ -72,6 +77,11 @@
   }
 
   @Override
+  public boolean isHtmlEnabled() {
+    return false;
+  }
+
+  @Override
   public CellStyle getCellStyle() {
     return this;
   }
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/ICell.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/ICell.java
index 650fe2e..ccd757e 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/ICell.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/ICell.java
@@ -27,6 +27,7 @@
   int FONT_BIT = 8;
   int ENABLED_BIT = 9;// default true, value Boolean
   int EDITABLE_BIT = 10;// default false, value Boolean
+  int HTML_ENABLED_BIT = 12; //default false, value Boolean
 
   Object getValue();
 
@@ -54,6 +55,11 @@
    */
   boolean isEditable();
 
+  /**
+   * @return true, if the cell may contain html that needs to be rendered. false otherwise.
+   */
+  boolean isHtmlEnabled();
+
   ICellObserver getObserver();
 
   /**
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/ICellSpecialization.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/ICellSpecialization.java
index 0e5c2b8..8d4cbe9 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/ICellSpecialization.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/cell/ICellSpecialization.java
@@ -67,4 +67,8 @@
   int getHorizontalAlignment();
 
   void setHorizontalAlignment(int horizontalAlignment);
+
+  void setHtmlEnabled(boolean enabled);
+
+  boolean isHtmlEnabled();
 }
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/table/AbstractTable.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/table/AbstractTable.java
index 84d6702..ef102f3 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/table/AbstractTable.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/table/AbstractTable.java
@@ -575,12 +575,13 @@
       boolean firstColumn = true;
       for (IColumn<?> column : columns) {
         String text;
+        ICell cell = row.getCell(column);
         if (column instanceof IBooleanColumn) {
           boolean value = BooleanUtility.nvl(((IBooleanColumn) column).getValue(row), false);
           text = value ? "X" : "";
         }
         else {
-          text = StringUtility.emptyIfNull(row.getCell(column).getText());
+          text = StringUtility.emptyIfNull(cell.getText());
         }
 
         // text/plain
@@ -601,6 +602,11 @@
         if (html == null) {
           html = StringUtility.htmlEncode(text);
         }
+
+        if (!cell.isHtmlEnabled()) {
+          html = StringUtility.htmlEncode(html);
+        }
+
         htmlText.append("<td>");
         htmlText.append(html);
         htmlText.append("</td>");
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/table/columns/AbstractColumn.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/table/columns/AbstractColumn.java
index d106955..5d29066 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/table/columns/AbstractColumn.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/table/columns/AbstractColumn.java
@@ -505,6 +505,20 @@
   }
 
   /**
+   * Configures, if HTML rendering is enabled for this column.
+   * <p>
+   * Subclasses can override this method. Default is {@code false}. Make sure that any user input (or other insecure
+   * input) is encoded (security), if this property is enabled.
+   * 
+   * @return {@code true}, if HTML rendering is enabled for this column.{@code false} otherwise.
+   */
+  @ConfigProperty(ConfigProperty.BOOLEAN)
+  @Order(220)
+  protected boolean getConfiguredHtmlEnabled() {
+    return false;
+  }
+
+  /**
    * Called after this column has been added to the column set of the surrounding table. This method may execute
    * additional initialization for this column (e.g. register listeners).
    * <p>
@@ -779,6 +793,7 @@
     if (getConfiguredFont() != null) {
       setFont(FontSpec.parse(getConfiguredFont()));
     }
+    setHtmlEnabled(getConfiguredHtmlEnabled());
   }
 
   /**
@@ -1386,6 +1401,7 @@
     }
     cell.setHorizontalAlignment(getHorizontalAlignment());
     cell.setEditableInternal(isCellEditable(row));
+    cell.setHtmlEnabled(isHtmlEnabled());
   }
 
   @Override
@@ -1619,6 +1635,16 @@
   }
 
   @Override
+  public void setHtmlEnabled(boolean enabled) {
+    propertySupport.setProperty(PROP_HTML_ENABLED, enabled);
+  }
+
+  @Override
+  public boolean isHtmlEnabled() {
+    return propertySupport.getPropertyBool(PROP_HTML_ENABLED);
+  }
+
+  @Override
   public String toString() {
     return getClass().getSimpleName() + "[" + getHeaderCell().getText() + " width=" + getWidth() + (isPrimaryKey() ? " primaryKey" : "") + (isSummary() ? " summary" : "") + " viewIndexHint=" + getVisibleColumnIndexHint() + "]";
   }
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/table/columns/IColumn.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/table/columns/IColumn.java
index cddd61e..ae20962 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/table/columns/IColumn.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/basic/table/columns/IColumn.java
@@ -18,6 +18,7 @@
 import org.eclipse.scout.commons.annotations.IOrdered;
 import org.eclipse.scout.commons.beans.IPropertyObserver;
 import org.eclipse.scout.commons.exception.ProcessingException;
+import org.eclipse.scout.rt.client.ui.IHtmlCapable;
 import org.eclipse.scout.rt.client.ui.basic.table.ColumnSet;
 import org.eclipse.scout.rt.client.ui.basic.table.IHeaderCell;
 import org.eclipse.scout.rt.client.ui.basic.table.ITable;
@@ -25,7 +26,7 @@
 import org.eclipse.scout.rt.client.ui.form.fields.IFormField;
 import org.eclipse.scout.rt.shared.data.basic.FontSpec;
 
-public interface IColumn<VALUE> extends IPropertyObserver, ITypeWithClassId, IOrdered {
+public interface IColumn<VALUE> extends IPropertyObserver, ITypeWithClassId, IOrdered, IHtmlCapable {
   /**
    * type boolean
    */
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/ScoutInfoForm.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/ScoutInfoForm.java
index d4215ac..d91e5b7 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/ScoutInfoForm.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/ScoutInfoForm.java
@@ -20,6 +20,8 @@
 import org.eclipse.scout.commons.LocaleThreadLocal;
 import org.eclipse.scout.commons.annotations.Order;
 import org.eclipse.scout.commons.exception.ProcessingException;
+import org.eclipse.scout.commons.html.HTML;
+import org.eclipse.scout.commons.html.HtmlHelper;
 import org.eclipse.scout.commons.logger.IScoutLogger;
 import org.eclipse.scout.commons.logger.ScoutLogManager;
 import org.eclipse.scout.rt.client.ClientSyncJob;
@@ -218,16 +220,16 @@
       buf.append("<img src=\"" + f.getPath() + "\">");
     }
     else {
-      buf.append("<h3>" + title + "</h3>");
+      buf.append(HTML.h3(title).toHtml());
     }
     buf.append("<p>");
-    buf.append("<h2>" + title + " " + v.getMajor() + "." + v.getMinor() + "." + v.getMicro() + "</h2>");
+    buf.append(HTML.h2(title + " " + v.getMajor() + "." + v.getMinor() + "." + v.getMicro()).toHtml());
     buf.append("<table cellspacing=0 cellpadding=0>");
     //
     StringBuffer contentBuf = new StringBuffer();
     createHtmlPropertyTableContent(contentBuf);
     buf.append(contentBuf.toString());
-    buf.append("<tr><td>" + ScoutTexts.get("DetailedVersion") + ":</td><td>&nbsp;</td><td>" + v.toString() + "</td></tr>");
+    buf.append("<tr><td>" + ScoutTexts.get("DetailedVersion") + ":</td><td>&nbsp;</td><td>" + HtmlHelper.escape(v.toString()) + "</td></tr>");
     //
     buf.append("</table>");
   }
@@ -238,27 +240,27 @@
     long memTotal = Runtime.getRuntime().totalMemory() / 1024 / 1024;
     long memMax = Runtime.getRuntime().maxMemory() / 1024 / 1024;
     //
-    buf.append("<tr><td>" + ScoutTexts.get("Username") + ":</td><td>&nbsp;</td><td>" + session.getUserId() + "</td></tr>");
-    buf.append("<tr><td>" + ScoutTexts.get("Language") + ":</td><td>&nbsp;</td><td>" + LocaleThreadLocal.get().getDisplayLanguage() + "</td></tr>");
-    buf.append("<tr><td>" + ScoutTexts.get("FormattingLocale") + ":</td><td>&nbsp;</td><td>" + LocaleThreadLocal.get() + "</td></tr>");
+    buf.append("<tr><td>" + ScoutTexts.get("Username") + ":</td><td>&nbsp;</td><td>" + HtmlHelper.escape(session.getUserId()) + "</td></tr>");
+    buf.append("<tr><td>" + ScoutTexts.get("Language") + ":</td><td>&nbsp;</td><td>" + HtmlHelper.escape(LocaleThreadLocal.get().getDisplayLanguage()) + "</td></tr>");
+    buf.append("<tr><td>" + ScoutTexts.get("FormattingLocale") + ":</td><td>&nbsp;</td><td>" + HtmlHelper.escape(LocaleThreadLocal.get().toString()) + "</td></tr>");
 
     /**
      * These information must only be presented in the case of an richclient. If the client is a webclient (ui.rap) then
      * these informations must be omitted (Security) https://bugs.eclipse.org/bugs/show_bug.cgi?id=365761
      */
     if (UserAgentUtility.isRichClient()) {
-      buf.append("<tr><td>" + ScoutTexts.get("JavaVersion") + ":</td><td>&nbsp;</td><td>" + System.getProperty("java.version") + "</td></tr>");
-      buf.append("<tr><td>" + ScoutTexts.get("JavaVMVersion") + ":</td><td>&nbsp;</td><td>" + System.getProperty("java.vm.version") + "</td></tr>");
-      buf.append("<tr><td>" + ScoutTexts.get("OSVersion") + ":</td><td>&nbsp;</td><td>" + System.getProperty("os.name") + " " + System.getProperty("os.version") + "</td></tr>");
-      buf.append("<tr><td>" + ScoutTexts.get("OSUser") + ":</td><td>&nbsp;</td><td>" + System.getProperty("user.name") + "</td></tr>");
+      buf.append("<tr><td>" + ScoutTexts.get("JavaVersion") + ":</td><td>&nbsp;</td><td>" + HtmlHelper.escape(System.getProperty("java.version")) + "</td></tr>");
+      buf.append("<tr><td>" + ScoutTexts.get("JavaVMVersion") + ":</td><td>&nbsp;</td><td>" + HtmlHelper.escape(System.getProperty("java.vm.version")) + "</td></tr>");
+      buf.append("<tr><td>" + ScoutTexts.get("OSVersion") + ":</td><td>&nbsp;</td><td>" + HtmlHelper.escape(System.getProperty("os.name") + " " + System.getProperty("os.version")) + "</td></tr>");
+      buf.append("<tr><td>" + ScoutTexts.get("OSUser") + ":</td><td>&nbsp;</td><td>" + HtmlHelper.escape(System.getProperty("user.name")) + "</td></tr>");
       buf.append("<tr><td>" + ScoutTexts.get("MemoryStatus") + ":</td><td>&nbsp;</td><td>" + memUsed + "MB (total " + memTotal + "MB / max " + memMax + "MB)</td></tr>");
       IPerformanceAnalyzerService perf = SERVICES.getService(IPerformanceAnalyzerService.class);
       if (perf != null) {
         buf.append("<tr><td>" + ScoutTexts.get("NetworkLatency") + ":</td><td>&nbsp;</td><td>" + perf.getNetworkLatency() + " ms</td></tr>");
         buf.append("<tr><td>" + ScoutTexts.get("ExecutionTime") + ":</td><td>&nbsp;</td><td>" + perf.getServerExecutionTime() + " ms</td></tr>");
       }
-      if (session.getServiceTunnel() != null) {
-        buf.append("<tr><td>" + ScoutTexts.get("Server") + ":</td><td>&nbsp;</td><td>" + session.getServiceTunnel().getServerURL() + "</td></tr>");
+      if (session.getServiceTunnel() != null && session.getServiceTunnel().getServerURL() != null) {
+        buf.append("<tr><td>" + ScoutTexts.get("Server") + ":</td><td>&nbsp;</td><td>" + HtmlHelper.escape(session.getServiceTunnel().getServerURL().toString()) + "</td></tr>");
       }
     }
   }
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/messagebox/IMessageBox.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/messagebox/IMessageBox.java
index abe9864..2c7aa02 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/messagebox/IMessageBox.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/messagebox/IMessageBox.java
@@ -11,8 +11,9 @@
 package org.eclipse.scout.rt.client.ui.messagebox;
 
 import org.eclipse.scout.commons.beans.IPropertyObserver;
+import org.eclipse.scout.rt.client.ui.IHtmlCapable;
 
-public interface IMessageBox extends IPropertyObserver {
+public interface IMessageBox extends IPropertyObserver, IHtmlCapable {
 
   /**
    * Result status YES
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/messagebox/MessageBox.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/messagebox/MessageBox.java
index 7d4bc29..74b5b1c 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/messagebox/MessageBox.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/messagebox/MessageBox.java
@@ -81,7 +81,7 @@
 
   /**
    * Convenience function for simple delete confirmation message box
-   * 
+   *
    * @param items
    *          one item or array of multiple items
    */
@@ -91,7 +91,7 @@
 
   /**
    * Convenience function for simple delete confirmation message box
-   * 
+   *
    * @param items
    *          a list of multiple items
    * @since Scout 4.0.1
@@ -102,7 +102,7 @@
 
   /**
    * Convenience function for simple delete confirmation message box
-   * 
+   *
    * @param itemType
    *          display text in plural such as "Persons", "Relations", "Tickets",
    *          ...
@@ -126,7 +126,7 @@
 
   /**
    * Convenience function for simple delete confirmation message box
-   * 
+   *
    * @param itemType
    *          display text in plural such as "Persons", "Relations", "Tickets",
    *          ...
@@ -192,6 +192,7 @@
   private String m_cancelButtonText;
   private String m_hiddenText;
   private String m_copyPasteText;
+  private boolean m_htmlEnabled;
   // cached
   private String m_copyPasteTextInternal;
   // modality
@@ -505,6 +506,21 @@
     m_blockingCondition.setBlocking(false);
   }
 
+  /**
+   * Enables HTML rendering of {@link #m_introText} and {@link #m_actionText}. The setter must be called before starting
+   * the message box.
+   * Subsequent changes of the html enabled flag have no effect after the widget has been initialized.
+   */
+  @Override
+  public void setHtmlEnabled(boolean enabled) {
+    m_htmlEnabled = enabled;
+  }
+
+  @Override
+  public boolean isHtmlEnabled() {
+    return m_htmlEnabled;
+  }
+
   private class P_UIFacade implements IMessageBoxUIFacade {
 
     @Override
diff --git a/org.eclipse.scout.rt.ui.rap.mobile/src/org/eclipse/scout/rt/ui/rap/mobile/form/fields/tablefield/RwtScoutListModel.java b/org.eclipse.scout.rt.ui.rap.mobile/src/org/eclipse/scout/rt/ui/rap/mobile/form/fields/tablefield/RwtScoutListModel.java
index 249677e..cbda6e8 100644
--- a/org.eclipse.scout.rt.ui.rap.mobile/src/org/eclipse/scout/rt/ui/rap/mobile/form/fields/tablefield/RwtScoutListModel.java
+++ b/org.eclipse.scout.rt.ui.rap.mobile/src/org/eclipse/scout/rt/ui/rap/mobile/form/fields/tablefield/RwtScoutListModel.java
@@ -18,16 +18,16 @@
 import org.eclipse.jface.viewers.ILabelProviderListener;
 import org.eclipse.jface.viewers.LabelProviderChangedEvent;
 import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.rap.rwt.RWT;
 import org.eclipse.scout.commons.CollectionUtility;
-import org.eclipse.scout.commons.StringUtility;
 import org.eclipse.scout.rt.client.ui.basic.cell.ICell;
 import org.eclipse.scout.rt.client.ui.basic.table.ITable;
 import org.eclipse.scout.rt.client.ui.basic.table.ITableRow;
 import org.eclipse.scout.rt.client.ui.basic.table.columns.IColumn;
+import org.eclipse.scout.rt.ui.rap.IRwtEnvironment;
+import org.eclipse.scout.rt.ui.rap.basic.AbstractRwtScoutCellTextHelper;
+import org.eclipse.scout.rt.ui.rap.basic.IRwtScoutCellTextHelper;
+import org.eclipse.scout.rt.ui.rap.basic.IRwtScoutComposite;
 import org.eclipse.scout.rt.ui.rap.basic.table.RwtScoutTableEvent;
-import org.eclipse.scout.rt.ui.rap.html.HtmlAdapter;
-import org.eclipse.scout.rt.ui.rap.util.HtmlTextUtility;
 import org.eclipse.swt.graphics.Image;
 
 public class RwtScoutListModel implements IRwtScoutListModel {
@@ -44,10 +44,12 @@
   private final ITable m_scoutTable;
   private final RwtScoutList m_uiList;
   private boolean m_multiline;
+  private final IRwtEnvironment m_env;
 
   public RwtScoutListModel(ITable scoutTable, RwtScoutList uiTable) {
     m_scoutTable = scoutTable;
     m_uiList = uiTable;
+    m_env = uiTable.getUiEnvironment();
   }
 
   @Override
@@ -162,37 +164,40 @@
 
   @Override
   public String getText(Object element) {
-    ICell cell = getCell(element);
-    if (cell == null) {
-      return "";
+    final ICell cell = getCell(element);
+    final IRwtScoutCellTextHelper cellTextHelper = createCellTextHelper(m_env, m_uiList, (ITableRow) element);
+
+    return cellTextHelper.processCellText(cell);
+  }
+
+  protected IRwtScoutCellTextHelper createCellTextHelper(IRwtEnvironment env, IRwtScoutComposite<?> uiComposite, ITableRow tableRow) {
+    return new P_RwtScoutListModelCellTextHelper(env, uiComposite, tableRow);
+  }
+
+  private class P_RwtScoutListModelCellTextHelper extends AbstractRwtScoutCellTextHelper {
+
+    private final ITableRow m_tableRow;
+
+    public P_RwtScoutListModelCellTextHelper(IRwtEnvironment env, IRwtScoutComposite<?> uiComposite, ITableRow tableRow) {
+      super(env, uiComposite);
+      m_tableRow = tableRow;
     }
 
-    String text = cell.getText();
-    if (text == null) {
-      text = "";
-    }
-    if (HtmlTextUtility.isTextWithHtmlMarkup(text)) {
-      HtmlAdapter htmlAdapter = m_uiList.getUiEnvironment().getHtmlAdapter();
-      text = htmlAdapter.adaptHtmlCell(m_uiList, text);
-
+    @Override
+    protected Map<String, String> createAdditionalLinkParams() {
       Map<String, String> params = new HashMap<String, String>();
-      ITableRow tableRow = (ITableRow) element;
-      params.put(HYPERLINK_ROW_PARAM, tableRow.getRowIndex() + "");
-      text = htmlAdapter.convertLinksInHtmlCell(m_uiList, text, params);
+      params.put(HYPERLINK_ROW_PARAM, Integer.toString(m_tableRow.getRowIndex()));
+      return params;
     }
-    else {
-      boolean multiline = false;
-      if (text.indexOf("\n") >= 0) {
-        multiline = isMultiline();
-        if (!multiline) {
-          text = StringUtility.replaceNewLines(text, " ");
-        }
-      }
-      boolean markupEnabled = Boolean.TRUE.equals(getUiList().getUiField().getData(RWT.MARKUP_ENABLED));
-      if (markupEnabled || multiline) {
-        text = HtmlTextUtility.transformPlainTextToHtml(text);
-      }
+
+    @Override
+    protected boolean isMultilineScoutObject() {
+      return isMultiline();
     }
-    return text;
+
+    @Override
+    protected boolean isWrapText() {
+      return false;
+    }
   }
 }
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/AbstractRwtEnvironment.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/AbstractRwtEnvironment.java
index 2500c61..c15b8af 100644
--- a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/AbstractRwtEnvironment.java
+++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/AbstractRwtEnvironment.java
@@ -22,6 +22,7 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 
@@ -73,6 +74,8 @@
 import org.eclipse.scout.rt.shared.ui.UiLayer;
 import org.eclipse.scout.rt.shared.ui.UserAgent;
 import org.eclipse.scout.rt.ui.rap.basic.IRwtScoutComposite;
+import org.eclipse.scout.rt.ui.rap.basic.IRwtScoutHtmlValidator;
+import org.eclipse.scout.rt.ui.rap.basic.RwtScoutHtmlValidator;
 import org.eclipse.scout.rt.ui.rap.basic.WidgetPrinter;
 import org.eclipse.scout.rt.ui.rap.busy.RwtBusyHandler;
 import org.eclipse.scout.rt.ui.rap.concurrency.RwtScoutSynchronizer;
@@ -174,6 +177,7 @@
   private LayoutValidateManager m_layoutValidateManager;
   private HtmlAdapter m_htmlAdapter;
   private P_RequestInterceptor m_requestInterceptor;
+  private IRwtScoutHtmlValidator m_htmlValidator;
 
   public AbstractRwtEnvironment(Bundle applicationBundle, Class<? extends IClientSession> clientSessionClazz) {
     m_applicationBundle = applicationBundle;
@@ -439,6 +443,8 @@
         }
       }.schedule();
 
+      m_htmlValidator = createHtmlValidator();
+
       m_status = RwtEnvironmentEvent.STARTED;
       fireEnvironmentChanged(new RwtEnvironmentEvent(this, m_status));
 
@@ -508,12 +514,12 @@
         }
         catch (Exception e) {
           String msg = new StringBuilder()
-          .append(" [thread=").append(Thread.currentThread())
-          .append(", httpSession=").append(event.getSession().getId())
-          .append(", clientSession=").append(clientSession)
-          .append(", environment=").append(AbstractRwtEnvironment.this)
-          .append(", userAgent=").append(clientSession.getUserAgent())
-          .append("]").toString();
+              .append(" [thread=").append(Thread.currentThread())
+              .append(", httpSession=").append(event.getSession().getId())
+              .append(", clientSession=").append(clientSession)
+              .append(", environment=").append(AbstractRwtEnvironment.this)
+              .append(", userAgent=").append(clientSession.getUserAgent())
+              .append("]").toString();
 
           if (Platform.isRunning()) {
             LOG.error("Failed to stop application." + msg, e);
@@ -644,6 +650,11 @@
   }
 
   @Override
+  public String convertLinksInHtmlCell(IRwtScoutComposite<?> uiComposite, String rawHtml, Map<String, String> params) {
+    return getHtmlAdapter().convertLinksInHtmlCell(uiComposite, rawHtml, params);
+  }
+
+  @Override
   public String styleHtmlText(IRwtScoutFormField<?> uiComposite, String rawHtml) {
     return getHtmlAdapter().styleHtmlText(uiComposite, rawHtml);
   }
@@ -1491,6 +1502,15 @@
     }
   }
 
+  protected IRwtScoutHtmlValidator createHtmlValidator() {
+    return new RwtScoutHtmlValidator();
+  }
+
+  @Override
+  public IRwtScoutHtmlValidator getHtmlValidator() {
+    return m_htmlValidator;
+  }
+
   private class P_LocaleListener implements ILocaleListener {
     @Override
     public void localeChanged(LocaleChangeEvent event) {
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/IRwtEnvironment.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/IRwtEnvironment.java
index 0fe367d..4474f0b 100644
--- a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/IRwtEnvironment.java
+++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/IRwtEnvironment.java
@@ -11,6 +11,7 @@
 package org.eclipse.scout.rt.ui.rap;
 
 import java.util.Collection;
+import java.util.Map;
 
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.scout.commons.job.JobEx;
@@ -25,6 +26,7 @@
 import org.eclipse.scout.rt.shared.data.basic.FontSpec;
 import org.eclipse.scout.rt.shared.servicetunnel.DefaultServiceTunnelContentHandler;
 import org.eclipse.scout.rt.ui.rap.basic.IRwtScoutComposite;
+import org.eclipse.scout.rt.ui.rap.basic.IRwtScoutHtmlValidator;
 import org.eclipse.scout.rt.ui.rap.form.IRwtScoutForm;
 import org.eclipse.scout.rt.ui.rap.form.fields.IRwtScoutFormField;
 import org.eclipse.scout.rt.ui.rap.form.fields.RwtScoutFieldComposite;
@@ -212,6 +214,11 @@
   String convertLinksInHtmlCell(IRwtScoutComposite<?> uiComposite, String rawHtml);
 
   /**
+   * Convenience for {@link HtmlAdapter#convertLinksInHtmlCell(IRwtScoutComposite, String, Map)}
+   */
+  String convertLinksInHtmlCell(IRwtScoutComposite<?> uiComposite, String rawHtml, Map<String, String> params);
+
+  /**
    * Convenience for {@link HtmlAdapter#styleHtmlText(IRwtScoutFormField, String)}.
    */
   String styleHtmlText(IRwtScoutFormField<?> uiComposite, String rawHtml);
@@ -245,4 +252,6 @@
 
   void removeEnvironmentListener(IRwtEnvironmentListener listener);
 
+  IRwtScoutHtmlValidator getHtmlValidator();
+
 }
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/AbstractRwtScoutCellTextHelper.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/AbstractRwtScoutCellTextHelper.java
new file mode 100644
index 0000000..e18cd13
--- /dev/null
+++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/AbstractRwtScoutCellTextHelper.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2016 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.rt.ui.rap.basic;
+
+import java.util.Map;
+
+import org.eclipse.scout.commons.StringUtility;
+import org.eclipse.scout.rt.client.ui.basic.cell.ICell;
+import org.eclipse.scout.rt.ui.rap.IRwtEnvironment;
+import org.eclipse.scout.rt.ui.rap.basic.table.RwtScoutColumnModel;
+import org.eclipse.scout.rt.ui.rap.basic.tree.RwtScoutTreeModel;
+import org.eclipse.scout.rt.ui.rap.util.HtmlTextUtility;
+import org.eclipse.scout.rt.ui.rap.util.RwtUtility;
+
+/**
+ * Abstract helper class that processes cell text rendering for {@link RwtScoutColumnModel}, {@link RwtScoutTreeModel}
+ * and {@link RwtScoutListModel}
+ *
+ * @since 4.2
+ */
+public abstract class AbstractRwtScoutCellTextHelper implements IRwtScoutCellTextHelper {
+
+  private final IRwtEnvironment m_env;
+  private final IRwtScoutComposite<?> m_uiComposite;
+
+  public AbstractRwtScoutCellTextHelper(IRwtEnvironment env, IRwtScoutComposite<?> uiComposite) {
+    m_env = env;
+    m_uiComposite = uiComposite;
+  }
+
+  @Override
+  public String processCellText(ICell cell) {
+    if (cell == null) {
+      return "";
+    }
+
+    String text = cell.getText();
+
+    if (text == null) {
+      text = "";
+    }
+    else if (HtmlTextUtility.isTextWithHtmlMarkup(text)) {
+      text = m_env.adaptHtmlCell(m_uiComposite, text);
+      text = m_env.convertLinksInHtmlCell(m_uiComposite, text, createAdditionalLinkParams());
+    }
+    else { // handle multi lines
+      boolean multilineScoutObject = isMultilineScoutObject();
+      if (!multilineScoutObject && isMultilineText(text)) {
+        text = StringUtility.replaceNewLines(text, " ");
+      }
+
+      if (RwtUtility.isMarkupEnabled(m_uiComposite.getUiField()) || multilineScoutObject) {
+        text = HtmlTextUtility.escapeHtmlCapableText(m_env.getHtmlValidator(), cell, text);
+        return StringUtility.convertPlainTextNewLinesToHtml(text, !isWrapText()); // !wrapText means that breakable chars should be replaced
+      }
+    }
+
+    return HtmlTextUtility.escapeHtmlCapableText(m_env.getHtmlValidator(), cell, text);
+  }
+
+  protected boolean isMultilineText(String text) {
+    return text.indexOf("\n") >= 0;
+  }
+
+  protected abstract Map<String, String> createAdditionalLinkParams();
+
+  protected abstract boolean isMultilineScoutObject();
+
+  protected abstract boolean isWrapText();
+
+}
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/IRwtScoutCellTextHelper.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/IRwtScoutCellTextHelper.java
new file mode 100644
index 0000000..64a290c
--- /dev/null
+++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/IRwtScoutCellTextHelper.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2016 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.rt.ui.rap.basic;
+
+import org.eclipse.scout.rt.client.ui.basic.cell.ICell;
+import org.eclipse.scout.rt.ui.rap.basic.table.RwtScoutColumnModel;
+import org.eclipse.scout.rt.ui.rap.basic.tree.RwtScoutTreeModel;
+
+/**
+ * @since 4.2
+ */
+public interface IRwtScoutCellTextHelper {
+
+  /**
+   * Process the cell text rendering in {@link RwtScoutColumnModel}, {@link RwtScoutTreeModel} or
+   * {@link RwtScoutListModel}
+   *
+   * @param cell
+   *          the cell of the column, tree or list model to be processed
+   * @return the processed text of cell, i.e. converted to multi-line text or (escaped) html text
+   */
+  String processCellText(ICell cell);
+
+}
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/IRwtScoutHtmlValidator.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/IRwtScoutHtmlValidator.java
new file mode 100644
index 0000000..74e55dc
--- /dev/null
+++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/IRwtScoutHtmlValidator.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.rt.ui.rap.basic;
+
+import org.eclipse.scout.rt.client.ui.IHtmlCapable;
+
+/**
+ * @since 4.2
+ */
+public interface IRwtScoutHtmlValidator {
+
+  /**
+   * Escape / sanitize a given HTML text on a given object of type {@link IHtmlCapable}.
+   *
+   * @param text
+   *          the HTML text to be escaped / sanitized
+   * @param htmlCapable
+   *          the object of type {@link IHtmlCapable}
+   * @return the escaped / sanitized text
+   */
+  String escape(String text, IHtmlCapable htmlCapable);
+
+}
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/RwtScoutHtmlValidator.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/RwtScoutHtmlValidator.java
new file mode 100644
index 0000000..471e750
--- /dev/null
+++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/RwtScoutHtmlValidator.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2015 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.rt.ui.rap.basic;
+
+import org.eclipse.scout.commons.html.HtmlHelper;
+import org.eclipse.scout.rt.client.ui.IHtmlCapable;
+import org.eclipse.scout.rt.ui.rap.util.RwtUtility;
+
+/**
+ * @since 4.2
+ */
+public class RwtScoutHtmlValidator implements IRwtScoutHtmlValidator {
+
+  @Override
+  public String escape(String text, IHtmlCapable htmlCapable) {
+    if (htmlCapable.isHtmlEnabled() || !RwtUtility.VALIDATE_HTML_CAPABLE) { // developer is responsible for validating user input
+      return text;
+    }
+    return HtmlHelper.escape(text);
+  }
+}
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/table/RwtScoutColumnModel.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/table/RwtScoutColumnModel.java
index 325a76b..2a89ff6 100644
--- a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/table/RwtScoutColumnModel.java
+++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/table/RwtScoutColumnModel.java
@@ -21,7 +21,11 @@
 import org.eclipse.scout.rt.client.ui.basic.table.columns.IProposalColumn;
 import org.eclipse.scout.rt.client.ui.basic.table.columns.IStringColumn;
 import org.eclipse.scout.rt.shared.AbstractIcons;
+import org.eclipse.scout.rt.ui.rap.IRwtEnvironment;
 import org.eclipse.scout.rt.ui.rap.RwtIcons;
+import org.eclipse.scout.rt.ui.rap.basic.AbstractRwtScoutCellTextHelper;
+import org.eclipse.scout.rt.ui.rap.basic.IRwtScoutCellTextHelper;
+import org.eclipse.scout.rt.ui.rap.basic.IRwtScoutComposite;
 import org.eclipse.scout.rt.ui.rap.extension.UiDecorationExtensionPoint;
 import org.eclipse.scout.rt.ui.rap.util.HtmlTextUtility;
 import org.eclipse.swt.graphics.Color;
@@ -47,14 +51,16 @@
   private final Color m_disabledForegroundColor;
 
   private volatile Map<ITableRow, Map<IColumn<?>, P_CachedCell>> m_cachedCells;
+  private final IRwtEnvironment m_env;
 
   public RwtScoutColumnModel(ITable scoutTable, RwtScoutTable uiTable, TableColumnManager columnManager) {
     m_scoutTable = scoutTable;
     m_uiTable = uiTable;
     m_columnManager = columnManager;
-    m_imgCheckboxTrue = getUiTable().getUiEnvironment().getIcon(RwtIcons.CheckboxYes);
-    m_imgCheckboxFalse = getUiTable().getUiEnvironment().getIcon(RwtIcons.CheckboxNo);
-    m_disabledForegroundColor = getUiTable().getUiEnvironment().getColor(UiDecorationExtensionPoint.getLookAndFeel().getColorForegroundDisabled());
+    m_env = getUiTable().getUiEnvironment();
+    m_imgCheckboxTrue = m_env.getIcon(RwtIcons.CheckboxYes);
+    m_imgCheckboxFalse = m_env.getIcon(RwtIcons.CheckboxNo);
+    m_disabledForegroundColor = m_env.getColor(UiDecorationExtensionPoint.getLookAndFeel().getColorForegroundDisabled());
     rebuildCache();
   }
 
@@ -86,53 +92,15 @@
   }
 
   public String getColumnText(ITableRow element, int columnIndex) {
-    ICell cell = getCell(element, columnIndex);
-    if (cell == null) {
-      return "";
-    }
+    final ICell cell = getCell(element, columnIndex);
+    final IColumn<?> column = m_columnManager.getColumnByModelIndex(columnIndex - 1);
+    final IRwtScoutCellTextHelper cellTextHelper = createCellTextHelper(m_env, getUiTable(), column);
 
-    String text = cell.getText();
-    if (text == null) {
-      text = "";
-    }
-    else if (HtmlTextUtility.isTextWithHtmlMarkup(text)) {
-      text = getUiTable().getUiEnvironment().adaptHtmlCell(getUiTable(), text);
-      text = getUiTable().getUiEnvironment().convertLinksInHtmlCell(getUiTable(), text);
-    }
-    else {
-      boolean multiline = isMultiline(text);
-      if (!multiline) {
-        text = replaceLineBreaksInMultilineText(text);
-      }
-      boolean isMultilineTable = getScoutTable().isMultilineText();
-      boolean markupEnabled = Boolean.TRUE.equals(getUiTable().getUiField().getData(RWT.MARKUP_ENABLED));
-
-      if (markupEnabled || multiline) {
-        boolean replaceBreakableChars = true;
-        IColumn<?> column = m_columnManager.getColumnByModelIndex(columnIndex - 1);
-        if (column instanceof IStringColumn && isMultilineTable) {
-          IStringColumn stringColumn = (IStringColumn) column;
-          replaceBreakableChars = !stringColumn.isTextWrap();
-        }
-        text = HtmlTextUtility.transformPlainTextToHtml(text, replaceBreakableChars);
-      }
-    }
-    return text;
+    return cellTextHelper.processCellText(cell);
   }
 
-  private boolean isMultiline(String text) {
-    return isMultilineText(text) && getScoutTable().isMultilineText();
-  }
-
-  private boolean isMultilineText(String text) {
-    return text.indexOf("\n") >= 0;
-  }
-
-  private String replaceLineBreaksInMultilineText(String text) {
-    if (isMultilineText(text)) {
-      text = StringUtility.replaceNewLines(text, " ");
-    }
-    return text;
+  protected IRwtScoutCellTextHelper createCellTextHelper(IRwtEnvironment env, IRwtScoutComposite<?> uiComposite, IColumn<?> column) {
+    return new P_RwtScoutColumnModelCellTextHelper(env, uiComposite, column);
   }
 
   public Image getColumnImage(ITableRow element, int columnIndex) {
@@ -173,7 +141,7 @@
     else if (columnOrder[1] == columnIndex) {
       iconId = element.getIconId();
     }
-    Image decoImage = getUiTable().getUiEnvironment().getIcon(iconId);
+    Image decoImage = m_env.getIcon(iconId);
     //merge
     if (checkBoxImage != null && decoImage != null) {
       //TODO rap/rwt: new GC(Image) is not possible since in rwt an image does not implement Drawable.
@@ -192,7 +160,7 @@
     if (columnIndex > 0) {
       ICell cell = getCell(element, columnIndex);
       if (cell != null) {
-        return getUiTable().getUiEnvironment().getColor(cell.getBackgroundColor());
+        return m_env.getColor(cell.getBackgroundColor());
       }
     }
     return null;
@@ -202,7 +170,7 @@
     if (columnIndex > 0) {
       ICell cell = getCell(element, columnIndex);
       if (cell != null) {
-        Color col = getUiTable().getUiEnvironment().getColor(cell.getForegroundColor());
+        Color col = m_env.getColor(cell.getForegroundColor());
         if (col == null) {
           if (!element.isEnabled() || !cell.isEnabled()) {
             col = m_disabledForegroundColor;
@@ -218,7 +186,7 @@
     if (columnIndex > 0) {
       ICell cell = getCell(element, columnIndex);
       if (cell != null) {
-        return getUiTable().getUiEnvironment().getFont(cell.getFont(), getUiTable().getUiField().getFont());
+        return m_env.getFont(cell.getFont(), getUiTable().getUiField().getFont());
       }
     }
     return null;
@@ -226,7 +194,7 @@
 
   @Override
   public String getToolTipText(Object element) {
-    Display display = getUiTable().getUiEnvironment().getDisplay();
+    Display display = m_env.getDisplay();
     Point cursorOnTable = display.map(null, getUiTable().getUiField(), display.getCursorLocation());
     ViewerCell uiCell = getUiTable().getUiTableViewer().getCell(cursorOnTable);
     String text = "";
@@ -240,6 +208,8 @@
           text = cell.getText();
           if (HtmlTextUtility.isTextWithHtmlMarkup(text)) {
             //Tooltips don't support html -> convert to plain text
+            //Tooltips with HTML are supported since RAP 2.2, see org.eclipse.rap.rwt.RWT.TOOLTIP_MARKUP_ENABLED
+            //However, since this property is not set to true in Scout, HTML encoding is currently not necessary
             text = HTMLUtility.getPlainText(text);
           }
           if (text == null || text.indexOf("\n") <= 0) {
@@ -375,4 +345,32 @@
       m_isEditable = isEditable;
     }
   }
+
+  private class P_RwtScoutColumnModelCellTextHelper extends AbstractRwtScoutCellTextHelper {
+
+    private final IColumn<?> m_column;
+
+    public P_RwtScoutColumnModelCellTextHelper(IRwtEnvironment env, IRwtScoutComposite<?> uiComposite, IColumn<?> column) {
+      super(env, uiComposite);
+      m_column = column;
+    }
+
+    @Override
+    protected Map<String, String> createAdditionalLinkParams() {
+      return null;
+    }
+
+    @Override
+    protected boolean isMultilineScoutObject() {
+      return getScoutTable().isMultilineText();
+    }
+
+    @Override
+    protected boolean isWrapText() {
+      if (m_column instanceof IStringColumn && isMultilineScoutObject()) {
+        return ((IStringColumn) m_column).isTextWrap();
+      }
+      return false;
+    }
+  }
 }
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/tree/RwtScoutTreeModel.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/tree/RwtScoutTreeModel.java
index 49d6aba..16bd113 100644
--- a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/tree/RwtScoutTreeModel.java
+++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/basic/tree/RwtScoutTreeModel.java
@@ -10,22 +10,25 @@
  *******************************************************************************/
 package org.eclipse.scout.rt.ui.rap.basic.tree;
 
+import java.util.Map;
+
 import org.eclipse.jface.viewers.IColorProvider;
 import org.eclipse.jface.viewers.IFontProvider;
 import org.eclipse.jface.viewers.ITreeContentProvider;
 import org.eclipse.jface.viewers.LabelProvider;
 import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.scout.commons.StringUtility;
 import org.eclipse.scout.commons.logger.IScoutLogger;
 import org.eclipse.scout.commons.logger.ScoutLogManager;
 import org.eclipse.scout.rt.client.ui.basic.cell.ICell;
 import org.eclipse.scout.rt.client.ui.basic.tree.ITree;
 import org.eclipse.scout.rt.client.ui.basic.tree.ITreeNode;
+import org.eclipse.scout.rt.ui.rap.IRwtEnvironment;
 import org.eclipse.scout.rt.ui.rap.RwtIcons;
+import org.eclipse.scout.rt.ui.rap.basic.AbstractRwtScoutCellTextHelper;
+import org.eclipse.scout.rt.ui.rap.basic.IRwtScoutCellTextHelper;
+import org.eclipse.scout.rt.ui.rap.basic.IRwtScoutComposite;
 import org.eclipse.scout.rt.ui.rap.extension.UiDecorationExtensionPoint;
-import org.eclipse.scout.rt.ui.rap.util.HtmlTextUtility;
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.Font;
 import org.eclipse.swt.graphics.Image;
@@ -41,14 +44,16 @@
   private Image m_imgCheckboxTrue;
   private Image m_imgCheckboxFalse;
   private Color m_disabledForegroundColor;
+  private final IRwtEnvironment m_env;
 
   public RwtScoutTreeModel(ITree tree, IRwtScoutTree uiTree, TreeViewer treeViewer) {
     m_scoutTree = tree;
     m_uiTree = uiTree;
     m_treeViewer = treeViewer;
-    m_imgCheckboxTrue = getUiTree().getUiEnvironment().getIcon(RwtIcons.CheckboxYes);
-    m_imgCheckboxFalse = getUiTree().getUiEnvironment().getIcon(RwtIcons.CheckboxNo);
-    m_disabledForegroundColor = getUiTree().getUiEnvironment().getColor(UiDecorationExtensionPoint.getLookAndFeel().getColorForegroundDisabled());
+    m_env = getUiTree().getUiEnvironment();
+    m_imgCheckboxTrue = m_env.getIcon(RwtIcons.CheckboxYes);
+    m_imgCheckboxFalse = m_env.getIcon(RwtIcons.CheckboxNo);
+    m_disabledForegroundColor = m_env.getColor(UiDecorationExtensionPoint.getLookAndFeel().getColorForegroundDisabled());
   }
 
   protected ITree getScoutTree() {
@@ -111,7 +116,7 @@
     //deco
     String iconId = scoutNode.getCell().getIconId();
     Image decoImage = null;
-    decoImage = getUiTree().getUiEnvironment().getIcon(iconId);
+    decoImage = m_env.getIcon(iconId);
     //merge
     if (checkBoxImage != null && decoImage != null) {
       //TODO rap/rwt: new GC(Image) is not possible since in rwt an image does not implement Drawable.
@@ -128,37 +133,26 @@
 
   @Override
   public String getText(Object element) {
-    ITreeNode scoutNode = (ITreeNode) element;
-    if (scoutNode != null && scoutNode.getCell() != null) {
-      ICell cell = scoutNode.getCell();
-      String text = cell.getText();
-      if (text == null) {
-        text = "";
-      }
+    final ITreeNode scoutNode = (ITreeNode) element;
 
-      if (HtmlTextUtility.isTextWithHtmlMarkup(cell.getText())) {
-        text = getUiTree().getUiEnvironment().adaptHtmlCell(getUiTree(), text);
-        text = getUiTree().getUiEnvironment().convertLinksInHtmlCell(getUiTree(), text);
-      }
-      else {
-        if (text.indexOf("\n") >= 0) {
-          text = StringUtility.replaceNewLines(text, " ");
-        }
-        boolean markupEnabled = Boolean.TRUE.equals(getUiTree().getUiField().getData(RWT.MARKUP_ENABLED));
-        if (markupEnabled) {
-          text = HtmlTextUtility.transformPlainTextToHtml(text);
-        }
-      }
-      return text;
+    if (scoutNode == null) {
+      return "";
     }
-    return "";
+
+    final IRwtScoutCellTextHelper cellTextHelper = createCellTextHelper(m_env, getUiTree());
+
+    return cellTextHelper.processCellText(scoutNode.getCell());
+  }
+
+  protected IRwtScoutCellTextHelper createCellTextHelper(IRwtEnvironment env, IRwtScoutComposite<?> uiComposite) {
+    return new P_RwtScoutTreeModelCellTextHelper(env, uiComposite);
   }
 
   @Override
   public Font getFont(Object element) {
     ITreeNode scoutNode = (ITreeNode) element;
     if (scoutNode.getCell().getFont() != null) {
-      return getUiTree().getUiEnvironment().getFont(scoutNode.getCell().getFont(), m_treeViewer.getTree().getFont());
+      return m_env.getFont(scoutNode.getCell().getFont(), m_treeViewer.getTree().getFont());
     }
     return null;
   }
@@ -167,7 +161,7 @@
   public Color getForeground(Object element) {
     ITreeNode scoutNode = (ITreeNode) element;
     ICell scoutCell = scoutNode.getCell();
-    Color col = getUiTree().getUiEnvironment().getColor(scoutCell.getForegroundColor());
+    Color col = m_env.getColor(scoutCell.getForegroundColor());
     if (col == null) {
       if (!scoutCell.isEnabled()) {
         col = m_disabledForegroundColor;
@@ -180,7 +174,7 @@
   public Color getBackground(Object element) {
     ITreeNode scoutNode = (ITreeNode) element;
     if (scoutNode.getCell().getBackgroundColor() != null) {
-      return getUiTree().getUiEnvironment().getColor(scoutNode.getCell().getBackgroundColor());
+      return m_env.getColor(scoutNode.getCell().getBackgroundColor());
     }
     return null;
   }
@@ -188,4 +182,27 @@
   @Override
   public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
   }
+
+  private class P_RwtScoutTreeModelCellTextHelper extends AbstractRwtScoutCellTextHelper {
+
+    public P_RwtScoutTreeModelCellTextHelper(IRwtEnvironment env, IRwtScoutComposite<?> uiComposite) {
+      super(env, uiComposite);
+    }
+
+    @Override
+    protected Map<String, String> createAdditionalLinkParams() {
+      return null;
+    }
+
+    @Override
+    protected boolean isMultilineScoutObject() {
+      return false;
+    }
+
+    @Override
+    protected boolean isWrapText() {
+      return false;
+    }
+
+  }
 }
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/form/fields/htmlfield/RwtScoutHtmlField.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/form/fields/htmlfield/RwtScoutHtmlField.java
index d0e79ab..15af931 100644
--- a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/form/fields/htmlfield/RwtScoutHtmlField.java
+++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/form/fields/htmlfield/RwtScoutHtmlField.java
@@ -179,6 +179,7 @@
         }
       }
     }
+    // assume that rawHTML is encoded properly in the model layer
     String cleanHtml = getUiEnvironment().styleHtmlText(this, rawHtml);
     cleanHtml = m_browserExtension.adaptHyperlinks(cleanHtml);
     //fast create of browser content if there are no attachments
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/util/HtmlTextUtility.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/util/HtmlTextUtility.java
index f5ad6e3..c7dfa4a 100644
--- a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/util/HtmlTextUtility.java
+++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/util/HtmlTextUtility.java
@@ -2,6 +2,12 @@
 
 import java.util.regex.Pattern;
 
+import org.eclipse.scout.commons.StringUtility;
+import org.eclipse.scout.commons.logger.IScoutLogger;
+import org.eclipse.scout.commons.logger.ScoutLogManager;
+import org.eclipse.scout.rt.client.ui.IHtmlCapable;
+import org.eclipse.scout.rt.ui.rap.basic.IRwtScoutHtmlValidator;
+
 /**
  * Utility class that provides a number of useful static methods to support the
  * implementation of widget life cycle adapters with regard to supporting html markup in table headers, cells, etc.
@@ -10,6 +16,7 @@
  */
 public final class HtmlTextUtility {
 
+  private static final IScoutLogger LOG = ScoutLogManager.getLogger(HtmlTextUtility.class);
   private static final Pattern htmlMarkupIdentifierPattern = Pattern.compile("<html[^>]*>(.*)</html>.*", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
   private static final Pattern htmlBracketPattern = Pattern.compile("<html[^>]*>(.*)</html>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
   private static final Pattern headBracketPattern = Pattern.compile("<head[^>]*>(.*)</head>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
@@ -87,11 +94,7 @@
     s = s.replaceAll("[']", "&#39;");
     s = s.replaceAll("[<]", "&lt;");
     s = s.replaceAll("[>]", "&gt;");
-    s = s.replaceAll("[\\n]", "<br/>");
-    if (replaceBreakableChars) {
-      s = s.replaceAll("[\\s]", "&nbsp;");
-      s = s.replaceAll("[-]", "&#8209;");
-    }
+    s = StringUtility.convertPlainTextNewLinesToHtml(s, replaceBreakableChars);
     return s;
   }
 
@@ -154,4 +157,26 @@
     return r;
   }
 
+  /**
+   * Escapes the text of a given object if the object is an instance of {@link IHtmlCapable}. Escaping is done with
+   * the given validator of type {@link IRwtScoutHtmlValidator}
+   *
+   * @since 4.2
+   * @param validator
+   *          the HTML validator
+   * @param obj
+   *          validation is only done if the object is of type {@link IHtmlCapable}
+   * @param text
+   *          the text to validate
+   * @return escaped text if the given object is of type {@link IHtmlCapable}, otherwise the input text will be
+   *         returned.
+   */
+  public static String escapeHtmlCapableText(IRwtScoutHtmlValidator validator, Object obj, String text) {
+    if (!(obj instanceof IHtmlCapable)) {
+      LOG.error("Passed object with text {} is not an instance of {}.", text, IHtmlCapable.class);
+      return text;
+    }
+    return validator.escape(text, (IHtmlCapable) obj);
+  }
+
 }
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/util/RwtUtility.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/util/RwtUtility.java
index 62afa99..73f993e 100644
--- a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/util/RwtUtility.java
+++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/util/RwtUtility.java
@@ -28,6 +28,7 @@
 import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.rap.rwt.RWT;
 import org.eclipse.rap.rwt.dnd.ClientFileTransfer;
+import org.eclipse.scout.commons.BundleContextUtility;
 import org.eclipse.scout.commons.CompositeLong;
 import org.eclipse.scout.commons.StringUtility;
 import org.eclipse.scout.commons.dnd.FileListTransferObject;
@@ -76,6 +77,8 @@
 public final class RwtUtility {
   private static final IScoutLogger LOG = ScoutLogManager.getLogger(RwtUtility.class);
 
+  public static final boolean VALIDATE_HTML_CAPABLE = BundleContextUtility.parseBooleanProperty("org.eclipse.scout.rt.ui.rap.validate.htmlCapable", true);
+
   public static final String BROWSER_INFO = "browser-Info";
 
   public static final String VARIANT_PROPOSAL_FORM = "proposal-form";
@@ -1598,4 +1601,14 @@
     int keyCode = getRwtKeyCode(ks);
     return LegacyActionTools.convertAccelerator(stateMask | keyCode);
   }
+
+  /**
+   * Checks if the given widget is enabled for markup.
+   *
+   * @since 4.2
+   */
+  public static boolean isMarkupEnabled(Widget w) {
+    return Boolean.TRUE.equals(w.getData(RWT.MARKUP_ENABLED));
+  }
+
 }
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/window/messagebox/AbstractLabelWrapper.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/window/messagebox/AbstractLabelWrapper.java
new file mode 100644
index 0000000..b271136
--- /dev/null
+++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/window/messagebox/AbstractLabelWrapper.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2016 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.rt.ui.rap.window.messagebox;
+
+import org.eclipse.scout.rt.ui.rap.ext.custom.StyledText;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * @since 4.2
+ */
+public abstract class AbstractLabelWrapper implements ILabelWrapper {
+
+  private final boolean m_htmlEnabled;
+  private final StyledText m_textLabel;
+  private final Label m_htmlLabel;
+
+  public AbstractLabelWrapper(boolean htmlEnabled, Composite container) {
+    m_htmlEnabled = htmlEnabled;
+    m_textLabel = createTextLabel(htmlEnabled, container);
+    m_htmlLabel = createHtmlLabel(htmlEnabled, container);
+  }
+
+  protected abstract Label createHtmlLabel(boolean htmlEnabled, Composite container);
+
+  protected abstract StyledText createTextLabel(boolean htmlEnabled, Composite container);
+
+  @Override
+  public boolean isHtmlEnabled() {
+    return m_htmlEnabled;
+  }
+
+  @Override
+  public Control getLabel() {
+    if (m_htmlEnabled) {
+      return m_htmlLabel;
+    }
+    return m_textLabel;
+  }
+
+  @Override
+  public String getLabelText() {
+    if (m_htmlEnabled) {
+      return m_htmlLabel.getText();
+    }
+    return m_textLabel.getText();
+  }
+
+  @Override
+  public void setLabelText(String text) {
+    if (m_htmlEnabled) {
+      m_htmlLabel.setText(text);
+    }
+    else {
+      m_textLabel.setText(text);
+    }
+  }
+}
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/window/messagebox/ILabelWrapper.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/window/messagebox/ILabelWrapper.java
new file mode 100644
index 0000000..c602a22
--- /dev/null
+++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/window/messagebox/ILabelWrapper.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2016 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.rt.ui.rap.window.messagebox;
+
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * @since 4.2
+ */
+public interface ILabelWrapper {
+
+  boolean isHtmlEnabled();
+
+  Control getLabel();
+
+  String getLabelText();
+
+  void setLabelText(String text);
+}
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/window/messagebox/RwtScoutMessageBoxDialog.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/window/messagebox/RwtScoutMessageBoxDialog.java
index 26dcb4f..0d24e30 100644
--- a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/window/messagebox/RwtScoutMessageBoxDialog.java
+++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/window/messagebox/RwtScoutMessageBoxDialog.java
@@ -21,6 +21,7 @@
 import org.eclipse.scout.rt.ui.rap.extension.UiDecorationExtensionPoint;
 import org.eclipse.scout.rt.ui.rap.form.fields.groupbox.layout.ButtonBarLayout;
 import org.eclipse.scout.rt.ui.rap.form.fields.groupbox.layout.ButtonBarLayoutData;
+import org.eclipse.scout.rt.ui.rap.util.HtmlTextUtility;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.DisposeEvent;
 import org.eclipse.swt.events.DisposeListener;
@@ -56,11 +57,11 @@
   private P_ScoutMessageBoxListener m_scoutMessageBoxListener;
 
   private final IMessageBox m_scoutObject;
-  private IRwtEnvironment m_uiEnvironment;
+  private final IRwtEnvironment m_uiEnvironment;
 
   private Label m_imageLabel;
-  private StyledText m_introLabel;
-  private StyledText m_actionLabel;
+  private ILabelWrapper m_actionLabelWrapper;
+  private ILabelWrapper m_introLabelWrapper;
 
   public RwtScoutMessageBoxDialog(Shell parentShell, IMessageBox scoutObject, IRwtEnvironment uiEnvironment) {
     super(parentShell);
@@ -126,17 +127,24 @@
       introText = "";
       exclude = true;
     }
-    m_introLabel.setText(introText);
-    if (m_introLabel.getLayoutData() instanceof GridData) {
-      GridData gridData = ((GridData) m_introLabel.getLayoutData());
+
+    if (m_introLabelWrapper.isHtmlEnabled()) {
+      // escape introText if HTML is enabled, i.e. text will be set on the Label control which renders HTML. This is not needed for the StyledText control since StyledText is not able to render HTML
+      introText = HtmlTextUtility.escapeHtmlCapableText(getUiEnvironment().getHtmlValidator(), getScoutObject(), introText);
+    }
+    m_introLabelWrapper.setLabelText(introText);
+
+    final Control introLabel = m_introLabelWrapper.getLabel();
+    if (introLabel.getLayoutData() instanceof GridData) {
+      GridData gridData = ((GridData) introLabel.getLayoutData());
       if (gridData.exclude != exclude) {
         gridData.exclude = exclude;
         getShell().layout(true);
-        m_introLabel.getParent().getParent().layout(true, true);
+        introLabel.getParent().getParent().layout(true, true);
       }
     }
     // Hide empty labels
-    m_introLabel.setVisible(StringUtility.hasText(m_introLabel.getText()));
+    introLabel.setVisible(StringUtility.hasText(m_introLabelWrapper.getLabelText()));
   }
 
   protected void setActionTextFromScout(String actionText) {
@@ -152,15 +160,21 @@
       actionText = "";
       exclude = true;
     }
-    m_actionLabel.setText(actionText);
+
+    if (m_actionLabelWrapper.isHtmlEnabled()) {
+      // escape actionText if HTML is enabled, i.e. text will be set on the Label control which renders HTML. This is not needed for the StyledText control since StyledText is not able to render HTML
+      actionText = HtmlTextUtility.escapeHtmlCapableText(getUiEnvironment().getHtmlValidator(), getScoutObject(), actionText);
+    }
+    m_actionLabelWrapper.setLabelText(actionText);
+
     // Hide empty labels
-    m_actionLabel.setVisible(StringUtility.hasText(m_actionLabel.getText()));
-    if (m_actionLabel.getLayoutData() instanceof GridData) {
-      GridData gridData = ((GridData) m_actionLabel.getLayoutData());
+    m_actionLabelWrapper.getLabel().setVisible(StringUtility.hasText(m_actionLabelWrapper.getLabelText()));
+    if (m_actionLabelWrapper.getLabel().getLayoutData() instanceof GridData) {
+      GridData gridData = ((GridData) m_actionLabelWrapper.getLabel().getLayoutData());
       if (gridData.exclude != exclude) {
         gridData.exclude = exclude;
         getShell().layout(true, true);
-        m_actionLabel.getParent().getParent().layout(true, true);
+        m_actionLabelWrapper.getLabel().getParent().getParent().layout(true, true);
       }
     }
   }
@@ -176,9 +190,7 @@
   protected Control createDialogArea(Composite parent) {
     Composite container = getUiEnvironment().getFormToolkit().createComposite(parent);
     Control header = createHeaderArea(container);
-    m_actionLabel = getUiEnvironment().getFormToolkit().createStyledText(container, SWT.WRAP | SWT.LEFT | SWT.V_SCROLL);
-    m_actionLabel.setEditable(false);
-    m_actionLabel.setData(WRAP_TEXT_WITHOUT_SPACES, Boolean.TRUE);
+    m_actionLabelWrapper = createActionLabel(getScoutObject().isHtmlEnabled(), container);
 
     // layout
     container.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH));
@@ -192,7 +204,7 @@
     header.setLayoutData(gridData);
     gridData = new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_BOTH);
     gridData.horizontalIndent = 5;
-    m_actionLabel.setLayoutData(gridData);
+    m_actionLabelWrapper.getLabel().setLayoutData(gridData);
 
     // No control in the dialog area should be in the tab list
     container.setTabList(new Control[]{});
@@ -202,13 +214,7 @@
   private Control createHeaderArea(Composite parent) {
     Composite container = getUiEnvironment().getFormToolkit().createComposite(parent);
     m_imageLabel = getUiEnvironment().getFormToolkit().createLabel(container, "");
-    m_introLabel = getUiEnvironment().getFormToolkit().createStyledText(container, SWT.WRAP | SWT.LEFT | SWT.V_SCROLL);
-    m_introLabel.setData(WRAP_TEXT_WITHOUT_SPACES, Boolean.TRUE);
-    m_introLabel.setEditable(false);
-    m_introLabel.setData(RWT.MARKUP_ENABLED, Boolean.TRUE);
-    //Unsafe configuration. Size for h1, h2, h3.. tags isn't well calculated at the first time
-    m_introLabel.setData(MarkupValidator.MARKUP_VALIDATION_DISABLED, Boolean.TRUE);
-
+    m_introLabelWrapper = createIntroLabel(getScoutObject().isHtmlEnabled(), container);
     // layout
     GridLayout headerLayout = new GridLayout(2, false);
     headerLayout.marginBottom = 7;
@@ -222,10 +228,18 @@
     gridData.horizontalIndent = 7;
     gridData.verticalIndent = 0;
     gridData.exclude = true;
-    m_introLabel.setLayoutData(gridData);
+    m_introLabelWrapper.getLabel().setLayoutData(gridData);
     return container;
   }
 
+  protected ILabelWrapper createIntroLabel(boolean htmlEnabled, Composite container) {
+    return new P_LabelWrapper(htmlEnabled, container);
+  }
+
+  protected ILabelWrapper createActionLabel(boolean htmlEnabled, Composite container) {
+    return new P_LabelWrapper(htmlEnabled, container);
+  }
+
   @Override
   protected Control createButtonBar(Composite parent) {
     if (getScoutObject().getYesButtonText() == null
@@ -410,4 +424,40 @@
     }
 
   }
+
+  private class P_LabelWrapper extends AbstractLabelWrapper {
+
+    public P_LabelWrapper(boolean htmlEnabled, Composite container) {
+      super(htmlEnabled, container);
+    }
+
+    @Override
+    protected Label createHtmlLabel(boolean htmlEnabled, Composite container) {
+      if (!htmlEnabled) {
+        return null;
+      }
+      // create Label control only if html is enabled since Label is able to render html.
+      Label htmlIntroLabel = getUiEnvironment().getFormToolkit().createLabel(container, "", SWT.WRAP | SWT.LEFT);
+      htmlIntroLabel.setData(RWT.MARKUP_ENABLED, Boolean.TRUE);
+      // Unsafe configuration. Size for h1, h2, h3.. tags isn't well calculated at the first time
+      htmlIntroLabel.setData(MarkupValidator.MARKUP_VALIDATION_DISABLED, Boolean.TRUE);
+
+      return htmlIntroLabel;
+    }
+
+    @Override
+    protected StyledText createTextLabel(boolean htmlEnabled, Composite container) {
+      if (htmlEnabled) {
+        return null;
+      }
+
+      // create StyledText control only if html is disabled since StyledText is not able to render html.
+      StyledText introLabel = getUiEnvironment().getFormToolkit().createStyledText(container, SWT.WRAP | SWT.LEFT | SWT.V_SCROLL);
+      introLabel.setData(WRAP_TEXT_WITHOUT_SPACES, Boolean.TRUE);
+      introLabel.setEditable(false);
+
+      return introLabel;
+    }
+  }
+
 }
diff --git a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/AbstractSwingEnvironment.java b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/AbstractSwingEnvironment.java
index fcf9080..974e943 100644
--- a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/AbstractSwingEnvironment.java
+++ b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/AbstractSwingEnvironment.java
@@ -78,7 +78,9 @@
 import org.eclipse.scout.rt.client.ui.messagebox.IMessageBox;
 import org.eclipse.scout.rt.ui.swing.action.ISwingScoutAction;
 import org.eclipse.scout.rt.ui.swing.basic.ISwingScoutComposite;
+import org.eclipse.scout.rt.ui.swing.basic.ISwingScoutHtmlValidator;
 import org.eclipse.scout.rt.ui.swing.basic.SwingScoutComposite;
+import org.eclipse.scout.rt.ui.swing.basic.SwingScoutHtmlValidator;
 import org.eclipse.scout.rt.ui.swing.basic.table.ISwingScoutTable;
 import org.eclipse.scout.rt.ui.swing.basic.table.SwingScoutTable;
 import org.eclipse.scout.rt.ui.swing.basic.table.SwingTableColumn;
@@ -140,6 +142,7 @@
   private Rectangle m_popupOwnerBounds;
   private final Object m_immediateSwingJobsLock = new Object();
   private final List<Runnable> m_immediateSwingJobs = new ArrayList<Runnable>();
+  private ISwingScoutHtmlValidator m_htmlValidator;
 
   public AbstractSwingEnvironment() {
     checkThread();
@@ -165,6 +168,7 @@
         setWindowIcon(m_rootFrame);
       }
       m_synchronizer = new SwingScoutSynchronizer(this);
+      m_htmlValidator = createHtmlValidator();
     }
   }
 
@@ -1241,4 +1245,12 @@
     return new CheckboxWithMarginIcon(insets);
   }
 
+  protected ISwingScoutHtmlValidator createHtmlValidator() {
+    return new SwingScoutHtmlValidator();
+  }
+
+  @Override
+  public ISwingScoutHtmlValidator getHtmlValidator() {
+    return m_htmlValidator;
+  }
 }
diff --git a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/ISwingEnvironment.java b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/ISwingEnvironment.java
index 24870e5..1e6ad31 100644
--- a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/ISwingEnvironment.java
+++ b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/ISwingEnvironment.java
@@ -37,6 +37,7 @@
 import org.eclipse.scout.rt.client.ui.form.fields.groupbox.IGroupBox;
 import org.eclipse.scout.rt.client.ui.messagebox.IMessageBox;
 import org.eclipse.scout.rt.ui.swing.action.ISwingScoutAction;
+import org.eclipse.scout.rt.ui.swing.basic.ISwingScoutHtmlValidator;
 import org.eclipse.scout.rt.ui.swing.basic.table.ISwingScoutTable;
 import org.eclipse.scout.rt.ui.swing.basic.table.SwingTableColumn;
 import org.eclipse.scout.rt.ui.swing.ext.JDialogEx;
@@ -125,7 +126,7 @@
    * Customize the ui defaults table.
    * <p>
    * Default entries include:
-   * 
+   *
    * <pre>
    * <li><b>ActivityMap, Calendar</b>
    * Table.focusCellForeground (Color)
@@ -274,7 +275,7 @@
    * create a gui for a list of action, takes care of duplicate, leading and trailing separator handling and
    * recursively creates and attaches child actions on {@link org.eclipse.scout.rt.client.ui.action.tree.IActionNode
    * IActionNode}s and menus
-   * 
+   *
    * @param parent
    *          must not be null, typically a {@link javax.swing.JPopupMenu JPopupMenu}, a {@link javax.swing.JMenu JMenu}
    *          or a {@link javax.swing.JMenuBar JMenuBar}
@@ -305,7 +306,7 @@
    * <p>
    * The job is only run when it reaches the model within the cancelTimeout. This means if the job is delayed longer
    * than cancelTimeout millis when the model job runs it, then the job is ignored.
-   * 
+   *
    * @return the created and scheduled job, a {@link org.eclipse.scout.rt.client.ClientJob ClientJob}
    */
   JobEx invokeScoutLater(Runnable j, long cancelTimeout);
@@ -320,7 +321,7 @@
    * <p>
    * Executes the given {@link Runnable} and waits until it has finished.<br>
    * If the waiting thread is interrupted, this method returns before the {@link Runnable} has finished!
-   * 
+   *
    * @param r
    *          The {@link Runnable} to execute.
    * @param timeout
@@ -335,7 +336,7 @@
   /**
    * Creates the logo of the application. May return a simple JLabel with an icon or an animation.
    * The default impl. creates a JLabel and uses the icon with the ID "logo".
-   * 
+   *
    * @return
    */
   JComponent createLogo();
@@ -360,21 +361,21 @@
 
   /**
    * Enables customization of JDialogEx by returning subtypes.
-   * 
+   *
    * @return
    */
   JDialogEx createJDialogEx(Dialog swingParent);
 
   /**
    * Enables customization of JDialogEx by returning subtypes.
-   * 
+   *
    * @return
    */
   JDialogEx createJDialogEx(Frame swingParent);
 
   /**
    * Enables customization of JFrameE by returning subtypes.
-   * 
+   *
    * @return
    */
   JFrameEx createJFrameEx();
@@ -382,7 +383,7 @@
   /**
    * Creates a swing scout table instance for the given table model. The default implementation returns a
    * SwingScoutTable instance.
-   * 
+   *
    * @param table
    *          Table model
    * @return
@@ -393,7 +394,7 @@
   /**
    * Creates a swing scout table column instance for the given column model. The default implementation returns a
    * SwingTableColumn instance.
-   * 
+   *
    * @param swingModelIndex
    *          modelIndex used to create the swing {@link javax.swing.table.TableColumn TableColumn}
    * @param scoutColumn
@@ -406,7 +407,7 @@
   /**
    * Creates the checkbox Icon used to display boolean values in a Scout table. The default implementation returns a
    * <code>CheckboxWithMarginIcon</code>.
-   * 
+   *
    * @param insets
    *          insets applied on the icon
    * @return a checkbox Icon
@@ -414,4 +415,6 @@
    */
   CheckboxIcon createCheckboxWithMarginIcon(Insets insets);
 
+  ISwingScoutHtmlValidator getHtmlValidator();
+
 }
diff --git a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/SwingUtility.java b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/SwingUtility.java
index 6b8f081..60cfdea 100644
--- a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/SwingUtility.java
+++ b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/SwingUtility.java
@@ -98,6 +98,7 @@
   public static final boolean IS_JAVA_7_OR_LESS = CompareUtility.compareTo(System.getProperty("java.version"), "1.7") <= 0;
   public static final boolean DO_RESET_COMPONENT_BOUNDS = BundleContextUtility.parseBooleanProperty("scout.ui.layout.resetBoundsOnInvalidate", true);
   public static final boolean VERIFY_INPUT_ON_WINDOW_CLOSED = BundleContextUtility.parseBooleanProperty("scout.ui.verifyInputOnWindowClosed", false);
+  public static final boolean VALIDATE_HTML_CAPABLE = BundleContextUtility.parseBooleanProperty("org.eclipse.scout.rt.ui.swing.validate.htmlCapable", true);
 
   private static Integer topMarginForField = null;
 
@@ -906,7 +907,7 @@
    * will be returned. In Windows environments these circumstances (task bar on a none primary screen) will be very rare
    * and therefore ignored until the bug will be fixed in a future Java version.
    * </p>
-   * 
+   *
    * @param screenDevice
    *          a screen thats {@link GraphicsConfiguration} will be used to determine the insets
    * @return the insets of this toolkit's screen, in pixels, if the given screen device is the primary screen, otherwise
@@ -1088,7 +1089,7 @@
 
   /**
    * Adjusts the window such that it fits on the screen, if necessary.
-   * 
+   *
    * @param window
    */
   public static void adjustBoundsToScreen(Window window) {
@@ -1197,7 +1198,7 @@
    * lies within the specified frame.
    * <p>
    * Intended be used in custom implementations of {@link JComponent#getToolTipLocation(MouseEvent)}.
-   * 
+   *
    * @param e
    *          the event that caused the display of the tool tip
    * @param c
@@ -1272,7 +1273,7 @@
   /**
    * This method is used to get a top margin for {@link SwingScoutLabelField} and {@link SwingScoutHtmlField} in order
    * to have correct alignment for customized look and feel (e.g. Rayo)
-   * 
+   *
    * @since 3.10.0-M2
    */
   public static int getTopMarginForField() {
@@ -1351,5 +1352,4 @@
     sb.append(rawHtml.substring(matchEndIndex, rawHtml.length()));
     return sb.toString();
   }
-
 }
diff --git a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/basic/ISwingScoutHtmlValidator.java b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/basic/ISwingScoutHtmlValidator.java
new file mode 100644
index 0000000..03c5cfc
--- /dev/null
+++ b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/basic/ISwingScoutHtmlValidator.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2016 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.rt.ui.swing.basic;
+
+import javax.swing.JLabel;
+
+import org.eclipse.scout.rt.client.ui.IHtmlCapable;
+
+/**
+ * @since 4.2
+ */
+public interface ISwingScoutHtmlValidator {
+
+  /**
+   * Escape / sanitize a given HTML text on a given object of type {@link IHtmlCapable}.
+   *
+   * @param text
+   *          the HTML text to be escaped / sanitized
+   * @param htmlCapable
+   *          the object of type {@link IHtmlCapable}
+   * @return the escaped / sanitized text
+   */
+  String escape(String text, IHtmlCapable htmlCapable);
+
+  /**
+   * Removes the HTML renderer from a given {@link JLabel} if the given text contains HTML and if the given object is of
+   * type {@link IHtmlCapable} that is not configured to enable HTML.
+   *
+   * @param obj
+   *          the object of type {@link IHtmlCapable}
+   * @param text
+   *          the text that might contain HTML
+   * @param label
+   *          the {@link JLabel} where the HTML renderer should be removed from
+   * @return {@code true} if the HTML is removed, {@code false} otherwise
+   */
+  boolean removeHtmlRenderer(Object obj, String text, JLabel label);
+
+}
diff --git a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/basic/SwingScoutHtmlValidator.java b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/basic/SwingScoutHtmlValidator.java
new file mode 100644
index 0000000..02a047d
--- /dev/null
+++ b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/basic/SwingScoutHtmlValidator.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2016 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.rt.ui.swing.basic;
+
+import javax.swing.JLabel;
+import javax.swing.plaf.basic.BasicHTML;
+
+import org.eclipse.scout.commons.html.HtmlHelper;
+import org.eclipse.scout.rt.client.ui.IHtmlCapable;
+import org.eclipse.scout.rt.ui.swing.SwingUtility;
+
+/**
+ * @since 4.2
+ */
+public class SwingScoutHtmlValidator implements ISwingScoutHtmlValidator {
+
+  @Override
+  public String escape(String text, IHtmlCapable htmlCapable) {
+    if (htmlCapable.isHtmlEnabled() || !SwingUtility.VALIDATE_HTML_CAPABLE) { // developer is responsible for validating user input
+      return text;
+    }
+    return HtmlHelper.escape(text);
+  }
+
+  @Override
+  public boolean removeHtmlRenderer(Object obj, String text, JLabel label) {
+    if (!(obj instanceof IHtmlCapable) || !SwingUtility.VALIDATE_HTML_CAPABLE) {
+      return false;
+    }
+
+    if (!BasicHTML.isHTMLString(text) || ((IHtmlCapable) obj).isHtmlEnabled()) {
+      return false;
+    }
+
+    label.putClientProperty(BasicHTML.propertyKey, null);
+    return true;
+  }
+}
diff --git a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/basic/table/SwingScoutTable.java b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/basic/table/SwingScoutTable.java
index 3cf757f..31646db 100644
--- a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/basic/table/SwingScoutTable.java
+++ b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/basic/table/SwingScoutTable.java
@@ -1237,7 +1237,9 @@
           if (scoutCol.getDataType() == Boolean.class && (!(scoutCol instanceof ISmartColumn) || ((ISmartColumn) scoutCol).getLookupCall() == null)) {
             text = null;
           }
-          if (wrapText || (scoutTable.isMultilineText() && SwingUtility.isMultilineLabelText(text))) {
+
+          final boolean wrapOrMultilineText = wrapText || (scoutTable.isMultilineText() && SwingUtility.isMultilineLabelText(text));
+          if (wrapOrMultilineText) {
             text = SwingUtility.createHtmlLabelText(text, wrapText);
           }
           else {
@@ -1247,9 +1249,16 @@
             }
           }
           if (c instanceof JLabel) {
-            ((JLabel) c).setText(text);
-            if (m_htmlViewCache != null) {
-              m_htmlViewCache.updateHtmlView((JLabel) c, cell.getForegroundColor() != null);
+            JLabel label = (JLabel) c;
+
+            boolean removedHtmlRenderer = false;
+            if (!wrapOrMultilineText) { // wrapped and multi-line texts need to be processed a HTML renderer, so it will not be removed
+              removedHtmlRenderer = getSwingEnvironment().getHtmlValidator().removeHtmlRenderer(cell, text, label);
+            }
+
+            label.setText(text);
+            if (!removedHtmlRenderer && m_htmlViewCache != null) {
+              m_htmlViewCache.updateHtmlView(label, cell.getForegroundColor() != null);
             }
           }
           // tooltip
diff --git a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/basic/tree/SwingTreeCellRenderer.java b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/basic/tree/SwingTreeCellRenderer.java
index 6dd8aae..065b94e 100644
--- a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/basic/tree/SwingTreeCellRenderer.java
+++ b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/basic/tree/SwingTreeCellRenderer.java
@@ -64,6 +64,7 @@
     if (label == null) {
       return comp;
     }
+    m_env.getHtmlValidator().removeHtmlRenderer(cell, cell.getText(), label);
     label.setEnabled(scoutTree.isEnabled() && node.isEnabled() && cell.isEnabled());
     // icon
     String iconName = cell.getIconId();
diff --git a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/ext/HtmlViewCache.java b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/ext/HtmlViewCache.java
index 6d9ab16..d41a358 100644
--- a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/ext/HtmlViewCache.java
+++ b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/ext/HtmlViewCache.java
@@ -11,6 +11,7 @@
 package org.eclipse.scout.rt.ui.swing.ext;
 
 import java.util.HashMap;
+import java.util.Map;
 
 import javax.swing.JLabel;
 import javax.swing.UIManager;
@@ -26,18 +27,16 @@
  * <p>
  * To use on JLabels you must perform the following actions:
  * <ul>
- * <li>Disable automatic html on the field:
- * label.putClientProperty("html.disable",true);</li>
- * <li>Whenever {@link JLabel#setText(String)} is called, call
- * {@link #updateHtmlView(JLabel)} just after it.</li>
+ * <li>Disable automatic html on the field: label.putClientProperty("html.disable",true);</li>
+ * <li>Whenever {@link JLabel#setText(String)} is called, call {@link #updateHtmlView(JLabel)} just after it.</li>
  * </ul>
  */
 public class HtmlViewCache {
-	private HashMap<Object, View> m_viewMap;
+  private final Map<Object, View> m_viewMap;
 
-	public HtmlViewCache() {
-		m_viewMap = new HashMap<Object, View>();
-	}
+  public HtmlViewCache() {
+    m_viewMap = new HashMap<Object, View>();
+  }
 
   /**
    * update html view using the cache
diff --git a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/window/messagebox/SwingScoutMessageBox.java b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/window/messagebox/SwingScoutMessageBox.java
index 995c810..a573167 100644
--- a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/window/messagebox/SwingScoutMessageBox.java
+++ b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/window/messagebox/SwingScoutMessageBox.java
@@ -45,6 +45,7 @@
 import javax.swing.border.Border;
 import javax.swing.border.CompoundBorder;
 import javax.swing.border.EmptyBorder;
+import javax.swing.plaf.basic.BasicHTML;
 import javax.swing.text.View;
 
 import org.eclipse.scout.commons.StringUtility;
@@ -114,6 +115,7 @@
       labelPanel.setBackground(Color.white);
       labelPanel.setOpaque(true);
       JLabelEx label = new JLabelEx();
+      s = processTextOnLabel(s, label, getScoutMessageBox().isHtmlEnabled());
       label.setText(s);
       ensureProperDimension(label, s);
       labelPanel.add(label);
@@ -125,6 +127,7 @@
       labelPanel.setBorder(new CompoundBorder(new P_TopSeparatorBorder(), new EmptyBorder(VERTICAL_PADDING, HORIZONTAL_PADDING, VERTICAL_PADDING, HORIZONTAL_PADDING)));
       labelPanel.setOpaque(false);
       JLabelEx label = new JLabelEx();
+      s = processTextOnLabel(s, label, getScoutMessageBox().isHtmlEnabled());
       label.setText(s);
       ensureProperDimension(label, s);
       labelPanel.add(label);
@@ -473,4 +476,17 @@
       }
     });
   }
+
+  protected String processTextOnLabel(String text, JLabelEx label, boolean htmlEnabled) {
+    if (!htmlEnabled && BasicHTML.isHTMLString(text)) {
+      if (SwingUtility.isMultilineLabelText(text)) {
+        String body = getSwingEnvironment().getHtmlValidator().escape(text, getScoutMessageBox());
+        text = "<html>" + StringUtility.convertPlainTextNewLinesToHtml(body, false) + "</html>";
+      }
+      else {
+        text = getSwingEnvironment().getHtmlValidator().escape(text, getScoutMessageBox());
+      }
+    }
+    return text;
+  }
 }
diff --git a/org.eclipse.scout.svg.ui.rap/src/org/eclipse/scout/svg/ui/rap/AbstractRwtScoutSvgComposite.java b/org.eclipse.scout.svg.ui.rap/src/org/eclipse/scout/svg/ui/rap/AbstractRwtScoutSvgComposite.java
index e2ae087..5112148 100644
--- a/org.eclipse.scout.svg.ui.rap/src/org/eclipse/scout/svg/ui/rap/AbstractRwtScoutSvgComposite.java
+++ b/org.eclipse.scout.svg.ui.rap/src/org/eclipse/scout/svg/ui/rap/AbstractRwtScoutSvgComposite.java
@@ -185,7 +185,7 @@
         backgroundColorInheritScript = "";
       }
 
-      // set the html content to the browser
+      // assume that html content is encoded properly. set the html content to the browser
       getUiField().setText("<html><body style=\"overflow: hidden;\" width=\"100%\" height=\"100%\" onload=\"" + backgroundColorInheritScript + "\" onclick=\"" + contextMenuHideScript + "\">" + svgText + "</body></html>");
     }
     catch (Exception e) {