From 1ad4d7783a9b49b6d33bd9697e08d3387719d23f Mon Sep 17 00:00:00 2001
From: srosse <stephane.rosse@frentix.com>
Date: Wed, 22 May 2019 10:57:21 +0200
Subject: [PATCH] OO-4063: support emojis

---
 pom.xml                                       | 11 ++++-
 .../ui/CalendarDetailsController.java         |  3 +-
 .../FullCalendarComponentRenderer.java        |  2 +-
 .../gui/components/choice/ChoiceRenderer.java | 10 ++--
 .../impl/elements/AbstractTextElement.java    | 10 ++--
 .../impl/elements/FileElementRenderer.java    | 11 ++---
 .../impl/elements/JSDateChooserRenderer.java  |  8 ++--
 .../elements/MultipleSelectionRenderer.java   |  9 ++--
 .../impl/elements/SelectboxRenderer.java      |  5 +-
 .../SelectionTreeComponentRenderer.java       |  7 ++-
 .../impl/elements/TextElementImpl.java        | 14 ++----
 .../impl/elements/TextElementRenderer.java    |  4 +-
 .../richText/RichTextElementRenderer.java     |  3 +-
 .../AbstractCSSIconFlexiCellRenderer.java     |  3 +-
 .../table/StaticFlexiCellRenderer.java        |  4 +-
 .../elements/table/XlsFlexiTableExporter.java |  3 +-
 .../gui/components/link/LinkRenderer.java     |  7 ++-
 .../table/CustomCssCellRenderer.java          |  5 +-
 .../table/DefaultXlsTableExporter.java        |  3 +-
 .../components/table/IconCssCellRenderer.java |  5 +-
 .../table/IconedTypeCellRenderer.java         |  5 +-
 .../gui/components/table/TableRenderer.java   |  4 +-
 .../components/table/TableSortRenderer.java   |  3 +-
 .../gui/components/tree/MenuTreeRenderer.java |  3 +-
 .../FloatingResizableDialogController.java    |  3 +-
 .../CloseableCalloutWindowController.java     |  4 +-
 .../textmarker/TextMarkerJsGenerator.java     |  3 +-
 .../olat/core/gui/render/StringOutput.java    | 12 +----
 .../velocity/VelocityRenderDecorator.java     |  5 +-
 .../java/org/olat/core/util/StringHelper.java | 48 ++++++++++++-------
 ...TranslationInterceptHandlerController.java | 11 ++---
 .../cl/ui/CheckListAssessmentDataModel.java   |  3 +-
 .../course/nodes/fo/FOPeekviewController.java |  5 +-
 .../nodes/info/InfoPeekViewController.java    |  3 +-
 .../IndentedStatisticNodeRenderer.java        |  9 ++--
 .../ui/edit/BusinessGroupEditController.java  |  4 +-
 .../export/QTIExportFormatterCSVType1.java    |  7 ++-
 .../export/QTIExportFormatterCSVType3.java    |  8 ++--
 .../FIBAssessmentItemBuilder.java             |  3 +-
 .../ims/qti21/pool/QTI12To21Converter.java    |  3 +-
 .../AssessmentObjectComponentRenderer.java    |  5 +-
 .../AssessmentTestComponentRenderer.java      |  3 +-
 .../modules/cp/CPOfflineReadableManager.java  |  8 ++--
 .../formatters/ForumRTFFormatter.java         |  3 +-
 .../formatters/ForumStreamedRTFFormatter.java |  3 +-
 .../modules/forms/ui/RubricAvgRenderer.java   |  3 +-
 .../olat/modules/iq/IQComponentRenderer.java  | 29 ++++++-----
 .../VideoMarkerTextCellRenderer.java          |  3 +-
 .../modules/webFeed/ui/ItemsController.java   |  4 +-
 .../olat/note/NotesPortletRunController.java  |  4 +-
 .../ui/RepositoryEntryIconRenderer.java       |  3 +-
 .../repository/ui/author/TypeRenderer.java    |  3 +-
 .../olat/user/DisplayPortraitController.java  |  4 +-
 .../org/olat/core/util/StringHelperTest.java  |  4 ++
 54 files changed, 160 insertions(+), 192 deletions(-)

diff --git a/pom.xml b/pom.xml
index 18247a13b76..0a00d26ff4c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2201,11 +2201,20 @@
 			<version>4.5.7</version>
 		</dependency>
 		<dependency>
-			<!-- Used by at least ical4j, basiclti -->
 			<groupId>commons-lang</groupId>
 			<artifactId>commons-lang</artifactId>
 			<version>2.6</version>
 		</dependency>
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-lang3</artifactId>
+			<version>3.9</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-text</artifactId>
+			<version>1.6</version>
+		</dependency>
 		<dependency>
 			<groupId>com.opencsv</groupId>
 			<artifactId>opencsv</artifactId>
diff --git a/src/main/java/org/olat/commons/calendar/ui/CalendarDetailsController.java b/src/main/java/org/olat/commons/calendar/ui/CalendarDetailsController.java
index 7739cdcd98a..a043f2dd26e 100644
--- a/src/main/java/org/olat/commons/calendar/ui/CalendarDetailsController.java
+++ b/src/main/java/org/olat/commons/calendar/ui/CalendarDetailsController.java
@@ -25,7 +25,6 @@ import java.util.Date;
 import java.util.List;
 import java.util.Locale;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.commons.lang.time.DateUtils;
 import org.olat.commons.calendar.CalendarManagedFlag;
 import org.olat.commons.calendar.CalendarManager;
