Index: /quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/__init__.py
===================================================================
--- /quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/__init__.py	(revision 1775)
+++ /quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/__init__.py	(revision 1776)
@@ -1,142 +1,6 @@
 from AccessControl import allow_module
-from zope.component import queryMultiAdapter
 from zope.i18nmessageid import MessageFactory
-
-from Acquisition import aq_inner
-from DateTime import DateTime
-
-from Products.CMFCore.utils import getToolByName
-
-from quintagroup.seoptimizer.interfaces import IMetaKeywords, IMappingMetaTags
-from quintagroup.seoptimizer.util import SortedDict
 
 SeoptimizerMessageFactory = MessageFactory('quintagroup.seoptimizer')
 
 allow_module('quintagroup.seoptimizer.util')
-qSEO_globals = globals()
-
-
-try:
-    from Products.CMFPlone.PloneTool import PloneTool, METADATA_DCNAME, \
-        FLOOR_DATE, CEILING_DATE
-    _present = hasattr(PloneTool, "listMetaTags")
-except ImportError:
-    _present = False
-
-
-if _present:
-    old_lmt = PloneTool.listMetaTags
-
-    def listMetaTags(self, context):
-        """Lists meta tags helper.
-
-        Creates a mapping of meta tags.
-        """
-
-        from quintagroup.seoptimizer.browser.interfaces import IPloneSEOLayer
-        if not IPloneSEOLayer.providedBy(self.REQUEST):
-            return old_lmt(getToolByName(self, 'plone_utils'), context)
-
-        result = SortedDict()
-        site_props = getToolByName(self, 'portal_properties').site_properties
-        use_all = site_props.getProperty('exposeDCMetaTags', None)
-
-        seo_context = queryMultiAdapter((context, self.REQUEST), name='seo_context')
-        adapter = IMappingMetaTags(context, None)
-        mapping_metadata = adapter and adapter.getMappingMetaTags() or SortedDict()
-
-        if not use_all:
-            metadata_names = mapping_metadata.has_key('DC.description') and {'DC.description': mapping_metadata['DC.description']} or SortedDict()
-            if mapping_metadata.has_key('description'):
-                metadata_names['description'] = mapping_metadata['description']
-        else:
-            metadata_names = mapping_metadata
-
-        for key, accessor in metadata_names.items():
-            if accessor == 'meta_keywords':
-                # Render all the existing keywords for the current content type
-                adapter = IMetaKeywords(context, None)
-                if adapter is not None:
-                    keywords = adapter.getMetaKeywords()
-                    if keywords:
-                        result['keywords'] = keywords
-                continue
-
-            method = getattr(seo_context, accessor, None)
-            if method is None:
-                method = getattr(aq_inner(context).aq_explicit, accessor, None)
-
-            if not callable(method):
-                continue
-
-            # Catch AttributeErrors raised by some AT applications
-            try:
-                value = method()
-            except AttributeError:
-                value = None
-
-            if not value:
-                # No data
-                continue
-            if accessor == 'Publisher' and value == 'No publisher':
-                # No publisher is hardcoded (TODO: still?)
-                continue
-            if isinstance(value, (list, tuple)):
-                # convert a list to a string
-                value = ', '.join(value)
-
-            # Special cases
-            if accessor == 'Description' and not metadata_names.has_key('description'):
-                result['description'] = value
-            elif accessor == 'Subject' and not metadata_names.has_key('keywords'):
-                result['keywords'] = value
-
-            if accessor not in ('Description', 'Subject'):
-                result[key] = value
-
-        if use_all:
-            created = context.CreationDate()
-
-            try:
-                effective = context.EffectiveDate()
-                if effective == 'None':
-                    effective = None
-                if effective:
-                    effective = DateTime(effective)
-            except AttributeError:
-                effective = None
-
-            try:
-                expires = context.ExpirationDate()
-                if expires == 'None':
-                    expires = None
-                if expires:
-                    expires = DateTime(expires)
-            except AttributeError:
-                expires = None
-
-            # Filter out DWIMish artifacts on effective / expiration dates
-            if effective is not None and \
-               effective > FLOOR_DATE and \
-               effective != created:
-                eff_str = effective.Date()
-            else:
-                eff_str = ''
-
-            if expires is not None and expires < CEILING_DATE:
-                exp_str = expires.Date()
-            else:
-                exp_str = ''
-
-            if exp_str or exp_str:
-                result['DC.date.valid_range'] = '%s - %s' % (eff_str, exp_str)
-
-        # add custom meta tags (added from qseo tab by user) for given context and default from configlet
-        custom_meta_tags = seo_context and seo_context.seo_customMetaTags() or []
-        for tag in custom_meta_tags:
-            if tag['meta_content']:
-                result[tag['meta_name']] = tag['meta_content']
-
-        return result
-
-    PloneTool.listMetaTags = listMetaTags
Index: /quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/configure.zcml
===================================================================
--- /quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/configure.zcml	(revision 1775)
+++ /quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/configure.zcml	(revision 1776)
@@ -9,4 +9,5 @@
     i18n_domain="quintagroup.seoptimizer">
 
+  <include file="patches.zcml" />
   <!-- include dependent packages -->
   <include package="quintagroup.canonicalpath" />
Index: /quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/listMetaTags.py
===================================================================
--- /quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/listMetaTags.py	(revision 1776)
+++ /quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/listMetaTags.py	(revision 1776)
@@ -0,0 +1,13 @@
+from Products.CMFPlone.PloneTool import PloneTool
+
+originalListMetaTags = PloneTool.listMetaTags
+
+def qsListMetaTags(self, context):
+    """ Custom listMetaTags method
+    """
+    return {}
+
+def qsListMetaTagsOriginal(self, context):
+    """ Returned original method listMetaTags
+    """
+    return originalListMetaTags(self, context)
Index: /quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/patches.zcml
===================================================================
--- /quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/patches.zcml	(revision 1776)
+++ /quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/patches.zcml	(revision 1776)
@@ -0,0 +1,25 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:monkey="http://namespaces.plone.org/monkey"
+    i18n_domain="quintagroup.seoptimizer">
+
+    <include package="collective.monkeypatcher" file="meta.zcml" />
+
+    <monkey:patch
+        description="listMetaTags method is now available as listMetaTagsOriginal"
+        class="Products.CMFPlone.PloneTool.PloneTool"
+        original="listMetaTagsOriginal"
+        ignoreOriginal="True"
+        replacement=".listMetaTags.qsListMetaTagsOriginal"
+        docstringWarning="true"
+        />
+
+    <monkey:patch
+        description="listMetaTags method now support advanced features"
+        class="Products.CMFPlone.PloneTool.PloneTool"
+        original="listMetaTags"
+        replacement=".listMetaTags.qsListMetaTags"
+        docstringWarning="true"
+        />
+
+</configure>
Index: /quintagroup.seoptimizer/branches/refactoring2.3.0/setup.py
===================================================================
--- /quintagroup.seoptimizer/branches/refactoring2.3.0/setup.py	(revision 1775)
+++ /quintagroup.seoptimizer/branches/refactoring2.3.0/setup.py	(revision 1776)
@@ -36,4 +36,5 @@
           'setuptools',
           'quintagroup.canonicalpath>=0.4',
+          'collective.monkeypatcher',
           # -*- Extra requirements: -*-
       ],
