diff --git a/common/source/java/ch/systemsx/cisd/common/utilities/ReflectingStringUnescaper.java b/common/source/java/ch/systemsx/cisd/common/utilities/ReflectingStringUnescaper.java
new file mode 100644
index 0000000000000000000000000000000000000000..afea31eab0884ead46b2fd54e00a8d3b21b28b6b
--- /dev/null
+++ b/common/source/java/ch/systemsx/cisd/common/utilities/ReflectingStringUnescaper.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2010 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.common.utilities;
+
+import java.lang.reflect.Field;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.log4j.Logger;
+
+import ch.systemsx.cisd.common.logging.LogCategory;
+import ch.systemsx.cisd.common.logging.LogFactory;
+
+/**
+ * Performs HTML unescaping the string fields of an object. Its implementation is based on
+ * {@link ReflectingStringEscaper} but there is no support to restrict unescaped fields.
+ * 
+ * @author Piotr Buczek
+ */
+public class ReflectingStringUnescaper
+{
+    private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION,
+            ReflectingStringUnescaper.class);
+
+    private static int MIN_TIME_LOGGED_MS = 100;
+
+    /**
+     * Unescape all the string fields on the bean and all fields of objects referred to by the bean.
+     */
+    public static <T> T unescapeDeep(T bean)
+    {
+        try
+        {
+            long time = System.currentTimeMillis();
+            T result = doUnescapeDeep(bean);
+            long timeSpent = System.currentTimeMillis() - time;
+            if (timeSpent >= MIN_TIME_LOGGED_MS)
+            {
+                operationLog.info((timeSpent) + "ms for unescaping "
+                        + (bean == null ? "" : bean.getClass().getSimpleName()));
+            }
+            return result;
+        } catch (Exception ex)
+        {
+            ex.printStackTrace();
+            LogUtils.logErrorWithFailingAssertion(operationLog, ex.toString());
+            return null;
+        }
+    }
+
+    /**
+     * Unescape all the string fields on the bean and all fields of objects referred to by the bean.
+     */
+    private static <T> T doUnescapeDeep(T bean)
+    {
+        ReflectingStringUnescaperUnrestricted<T> escaper =
+                new ReflectingStringUnescaperUnrestricted<T>(true, bean);
+        return escaper.escape();
+    }
+
+}
+
+/**
+ * @author Piotr Buczek
+ */
+class ReflectingStringUnescaperImpl<T>
+{
+
+    protected final boolean isDeep;
+
+    protected final T bean;
+
+    protected ReflectingStringUnescaperImpl(boolean isDeep, T bean)
+    {
+        this.isDeep = isDeep;
+        this.bean = bean;
+    }
+
+    protected T traverse(ReflectionStringTraverser.ReflectionFieldVisitor visitor)
+    {
+        if (isDeep)
+        {
+            ReflectionStringTraverser.traverseDeep(bean, visitor);
+        } else
+        {
+            ReflectionStringTraverser.traverseShallow(bean, visitor);
+        }
+        return bean;
+    }
+
+}
+
+/**
+ * Utility Class that preforms the unrestricted escaping.
+ * 
+ * @author Piotr Buczek
+ */
+class ReflectingStringUnescaperUnrestricted<T> extends ReflectingStringUnescaperImpl<T>
+{
+
+    private static class Visitor implements ReflectionStringTraverser.ReflectionFieldVisitor
+    {
+        public String tryVisit(String value, Object object, Field fieldOrNull)
+        {
+            if (null == fieldOrNull)
+            {
+                // happens e.g. when array of strings is unescaped
+                return StringEscapeUtils.unescapeHtml(value);
+            }
+
+            return StringEscapeUtils.unescapeHtml(value);
+        }
+    }
+
+    ReflectingStringUnescaperUnrestricted(boolean isDeep, T bean)
+    {
+        super(isDeep, bean);
+    }
+
+    T escape()
+    {
+        return traverse(new Visitor());
+    }
+}
diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/utilities/ReflectingStringEscaperTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/utilities/ReflectingStringEscaperTest.java
index 51efad2c1db1237ad48b86ba20d08adfb3ab5dbe..210ee5ebe973a1aac6ccff80aa87078039753efd 100644
--- a/common/sourceTest/java/ch/systemsx/cisd/common/utilities/ReflectingStringEscaperTest.java
+++ b/common/sourceTest/java/ch/systemsx/cisd/common/utilities/ReflectingStringEscaperTest.java
@@ -16,6 +16,8 @@
 
 package ch.systemsx.cisd.common.utilities;
 
