diff --git a/product/ERP5/Document/EmailDocument.py b/product/ERP5/Document/EmailDocument.py
index 01af7dbb18518c40eceddda97909f442f7d9a916..4aba2c7e10d935fdd152c49d5dee2b8d82cb0a40 100644
--- a/product/ERP5/Document/EmailDocument.py
+++ b/product/ERP5/Document/EmailDocument.py
@@ -48,18 +48,11 @@ except ImportError:
     A dummy exception class which is used when MimetypesRegistry product is
     not installed yet.
     """
-  
+
 
 from email import message_from_string
 from email.Header import decode_header
 from email.Utils import parsedate
-from email import Encoders
-from email.Message import Message
-from email.MIMEAudio import MIMEAudio
-from email.MIMEBase import MIMEBase
-from email.MIMEImage import MIMEImage
-from email.MIMEMultipart import MIMEMultipart
-from email.MIMEText import MIMEText
 
 DEFAULT_TEXT_FORMAT = 'text/html'
 COMMASPACE = ', '
@@ -400,9 +393,6 @@ class EmailDocument(File, TextDocument):
       download - if set to True returns, the message online
                 rather than sending it.
 
-      This method is based on the examples provided by
-      http://docs.python.org/lib/node162.html
-
       TODO: support conversion to base format and use
       base format rather than original format
 
@@ -412,11 +402,17 @@ class EmailDocument(File, TextDocument):
     if not _checkPermission(Permissions.View, self):
       raise Unauthorized
 
+    #
     # Prepare header data
+    #
     if body is None:
       body = self.asText()
+
+    # Subject
     if subject is None:
       subject = self.getTitle()
+
+    # From
     if from_url is None:
       sender = self.getSourceValue()
       if sender.getTitle():
@@ -424,101 +420,100 @@ class EmailDocument(File, TextDocument):
                                 sender.getDefaultEmailText())
       else:
         from_url = sender.getDefaultEmailText()
+
+    # Return-Path
     if reply_url is None:
       reply_url = self.portal_preferences.getPreferredEventSenderEmail()
+    additional_headers = None
+    if reply_url:
+      additional_headers = {'Return-Path':reply_url}
+
+    # To (multiple)
+    to_url_list = []
     if to_url is None:
-      to_url = []
       for recipient in self.getDestinationValueList():
         email = recipient.getDefaultEmailText()
         if email:
           if recipient.getTitle():
-            to_url.append('"%s" <%s>' % (recipient.getTitle(), email))
+            to_url_list.append('"%s" <%s>' % (recipient.getTitle(), email))
           else:
-            to_url.append(email)
+            to_url_list.append(email)
         else:
           raise ValueError, 'Recipient %s has no defined email' % recipient
     elif type(to_url) in types.StringTypes:
-      to_url = [to_url]
-
-    # Not efficient but clean
-    for recipient in to_url:
-      # Create the container (outer) email message.
-      message = MIMEMultipart()
-      message['Subject'] = subject
-      message['From'] = from_url
-      message['To'] = recipient
-      message['Return-Path'] = reply_url
-      message.preamble = 'You will not see this in a MIME-aware mail reader.\n'
-  
-      # Add the body of the message
-      attached_message = MIMEText(str(body), _charset='UTF-8')
-      message.attach(attached_message)
-  
-      # Attach files
-      document_type_list = self.getPortalDocumentTypeList()
-      for attachment in self.getAggregateValueList():
-        mime_type = None
-        attached_data = None
-        if attachment.getPortalType() in document_type_list:
-          # If this is a document, use
-
-          # WARNING - this could fail since getContentType
-          # is not (yet) part of Document API
-          if getattr(attachment, 'getContentType', None) is not None:
-            mime_type = attachment.getContentType()
-          elif getattr(attachment, 'getTextFormat', None) is not None:
-            mime_type = attachment.getTextFormat()
-          else:
-            raise ValueError, "Cannot find mimetype of the document."
-
-          if mime_type is not None:
-            try:
-              mime_type, attached_data = attachment.convert(mime_type)
-            except ConversionError:
-              mime_type = attachment.getBaseContentType()
-              attached_data = attachment.getBaseData()
-            except (NotImplementedError, MimeTypeException):
-              pass
-
-          if attached_data is None:
-            if getattr(attachment, 'getTextContent', None) is not None:
-              attached_data = attachment.getTextContent()
-            elif getattr(attachment, 'getData', None) is not None:
-              attached_data = attachment.getData()
-            elif getattr(attachment, 'getBaseData', None) is not None:
-              attached_data = attachment.getBaseData()
-        else:
-          mime_type = 'application/pdf'
-          attached_data = attachment.asPDF() # XXX - Not implemented yet
-                                                # should provide a default printout
-
-        if not isinstance(attached_data, str):
-          attached_data = str(attached_data)
-
-        if not mime_type:
-          mime_type = 'application/octet-stream'
-        # Use appropriate class based on mime_type
-        maintype, subtype = mime_type.split('/', 1)
-        if maintype == 'text':
-          attached_message = MIMEText(attached_data, _subtype=subtype)
-        elif maintype == 'image':
-          attached_message = MIMEImage(attached_data, _subtype=subtype)
-        elif maintype == 'audio':
-          attached_message = MIMEAudio(attached_data, _subtype=subtype)
+      to_url_list.append(to_url)
+
+    # Attachments
+    attachment_list = []
+    document_type_list = self.getPortalDocumentTypeList()
+    for attachment in self.getAggregateValueList():
+      mime_type = None
+      content = None
+      name = None
+      if not attachment.getPortalType() in document_type_list:
+        mime_type = 'application/pdf'
+        content = attachment.asPDF() # XXX - Not implemented yet
+      else:
+        #
+        # Document type attachment
+        #
+
+        # WARNING - this could fail since getContentType
+        # is not (yet) part of Document API
+        if getattr(attachment, 'getContentType', None) is not None:
+          mime_type = attachment.getContentType()
+        elif getattr(attachment, 'getTextFormat', None) is not None:
+          mime_type = attachment.getTextFormat()
         else:
-          attached_message = MIMEBase(maintype, subtype)
-          attached_message.set_payload(attached_data)
-          Encoders.encode_base64(attached_message)
-        attached_message.add_header('Content-Disposition', 'attachment', filename=attachment.getReference())
-        message.attach(attached_message)
+          raise ValueError, "Cannot find mimetype of the document."
+
+        if mime_type is not None:
+          try:
+            mime_type, content = attachment.convert(mime_type)
+          except ConversionError:
+            mime_type = attachment.getBaseContentType()
+            content = attachment.getBaseData()
+          except (NotImplementedError, MimeTypeException):
+            pass
+
+        if content is None:
+          if getattr(attachment, 'getTextContent', None) is not None:
+            content = attachment.getTextContent()
+          elif getattr(attachment, 'getData', None) is not None:
+            content = attachment.getData()
+          elif getattr(attachment, 'getBaseData', None) is not None:
+            content = attachment.getBaseData()
+
+      if not isinstance(content, str):
+        content = str(content)
+
+      attachment_list.append({'mime_type':mime_type,
+                              'content':content,
+                              'name':attachment.getReference()}
+                             )
+
+    portal_notifications = getToolByName(self, 'portal_notifications')
+    kw = {}
+
+    # Only for debugging purpose
+    if download:
+      kw = {'debug':True}
+    else:
+      portal_notifications = portal_notifications.activate(activity="SQLQueue")
 
-      # Send the message
-      if download:
-        return message.as_string() # Only for debugging purpose
+    for to_url in to_url_list:
+      result = portal_notifications.sendMessageLowLevel(
+        from_url=from_url, to_url=to_url, body=body, subject=subject,
+        attachment_list=attachment_list,
+        additional_headers=additional_headers,
+        **kw
+        )
 
-      # Use activities
-      self.activate(activity="SQLQueue").sendMailHostMessage(message.as_string())
+    # Send the message
+    if download:
+      return result # Only for debugging purpose
 
+  # XXX Obsolete method, Use portal_notifications instead.
   security.declareProtected(Permissions.UseMailhostServices, 'sendMailHostMessage')
   def sendMailHostMessage(self, message):
     """