@@ -146,7 +145,7 @@ public class CalendarDetailsController extends BasicController {
 				
 				wrapper.setUri(uri);
 				wrapper.setDisplayName(link.getDisplayName());
-				wrapper.setTitle(StringEscapeUtils.escapeHtml(link.getDisplayName()));
+				wrapper.setTitle(StringHelper.escapeHtml(link.getDisplayName()));
 				if (StringHelper.containsNonWhitespace(iconCssClass)) {
 					wrapper.setCssClass(iconCssClass);
 				}
diff --git a/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarComponentRenderer.java b/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarComponentRenderer.java
index 09febe56c7f..2467ee10266 100644
--- a/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarComponentRenderer.java
+++ b/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarComponentRenderer.java
@@ -19,7 +19,7 @@
  */
 package org.olat.commons.calendar.ui.components;
 
-import static org.apache.commons.lang.StringEscapeUtils.escapeJavaScript;
+import static org.olat.core.util.StringHelper.escapeJavaScript;
 
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
diff --git a/src/main/java/org/olat/core/gui/components/choice/ChoiceRenderer.java b/src/main/java/org/olat/core/gui/components/choice/ChoiceRenderer.java
index 29978559d33..97dbbfff309 100644
--- a/src/main/java/org/olat/core/gui/components/choice/ChoiceRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/choice/ChoiceRenderer.java
@@ -26,7 +26,6 @@
 
 package org.olat.core.gui.components.choice;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.DefaultComponentRenderer;
 import org.olat.core.gui.control.winmgr.AJAXFlags;
@@ -35,6 +34,7 @@ import org.olat.core.gui.render.Renderer;
 import org.olat.core.gui.render.StringOutput;
 import org.olat.core.gui.render.URLBuilder;
 import org.olat.core.gui.translator.Translator;
+import org.olat.core.util.StringHelper;
 
 /**
  * Initial Date: Feb 2, 2004 A <b>ChoiceRenderer </b> is
@@ -88,7 +88,7 @@ public class ChoiceRenderer extends DefaultComponentRenderer {
 			String label = model.getLabel(i);
 			target.append("<td class='o_choice_textrow'>");
 			if(choice.isEscapeHtml()) {
-				target.append(StringEscapeUtils.escapeHtml(label));
+				target.append(StringHelper.escapeHtml(label));
 			} else {
 				target.append(label);
 			}
@@ -110,14 +110,14 @@ public class ChoiceRenderer extends DefaultComponentRenderer {
 		// Submit button
 		target.append("<button type='button' class='btn btn-primary'")
 	          .append(" onclick=\"o_TableMultiActionEvent('").append(id).append("','olat_fosm');\"><span>")
-	          .append(StringEscapeUtils.escapeHtml(translator.translate(choice.getSubmitKey()))).append("</span></button>");
+	          .append(StringHelper.escapeHtml(translator.translate(choice.getSubmitKey()))).append("</span></button>");
 
 		//Reset button
 		String resetKey = choice.getResetKey();
 		if (resetKey != null) {
 			target.append("<button type='button' class='btn btn-default'")
 			      .append(" onclick=\"o_TableMultiActionEvent('").append(id).append("','").append(Choice.RESET_IDENTIFICATION).append("');\"><span>")
-			      .append(StringEscapeUtils.escapeHtml(translator.translate(resetKey))).append("</span></button>");
+			      .append(StringHelper.escapeHtml(translator.translate(resetKey))).append("</span></button>");
 		}
 		
 		// Cancel button
@@ -125,7 +125,7 @@ public class ChoiceRenderer extends DefaultComponentRenderer {
 		if (cancelKey != null) {
 			target.append("<button type='button' class='btn btn-default'")
 		          .append(" onclick=\"o_TableMultiActionEvent('").append(id).append("','").append(Choice.CANCEL_IDENTIFICATION).append("');\"><span>")
-		          .append(StringEscapeUtils.escapeHtml(translator.translate(cancelKey))).append("</span></button>");
+		          .append(StringHelper.escapeHtml(translator.translate(cancelKey))).append("</span></button>");
 		}
 		target.append("</div></td></tr></table></form>");
 	}
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/AbstractTextElement.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/AbstractTextElement.java
index a3a7be878bf..4107276d69d 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/AbstractTextElement.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/AbstractTextElement.java
@@ -29,7 +29,6 @@ import java.io.UnsupportedEncodingException;
 import java.util.List;
 import java.util.Locale;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.form.ValidationError;
 import org.olat.core.gui.components.form.flexible.elements.TextElement;
@@ -40,9 +39,6 @@ import org.olat.core.util.ValidationStatusImpl;
 import org.olat.core.util.filter.Filter;
 
 /**
- * Description:<br>
- * TODO: patrickb Class Description for AbstractTextElement
- * <P>
  * Initial Date: 27.11.2006 <br>
  * 
  * @author patrickb
@@ -168,7 +164,7 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 			// null value is not regarded as initial value. only
 			// real values are used inital values
 			if (!originalInitialised){
-				original = new String(value);
+				original = value;
 				originalInitialised = true;
 			}
 		}
@@ -193,7 +189,7 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 	@Override
 	public void setNewOriginalValue(String value) {
 		if (value == null) value = "";
-		original = new String(value);
+		original = value;
 		originalInitialised = true;
 		if (getValue() != null && !getValue().equals(value)) {
 			getComponent().setDirty(true);
@@ -337,7 +333,7 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 	@Override
 	public void setPlaceholderText(String placeholderText) {
 		if (StringHelper.containsNonWhitespace(placeholderText)) {
-			placeholder = StringEscapeUtils.escapeHtml(placeholderText);
+			placeholder = StringHelper.escapeHtml(placeholderText);
 		} else {
 			placeholder = null;
 		}
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/FileElementRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/FileElementRenderer.java
index 5af54fceb17..6e0855cbc3a 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/FileElementRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/FileElementRenderer.java
@@ -22,7 +22,6 @@ package org.olat.core.gui.components.form.flexible.impl.elements;
 
 import java.io.File;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.DefaultComponentRenderer;
 import org.olat.core.gui.components.form.flexible.elements.FileElement;
@@ -124,18 +123,18 @@ public class FileElementRenderer extends DefaultComponentRenderer {
 				 sb.append(" onfocus=\"this.form.fake_").append(id).append(".nextSibling.style.border = '1px dotted black';\"")
 				   .append(" onblur=\"this.form.fake_").append(id).append(".nextSibling.style.border = '0';\"");
 				 // Add select text (hover)
-				 sb.append(" title=\"").append(StringEscapeUtils.escapeHtml(trans.translate("file.element.select"))).append("\" />");
+				 sb.append(" title=\"").appendHtmlEscaped(trans.translate("file.element.select")).append("\" />");
 			}
 			// Add the visible but fake input field and a styled faked file chooser button
 			sb.append("<div class='o_fakechooser input-group'>");
-			sb.append("<input class='form-control' name='fake_").append(id).append("' value=\"").append(StringEscapeUtils.escapeHtml(fileName))
-			  .append("\" placeholder=\"").append(StringEscapeUtils.escapeHtml(trans.translate("file.element.select"))).append("\" />");  
+			sb.append("<input class='form-control' name='fake_").append(id).append("' value=\"").appendHtmlEscaped(fileName)
+			  .append("\" placeholder=\"").appendHtmlEscaped(trans.translate("file.element.select")).append("\" />");  
 			sb.append("<span class='input-group-addon'><a href='javascript:;'><i class='o_icon o_icon_upload'> </i></a></span>");
 			if(showDeleteButton) {
 				sb.append("<a class='input-group-addon' href=\"javascript:")
 				  .append(FormJSHelper.getXHRFnCallFor(fileElem.getRootForm(), fileComp.getFormDispatchId(), 1, false, false, new NameValuePair("delete", "delete")))
 				  .append(";\" onclick=\"\" ")
-				  .append(" title=\"").append(StringEscapeUtils.escapeHtml(trans.translate("file.element.delete"))).append("\" ><i class='o_icon o_icon_delete'> </i></a>");
+				  .append(" title=\"").appendHtmlEscaped(trans.translate("file.element.delete")).append("\" ><i class='o_icon o_icon_delete'> </i></a>");
 			}
 			sb.append("</div></div>");
 			// Add example text and  max upload size
@@ -165,7 +164,7 @@ public class FileElementRenderer extends DefaultComponentRenderer {
 			  .append(" >")
 			  .append("<input type='text' disabled=\"disabled\" class=\"form-control o_disabled\" size=\"")
 			  .append("\" value=\"")
-			  .append(StringEscapeUtils.escapeHtml(fileName)).append("\" ")
+			  .appendHtmlEscaped(fileName).append("\" ")
 			  .append("\" />")
 			  .append("</span>");
 		}
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/JSDateChooserRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/JSDateChooserRenderer.java
index b9e2f8282b9..b4950627719 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/JSDateChooserRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/JSDateChooserRenderer.java
@@ -28,7 +28,6 @@ package org.olat.core.gui.components.form.flexible.impl.elements;
 import java.util.Calendar;
 import java.util.Date;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.DefaultComponentRenderer;
 import org.olat.core.gui.components.form.flexible.impl.FormJSHelper;
@@ -37,6 +36,7 @@ import org.olat.core.gui.render.Renderer;
 import org.olat.core.gui.render.StringOutput;
 import org.olat.core.gui.render.URLBuilder;
 import org.olat.core.gui.translator.Translator;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
 
 /**
@@ -80,7 +80,7 @@ class JSDateChooserRenderer extends DefaultComponentRenderer {
 
 			//date chooser button
 			sb.append("<span class='input-group-addon'>")
-			  .append("<i class='o_icon o_icon_calendar' id=\"").append(triggerId).append("\" title=\"").append(StringEscapeUtils.escapeHtml(sourceTranslator.translate("calendar.choose"))).append("\"")
+			  .append("<i class='o_icon o_icon_calendar' id=\"").append(triggerId).append("\" title=\"").appendHtmlEscaped(sourceTranslator.translate("calendar.choose")).append("\"")
 			  .append(" onclick=\"jQuery('#").append(receiverId).append("').datepicker('show');\"")
 			  .append("></i></span>")
 			  .append("</div></div>");//input-group
@@ -168,7 +168,7 @@ class JSDateChooserRenderer extends DefaultComponentRenderer {
 		if(value == null){
 			value = "";
 		}
-		value = StringEscapeUtils.escapeHtml(value);
+		value = StringHelper.escapeHtml(value);
 		sb.append("<span id='").append(id).append("_wp' ")
 		  .append(FormJSHelper.getRawJSFor(te.getRootForm(), id, te.getAction()))
 		  .append("title=\"").append(value).append("\">");
@@ -234,7 +234,7 @@ class JSDateChooserRenderer extends DefaultComponentRenderer {
 		  .append(id).append("\" name=\"").append(id)
 		  .append("\" size=\"").append(te.displaySize)
 		  .append("\" maxlength=\"").append(maxlength)
-		  .append("\" value=\"").append(StringEscapeUtils.escapeHtml(te.getValue())).append("\" ")
+		  .append("\" value=\"").append(StringHelper.escapeHtml(te.getValue())).append("\" ")
 		  .append(FormJSHelper.getRawJSFor(te.getRootForm(), id, te.getAction()))
 		  .append("/>");
 		//add set dirty form only if enabled
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/MultipleSelectionRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/MultipleSelectionRenderer.java
index 65b9cced06c..34f65b60e9e 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/MultipleSelectionRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/MultipleSelectionRenderer.java
@@ -19,7 +19,6 @@
  */
 package org.olat.core.gui.components.form.flexible.impl.elements;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.DefaultComponentRenderer;
 import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement;
@@ -90,8 +89,8 @@ public class MultipleSelectionRenderer extends DefaultComponentRenderer {
 			String cssClass = check.getCssClass();
 
 			if(stF.isEscapeHtml()){
-				key = StringEscapeUtils.escapeHtml(key);
-				value = StringEscapeUtils.escapeHtml(value);
+				key = StringHelper.escapeHtml(key);
+				value = StringHelper.escapeHtml(value);
 			}
 				
 			sb.append("<li class='");
@@ -274,8 +273,8 @@ public class MultipleSelectionRenderer extends DefaultComponentRenderer {
 		String key = check.getKey();
 		String value = check.getValue();
 		if(stF.isEscapeHtml()){
-			key = StringEscapeUtils.escapeHtml(key);
-			value = StringEscapeUtils.escapeHtml(value);
+			key = StringHelper.escapeHtml(key);
+			value = StringHelper.escapeHtml(value);
 		}
 			
 		boolean selected = check.isSelected();
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectboxRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectboxRenderer.java
index a77026bc83b..22a834736ae 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectboxRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectboxRenderer.java
@@ -25,7 +25,6 @@
 */
 package org.olat.core.gui.components.form.flexible.impl.elements;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.DefaultComponentRenderer;
 import org.olat.core.gui.components.form.flexible.impl.FormEvent;
@@ -38,8 +37,6 @@ import org.olat.core.gui.translator.Translator;
 import org.olat.core.util.StringHelper;
 
 /**
- * Description:<br>
- * TODO: patrickb Class Description for SingleSelectionSelectboxRenderer
  * 
  * <P>
  * Initial Date:  02.01.2007 <br>
@@ -104,7 +101,7 @@ class SelectboxRenderer extends DefaultComponentRenderer {
 			}
 			sb.append(">");
 			if(escapeHtml) {
-				sb.append(StringEscapeUtils.escapeHtml(values[i]));
+				sb.appendHtmlEscaped(values[i]);
 			} else {
 				sb.append(values[i]);
 			}
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectionTreeComponentRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectionTreeComponentRenderer.java
index c44161d7a87..89689d9a709 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectionTreeComponentRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectionTreeComponentRenderer.java
@@ -27,7 +27,6 @@ package org.olat.core.gui.components.form.flexible.impl.elements;
 
 import java.util.Map;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.DefaultComponentRenderer;
 import org.olat.core.gui.components.form.flexible.impl.FormJSHelper;
@@ -85,7 +84,7 @@ class SelectionTreeComponentRenderer extends DefaultComponentRenderer {
 				if(cssClass != null) {
 					sb.append("<i class='").append(cssClass).append("'> </i> ");
 				}
-				sb.append(StringEscapeUtils.escapeHtml(currentNode.getTitle()));
+				sb.appendHtmlEscaped(currentNode.getTitle());
 				renderNodeDecorator(sb, currentNode);
 				sb.append("</span>");
 			}
@@ -113,8 +112,8 @@ class SelectionTreeComponentRenderer extends DefaultComponentRenderer {
 		String key = check.getKey();
 		String value = check.getValue();
 		if(stF.isEscapeHtml()){
-			key = StringEscapeUtils.escapeHtml(key);
-			value = StringEscapeUtils.escapeHtml(value);
+			key = StringHelper.escapeHtml(key);
+			value = StringHelper.escapeHtml(value);
 		}
 		
 		boolean selected = check.isSelected();
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementImpl.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementImpl.java
index caf8ef7b8bf..7ed6eb0bc85 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementImpl.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementImpl.java
@@ -27,7 +27,6 @@ package org.olat.core.gui.components.form.flexible.impl.elements;
 
 import java.util.ArrayList;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.ComponentRenderer;
@@ -50,8 +49,6 @@ import org.olat.core.util.Util;
 import org.olat.core.util.ValidationStatus;
 
 /**
- * Description:<br>
- * TODO: patrickb Class Description for TextElement
  * <P>
  * Initial Date: 25.11.2006 <br>
  * 
@@ -63,8 +60,8 @@ public class TextElementImpl extends AbstractTextElement implements InlineTextEl
 	//set text input type as default
 	private String htmlInputType = HTML_INPUT_TYPE_TEXT;
 	
-	public final static String HTML_INPUT_TYPE_TEXT = "text";
-	public final static String HTML_INPUT_TYPE_PASSWORD = "password";
+	public static final String HTML_INPUT_TYPE_TEXT = "text";
+	public static final String HTML_INPUT_TYPE_PASSWORD = "password";
 	
 	//inline stuff
 	protected String transientValue;//last submitted value, which may be good or wrong
@@ -78,7 +75,6 @@ public class TextElementImpl extends AbstractTextElement implements InlineTextEl
 	}
 	
 	/**
-	 * TODO: check if htmlInputType is valid
 	 * @param id A fix identifier for state-less behavior, must be unique or null
 	 * @param name
 	 * @param predefinedValue
@@ -173,7 +169,7 @@ public class TextElementImpl extends AbstractTextElement implements InlineTextEl
 				tmpVal = StringHelper.containsNonWhitespace(getValue()) ? getValue() : emptyVal;
 			}
 			// append the html safe value
-			htmlVal.append(StringEscapeUtils.escapeHtml(tmpVal));
+			htmlVal.append(StringHelper.escapeHtml(tmpVal));
 			if (!itei.isEnabled()) {
 				// RO view and not clickable
 				String id = aiec.getFormDispatchId();
@@ -207,7 +203,7 @@ public class TextElementImpl extends AbstractTextElement implements InlineTextEl
 					// Javascript
 					sb.append(FormJSHelper.getJSStart());
 					// clicking outside or pressing enter -> OK, pressing ESC -> Cancel
-					FormJSHelper.getInlineEditOkCancelJS(sb, id, StringEscapeUtils.escapeHtml(getValue()), itei.getRootForm());
+					FormJSHelper.getInlineEditOkCancelJS(sb, id, StringHelper.escapeHtml(getValue()), itei.getRootForm());
 					sb.append(FormJSHelper.getJSEnd());
 
 				} else {
@@ -215,7 +211,7 @@ public class TextElementImpl extends AbstractTextElement implements InlineTextEl
 					Translator trans = Util.createPackageTranslator(TextElementImpl.class, translator.getLocale(), translator);
 					String id = aiec.getFormDispatchId();
 					sb.append("<div id='").append(id).append("' class='form-control-static' title=\"")
-						.append(StringEscapeUtils.escapeHtml(trans.translate("inline.edit.help")))
+						.appendHtmlEscaped(trans.translate("inline.edit.help"))
 						.append("\" ")
 						.append(FormJSHelper.getRawJSFor(itei.getRootForm(), id, itei.getAction()))
 						.append("> ")
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementRenderer.java
index be7ee578254..99f3a8f5d09 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementRenderer.java
@@ -25,7 +25,6 @@
 */ 
 package org.olat.core.gui.components.form.flexible.impl.elements;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.DefaultComponentRenderer;
 import org.olat.core.gui.components.form.flexible.impl.FormJSHelper;
@@ -34,6 +33,7 @@ import org.olat.core.gui.render.Renderer;
 import org.olat.core.gui.render.StringOutput;
 import org.olat.core.gui.render.URLBuilder;
 import org.olat.core.gui.translator.Translator;
+import org.olat.core.util.StringHelper;
 
 /**
  * Initial Date: 08.12.2006 <br>
@@ -55,7 +55,7 @@ class TextElementRenderer extends DefaultComponentRenderer {
 			value = "";
 		}
 		StringBuilder htmlVal = new StringBuilder();
-		htmlVal.append(StringEscapeUtils.escapeHtml(value));
+		htmlVal.append(StringHelper.escapeHtml(value));
 		if (source.isEnabled()) {
 			//read write view			
 			String elementCSS = te.getElementCssClass();
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/richText/RichTextElementRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/richText/RichTextElementRenderer.java
index 9e4c59258ca..f8f19037e74 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/richText/RichTextElementRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/richText/RichTextElementRenderer.java
@@ -22,7 +22,6 @@ package org.olat.core.gui.components.form.flexible.impl.elements.richText;
 
 import java.util.List;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.dispatcher.impl.StaticMediaDispatcher;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.DefaultComponentRenderer;
@@ -283,7 +282,7 @@ class RichTextElementRenderer extends DefaultComponentRenderer {
 		sb.append("\" class=\"BGlossarIgnore\">");
 		// The value needs to be encoded when loading into the editor to properly display < > etc values. 
 		// See http://tinymce.moxiecode.com/punbb/viewtopic.php?id=1846
-		sb.append(StringEscapeUtils.escapeHtml(value));
+		sb.appendHtmlEscaped(value);
 		sb.append("</textarea>");
 	}
 }
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/AbstractCSSIconFlexiCellRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/AbstractCSSIconFlexiCellRenderer.java
index f477ed1073f..385ce31adaf 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/AbstractCSSIconFlexiCellRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/AbstractCSSIconFlexiCellRenderer.java
@@ -19,7 +19,6 @@
  */
 package org.olat.core.gui.components.form.flexible.impl.elements.table;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.render.Renderer;
 import org.olat.core.gui.render.StringOutput;
 import org.olat.core.gui.render.URLBuilder;
@@ -58,7 +57,7 @@ public abstract class AbstractCSSIconFlexiCellRenderer implements FlexiCellRende
 		String hoverText = getHoverText(cellValue, translator);
 		if (StringHelper.containsNonWhitespace(hoverText)) {
 			target.append("\" title=\"");
-			target.append(StringEscapeUtils.escapeHtml(hoverText));
+			target.append(StringHelper.escapeHtml(hoverText));
 		}
 		target.append("\"> </i>");
 		if(delegate == null) {
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/StaticFlexiCellRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/StaticFlexiCellRenderer.java
index 669bc341a0a..5611e782e6b 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/StaticFlexiCellRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/StaticFlexiCellRenderer.java
@@ -19,8 +19,6 @@
  */
 package org.olat.core.gui.components.form.flexible.impl.elements.table;
 
-
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.form.flexible.impl.Form;
 import org.olat.core.gui.components.form.flexible.impl.FormJSHelper;
 import org.olat.core.gui.components.form.flexible.impl.NameValuePair;
@@ -124,7 +122,7 @@ public class StaticFlexiCellRenderer implements FlexiCellRenderer {
 			String jsCode = FormJSHelper.getXHRFnCallFor(rootForm, id, 1, true, true, pair);
 			target.append("<a href=\"javascript:").append(jsCode).append(";\"");
 			if(StringHelper.containsNonWhitespace(linkTitle)) {
-				target.append(" title=\"").append(StringEscapeUtils.escapeHtml(linkTitle)).append("\"");
+				target.append(" title=\"").appendHtmlEscaped(linkTitle).append("\"");
 			}
 			if(StringHelper.containsNonWhitespace(linkCSS)) {
 				target.append(" class=\"").append(linkCSS).append("\"");
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/XlsFlexiTableExporter.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/XlsFlexiTableExporter.java
index 416497cbd21..3b5c0ff6ace 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/XlsFlexiTableExporter.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/XlsFlexiTableExporter.java
@@ -24,7 +24,6 @@ import java.io.OutputStream;
 import java.util.Date;
 import java.util.List;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.form.flexible.FormItem;
 import org.olat.core.gui.media.MediaResource;
 import org.olat.core.gui.render.EmptyURLBuilder;
@@ -124,7 +123,7 @@ public class XlsFlexiTableExporter implements FlexiTableExporter {
 					cellValue = StringHelper.stripLineBreaks(cellValue);
 					cellValue = FilterFactory.getHtmlTagsFilter().filter(cellValue);
 					if(StringHelper.containsNonWhitespace(cellValue)) {
-						cellValue = StringEscapeUtils.unescapeHtml(cellValue);
+						cellValue = StringHelper.unescapeHtml(cellValue);
 					}
 					dataRow.addCell(col, cellValue, null);
 				}
diff --git a/src/main/java/org/olat/core/gui/components/link/LinkRenderer.java b/src/main/java/org/olat/core/gui/components/link/LinkRenderer.java
index 0a659e067e2..8a58cd88a8e 100644
--- a/src/main/java/org/olat/core/gui/components/link/LinkRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/link/LinkRenderer.java
@@ -29,7 +29,6 @@ package org.olat.core.gui.components.link;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.DefaultComponentRenderer;
 import org.olat.core.gui.components.form.flexible.impl.Form;
@@ -178,9 +177,9 @@ public class LinkRenderer extends DefaultComponentRenderer {
 				if (!link.isHasTooltip()) {
 					sb.append(" title=\"");
 					if (nontranslated){
-						sb.append(StringEscapeUtils.escapeHtml(title)).append("\"");
+						sb.appendHtmlEscaped(title).append("\"");
 					} else {
-						sb.append(StringEscapeUtils.escapeHtml(translator.translate(title))).append("\"");
+						sb.appendHtmlEscaped(translator.translate(title)).append("\"");
 					}
 				}
 				//tooltips based on the extjs library, see webapp/static/js/ext*
@@ -191,7 +190,7 @@ public class LinkRenderer extends DefaultComponentRenderer {
 					} else {
 						text = translator.translate(title);
 					}
-					sb.append(" title=\"").append(StringEscapeUtils.escapeHtml(text)).append("\"");
+					sb.append(" title=\"").appendHtmlEscaped(text).append("\"");
 				}
 			}
 			sb.append(">");
diff --git a/src/main/java/org/olat/core/gui/components/table/CustomCssCellRenderer.java b/src/main/java/org/olat/core/gui/components/table/CustomCssCellRenderer.java
index 09280d7df6a..2414bcb8dea 100644
--- a/src/main/java/org/olat/core/gui/components/table/CustomCssCellRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/table/CustomCssCellRenderer.java
@@ -27,7 +27,6 @@ package org.olat.core.gui.components.table;
 
 import java.util.Locale;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent;
 import org.olat.core.gui.render.Renderer;
@@ -79,8 +78,8 @@ public abstract class CustomCssCellRenderer implements CustomCellRenderer, Flexi
 			sb.append(getCssClass(val));
 			String hoverText = getHoverText(val);
 			if (StringHelper.containsNonWhitespace(hoverText)) {
-				sb.append("\" title=\"");
-				sb.append(StringEscapeUtils.escapeHtml(hoverText));
+				sb.append("\" title=\"")
+				  .appendHtmlEscaped(hoverText);
 			}
 			sb.append("\"> </i> ").append(getCellValue(val));			
 		}
diff --git a/src/main/java/org/olat/core/gui/components/table/DefaultXlsTableExporter.java b/src/main/java/org/olat/core/gui/components/table/DefaultXlsTableExporter.java
index 1f9b1acdc01..2c291cdc981 100644
--- a/src/main/java/org/olat/core/gui/components/table/DefaultXlsTableExporter.java
+++ b/src/main/java/org/olat/core/gui/components/table/DefaultXlsTableExporter.java
@@ -28,7 +28,6 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.util.Date;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.media.MediaResource;
 import org.olat.core.gui.render.StringOutput;
 import org.olat.core.gui.translator.Translator;
@@ -111,7 +110,7 @@ public class DefaultXlsTableExporter implements TableExporter {
 				cellValue = StringHelper.stripLineBreaks(cellValue);
 				cellValue = FilterFactory.getHtmlTagsFilter().filter(cellValue);
 				if(StringHelper.containsNonWhitespace(cellValue)) {
-					cellValue = StringEscapeUtils.unescapeHtml(cellValue);
+					cellValue = StringHelper.unescapeHtml(cellValue);
 					if(cellValue.length() >= 32767) {
 						cellValue = Formatter.truncate(cellValue, 32760);
 					}
diff --git a/src/main/java/org/olat/core/gui/components/table/IconCssCellRenderer.java b/src/main/java/org/olat/core/gui/components/table/IconCssCellRenderer.java
index e39c9774283..b5b80cd049c 100644
--- a/src/main/java/org/olat/core/gui/components/table/IconCssCellRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/table/IconCssCellRenderer.java
@@ -29,7 +29,6 @@ import static org.olat.core.util.StringHelper.blankIfNull;
 
 import java.util.Locale;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent;
 import org.olat.core.gui.render.Renderer;
@@ -60,7 +59,7 @@ public abstract class IconCssCellRenderer implements CustomCellRenderer, FlexiCe
 			String hoverText = getHoverText(cellValue);
 			if (StringHelper.containsNonWhitespace(hoverText)) {
 				target.append(" title=\"");
-				target.append(StringEscapeUtils.escapeHtml(hoverText));
+				target.appendHtmlEscaped(hoverText);
 			}
 			target.append("\">");
 			target.append("<i class='").append(blankIfNull(getCssClass(cellValue))).append("'> </i> <span>");
@@ -85,7 +84,7 @@ public abstract class IconCssCellRenderer implements CustomCellRenderer, FlexiCe
 			String hoverText = getHoverText(val);
 			if (StringHelper.containsNonWhitespace(hoverText)) {
 				sb.append(" title=\"");
-				sb.append(StringEscapeUtils.escapeHtml(hoverText));
+				sb.appendHtmlEscaped(hoverText);
 			}
 			sb.append("\">");
 			sb.append(blankIfNull(getCellValue(val)));
diff --git a/src/main/java/org/olat/core/gui/components/table/IconedTypeCellRenderer.java b/src/main/java/org/olat/core/gui/components/table/IconedTypeCellRenderer.java
index 054684bc56f..77adf10ce5b 100644
--- a/src/main/java/org/olat/core/gui/components/table/IconedTypeCellRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/table/IconedTypeCellRenderer.java
@@ -28,7 +28,6 @@ package org.olat.core.gui.components.table;
 
 import java.util.Locale;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.render.Renderer;
 import org.olat.core.gui.render.StringOutput;
 
@@ -55,8 +54,8 @@ public abstract class IconedTypeCellRenderer implements CustomCellRenderer {
 				Renderer.renderStaticURI(sb, iconPath);
 				sb.append(DOUBLE_QUOTES);
 				if (altText != null) {
-					sb.append(" alt=\"").append(StringEscapeUtils.escapeHtml(altText)).append(DOUBLE_QUOTES);
-					sb.append(" title= \"").append(StringEscapeUtils.escapeHtml(altText)).append(DOUBLE_QUOTES);
+					sb.append(" alt=\"").appendHtmlEscaped(altText).append(DOUBLE_QUOTES);
+					sb.append(" title= \"").appendHtmlEscaped(altText).append(DOUBLE_QUOTES);
 				}
 			}
 			sb.append(" />");			
diff --git a/src/main/java/org/olat/core/gui/components/table/TableRenderer.java b/src/main/java/org/olat/core/gui/components/table/TableRenderer.java
index 2d7fd13f698..d2e4e280a4d 100644
--- a/src/main/java/org/olat/core/gui/components/table/TableRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/table/TableRenderer.java
@@ -28,7 +28,6 @@ package org.olat.core.gui.components.table;
 
 import java.util.List;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.DefaultComponentRenderer;
 import org.olat.core.gui.components.form.flexible.impl.NameValuePair;
@@ -40,6 +39,7 @@ import org.olat.core.gui.render.URLBuilder;
 import org.olat.core.gui.translator.Translator;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
+import org.olat.core.util.StringHelper;
 
 /**
  * enclosing_type Description: <br>
@@ -138,7 +138,7 @@ public class TableRenderer extends DefaultComponentRenderer {
 				String multiSelectActionIdentifer = action.getAction();
 				String value;
 				if(action.getI18nKey() != null) {
-					value = StringEscapeUtils.escapeHtml(translator.translate(action.getI18nKey()));
+					value = StringHelper.escapeHtml(translator.translate(action.getI18nKey()));
 				} else {
 					value = action.getLabel();
 				}
diff --git a/src/main/java/org/olat/core/gui/components/table/TableSortRenderer.java b/src/main/java/org/olat/core/gui/components/table/TableSortRenderer.java
index ceffa1c9a67..e1ebb5d91c0 100644
--- a/src/main/java/org/olat/core/gui/components/table/TableSortRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/table/TableSortRenderer.java
@@ -19,7 +19,6 @@
  */
 package org.olat.core.gui.components.table;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.DefaultComponentRenderer;
 import org.olat.core.gui.render.RenderResult;
@@ -63,7 +62,7 @@ class TableSortRenderer extends DefaultComponentRenderer {
 	              .append(formName).append("','").append(Table.FORM_CMD).append("','").append(Table.COMMAND_SORTBYCOLUMN)
 	              .append("','").append(Table.FORM_PARAM).append("','").append(i).append("'); return false;\"")
 				  .append(" title=\"")
-				  .append(StringEscapeUtils.escapeHtml(translator.translate("row.sort"))).append("\">");
+				  .appendHtmlEscaped(translator.translate("row.sort")).append("\">");
 				
 				if(sortedCD == cd) {
 					if(asc) {
diff --git a/src/main/java/org/olat/core/gui/components/tree/MenuTreeRenderer.java b/src/main/java/org/olat/core/gui/components/tree/MenuTreeRenderer.java
index 966c8de9d26..e1fd3f42553 100644
--- a/src/main/java/org/olat/core/gui/components/tree/MenuTreeRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/tree/MenuTreeRenderer.java
@@ -40,7 +40,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.DefaultComponentRenderer;
 import org.olat.core.gui.components.form.flexible.impl.FormEvent;
@@ -335,7 +334,7 @@ public class MenuTreeRenderer extends DefaultComponentRenderer {
 		String alt = curRoot.getAltText();
 		if (alt != null) {
 			target.append(" title=\"")
-			      .append(StringEscapeUtils.escapeHtml(alt))
+			      .appendHtmlEscaped(alt)
 			      .append("\"");
 		}
 		target.append(">");
diff --git a/src/main/java/org/olat/core/gui/control/floatingresizabledialog/FloatingResizableDialogController.java b/src/main/java/org/olat/core/gui/control/floatingresizabledialog/FloatingResizableDialogController.java
index de95c070a8f..54fed3fecdf 100644
--- a/src/main/java/org/olat/core/gui/control/floatingresizabledialog/FloatingResizableDialogController.java
+++ b/src/main/java/org/olat/core/gui/control/floatingresizabledialog/FloatingResizableDialogController.java
@@ -29,7 +29,6 @@ import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
 import java.util.StringTokenizer;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.htmlheader.jscss.JSAndCSSComponent;
@@ -137,7 +136,7 @@ public class FloatingResizableDialogController extends BasicController {
 		wrapper.contextPut("offsetX", this.offsetX);
 		wrapper.contextPut("offsetY", this.offsetY);
 		wrapper.contextPut("title", escapedTitle);
-		wrapper.contextPut("collabsibleContentPanelTitel", StringEscapeUtils.escapeHtml(collabsibleContentPanelTitel));
+		wrapper.contextPut("collabsibleContentPanelTitel", StringHelper.escapeHtml(collabsibleContentPanelTitel));
 		wrapper.contextPut("resizable", resizable);
 		wrapper.contextPut("constrain", constrain);
 		wrapper.contextPut("scroll", Boolean.valueOf(autoScroll).toString());
diff --git a/src/main/java/org/olat/core/gui/control/generic/closablewrapper/CloseableCalloutWindowController.java b/src/main/java/org/olat/core/gui/control/generic/closablewrapper/CloseableCalloutWindowController.java
index c63d92faab6..47c745f3688 100644
--- a/src/main/java/org/olat/core/gui/control/generic/closablewrapper/CloseableCalloutWindowController.java
+++ b/src/main/java/org/olat/core/gui/control/generic/closablewrapper/CloseableCalloutWindowController.java
@@ -21,7 +21,6 @@ package org.olat.core.gui.control.generic.closablewrapper;
 
 import java.util.List;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.form.flexible.elements.FormLink;
@@ -36,6 +35,7 @@ import org.olat.core.gui.control.controller.BasicController;
 import org.olat.core.gui.control.util.ZIndexWrapper;
 import org.olat.core.gui.render.ValidationResult;
 import org.olat.core.logging.OLATRuntimeException;
+import org.olat.core.util.StringHelper;
 
 /**
  * Description:<br>
@@ -122,7 +122,7 @@ public class CloseableCalloutWindowController extends BasicController {
 			calloutVC.contextPut("closable", Boolean.toString(closable));
 			calloutVC.contextPut("cssClasses", (cssClasses == null ? "small" : cssClasses));
 			if (title != null) {
-				String escapedTitle = StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml(title));
+				String escapedTitle = StringHelper.escapeJavaScript(StringHelper.escapeHtml(title));
 				calloutVC.contextPut("title", escapedTitle);
 			}
 			putInitialPanel(calloutVC);
diff --git a/src/main/java/org/olat/core/gui/control/generic/textmarker/TextMarkerJsGenerator.java b/src/main/java/org/olat/core/gui/control/generic/textmarker/TextMarkerJsGenerator.java
index 9e524e43fab..dacdd977fd5 100644
--- a/src/main/java/org/olat/core/gui/control/generic/textmarker/TextMarkerJsGenerator.java
+++ b/src/main/java/org/olat/core/gui/control/generic/textmarker/TextMarkerJsGenerator.java
@@ -29,7 +29,6 @@ package org.olat.core.gui.control.generic.textmarker;
 import java.util.Iterator;
 import java.util.List;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.commons.modules.glossary.GlossaryItem;
 import org.olat.core.commons.modules.glossary.GlossaryItemManager;
@@ -74,7 +73,7 @@ public class TextMarkerJsGenerator {
 			sb.append("new Array(\"");
 			for (Iterator<String> iterator2 = allHighlightStrings.iterator(); iterator2.hasNext();) {
 				String termFlexionSynonym = iterator2.next();
-				String javaEscapedTermFlexionSynonym = StringEscapeUtils.escapeJava(termFlexionSynonym);
+				String javaEscapedTermFlexionSynonym = StringHelper.escapeJava(termFlexionSynonym);
 				sb.append(javaEscapedTermFlexionSynonym).append("\"");
 				if(!termFlexionSynonym.equals(javaEscapedTermFlexionSynonym)) {
 					String htmlEscapedTermFlexionSynonym = StringHelper.escapeHtml(termFlexionSynonym);
diff --git a/src/main/java/org/olat/core/gui/render/StringOutput.java b/src/main/java/org/olat/core/gui/render/StringOutput.java
index b2f2ec1fbc1..58b2db23215 100644
--- a/src/main/java/org/olat/core/gui/render/StringOutput.java
+++ b/src/main/java/org/olat/core/gui/render/StringOutput.java
@@ -30,10 +30,8 @@ import java.io.IOException;
 import java.io.Reader;
 import java.io.Writer;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.form.flexible.impl.FormJSHelper;
-import org.olat.core.logging.OLog;
-import org.olat.core.logging.Tracing;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.filter.impl.OWASPAntiSamyXSSFilter;
 
 /**
@@ -41,8 +39,6 @@ import org.olat.core.util.filter.impl.OWASPAntiSamyXSSFilter;
  */
 public class StringOutput extends Writer {
 	
-	private static final OLog log = Tracing.createLoggerFor(StringOutput.class);
-
 	private final StringBuilder sb;
 
 	/**
@@ -182,11 +178,7 @@ public class StringOutput extends Writer {
 	 * @return Itself
 	 */
 	public StringOutput appendHtmlEscaped(String str) {
-		try {
-			StringEscapeUtils.escapeHtml(this, str);
-		} catch (IOException e) {
-			log.error("Error escaping HTML", e);
-		}
+		StringHelper.escapeHtml(this, str);
 		return this;
 	}
 	
diff --git a/src/main/java/org/olat/core/gui/render/velocity/VelocityRenderDecorator.java b/src/main/java/org/olat/core/gui/render/velocity/VelocityRenderDecorator.java
index 407daf2530d..6e144169a37 100644
--- a/src/main/java/org/olat/core/gui/render/velocity/VelocityRenderDecorator.java
+++ b/src/main/java/org/olat/core/gui/render/velocity/VelocityRenderDecorator.java
@@ -36,7 +36,6 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.UUID;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.commons.services.help.HelpModule;
 import org.olat.core.gui.components.Component;
@@ -461,7 +460,7 @@ public class VelocityRenderDecorator implements Closeable {
 			Locale locale = renderer.getTranslator().getLocale();
 			String url = getHelpModule().getHelpProvider().getURL(locale, page);
 			if(url != null) {
-				String title = StringEscapeUtils.escapeHtml(renderer.getTranslator().translate("help.button"));
+				String title = StringHelper.escapeHtml(renderer.getTranslator().translate("help.button"));
 				sb.append("<span class=\"o_chelp_wrapper\">")
 				  .append("<a href=\"").append(url)
 				  .append("\" class=\"o_chelp\" target=\"_blank\" title=\"").append(title).append("\"><i class='o_icon o_icon_help'></i> ")
@@ -707,7 +706,7 @@ public class VelocityRenderDecorator implements Closeable {
 	 * @return
 	 */
 	public String translateInAttribute(String key) {
-		return StringEscapeUtils.escapeHtml(translate(key));
+		return StringHelper.escapeHtml(translate(key));
 	}
 
 	/** 
diff --git a/src/main/java/org/olat/core/util/StringHelper.java b/src/main/java/org/olat/core/util/StringHelper.java
index 94a6d495d23..935e94f1609 100644
--- a/src/main/java/org/olat/core/util/StringHelper.java
+++ b/src/main/java/org/olat/core/util/StringHelper.java
@@ -46,7 +46,6 @@ import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.id.Identity;
 import org.olat.core.logging.AssertException;
 import org.olat.core.logging.OLog;
@@ -96,7 +95,7 @@ public class StringHelper {
 	 * @return List
 	 */
 	public static List<String> getParts(String in, String delim) {
-		List<String> li = new ArrayList<String>();
+		List<String> li = new ArrayList<>();
 		String part;
 		int delimlen = delim.length();
 		int oldpos = 0;
@@ -398,17 +397,25 @@ public class StringHelper {
 	}
 	
 	public static final String escapeHtml(String str) {
-		return StringEscapeUtils.escapeHtml(str);
+		return org.apache.commons.text.StringEscapeUtils.escapeHtml4(str);
+	}
+	
+	public static final String unescapeHtml(String str) {
+		return org.apache.commons.text.StringEscapeUtils.unescapeHtml4(str);
 	}
 	
 	public static final void escapeHtml(Writer writer, String str) {
 		try {
-			StringEscapeUtils.escapeHtml(writer, str);
+			org.apache.commons.text.StringEscapeUtils.ESCAPE_HTML4.translate(str, writer);
 		} catch (IOException e) {
 			log.error("Error escaping HTML", e);
 		}
 	}
 	
+	public static final String escapeXml(String str) {
+		return org.apache.commons.text.StringEscapeUtils.escapeXml11(str);
+	}
+	
 	public static final String xssScan(String str) {
 		return new OWASPAntiSamyXSSFilter().filter(str);
 	}
@@ -425,13 +432,17 @@ public class StringHelper {
 		return filter.getNumOfErrors() > 0;
 	}
 	
+	public static final String escapeJava(String str) {
+		return org.apache.commons.text.StringEscapeUtils.escapeJava(str);
+	}
+	
 	public static final String escapeJavaScript(String str) {
-		return StringEscapeUtils.escapeJavaScript(str);
+		return org.apache.commons.text.StringEscapeUtils.escapeEcmaScript(str);
 	}
 	
 	public static final void escapeJavaScript(Writer writer, String str) {
 		try {
-			StringEscapeUtils.escapeJavaScript(writer, str);
+			org.apache.commons.text.StringEscapeUtils.ESCAPE_ECMASCRIPT.translate(str, writer);
 		} catch (IOException e) {
 			log.error("Error escaping JavaScript", e);
 		}
@@ -488,25 +499,26 @@ public class StringHelper {
 	
 	public static String cleanUTF8ForXml(String string) {
 		if(string == null) return null;
-		if(string.length() == 0) return string;
 		
-		StringBuilder sb = new StringBuilder();
-		char[] charArr = string.toCharArray();
-		int numOfCharacters = charArr.length;
-		for(int i=0; i<numOfCharacters; i++) {
-			char ch = charArr[i];
+		int length = string.length();
+		if(length == 0) return string;
+
+		StringBuilder sb = new StringBuilder(length);
+		for(int i=0; i<length; i++) {
+			int ch = string.codePointAt(i);
 			if(ch < 32) {
 				switch(ch) {
-					case '\n': sb.append(ch); break;//0x000A
-					case '\t': sb.append(ch); break;//0x0009
-					case '\r': sb.append(ch); break;//0x000D
+					case '\n': //0x000A
+					case '\t': //0x0009
+					case '\r': sb.appendCodePoint(ch); break;//0x000D
+					default: // dump them
 				}
 			} else if(ch >= 0x0020 && ch <= 0xD7FF) {
-				sb.append(ch);
+				sb.appendCodePoint(ch);
 			} else if(ch >= 0xE000 && ch <= 0xFFFD) {
-				sb.append(ch);
+				sb.appendCodePoint(ch);
 			} else if(ch >= 0x10000 && ch <= 0x10FFFF) {
-				sb.append(ch);
+				sb.appendCodePoint(ch);
 			}
 		}
 		return sb.toString();
diff --git a/src/main/java/org/olat/core/util/i18n/ui/InlineTranslationInterceptHandlerController.java b/src/main/java/org/olat/core/util/i18n/ui/InlineTranslationInterceptHandlerController.java
index c65e010f507..cd22ad08a27 100644
--- a/src/main/java/org/olat/core/util/i18n/ui/InlineTranslationInterceptHandlerController.java
+++ b/src/main/java/org/olat/core/util/i18n/ui/InlineTranslationInterceptHandlerController.java
@@ -24,7 +24,6 @@ import java.util.Locale;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
@@ -390,7 +389,7 @@ public class InlineTranslationInterceptHandlerController extends BasicController
 
 			// Case 4: default case: normal translation, surround with inline
 			// translation link
-			StringBuffer tmp = new StringBuffer();
+			StringBuilder tmp = new StringBuilder();
 			tmp.append(stringWithMarkup.substring(0, startSPos));
 			tmp.append(SPAN_TRANSLATION_I18NITEM_OPEN);
 			tmp.append(link);
@@ -417,7 +416,7 @@ public class InlineTranslationInterceptHandlerController extends BasicController
 	 */
 	private static String replaceItemWithHTMLMarkupSurrounded(String stringWithMarkup, StringOutput link, int startSPos, int startEPos,
 			int endSPos, int endEPos, int wrapperOpen, int wrapperClose) {
-		StringBuffer tmp = new StringBuffer();
+		StringBuilder tmp = new StringBuilder();
 		tmp.append(stringWithMarkup.substring(0, wrapperOpen));
 		tmp.append(SPAN_TRANSLATION_I18NITEM_OPEN);
 		tmp.append(link);
@@ -441,7 +440,7 @@ public class InlineTranslationInterceptHandlerController extends BasicController
 	 * @return
 	 */
 	private static String replaceItemWithoutHTMLMarkup(String stringWithMarkup, int startSPos, int startEPos, int endSPos, int endEPos) {
-		StringBuffer tmp = new StringBuffer();
+		StringBuilder tmp = new StringBuilder();
 		tmp.append(stringWithMarkup.substring(0, startSPos));
 		tmp.append(stringWithMarkup.substring(startEPos, endSPos));
 		tmp.append(stringWithMarkup.substring(endEPos));
@@ -465,9 +464,9 @@ public class InlineTranslationInterceptHandlerController extends BasicController
 			link.append("\" title=\"");
 			String combinedKey = arguments[0] + ":" + arguments[1];
 			if (CoreSpringFactory.getImpl(I18nModule.class).isTransToolEnabled()) {
-				link.append(StringEscapeUtils.escapeHtml(inlineTrans.translate("inline.translate", new String[] { combinedKey })));
+				link.appendHtmlEscaped(inlineTrans.translate("inline.translate", new String[] { combinedKey }));
 			} else {
-				link.append(StringEscapeUtils.escapeHtml(inlineTrans.translate("inline.customize.translate", new String[] { combinedKey })));			
+				link.appendHtmlEscaped(inlineTrans.translate("inline.customize.translate", new String[] { combinedKey }));			
 			}
 			link.append("\"><i class='o_icon o_icon_translation_item'> </i></a>");			
 	}
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentDataModel.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentDataModel.java
index 90eeac2bf37..f29ba73534b 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentDataModel.java
+++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentDataModel.java
@@ -26,7 +26,6 @@ import java.util.Date;
 import java.util.List;
 import java.util.Locale;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.commons.persistence.SortKey;
 import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter;
 import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement;
@@ -347,7 +346,7 @@ public class CheckListAssessmentDataModel extends DefaultFlexiTableDataModel<Che
 				cellValue = StringHelper.stripLineBreaks(cellValue);
 				cellValue = FilterFactory.getHtmlTagsFilter().filter(cellValue);
 				if(StringHelper.containsNonWhitespace(cellValue)) {
-					cellValue = StringEscapeUtils.unescapeHtml(cellValue);
+					cellValue = StringHelper.unescapeHtml(cellValue);
 				}
 				dataRow.addCell(sheetCol, cellValue, null);
 			}
diff --git a/src/main/java/org/olat/course/nodes/fo/FOPeekviewController.java b/src/main/java/org/olat/course/nodes/fo/FOPeekviewController.java
index bc7b8157050..b453cbfc96f 100644
--- a/src/main/java/org/olat/course/nodes/fo/FOPeekviewController.java
+++ b/src/main/java/org/olat/course/nodes/fo/FOPeekviewController.java
@@ -23,7 +23,6 @@ import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.NewControllerFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
@@ -85,7 +84,7 @@ public class FOPeekviewController extends BasicController implements Controller
 		// add items, only as many as configured
 		List<MessagePeekview> messages = forumManager.getPeekviewMessages(forum, itemsToDisplay);
 		// only take the configured amount of messages
-		List<MessageView> views = new ArrayList<MessageView>(itemsToDisplay);
+		List<MessageView> views = new ArrayList<>(itemsToDisplay);
 		for (MessagePeekview message :messages) {
 			// add link to item
 			// Add link to jump to course node
@@ -98,7 +97,7 @@ public class FOPeekviewController extends BasicController implements Controller
 			String body = message.getBody();
 			if(body.length() > 256) {
 				String truncateBody = FilterFactory.getHtmlTagsFilter().filter(body);
-				truncateBody = StringEscapeUtils.unescapeHtml(truncateBody);// remove entities
+				truncateBody = StringHelper.unescapeHtml(truncateBody);// remove entities
 				if(truncateBody.length() < 256) {
 					body = StringHelper.xssScan(body);
 				} else {
diff --git a/src/main/java/org/olat/course/nodes/info/InfoPeekViewController.java b/src/main/java/org/olat/course/nodes/info/InfoPeekViewController.java
index 225d0551255..3e315be5877 100644
--- a/src/main/java/org/olat/course/nodes/info/InfoPeekViewController.java
+++ b/src/main/java/org/olat/course/nodes/info/InfoPeekViewController.java
@@ -24,7 +24,6 @@ import java.text.DateFormat;
 import java.util.List;
 import java.util.Locale;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.commons.info.InfoMessage;
 import org.olat.commons.info.InfoMessageFrontendManager;
 import org.olat.core.gui.UserRequest;
@@ -179,7 +178,7 @@ public class InfoPeekViewController extends BasicController {
 				boolean tooltip = StringHelper.containsNonWhitespace(item.getMessage());
 				if(tooltip) {
 					String message = Formatter.escWithBR(Formatter.truncate(item.getMessage(), 255)).toString();
-					sb.append("<span title=\"").append(StringEscapeUtils.escapeHtml(message)).append("\">");
+					sb.append("<span title=\"").appendHtmlEscaped(message).append("\">");
 				} else {
 					sb.append("<span>");
 				}
diff --git a/src/main/java/org/olat/course/statistic/IndentedStatisticNodeRenderer.java b/src/main/java/org/olat/course/statistic/IndentedStatisticNodeRenderer.java
index aa4d40293ad..060f1ffab74 100644
--- a/src/main/java/org/olat/course/statistic/IndentedStatisticNodeRenderer.java
+++ b/src/main/java/org/olat/course/statistic/IndentedStatisticNodeRenderer.java
@@ -28,17 +28,14 @@ package org.olat.course.statistic;
 import java.util.Locale;
 import java.util.Map;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.table.CustomCellRenderer;
 import org.olat.core.gui.render.Renderer;
 import org.olat.core.gui.render.StringOutput;
 import org.olat.core.gui.translator.Translator;
-import org.olat.core.util.StringHelper;
 import org.olat.course.assessment.AssessmentHelper;
 import org.olat.course.nodes.CourseNodeFactory;
 
 /**
- *@TODO
  * Copy/Pasted class from assessment.IndentedNodeRenderer.
  * <p>
  * The idea was not to disturb anything in the assessment area - but it is 
@@ -104,7 +101,7 @@ public class IndentedStatisticNodeRenderer implements CustomCellRenderer {
 		Integer indent = (Integer) nodeData.get(AssessmentHelper.KEY_INDENT);
 		String type = (String)  nodeData.get(AssessmentHelper.KEY_TYPE);
 		if (type==null) {
-			sb.append(StringHelper.escapeHtml(title));
+			sb.appendHtmlEscaped(title);
 			return;
 		}
 		appendIndent(sb,indent);
@@ -112,9 +109,9 @@ public class IndentedStatisticNodeRenderer implements CustomCellRenderer {
 		String cssClass = CourseNodeFactory.getInstance().getCourseNodeConfigurationEvenForDisabledBB(type).getIconCSSClass();
 		sb.append("<i class='o_icon ").append(cssClass).append("'> </i> <span ");
 		if (altText != null) {
-			sb.append("title= \"").append(StringEscapeUtils.escapeHtml(altText));
+			sb.append("title= \"").appendHtmlEscaped(altText);
 		}
-		sb.append("\">").append(StringHelper.escapeHtml(title)).append("</span>");
+		sb.append("\">").appendHtmlEscaped(title).append("</span>");
 	}
 	
 	private void appendIndent(StringOutput sb, Integer indent) {
diff --git a/src/main/java/org/olat/group/ui/edit/BusinessGroupEditController.java b/src/main/java/org/olat/group/ui/edit/BusinessGroupEditController.java
index ae44a82aea9..ef77de96e97 100644
--- a/src/main/java/org/olat/group/ui/edit/BusinessGroupEditController.java
+++ b/src/main/java/org/olat/group/ui/edit/BusinessGroupEditController.java
@@ -27,7 +27,6 @@ package org.olat.group.ui.edit;
 
 import java.util.List;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.panel.Panel;
@@ -49,6 +48,7 @@ import org.olat.core.id.context.StateEntry;
 import org.olat.core.logging.AssertException;
 import org.olat.core.logging.activity.ActionType;
 import org.olat.core.logging.activity.ThreadLocalUserActivityLogger;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
 import org.olat.core.util.coordinate.CoordinatorManager;
 import org.olat.core.util.coordinate.LockResult;
@@ -144,7 +144,7 @@ public class BusinessGroupEditController extends BasicController implements Cont
 				setAllTabs(ureq);
 				mainVC = createVelocityContainer("edit");
 				mainVC.put("tabbedpane", tabbedPane);
-				String[] title = new String[] { StringEscapeUtils.escapeHtml(currBusinessGroup.getName()) };
+				String[] title = new String[] { StringHelper.escapeHtml(currBusinessGroup.getName()) };
 				mainVC.contextPut("title", getTranslator().translate("group.edit.title", title));
 				putInitialPanel(mainVC);
 			}
diff --git a/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType1.java b/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType1.java
index 3154ae23194..97ebb2a43bc 100644
--- a/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType1.java
+++ b/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType1.java
@@ -33,7 +33,6 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.id.User;
 import org.olat.core.id.context.BusinessControlFactory;
 import org.olat.core.id.context.ContextEntry;
@@ -120,7 +119,7 @@ public class QTIExportFormatterCSVType1 extends QTIExportFormatter {
 				if (question.length() > cut) {
 					question = question.substring(0, cut) + "...";
 				}
-				question = StringEscapeUtils.unescapeHtml(question);
+				question = StringHelper.unescapeHtml(question);
 				hR1.append(": " + escape(question));
 				// CELFI#107 END
 
@@ -362,7 +361,7 @@ public class QTIExportFormatterCSVType1 extends QTIExportFormatter {
 				question = FilterFactory.getXSSFilter(-1).filter(question);
 				question = FilterFactory.getHtmlTagsFilter().filter(question);
 			}
-			question = StringEscapeUtils.unescapeHtml(question);
+			question = StringHelper.unescapeHtml(question);
 			sb.append(question);
 			sb.append(car);
 			// CELFI#107 END
@@ -381,7 +380,7 @@ public class QTIExportFormatterCSVType1 extends QTIExportFormatter {
 
 				if (responseLabelMaterials != null) {
 					String s = responseLabelMaterials.get(i);
-					s = StringEscapeUtils.unescapeHtml(s);
+					s = StringHelper.unescapeHtml(s);
 					if (tagless) {
 						s = s.replaceAll("\\<.*?\\>", "");
 					}
diff --git a/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType3.java b/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType3.java
index e5b056971d4..5c347a9073c 100644
--- a/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType3.java
+++ b/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType3.java
@@ -32,9 +32,9 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.logging.OLATRuntimeException;
 import org.olat.core.util.Formatter;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.filter.FilterFactory;
 import org.olat.ims.qti.editor.beecom.parser.ItemParser;
 import org.olat.ims.qti.export.helper.IdentityAnonymizerCallback;
@@ -112,7 +112,7 @@ public class QTIExportFormatterCSVType3 extends QTIExportFormatter {
 				if (question.length() > cut) {
 					question = question.substring(0, cut) + "...";
 				}
-				question = StringEscapeUtils.unescapeHtml(question);
+				question = StringHelper.unescapeHtml(question);
 				hR1.append(": " + escape(question));
 				// CELFI#107 END
 				
@@ -271,7 +271,7 @@ public class QTIExportFormatterCSVType3 extends QTIExportFormatter {
 				question = FilterFactory.getXSSFilter(-1).filter(question);
 				question = FilterFactory.getHtmlTagsFilter().filter(question);
 			}
-			question = StringEscapeUtils.unescapeHtml(question);
+			question = StringHelper.unescapeHtml(question);
 			sb.append(question);
 			sb.append(car);
 			// CELFI#107 END
@@ -290,7 +290,7 @@ public class QTIExportFormatterCSVType3 extends QTIExportFormatter {
 				
 				if(responseLabelMaterials != null){
 					String s = responseLabelMaterials.get(i);
-					s = StringEscapeUtils.unescapeHtml(s);
+					s = StringHelper.unescapeHtml(s);
 					if(tagless){
 						s = s.replaceAll("\\<.*?\\>", "");
 					}
diff --git a/src/main/java/org/olat/ims/qti21/model/xml/interactions/FIBAssessmentItemBuilder.java b/src/main/java/org/olat/ims/qti21/model/xml/interactions/FIBAssessmentItemBuilder.java
index 59d41453b5d..e1b9be1ce4f 100644
--- a/src/main/java/org/olat/ims/qti21/model/xml/interactions/FIBAssessmentItemBuilder.java
+++ b/src/main/java/org/olat/ims/qti21/model/xml/interactions/FIBAssessmentItemBuilder.java
@@ -36,7 +36,6 @@ import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.DoubleAdder;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.render.StringOutput;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
@@ -399,7 +398,7 @@ public class FIBAssessmentItemBuilder extends AssessmentItemBuilder {
 	}
 	
 	public String unescapeDataQtiSolution(String solution) {
-		return StringEscapeUtils.unescapeHtml(solution).replace("\u2215", "/");
+		return StringHelper.unescapeHtml(solution).replace("\u2215", "/");
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/ims/qti21/pool/QTI12To21Converter.java b/src/main/java/org/olat/ims/qti21/pool/QTI12To21Converter.java
index 111849690f2..c8fad85f4ba 100644
--- a/src/main/java/org/olat/ims/qti21/pool/QTI12To21Converter.java
+++ b/src/main/java/org/olat/ims/qti21/pool/QTI12To21Converter.java
@@ -42,7 +42,6 @@ import javax.xml.stream.XMLOutputFactory;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.cyberneko.html.parsers.SAXParser;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.translator.Translator;
@@ -789,7 +788,7 @@ public class QTI12To21Converter {
 				}
 				
 			} else {
-				text = StringEscapeUtils.unescapeHtml(text);
+				text = StringHelper.unescapeHtml(text);
 			}
 		}
 		return text;
diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java
index 0695aa9b651..447060d05f6 100644
--- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java
+++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java
@@ -61,7 +61,6 @@ import java.util.List;
 import javax.xml.transform.sax.TransformerHandler;
 import javax.xml.transform.stream.StreamResult;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.velocity.VelocityContext;
 import org.apache.velocity.context.Context;
 import org.olat.core.CoreSpringFactory;
@@ -248,7 +247,7 @@ public abstract class AssessmentObjectComponentRenderer extends DefaultComponent
 	
 	private void renderItemStatusMessage(String status, String i18nKey, StringOutput sb, Translator translator) {
 		String title = translator.translate(i18nKey);
-		sb.append("<span class='o_assessmentitem_status ").append(status).append(" ' title=\"").append(StringEscapeUtils.escapeHtml(title))
+		sb.append("<span class='o_assessmentitem_status ").append(status).append(" ' title=\"").append(StringHelper.escapeHtml(title))
 		.append("\"><i class='o_icon o_icon-fw o_icon_qti_").append(status).append("'> </i><span>").append(title).append("</span></span>");
 	}
 	
@@ -1476,7 +1475,7 @@ public abstract class AssessmentObjectComponentRenderer extends DefaultComponent
 				renderEndTag(out, fElement);
 			}
 		} else if(mathElement instanceof TextRun) {
-			out.append(StringEscapeUtils.escapeXml(((TextRun)mathElement).getTextContent()));
+			out.append(StringHelper.escapeXml(((TextRun)mathElement).getTextContent()));
 		}
 	}
 	
diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTestComponentRenderer.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTestComponentRenderer.java
index f3de9169f2b..946ad379a5a 100644
--- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTestComponentRenderer.java
+++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTestComponentRenderer.java
@@ -38,7 +38,6 @@ import javax.xml.transform.TransformerFactoryConfigurationError;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.form.flexible.impl.Form;
 import org.olat.core.gui.components.form.flexible.impl.FormJSHelper;
@@ -750,7 +749,7 @@ public class AssessmentTestComponentRenderer extends AssessmentObjectComponentRe
 	
 	private void renderItemStatusMessage(String status, String i18nKey, StringOutput sb, Translator translator) {
 		String title = translator.translate(i18nKey);
-		sb.append("<span class='o_assessmentitem_status ").append(status).append(" ' title=\"").append(StringEscapeUtils.escapeHtml(title))
+		sb.append("<span class='o_assessmentitem_status ").append(status).append(" ' title=\"").append(StringHelper.escapeHtml(title))
 		.append("\"><i class='o_icon o_icon-fw o_icon_qti_").append(status).append("'> </i><span>").append(title).append("</span></span>");
 	}
 
diff --git a/src/main/java/org/olat/modules/cp/CPOfflineReadableManager.java b/src/main/java/org/olat/modules/cp/CPOfflineReadableManager.java
index 33daae65014..57887924e6c 100644
--- a/src/main/java/org/olat/modules/cp/CPOfflineReadableManager.java
+++ b/src/main/java/org/olat/modules/cp/CPOfflineReadableManager.java
@@ -37,7 +37,6 @@ import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
 import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.velocity.VelocityContext;
 import org.apache.velocity.app.VelocityEngine;
 import org.apache.velocity.runtime.RuntimeConstants;
@@ -50,6 +49,7 @@ import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.ExportUtil;
 import org.olat.core.util.FileUtils;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.WebappHelper;
 import org.olat.core.util.ZipUtil;
 import org.olat.core.util.vfs.LocalFileImpl;
@@ -271,15 +271,15 @@ public class CPOfflineReadableManager {
 			sb.append("\" target=\"");
 			sb.append(FRAME_NAME_CONTENT);
 			sb.append("\" alt=\"");
-			sb.append(StringEscapeUtils.escapeHtml(altText));
+			sb.append(StringHelper.escapeHtml(altText));
 			sb.append("\" title=\"");
-			sb.append(StringEscapeUtils.escapeHtml(altText));
+			sb.append(StringHelper.escapeHtml(altText));
 			sb.append("\">");
 			sb.append(title);
 			sb.append("</a>\n");
 		} else {
 			sb.append("<span title=\"");
-			sb.append(StringEscapeUtils.escapeHtml(altText));
+			sb.append(StringHelper.escapeHtml(altText));
 			sb.append("\">");
 			sb.append(title);
 			sb.append("</span>");
diff --git a/src/main/java/org/olat/modules/fo/archiver/formatters/ForumRTFFormatter.java b/src/main/java/org/olat/modules/fo/archiver/formatters/ForumRTFFormatter.java
index 971fdd56f01..1eb69b89867 100644
--- a/src/main/java/org/olat/modules/fo/archiver/formatters/ForumRTFFormatter.java
+++ b/src/main/java/org/olat/modules/fo/archiver/formatters/ForumRTFFormatter.java
@@ -39,7 +39,6 @@ import java.util.Locale;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.id.Identity;
 import org.olat.core.id.UserConstants;
@@ -377,7 +376,7 @@ public class ForumRTFFormatter extends ForumFormatter {
 		// Remove all &nbsp;
 		Matcher tmp = HTML_SPACE_PATTERN.matcher(htmlText);
 		htmlText = tmp.replaceAll(" ");
-		htmlText = StringEscapeUtils.unescapeHtml(htmlText);
+		htmlText = StringHelper.unescapeHtml(htmlText);
 
 		return htmlText;
 	}
diff --git a/src/main/java/org/olat/modules/fo/archiver/formatters/ForumStreamedRTFFormatter.java b/src/main/java/org/olat/modules/fo/archiver/formatters/ForumStreamedRTFFormatter.java
index 49847b8ff0c..b0d0f4544c0 100644
--- a/src/main/java/org/olat/modules/fo/archiver/formatters/ForumStreamedRTFFormatter.java
+++ b/src/main/java/org/olat/modules/fo/archiver/formatters/ForumStreamedRTFFormatter.java
@@ -38,7 +38,6 @@ import java.util.zip.ZipOutputStream;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.id.Identity;
 import org.olat.core.id.UserConstants;
@@ -358,7 +357,7 @@ public class ForumStreamedRTFFormatter extends ForumFormatter {
 		// Remove all &nbsp;
 		Matcher tmp = HTML_SPACE_PATTERN.matcher(htmlText);
 		htmlText = tmp.replaceAll(" ");
-		htmlText = StringEscapeUtils.unescapeHtml(htmlText);
+		htmlText = StringHelper.unescapeHtml(htmlText);
 
 		return htmlText;
 	}
diff --git a/src/main/java/org/olat/modules/forms/ui/RubricAvgRenderer.java b/src/main/java/org/olat/modules/forms/ui/RubricAvgRenderer.java
index 5ea399dc29f..4b5bebe6eed 100644
--- a/src/main/java/org/olat/modules/forms/ui/RubricAvgRenderer.java
+++ b/src/main/java/org/olat/modules/forms/ui/RubricAvgRenderer.java
@@ -19,7 +19,6 @@
  */
 package org.olat.modules.forms.ui;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent;
@@ -70,7 +69,7 @@ public class RubricAvgRenderer implements FlexiCellRenderer {
 		target.append("'>");
 		if (ratingCss != null) {
 			target.append("<i class='o_icon o_icon-fw ").append(getRatingIconCssClass(rating)).append("' title=\"");
-			target.append(StringEscapeUtils.escapeHtml(getRatingIconExplanation(rating, rubric, translator))).append("\"> </i> ");
+			target.appendHtmlEscaped(getRatingIconExplanation(rating, rubric, translator)).append("\"> </i> ");
 		}
 		target.append(EvaluationFormFormatter.formatDouble(value));
 		target.append("</div>");
diff --git a/src/main/java/org/olat/modules/iq/IQComponentRenderer.java b/src/main/java/org/olat/modules/iq/IQComponentRenderer.java
index 5b9dcc9c1e1..369bb94b337 100644
--- a/src/main/java/org/olat/modules/iq/IQComponentRenderer.java
+++ b/src/main/java/org/olat/modules/iq/IQComponentRenderer.java
@@ -29,7 +29,6 @@ import java.util.Date;
 import java.util.List;
 import java.util.Locale;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.dom4j.Element;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.ComponentRenderer;
@@ -225,9 +224,9 @@ public class IQComponentRenderer implements ComponentRenderer {
 			
 			sb.append("<input class=\"btn btn-primary\" type=\"submit\" name=\"olat_fosm\" value=\"");
 			if (ai.isSectionPage())
-				sb.append(StringEscapeUtils.escapeHtml(translator.translate("submitMultiAnswers")));
+				sb.appendHtmlEscaped(translator.translate("submitMultiAnswers"));
 			else
-				sb.append(StringEscapeUtils.escapeHtml(translator.translate("submitSingleAnswer")));
+				sb.appendHtmlEscaped(translator.translate("submitSingleAnswer"));
 			sb.append("\"");
 			if (!displayForm) sb.append(" style=\"display: none;\"");
 			sb.append(" />")
@@ -266,7 +265,7 @@ public class IQComponentRenderer implements ComponentRenderer {
 					sb.append("<a class=\"btn btn-primary\" onclick=\"return o2cl()\" href=\"");
 					ubu.buildURI(sb, new String[] { VelocityContainer.COMMAND_ID }, new String[] { "sitsec" });
 					String title = translator.translate("next"); 
-					sb.append("\" title=\"" + StringEscapeUtils.escapeHtml(title) + "\">");
+					sb.append("\" title=\"" + StringHelper.escapeHtml(title) + "\">");
 					sb.append("<span>").append(title).append("</span>");
 					sb.append("</a>");
 				}
@@ -332,7 +331,7 @@ public class IQComponentRenderer implements ComponentRenderer {
 			sb.append("<a onclick=\"return o2cl();\" href=\"");
 			ubu.buildURI(sb, new String[] { VelocityContainer.COMMAND_ID }, new String[] { "git" });
 			sb.append("?itid="	+ itemPos	+ "&seid=" + sectionPos);
-			sb.append("\" class=\"o_sel_qti_menu_item\" title=\"" + StringEscapeUtils.escapeHtml(titleNotEscaped) + "\">");
+			sb.append("\" class=\"o_sel_qti_menu_item\" title=\"" + StringHelper.escapeHtml(titleNotEscaped) + "\">");
 		}
 		
 		sb.append("<b>" + (sectionPos + 1) + "." + (itemPos + 1) + ".</b>&nbsp;");	
@@ -351,7 +350,7 @@ public class IQComponentRenderer implements ComponentRenderer {
 			// add lock image
 			sb.append("<td>");
 			sb.append("<div class='o_qti_closed_icon' title=\"");
-			sb.append(StringEscapeUtils.escapeHtml(r.getTranslator().translate("itemclosed")));
+			sb.appendHtmlEscaped(r.getTranslator().translate("itemclosed"));
 			sb.append("\"><i class='o_icon o_icon_locked'> </i></div>");
 			sb.append("</td>");
 		} else if (info) {
@@ -360,9 +359,9 @@ public class IQComponentRenderer implements ComponentRenderer {
 			if (maxdur != -1) {
 					sb.append("<div class='o_qti_timelimit_icon' title=\"");
 					if (!itc.isStarted()) {
-						sb.append(StringEscapeUtils.escapeHtml(r.getTranslator().translate("timelimit.initial", new String[] {getFormattedLimit(maxdur)})));
+						sb.appendHtmlEscaped(r.getTranslator().translate("timelimit.initial", new String[] {getFormattedLimit(maxdur)}));
 					} else  {
-						sb.append(StringEscapeUtils.escapeHtml(r.getTranslator().translate("timelimit.running", new String[] {fdue})));
+						sb.appendHtmlEscaped(r.getTranslator().translate("timelimit.running", new String[] {fdue}));
 					}
 					sb.append("\" ><i class='o_icon o_icon_timelimit'> </i></div>");
 			}
@@ -374,7 +373,7 @@ public class IQComponentRenderer implements ComponentRenderer {
 			int attempts = itc.getTimesAnswered();
 			if (maxa != -1) { // only limited times of answers
 				sb.append("<div class='o_qti_attemptslimit_icon' title=\"");
-				sb.append(StringEscapeUtils.escapeHtml(r.getTranslator().translate("attemptsleft", new String[] {"" + (maxa - attempts)})));
+				sb.appendHtmlEscaped(r.getTranslator().translate("attemptsleft", new String[] {"" + (maxa - attempts)}));
 				sb.append("\" ><i class='o_icon o_icon_attempt_limit'> </i></div>");
 			}
 			sb.append("</td>");
@@ -433,7 +432,7 @@ public class IQComponentRenderer implements ComponentRenderer {
 			sb.append("<a onclick=\"return o2cl()\" href=\"");
 			ubu.buildURI(sb, new String[] { VelocityContainer.COMMAND_ID }, new String[] { "gse" });
 			sb.append("?seid=" + sectionPos);
-			sb.append("\" title=\"" + StringEscapeUtils.escapeHtml(sc.getTitle()) + "\">");
+			sb.append("\" title=\"" + StringHelper.escapeHtml(sc.getTitle()) + "\">");
 		}
 		sb.append("<b>" + (sectionPos + 1) + ".</b>&nbsp;");
 		sb.append(title);
@@ -446,16 +445,16 @@ public class IQComponentRenderer implements ComponentRenderer {
 		sb.append("<td>");
 		if (!sc.isOpen()) {
 			sb.append("<div class='o_qti_closed_icon' title=\"");
-			sb.append(StringEscapeUtils.escapeHtml(r.getTranslator().translate("itemclosed")));
+			sb.appendHtmlEscaped(r.getTranslator().translate("itemclosed"));
 			sb.append("\"><i class='o_icon o_icon_locked'> </i></div>");
 		} else {
 			// max duration info
 			if (maxdur != -1) {
 					sb.append("<div class='o_qti_timelimit_icon' title=\"");
 					if (!sc.isStarted()) {
-						sb.append(StringEscapeUtils.escapeHtml(r.getTranslator().translate("timelimit.initial", new String[] {getFormattedLimit(maxdur)})));
+						sb.appendHtmlEscaped(r.getTranslator().translate("timelimit.initial", new String[] {getFormattedLimit(maxdur)}));
 					} else  {
-						sb.append(StringEscapeUtils.escapeHtml(r.getTranslator().translate("timelimit.running", new String[] {fdue})));
+						sb.appendHtmlEscaped(r.getTranslator().translate("timelimit.running", new String[] {fdue}));
 					}
 					sb.append("\" ><i class='o_icon o_icon_timelimit'> </i></div>");
 			}
@@ -589,7 +588,7 @@ public class IQComponentRenderer implements ComponentRenderer {
 			int sectionPos = ac.getCurrentSectionContextPos();
 			sb.append("?itid=" + 0 + "&seid=" + sectionPos);
 			String title = translator.translate("next"); 
-			sb.append("\" title=\"" + StringEscapeUtils.escapeHtml(title) + "\">");
+			sb.append("\" title=\"" + StringHelper.escapeHtml(title) + "\">");
 			sb.append("<span>").append(title).append("</span>");
 			sb.append("</a>");
 		}		
@@ -612,7 +611,7 @@ public class IQComponentRenderer implements ComponentRenderer {
 			ubu.buildURI(sb, new String[] { VelocityContainer.COMMAND_ID }, new String[] { "gse" });
 			sb.append("?seid=" + 0);				
 			String title = translator.translate("next"); 
-			sb.append("\" title=\"" + StringEscapeUtils.escapeHtml(title) + "\">");	
+			sb.append("\" title=\"" + StringHelper.escapeHtml(title) + "\">");	
 			sb.append("<span>").append(title).append("</span>");
 			sb.append("</a>");
 		}				
diff --git a/src/main/java/org/olat/modules/video/ui/component/VideoMarkerTextCellRenderer.java b/src/main/java/org/olat/modules/video/ui/component/VideoMarkerTextCellRenderer.java
index c68d43437d3..ecf5ff6f618 100644
--- a/src/main/java/org/olat/modules/video/ui/component/VideoMarkerTextCellRenderer.java
+++ b/src/main/java/org/olat/modules/video/ui/component/VideoMarkerTextCellRenderer.java
@@ -19,7 +19,6 @@
  */
 package org.olat.modules.video.ui.component;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent;
 import org.olat.core.gui.render.Renderer;
@@ -44,7 +43,7 @@ public class VideoMarkerTextCellRenderer implements FlexiCellRenderer {
 		if(cellValue instanceof String) {
 			String val = FilterFactory.getHtmlTagsFilter().filter((String)cellValue);
 			if(val.length() > 50) {
-				val = StringEscapeUtils.unescapeHtml(val);// remove entities
+				val = StringHelper.unescapeHtml(val);// remove entities
 				val = Formatter.truncate(val, 50);// truncate
 				val = StringHelper.escapeHtml(val);
 			}
diff --git a/src/main/java/org/olat/modules/webFeed/ui/ItemsController.java b/src/main/java/org/olat/modules/webFeed/ui/ItemsController.java
index 8e9ec5cff9c..71b875c09f8 100644
--- a/src/main/java/org/olat/modules/webFeed/ui/ItemsController.java
+++ b/src/main/java/org/olat/modules/webFeed/ui/ItemsController.java
@@ -26,7 +26,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.NewControllerFactory;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.commons.controllers.navigation.Dated;
@@ -59,6 +58,7 @@ import org.olat.core.id.context.ContextEntry;
 import org.olat.core.id.context.StateEntry;
 import org.olat.core.logging.activity.ThreadLocalUserActivityLogger;
 import org.olat.core.util.CodeHelper;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.coordinate.LockResult;
 import org.olat.modules.portfolio.PortfolioV2Module;
 import org.olat.modules.portfolio.ui.component.MediaCollectorComponent;
@@ -346,7 +346,7 @@ public class ItemsController extends BasicController implements Activateable2 {
 		itemLink_more.setUserObject(item);
 
 		Link itemLink_title = LinkFactory.createCustomLink("titlelink.to." + guid, "titlelink.to." + guid,
-				StringEscapeUtils.escapeHtml(item.getTitle()), Link.NONTRANSLATED, vcItems, this);
+				StringHelper.escapeHtml(item.getTitle()), Link.NONTRANSLATED, vcItems, this);
 		itemLink_title.setUserObject(item);
 
 		itemLinks.add(itemLink_title);
diff --git a/src/main/java/org/olat/note/NotesPortletRunController.java b/src/main/java/org/olat/note/NotesPortletRunController.java
index 07efc0564de..5a80b9d0645 100644
--- a/src/main/java/org/olat/note/NotesPortletRunController.java
+++ b/src/main/java/org/olat/note/NotesPortletRunController.java
@@ -32,7 +32,6 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.NewControllerFactory;
 import org.olat.core.commons.fullWebApp.LayoutMain3ColsController;
 import org.olat.core.commons.fullWebApp.popup.BaseFullWebappPopupLayoutFactory;
@@ -62,6 +61,7 @@ import org.olat.core.id.Identity;
 import org.olat.core.id.OLATResourceable;
 import org.olat.core.id.context.BusinessControl;
 import org.olat.core.id.context.BusinessControlFactory;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.coordinate.CoordinatorManager;
 import org.olat.core.util.event.GenericEventListener;
 import org.olat.core.util.resource.OresHelper;
@@ -292,7 +292,7 @@ public class NotesPortletRunController extends AbstractPortletRunController<Note
 			public int compare(final Note note1, final Note note2) {	
 				int comparisonResult = 0;
 			  if(criteria.getSortingTerm()==SortingCriteria.ALPHABETICAL_SORTING) {			  	
-			  	comparisonResult = collator.compare(StringEscapeUtils.escapeHtml(note1.getNoteTitle()).toString(), StringEscapeUtils.escapeHtml(note2.getNoteTitle()).toString());			  		  	
+			  	comparisonResult = collator.compare(StringHelper.escapeHtml(note1.getNoteTitle()).toString(), StringHelper.escapeHtml(note2.getNoteTitle()).toString());			  		  	
 			  } else if(criteria.getSortingTerm()==SortingCriteria.DATE_SORTING) {
 			  	comparisonResult = note1.getLastModified().compareTo(note2.getLastModified());
 			  } 
diff --git a/src/main/java/org/olat/repository/ui/RepositoryEntryIconRenderer.java b/src/main/java/org/olat/repository/ui/RepositoryEntryIconRenderer.java
index b48a32b1c06..3a6e94c959f 100644
--- a/src/main/java/org/olat/repository/ui/RepositoryEntryIconRenderer.java
+++ b/src/main/java/org/olat/repository/ui/RepositoryEntryIconRenderer.java
@@ -21,7 +21,6 @@ package org.olat.repository.ui;
 
 import java.util.Locale;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.NewControllerFactory;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent;
@@ -98,7 +97,7 @@ public class RepositoryEntryIconRenderer implements CustomCellRenderer, FlexiCel
 			sb.append("<i class='o_icon ").append(cssClass).append("'");
 			if (StringHelper.containsNonWhitespace(type)) {
 				sb.append(" title=\"");
-				sb.append(StringEscapeUtils.escapeHtml(type));
+				sb.appendHtmlEscaped(type);
 			}
 			sb.append("\"> </i>");	
 			if(managed) {
diff --git a/src/main/java/org/olat/repository/ui/author/TypeRenderer.java b/src/main/java/org/olat/repository/ui/author/TypeRenderer.java
index 640dd8f5c57..05cf701b938 100644
--- a/src/main/java/org/olat/repository/ui/author/TypeRenderer.java
+++ b/src/main/java/org/olat/repository/ui/author/TypeRenderer.java
@@ -19,7 +19,6 @@
  */
 package org.olat.repository.ui.author;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.NewControllerFactory;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent;
@@ -57,7 +56,7 @@ public class TypeRenderer implements FlexiCellRenderer {
 		} else {
 			type = NewControllerFactory.translateResourceableTypeName(type, translator.getLocale());
 		}
-		type = StringEscapeUtils.escapeHtml(type);
+		type = StringHelper.escapeHtml(type);
 		
 		String cssClass = "";
 		boolean managed = false;
diff --git a/src/main/java/org/olat/user/DisplayPortraitController.java b/src/main/java/org/olat/user/DisplayPortraitController.java
index 80a11af30e7..005caced011 100644
--- a/src/main/java/org/olat/user/DisplayPortraitController.java
+++ b/src/main/java/org/olat/user/DisplayPortraitController.java
@@ -27,7 +27,6 @@ package org.olat.user;
 
 import java.io.File;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.olat.core.commons.fullWebApp.popup.BaseFullWebappPopupLayoutFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
@@ -41,6 +40,7 @@ import org.olat.core.gui.control.generic.popup.PopupBrowserWindow;
 import org.olat.core.id.Identity;
 import org.olat.core.id.OLATResourceable;
 import org.olat.core.id.UserConstants;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.UserSession;
 import org.olat.core.util.coordinate.CoordinatorManager;
 import org.olat.core.util.event.GenericEventListener;
@@ -159,7 +159,7 @@ public class DisplayPortraitController extends BasicController implements Generi
 		String fullName = UserManager.getInstance().getUserDisplayName(portraitIdent);
 		myContent.contextPut("fullName", fullName);		
 		String altText = translate("title.homepage") + ": " + fullName;
-		myContent.contextPut("altText", StringEscapeUtils.escapeHtml(altText));
+		myContent.contextPut("altText", StringHelper.escapeHtml(altText));
 		putInitialPanel(myContent);
 		
 		loadPortrait();
diff --git a/src/test/java/org/olat/core/util/StringHelperTest.java b/src/test/java/org/olat/core/util/StringHelperTest.java
index 61185ec8372..d918a7f722a 100644
--- a/src/test/java/org/olat/core/util/StringHelperTest.java
+++ b/src/test/java/org/olat/core/util/StringHelperTest.java
@@ -139,6 +139,10 @@ public class StringHelperTest {
 		//it's pahlavi \u10B7x
 		String value12 = StringHelper.cleanUTF8ForXml("Hello\u10B7x pahlavi");
 		Assert.assertEquals("Pahlavi test", "Hello\u10B7x pahlavi", value12);
+
+		// smile
+		String value13 = StringHelper.cleanUTF8ForXml("Smile \uD83D\uDE00x now");
+		Assert.assertEquals("Smile test", "Smile \uD83D\uDE00x now", value13);
 	}
 	
 	@Test
-- 
GitLab