+import java.io.Serializable;
+
 import org.testng.AssertJUnit;
 import org.testng.annotations.Test;
 
@@ -24,8 +26,10 @@ import org.testng.annotations.Test;
  */
 public class ReflectingStringEscaperTest extends AssertJUnit
 {
-    public class TestBean
+    public static class TestBean implements Serializable
     {
+        private static final long serialVersionUID = 1L;
+
         private String foo;
 
         private String bar;
@@ -33,6 +37,11 @@ public class ReflectingStringEscaperTest extends AssertJUnit
         private String baz;
 
         private TestBean wrappedBean;
+
+        public TestBean()
+        {
+
+        }
     }
 
     @Test
@@ -43,19 +52,19 @@ public class ReflectingStringEscaperTest extends AssertJUnit
         bean.bar = "<b>bar</b>";
         bean.baz = "<i>baz</i>";
         bean.wrappedBean = new TestBean();
-        bean.wrappedBean.foo = "<a>foo</a>";
-        bean.wrappedBean.bar = "<b>bar</b>";
-        bean.wrappedBean.baz = "<i>baz</i>";
+        bean.wrappedBean.foo = "<wa>foo</wa>";
+        bean.wrappedBean.bar = "<wb>bar</wb>";
+        bean.wrappedBean.baz = "<wi>baz</wi>";
 
         TestBean escaped = ReflectingStringEscaper.escapeShallow(bean);
-        assertEquals(bean, escaped);
+        assertSame(bean, escaped);
         assertEquals("&lt;a&gt;foo&lt;/a&gt;", bean.foo);
         assertEquals("&lt;b&gt;bar&lt;/b&gt;", bean.bar);
         assertEquals("&lt;i&gt;baz&lt;/i&gt;", bean.baz);
 
-        assertEquals("<a>foo</a>", bean.wrappedBean.foo);
-        assertEquals("<b>bar</b>", bean.wrappedBean.bar);
-        assertEquals("<i>baz</i>", bean.wrappedBean.baz);
+        assertEquals("<wa>foo</wa>", bean.wrappedBean.foo);
+        assertEquals("<wb>bar</wb>", bean.wrappedBean.bar);
+        assertEquals("<wi>baz</wi>", bean.wrappedBean.baz);
     }
 
     @Test
@@ -66,21 +75,51 @@ public class ReflectingStringEscaperTest extends AssertJUnit
         bean.bar = "<b>bar</b>";
         bean.baz = "<i>baz</i>";
         bean.wrappedBean = new TestBean();
-        bean.wrappedBean.foo = "<a>foo</a>";
-        bean.wrappedBean.bar = "<b>bar</b>";
-        bean.wrappedBean.baz = "<i>baz</i>";
+        bean.wrappedBean.foo = "<wa>foo</wa>";
+        bean.wrappedBean.bar = "<wb>bar</wb>";
+        bean.wrappedBean.baz = "<wi>baz</wi>";
 
         TestBean escaped = ReflectingStringEscaper.escapeDeep(bean);
-        assertEquals(bean, escaped);
+        assertSame(bean, escaped);
         assertEquals("&lt;a&gt;foo&lt;/a&gt;", bean.foo);
         assertEquals("&lt;b&gt;bar&lt;/b&gt;", bean.bar);
         assertEquals("&lt;i&gt;baz&lt;/i&gt;", bean.baz);
 