diff --git a/product/ERP5/Document/Url.py b/product/ERP5/Document/Url.py
index f5d05be39c2c77f64cb11dd9238050149ab44863..e7063e0dee4ca5010987fc60887d4da7d753d248 100644
--- a/product/ERP5/Document/Url.py
+++ b/product/ERP5/Document/Url.py
@@ -146,10 +146,6 @@ class Url(Coordinate, Base, UrlMixIn):
     * extra_headers is a dictionnary of custom headers to add to the email.
       "X-" prefix is automatically added to those headers.
     """
-    # get the mailhost object
-    mailhost = getattr(self.getPortalObject(), 'MailHost', None)
-    if mailhost is None:
-      raise AttributeError, "Cannot find a MailHost object"
     if from_url is None:
       from_url = self.getUrlString(None)
     if to_url is None:
@@ -157,9 +153,9 @@ class Url(Coordinate, Base, UrlMixIn):
     if from_url is None or to_url is None:
       raise AttributeError, "No mail defined"
 
-    message = buildEmailMessage(from_url, to_url, msg=msg,
-                                subject=subject, attachment_list=attachment_list,
-                                extra_headers=extra_headers)
+    portal_notifications = getToolByName(self, 'portal_notifications')
 
-    # send mail to user
-    mailhost.send(message.as_string(), to_url, from_url)
\ No newline at end of file
+    portal_notifications.sendMessageLowLevel(from_url=from_url, to_url=to_url,
+                                             body=msg, subject=subject,
+                                             attachment_list=attachment_list,
+                                             extra_headers=extra_headers)
diff --git a/product/ERP5/Tool/NotificationTool.py b/product/ERP5/Tool/NotificationTool.py
index 37df5090e8168e8d7d8e6a6844b460c208d37eef..b52c7174b24bad8d9726a6fcfd2df7b76317abeb 100644
--- a/product/ERP5/Tool/NotificationTool.py
+++ b/product/ERP5/Tool/NotificationTool.py
@@ -36,13 +36,16 @@ from mimetypes import guess_type
 from email.MIMEMultipart import MIMEMultipart
 from email.MIMEText import MIMEText
 from email.MIMEBase import MIMEBase
+from email.MIMEAudio import MIMEAudio
+from email.MIMEImage import MIMEImage
 from email.Header import make_header
 from email import Encoders
 
 
 def buildEmailMessage(from_url, to_url, msg=None,
                       subject=None, attachment_list=None,
-                      extra_headers=None):
+                      extra_headers=None,
+                      additional_headers=None):
   """
     Builds a mail message which is ready to be
     sent by Zope MailHost.
