Index: quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/profiles.zcml
===================================================================
--- quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/profiles.zcml	(revision 3213)
+++ quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/profiles.zcml	(revision 3223)
@@ -38,3 +38,10 @@
       profile="quintagroup.seoptimizer:default" />
 
+  <genericsetup:upgradeStep
+      title="Upgrade quintagroup.seoptimizer"
+      description="Unescape quintagroup.seoptimizer title and comment properties"
+      destination="4.0.5"
+      handler=".upgrades.unescapeOldTitle"
+      profile="quintagroup.seoptimizer:default" />
+
 </configure>
Index: quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/profiles/default/metadata.xml
===================================================================
--- quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/profiles/default/metadata.xml	(revision 3213)
+++ quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/profiles/default/metadata.xml	(revision 3223)
@@ -1,4 +1,4 @@
 <?xml version="1.0"?>
 <metadata>
-  <version>4.0.3</version>
+  <version>4.0.5</version>
 </metadata>
Index: quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/tests/testUtils.py
===================================================================
--- quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/tests/testUtils.py	(revision 3213)
+++ quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/tests/testUtils.py	(revision 3223)
@@ -1,2 +1,3 @@
+# -*- coding: utf8 -*-
 from unittest import TestSuite, makeSuite, TestCase
 from quintagroup.seoptimizer.util import unescape
@@ -6,26 +7,34 @@
 
     def test_unicode_str_unescaping(self):
-        self.assertEqual(unescape(u"&&amp;-/&#91;"), u"&&-/[")
+        self.assertEqual(unescape("&&amp;-/&#91;"), "&&-/[")
 
     def test_str_unescaping(self):
-        self.assertEqual(unescape("&&amp;-/&#91;"), u"&&-/[")
+        self.assertEqual(unescape("&&amp;-/&#91;"), "&&-/[")
+
+    def test_entity_unicode_unescaping(self):
+        self.assertEqual(unescape(u"&&amp;ї".encode('utf-8')),
+                                  u"&&ї".encode('utf-8'))
 
     def test_hex_unescaping(self):
-        self.assertEqual(unescape('&#x5B;'), u'[')
+        self.assertEqual(unescape('&#x5B;'), '[')
 
     def test_simple_text_unescaping(self):
-        self.assertEqual(unescape("Simple text."), u"Simple text.")
+        self.assertEqual(unescape("Simple text."), "Simple text.")
 
     def test_entity_hex_unescaping(self):
-        self.assertEqual(unescape('&amp;#x5B;'), u'&#x5B;')
+        self.assertEqual(unescape('&amp;#x5B;'), '&#x5B;')
 
     def test_intity_dec_unescaping(self):
-        self.assertEqual(unescape('&amp;#91;'), u'&#91;')
+        self.assertEqual(unescape('&amp;#91;'), '&#91;')
 
     def test_entity_dec_hex_unescaping(self):
-        self.assertEqual(unescape('&amp;#38;#x5B;'), u'&#38;#x5B;')
+        self.assertEqual(unescape('&amp;#38;#x5B;'), '&#38;#x5B;')
 
     def test_fake_entity_unescaping(self):
-        self.assertEqual(unescape("&asd;"), u"&asd;")
+        self.assertEqual(unescape("&asd;"), "&asd;")
+
+    def test_aentity_unescaping(self):
+        self.assertEqual(unescape("&mdash;").encode('utf-8'),
+                         u"—".encode('utf-8'))
 
 
Index: quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/upgrades.py
===================================================================
--- quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/upgrades.py	(revision 3213)
+++ quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/upgrades.py	(revision 3223)
@@ -2,4 +2,9 @@
 from zope.component import queryMultiAdapter
 
+from Products.CMFCore.utils import getToolByName
+from Products.CMFPlone.utils import getSiteEncoding, safe_unicode
+
+from quintagroup.seoptimizer.browser.seo_configlet import ISEOConfigletSchema
+from quintagroup.seoptimizer.util import unescape
 from quintagroup.canonicalpath.interfaces  import ICanonicalLink
 from quintagroup.canonicalpath.adapters import PROPERTY_LINK
@@ -146,2 +151,27 @@
     removeSkin(plone_tools)
     migrateCanonical(plone_tools)
+
+
+def unescapeOldTitle(setuptool):
+    """ Upgrade quintagroup.seoptimizer title and comments properties.
+    """
+    portal = getToolByName(setuptool, "portal_url").getPortalObject()
+    types = ISEOConfigletSchema(portal).types_seo_enabled
+
+    catalog = getToolByName(portal, "portal_catalog")
+    brains = catalog(portal_type=types)
+
+    for b in brains:
+        obj = b.getObject()
+        obj_enc = getSiteEncoding(obj)
+
+        if obj.hasProperty("qSEO_title"):
+            uni_qSEO_title = safe_unicode(obj.qSEO_title, encoding=obj_enc)
+            fixed_title = unescape(uni_qSEO_title).encode(obj_enc)
+            obj._updateProperty("qSEO_title", fixed_title)
+
+        if obj.hasProperty("qSEO_html_comment"):
+            uni_qSEO_html_comment = safe_unicode(obj.qSEO_html_comment,
+                                                 encoding=obj_enc)
+            fixed_comment = unescape(uni_qSEO_html_comment).encode(obj_enc)
+            obj._updateProperty("qSEO_html_comment", fixed_comment)
Index: quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/util.py
===================================================================
--- quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/util.py	(revision 3213)
+++ quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/util.py	(revision 3223)
@@ -52,5 +52,5 @@
     if m.group("ent"):
         try:
-            return entitydefs[m.group("ent")]
+            return unescape(entitydefs[m.group("ent")])
         except KeyError:
             return m.group(0)
@@ -66,8 +66,3 @@
 
 def unescape(s):
-    result = expr.sub(_group_unescape, s)
-
-    if isinstance(s, unicode):
-        return result
-    else:
-        return unicode(result)
+    return expr.sub(_group_unescape, s)