-        assertEquals("&lt;a&gt;foo&lt;/a&gt;", bean.wrappedBean.foo);
-        assertEquals("&lt;b&gt;bar&lt;/b&gt;", bean.wrappedBean.bar);
-        assertEquals("&lt;i&gt;baz&lt;/i&gt;", bean.wrappedBean.baz);
+        assertEquals("&lt;wa&gt;foo&lt;/wa&gt;", bean.wrappedBean.foo);
+        assertEquals("&lt;wb&gt;bar&lt;/wb&gt;", bean.wrappedBean.bar);
+        assertEquals("&lt;wi&gt;baz&lt;/wi&gt;", bean.wrappedBean.baz);
+    }
+
+    @Test
+    public void testDeepEscaperWithCopy()
+    {
+        TestBean bean = new TestBean();
+        bean.foo = "<a>foo</a>";
+        bean.bar = "<b>bar</b>";
+        bean.baz = "<i>baz</i>";
+        bean.wrappedBean = new TestBean();
+        bean.wrappedBean.foo = "<wa>foo</wa>";
+        bean.wrappedBean.bar = "<wb>bar</wb>";
+        bean.wrappedBean.baz = "<wi>baz</wi>";
+
+        TestBean escaped = ReflectingStringEscaper.escapeDeepWithCopy(bean);
+        assertNotSame(bean, escaped);
+        assertEquals("<a>foo</a>", bean.foo);
+        assertEquals("<b>bar</b>", bean.bar);
+        assertEquals("<i>baz</i>", bean.baz);
+        assertEquals("&lt;a&gt;foo&lt;/a&gt;", escaped.foo);
+        assertEquals("&lt;b&gt;bar&lt;/b&gt;", escaped.bar);
+        assertEquals("&lt;i&gt;baz&lt;/i&gt;", escaped.baz);
+
+        assertNotSame(bean.wrappedBean, escaped.wrappedBean);
+        assertEquals("<wa>foo</wa>", bean.wrappedBean.foo);
+        assertEquals("<wb>bar</wb>", bean.wrappedBean.bar);
+        assertEquals("<wi>baz</wi>", bean.wrappedBean.baz);
+        assertEquals("&lt;wa&gt;foo&lt;/wa&gt;", escaped.wrappedBean.foo);
+        assertEquals("&lt;wb&gt;bar&lt;/wb&gt;", escaped.wrappedBean.bar);
+        assertEquals("&lt;wi&gt;baz&lt;/wi&gt;", escaped.wrappedBean.baz);
     }
-    
+
     @Test
     public void testCircular()
     {
@@ -89,20 +128,20 @@ public class ReflectingStringEscaperTest extends AssertJUnit
         bean.bar = "<b>bar</b>";
         bean.baz = "<i>baz</i>";
         bean.wrappedBean = new TestBean();
-        bean.wrappedBean.foo = "<a>foo</a>";
-        bean.wrappedBean.bar = "<b>bar</b>";
-        bean.wrappedBean.baz = "<i>baz</i>";
+        bean.wrappedBean.foo = "<wa>foo</wa>";
+        bean.wrappedBean.bar = "<wb>bar</wb>";
+        bean.wrappedBean.baz = "<wi>baz</wi>";
         bean.wrappedBean.wrappedBean = bean;
 
         TestBean escaped = ReflectingStringEscaper.escapeDeep(bean);
-        assertEquals(bean, escaped);
+        assertSame(bean, escaped);
         assertEquals("&lt;a&gt;foo&lt;/a&gt;", bean.foo);
         assertEquals("&lt;b&gt;bar&lt;/b&gt;", bean.bar);
         assertEquals("&lt;i&gt;baz&lt;/i&gt;", bean.baz);
 
-        assertEquals("&lt;a&gt;foo&lt;/a&gt;", bean.wrappedBean.foo);
-        assertEquals("&lt;b&gt;bar&lt;/b&gt;", bean.wrappedBean.bar);
-        assertEquals("&lt;i&gt;baz&lt;/i&gt;", bean.wrappedBean.baz);
+        assertEquals("&lt;wa&gt;foo&lt;/wa&gt;", bean.wrappedBean.foo);
+        assertEquals("&lt;wb&gt;bar&lt;/wb&gt;", bean.wrappedBean.bar);
+        assertEquals("&lt;wi&gt;baz&lt;/wi&gt;", bean.wrappedBean.baz);
     }
 
     @Test
@@ -113,19 +152,19 @@ public class ReflectingStringEscaperTest extends AssertJUnit
         bean.bar = "<b>bar</b>";
         bean.baz = "<i>baz</i>";
         bean.wrappedBean = new TestBean();
-        bean.wrappedBean.foo = "<a>foo</a>";
-        bean.wrappedBean.bar = "<b>bar</b>";
-        bean.wrappedBean.baz = "<i>baz</i>";
+        bean.wrappedBean.foo = "<wa>foo</wa>";
+        bean.wrappedBean.bar = "<wb>bar</wb>";
+        bean.wrappedBean.baz = "<wi>baz</wi>";
 
         TestBean escaped = ReflectingStringEscaper.escapeShallowRestricted(bean, "foo", "baz");
-        assertEquals(bean, escaped);
+        assertSame(bean, escaped);
         assertEquals("&lt;a&gt;foo&lt;/a&gt;", bean.foo);
         assertEquals("<b>bar</b>", bean.bar);
         assertEquals("&lt;i&gt;baz&lt;/i&gt;", bean.baz);
 
-        assertEquals("<a>foo</a>", bean.wrappedBean.foo);
-        assertEquals("<b>bar</b>", bean.wrappedBean.bar);
-        assertEquals("<i>baz</i>", bean.wrappedBean.baz);
+        assertEquals("<wa>foo</wa>", bean.wrappedBean.foo);
+        assertEquals("<wb>bar</wb>", bean.wrappedBean.bar);
+        assertEquals("<wi>baz</wi>", bean.wrappedBean.baz);
     }
 
     @Test