@@ -53,6 +56,7 @@ def buildEmailMessage(from_url, to_url, msg=None,
      - mime_type: mime-type corresponding to the attachment
     * extra_headers is a dictionnary of custom headers to add to the email.
       "X-" prefix is automatically added to those headers.
+    * additional_headers is similar to extra_headers, but no prefix is added.
   """
 
   if attachment_list == None:
@@ -67,8 +71,12 @@ def buildEmailMessage(from_url, to_url, msg=None,
     message.attach(MIMEText(msg, _charset='utf-8'))
 
   if extra_headers:
-    for k, v in extra_headers.items():
-      message.add_header('X-%s' % k, v)
+    for key, value in extra_headers.items():
+      message.add_header('X-%s' % key, value)
+
+  if additional_headers:
+    for key, value in additional_headers.items():
+      message.add_header(key, value)
 
   message.add_header('Subject',
                       make_header([(subject, 'utf-8')]).encode())
@@ -92,10 +100,18 @@ def buildEmailMessage(from_url, to_url, msg=None,
     if attachment['mime_type'] == 'text/plain':
       part = MIMEText(attachment['content'], _charset='utf-8')
     else:
-      #  encode non-plaintext attachment in base64
-      part = MIMEBase(*attachment['mime_type'].split('/', 1))
-      part.set_payload(attachment['content'])
-      Encoders.encode_base64(part)
+      major, minor = attachment['mime_type'].split('/', 1)
+      if major == 'text':
+        part = MIMEText(attachment['content'], _subtype=minor)
+      elif major == 'image':
+        part = MIMEImage(attachment['content'], _subtype=minor)
+      elif major == 'audio':
+        part = MIMEAudio(attachment['content'], _subtype=minor)
+      else:
+        #  encode non-plaintext attachment in base64      
+        part = MIMEBase(major, minor)
+        part.set_payload(attachment['content'])
+        Encoders.encode_base64(part)
 
     part.add_header('Content-Disposition',
                     'attachment; filename=%s' % attachment_name)
@@ -133,6 +149,24 @@ class NotificationTool(BaseTool):
   security.declareProtected( Permissions.ManagePortal, 'manage_overview' )
   manage_overview = DTMLFile( 'explainNotificationTool', _dtmldir )
 
+  # XXX Bad Name...Any Idea?
+  security.declareProtected(Permissions.UseMailhostServices, 'sendMessageLowLevel')
+  def sendMessageLowLevel(self, from_url, to_url, body=None, subject=None,
+                          attachment_list=None, extra_headers=None, additional_headers=None,
+                          debug=False):
+    portal = self.getPortalObject()
+    mailhost = getattr(portal, 'MailHost', None)
+    if mailhost is None:
+      raise ValueError, "Can't find MailHost."
+    message = buildEmailMessage(from_url, to_url, msg=body, subject=subject,
+                                attachment_list=attachment_list, extra_headers=extra_headers,
+                                additional_headers=additional_headers)
+
+    if debug:
+      return message.as_string()
+
+    mailhost.send(messageText=message.as_string(), mto=to_url, mfrom=from_url)
+
   security.declareProtected(Permissions.UseMailhostServices, 'sendMessage')
   def sendMessage(self, sender=None, recipient=None, subject=None, 
                         message=None, attachment_list=None,
@@ -171,9 +205,6 @@ class NotificationTool(BaseTool):
     """
     portal = self.getPortalObject()
     catalog_tool = getToolByName(self, 'portal_catalog')
-    mailhost = getattr(portal, 'MailHost', None)
-    if mailhost is None:
-      raise ValueError, "Can't find MailHost."
 
     # Find Default Values
     default_from_email = portal.email_from_address
@@ -214,14 +245,12 @@ class NotificationTool(BaseTool):
 
     # Build and Send Messages
     for to_address in to_address_list:
-      mail_message = buildEmailMessage(from_url=from_address,
-                                       to_url=to_address,
-                                       msg=message,
-                                       subject=subject,
-                                       attachment_list=attachment_list
-                                       )
-      mailhost.send(mail_message.as_string(), to_address, from_address)
-
+      self.sendMessageLowLevel(from_url=from_address,
+                               to_url=to_address,
+                               body=message,
+                               subject=subject,
+                               attachment_list=attachment_list
+                               )
 
     return
     # Future implemetation could consist in implementing
diff --git a/product/ERP5/tests/testCRM.py b/product/ERP5/tests/testCRM.py
index 207ad61079a20156ca3680b8fe66cb1528c78e7f..ba3c2e074594c8488204fc57de93b8f7886c4f53 100644
--- a/product/ERP5/tests/testCRM.py
+++ b/product/ERP5/tests/testCRM.py
@@ -28,6 +28,7 @@
 import unittest
 import os
 import email
+import email.Header
 
 from Products.ERP5Type.tests.utils import DummyMailHost
 from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
@@ -515,7 +516,8 @@ class TestCRMMailSend(ERP5TypeTestCase):
     
     message = email.message_from_string(messageText)
 
-    self.assertEquals('A Mail', message['Subject'])
+    self.assertEquals('A Mail',
+                      email.Header.decode_header(message['Subject'])[0][0])
     part = None
     for i in message.get_payload():
       if i.get_content_type()=='text/plain':
@@ -598,7 +600,8 @@ class TestCRMMailSend(ERP5TypeTestCase):
     
     message = email.message_from_string(messageText)
 
-    self.assertEquals('H茅h茅', message['Subject'])
+    self.assertEquals('H茅h茅',
+                      email.Header.decode_header(message['Subject'])[0][0])
     part = None
     for i in message.get_payload():
       if i.get_content_type()=='text/plain':