@@ -136,18 +175,18 @@ public class ReflectingStringEscaperTest extends AssertJUnit
         bean.bar = "<b>bar</b>";
         bean.baz = "<i>baz</i>";
         bean.wrappedBean = new TestBean();
-        bean.wrappedBean.foo = "<a>foo</a>";
-        bean.wrappedBean.bar = "<b>bar</b>";
-        bean.wrappedBean.baz = "<i>baz</i>";
+        bean.wrappedBean.foo = "<wa>foo</wa>";
+        bean.wrappedBean.bar = "<wb>bar</wb>";
+        bean.wrappedBean.baz = "<wi>baz</wi>";
 
         TestBean escaped = ReflectingStringEscaper.escapeDeepRestricted(bean, "foo", "baz");
-        assertEquals(bean, escaped);
+        assertSame(bean, escaped);
         assertEquals("&lt;a&gt;foo&lt;/a&gt;", bean.foo);
         assertEquals("<b>bar</b>", bean.bar);
         assertEquals("&lt;i&gt;baz&lt;/i&gt;", bean.baz);
 
-        assertEquals("&lt;a&gt;foo&lt;/a&gt;", bean.wrappedBean.foo);
-        assertEquals("<b>bar</b>", bean.wrappedBean.bar);
-        assertEquals("&lt;i&gt;baz&lt;/i&gt;", bean.wrappedBean.baz);
+        assertEquals("&lt;wa&gt;foo&lt;/wa&gt;", bean.wrappedBean.foo);
+        assertEquals("<wb>bar</wb>", bean.wrappedBean.bar);
+        assertEquals("&lt;wi&gt;baz&lt;/wi&gt;", bean.wrappedBean.baz);
     }
 }
diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/utilities/ReflectingStringUnescaperTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/utilities/ReflectingStringUnescaperTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..456a7bc0fa5e42b4f58031dd3b1dbf38481874dd
--- /dev/null
+++ b/common/sourceTest/java/ch/systemsx/cisd/common/utilities/ReflectingStringUnescaperTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2010 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.common.utilities;
+
+import org.testng.AssertJUnit;
+import org.testng.annotations.Test;
+
+/**
+ * @author Piotr Buczek
+ */
+public class ReflectingStringUnescaperTest extends AssertJUnit
+{
+    public class TestBean
+    {
+        private String foo;
+
+        private String bar;
+
+        private String baz;
+
+        private TestBean wrappedBean;
+    }
+
+    @Test
+    public void testDeepEscaper()
+    {
+        TestBean bean = new TestBean();
+        bean.foo = "<a>foo</a>";
+        bean.bar = "<b>bar</b>";
+        bean.baz = "<i>baz</i>";
+        bean.wrappedBean = new TestBean();
+        bean.wrappedBean.foo = "<wa>foo</wa>";
+        bean.wrappedBean.bar = "<wb>bar</wb>";
+        bean.wrappedBean.baz = "<wi>baz</wi>";
+
+        // first escape
+        TestBean escaped = ReflectingStringEscaper.escapeDeep(bean);
+        assertSame(bean, escaped);
+        assertEquals("&lt;a&gt;foo&lt;/a&gt;", bean.foo);
+        assertEquals("&lt;b&gt;bar&lt;/b&gt;", bean.bar);
+        assertEquals("&lt;i&gt;baz&lt;/i&gt;", bean.baz);
+        assertEquals("&lt;wa&gt;foo&lt;/wa&gt;", bean.wrappedBean.foo);
+        assertEquals("&lt;wb&gt;bar&lt;/wb&gt;", bean.wrappedBean.bar);
+        assertEquals("&lt;wi&gt;baz&lt;/wi&gt;", bean.wrappedBean.baz);
+
+        // unescaping goes back to original
+        TestBean unescaped = ReflectingStringUnescaper.unescapeDeep(bean);
+        assertSame(bean, unescaped);
+        assertEquals("<a>foo</a>", bean.foo);
+        assertEquals("<b>bar</b>", bean.bar);
+        assertEquals("<i>baz</i>", bean.baz);
+        assertEquals("<wa>foo</wa>", bean.wrappedBean.foo);
+        assertEquals("<wb>bar</wb>", bean.wrappedBean.bar);
+        assertEquals("<wi>baz</wi>", bean.wrappedBean.baz);
+    }
+
+}