Index: acct_mgr/admin.py
===================================================================
--- acct_mgr/admin.py	(revision 15372)
+++ acct_mgr/admin.py	(working copy)
@@ -13,7 +13,6 @@
 import re
 
 from genshi.builder import tag
-from genshi.core import Markup
 
 from trac import __version__ as trac_version
 from trac.admin import IAdminPanelProvider
@@ -240,9 +239,9 @@
                         set_user_attribute(env, account['username'],
                                            'email_verification_sent_to',
                                            account['email'])
-                    add_notice(req, Markup(tag_(
+                    add_notice(req, tag_(
                                "Account %(username)s created.",
-                               username=tag.b(account['username']))))
+                               username=tag.b(account['username'])))
                     # User editor form clean-up.
                     account = {}
                 except NotificationError, e:
@@ -253,14 +252,7 @@
                     self.log.error('Unable to send change notification: %s',
                                    exception_to_unicode(e, traceback=True))
                 except RegistrationError, e:
-                    # Attempt deferred translation.
-                    message = gettext(e.message)
-                    # Check for (matching number of) message arguments
-                    # before attempting string substitution.
-                    if e.msg_args and \
-                            len(e.msg_args) == len(re.findall('%s', message)):
-                        message = message % e.msg_args
-                    add_warning(req, Markup(message))
+                    add_warning(req, e)
         else:
             add_warning(req, _(
                 "None of the configured password stores is writable."))
@@ -344,8 +336,8 @@
                         "%(count)s account attributes",
                         n_plural, count=n_plural
                     ))))
-                add_notice(req, Markup(tag(_("Successfully deleted:"),
-                                       tag.ul(accounts_, attributes))))
+                add_notice(req, tag_("Successfully deleted: %(account)s"),
+                                     account=tag.ul(accounts_, attributes))
                 # Update the dict after changes.
                 attr = get_user_attribute(env, username=None,
                                           authenticated=1)
@@ -415,17 +407,17 @@
                 if any([k.startswith('delete_email')
                         for k in req.args.keys()]):
                     del_user_attribute(env, username, attribute='email')
-                    add_notice(req, Markup(_(
-                               "Deleted %(attribute)s for %(username)s.",
-                               attribute=tag.b(labels.get('email')),
-                               username=tag.b(username))))
+                    add_notice(req, tag_(
+                        "Deleted %(attribute)s for %(username)s.",
+                        attribute=tag.b(labels.get('email')),
+                        username=tag.b(username)))
                 elif any([k.startswith('delete_name')
                           for k in req.args.keys()]):
                     del_user_attribute(env, username, attribute='name')
-                    add_notice(req, Markup(_(
-                               "Deleted %(attribute)s for %(username)s.",
-                               attribute=tag.b(labels.get('name')),
-                               username=tag.b(username))))
+                    add_notice(req, tag_(
+                        "Deleted %(attribute)s for %(username)s.",
+                        attribute=tag.b(labels.get('name')),
+                        username=tag.b(username)))
 
                 password = req.args.get('password')
                 if password and (password.strip() != ''):
@@ -460,10 +452,10 @@
                         success.append(labels.get(attribute))
                 if success:
                     attributes = tag.b(', '.join(success))
-                    add_notice(req, Markup(_(
+                    add_notice(req, tag_(
                                "Updated %(attributes)s for %(username)s.",
                                attributes=attributes,
-                               username=tag.b(username))))
+                               username=tag.b(username)))
 
             # Change user ID of existing user account.
             elif action == 'uid':
@@ -480,8 +472,8 @@
                     else:
                         result_list = sorted([(k, v) for k, v in
                                               results.iteritems()])
-                        add_notice(req, Markup(tag.ul(
-                                   [tag.li(Markup(ngettext(
+                        add_notice(req, tag.ul(
+                                   [tag.li(ngettext(
                                         "Table %(table)s column %(column)s"
                                         "%(constraint)s: %(result)s change",
                                         "Table %(table)s column %(column)s"
@@ -490,9 +482,9 @@
                                         column=tag.b(result[0][1]),
                                         constraint=result[0][2] and
                                         '(' + result[0][2] + ')' or '',
-                                        result=tag.b(result[1]))))
+                                        result=tag.b(result[1])))
                                     for result in result_list]
-                                   )))
+                                   ))
                         # Switch to display information for new user ID.
                         username = new_uid
                         data.update(
@@ -535,15 +527,15 @@
             if approval and req.args.get('release'):
                 # Admit authenticated/registered session.
                 del_user_attribute(env, username, attribute='approval')
-                add_notice(req, Markup(_(
+                add_notice(req, tag_(
                     "Account lock (%(condition)s) for user %(user)s cleared",
-                    condition=gettext(approval), user=tag.b(username))))
+                    condition=gettext(approval), user=tag.b(username)))
                 approval = None
             # Delete failed login attempts, evaluating attempts count.
             if guard.failed_count(username, reset=True) > 0:
-                add_notice(req, Markup(_(
+                add_notice(req, tag_(
                     "Failed login attempts for user %(user)s deleted",
-                    user=tag.b(username))))
+                    user=tag.b(username)))
         data['approval'] = approval
 
         # Get access history.
@@ -648,15 +640,15 @@
                                    len(unban), accounts=accounts)
                 if ban:
                     if msg:
-                        msg = tag(Markup(msg), Markup('<br />'))
+                        msg = tag(msg, tag.br())
                     else:
                         msg = tag()
                     accounts = tag.b(', '.join(ban))
-                    msg(Markup(ngettext("Banned account: %(accounts)s",
-                                        "Banned accounts: %(accounts)s",
-                                        len(ban), accounts=accounts)))
+                    msg(ngettext("Banned account: %(accounts)s",
+                                 "Banned accounts: %(accounts)s",
+                                 len(ban), accounts=accounts))
                 if ban or unban:
-                    add_notice(req, Markup(msg))
+                    add_notice(req, msg)
             elif req.args.get('reset') and req.args.get('sel'):
                 # Password reset for one or more accounts.
                 if password_reset_enabled:
@@ -664,9 +656,9 @@
                         if username in sel:
                             acctmod._reset_password(req, username, email)
                     if sel:
-                        add_notice(req, Markup(_(
+                        add_notice(req, tag_(
                                    "Password reset for %(accounts)s.",
-                                   accounts=tag.b(', '.join(sel)))))
+                                   accounts=tag.b(', '.join(sel))))
                 else:
                     add_warning(req, _(
                         "The password reset procedure is not enabled."))
@@ -753,9 +745,9 @@
         store_old = acctmgr.find_user_store(old_uid)
         if delete_user and store_old and \
                 not hasattr(store_old, 'delete_user'):
-            add_warning(req, Markup(tag_(
+            add_warning(req, tag_(
                 "Removing the old user is not supported by %(store)s.",
-                store=tag.b(store_old.__class__.__name__))))
+                store=tag.b(store_old.__class__.__name__)))
             return
         stores = ExtensionOrder(components=acctmgr.stores,
                                 list=acctmgr.password_stores)
@@ -784,9 +776,9 @@
                                     list=acctmgr.register_checks)
             required_check = 'BasicCheck'
             if required_check not in checks.get_enabled_component_names():
-                add_warning(req, Markup(tag_(
+                add_warning(req, tag_(
                     "At least %(required_check)s must be configured and "
-                    "enabled.", required_check=tag.b(required_check))))
+                    "enabled.", required_check=tag.b(required_check)))
                 return
 
             req.args['username'] = new_uid
@@ -809,14 +801,7 @@
             try:
                 acctmgr.validate_account(req)
             except RegistrationError, e:
-                # Attempt deferred translation.
-                message = gettext(e.message)
-                # Check for (matching number of) message arguments before
-                #   attempting string substitution.
-                if e.msg_args and \
-                        len(e.msg_args) == len(re.findall('%s', message)):
-                    message = message % e.msg_args
-                add_warning(req, Markup(message))
+                add_warning(req, e)
                 if email:
                     set_user_attribute(self.env, old_uid, 'email', email)
                 return
@@ -850,10 +835,10 @@
         elif email_new and not keep_passwd:
             acctmod._reset_password(req, new_uid, email_new)
         elif not keep_passwd:
-            add_warning(req, Markup(tag_(
+            add_warning(req, tag_(
                 "Cannot send the new password to the user, because no email "
                 "address is associated with %(username)s.",
-                username=tag.b(new_uid))))
+                username=tag.b(new_uid)))
         if delete_user:
             # Finally delete old user ID.
             self._delete_user(req, old_uid)
Index: acct_mgr/macros.py
===================================================================
--- acct_mgr/macros.py	(revision 15146)
+++ acct_mgr/macros.py	(working copy)
@@ -8,7 +8,7 @@
 #
 # Author: Steffen Hoffmann <hoff.st@web.de>
 
-from genshi.builder import Markup, tag
+from genshi.builder import tag
 
 from trac.core import Component, implements
 from trac.perm import PermissionSystem
@@ -18,7 +18,7 @@
 from trac.wiki.formatter import format_to_oneliner
 
 from acct_mgr.admin import fetch_user_data
-from acct_mgr.api import AccountManager, CommonTemplateProvider, _
+from acct_mgr.api import AccountManager, CommonTemplateProvider, _, tag_
 from acct_mgr.compat import get_pretty_dateinfo
 from acct_mgr.guard import AccountGuard
 
@@ -91,8 +91,8 @@
                 if kw['wiki'] == 'count' or 'count' in args:
                     return tag(sum(1 for page in wiki.get_pages(prefix)))
         elif name == 'UserQuery':
-            msg_no_perm = tag.p(Markup(_("(required %(perm)s missing)",
-                                         perm=tag.strong('USER_VIEW'))),
+            msg_no_perm = tag.p(tag_("(required %(perm)s missing)",
+                                     perm=tag.strong('USER_VIEW')),
                                 class_='hint')
             users = []
             if 'perm' in kw.keys():
Index: acct_mgr/register.py
===================================================================
--- acct_mgr/register.py	(revision 15146)
+++ acct_mgr/register.py	(working copy)
@@ -14,7 +14,6 @@
 import time
 
 from genshi.builder import tag
-from genshi.core import Markup
 from os import urandom
 
 from trac import perm, util
@@ -148,10 +147,10 @@
         for store_user in acctmgr.get_users():
             # Do it carefully by disregarding case.
             if store_user.lower() == username.lower():
-                raise RegistrationError(N_(
+                raise RegistrationError(tag_(
                     "Another account or group already exists, who's name "
-                    "differs from %s only by case or is identical."),
-                    tag.b(username)
+                    "differs from %(username)s only by case or is identical.",
+                    username=tag.b(username))
                 )
 
         # Password consistency checks follow.
@@ -197,10 +196,10 @@
             else:
                 # TRANSLATOR: Verbatim token hint for visible bot trap
                 # registration input field.
-                hint = tag.p(Markup(_(
-                    """Please type [%(token)s] as verification token,
-                    exactly replicating everything within the braces.""",
-                    token=tag.b(self.reg_basic_token))), class_='hint')
+                hint = tag.p(tag_(
+                    "Please type [%(token)s] as verification token, "
+                    "exactly replicating everything within the braces.",
+                    token=tag.b(self.reg_basic_token)), class_='hint')
             insert = tag(
                 tag.label(_("Parole:"),
                           tag.input(type='text', name='basic_token', size=20,
@@ -364,10 +363,10 @@
         for (perm_user, perm_action) in \
                 perm.PermissionSystem(self.env).get_all_permissions():
             if perm_user.lower() == username.lower():
-                raise RegistrationError(N_(
+                raise RegistrationError(tag_(
                     "Another account or group already exists, who's name "
-                    "differs from %s only by case or is identical."),
-                    tag.b(username)
+                    "differs from %(username)s only by case or is identical.",
+                    username=tag.b(username))
                 )
 
 
@@ -451,14 +450,7 @@
                         'Unable to send registration notification: %s',
                         exception_to_unicode(e, traceback=True))
             except RegistrationError, e:
-                # Attempt deferred translation.
-                message = gettext(e.message)
-                # Check for (matching number of) message arguments before
-                #   attempting string substitution.
-                if e.msg_args and \
-                        len(e.msg_args) == len(re.findall('%s', message)):
-                    message = message % e.msg_args
-                chrome.add_warning(req, Markup(message))
+                chrome.add_warning(req, e)
             else:
                 if self.require_approval:
                     set_user_attribute(self.env, username, 'approval',
@@ -470,30 +462,27 @@
                     except NotificationError, e:
                         chrome.add_warning(req, _(
                             "Error raised while sending a change "
-                            "notification.") + _("You should report that "
-                            "issue to a Trac admin."))
+                            "notification.") + _(
+                            "You should report that issue to a Trac admin."))
                         self.log.error('Unable to send admin notification: %s',
                                        exception_to_unicode(e, traceback=True))
                     else:
-                        chrome.add_notice(req, Markup(tag.span(Markup(_(
+                        chrome.add_notice(req, tag_(
                             "Your username has been registered successfully, "
                             "but your account requires administrative "
                             "approval. Please proceed according to local "
-                            "policy."))))
-                    )
+                            "policy."))
                 if verify_enabled:
-                    chrome.add_notice(req, Markup(tag.span(Markup(_(
-                        """Your username has been successfully registered but
-                        your account still requires activation. Please login
-                        as user %(user)s, and follow the instructions.""",
-                        user=tag.b(username)))))
-                    )
+                    chrome.add_notice(req, tag_(
+                        "Your username has been successfully registered but "
+                        "your account still requires activation. Please "
+                        "login as user %(user)s, and follow the "
+                        "instructions.", user=tag.b(username)))
                     req.redirect(req.href.login())
-                chrome.add_notice(req, Markup(tag.span(Markup(_(
-                     """Registration has been finished successfully.
-                     You may log in as user %(user)s now.""",
-                     user=tag.b(username)))))
-                )
+                chrome.add_notice(req, tag_(
+                    "Registration has been finished successfully. "
+                    "You may log in as user %(user)s now.",
+                    user=tag.b(username)))
                 req.redirect(req.href.login())
         # Collect additional fields from IAccountRegistrationInspector's.
         fragments = dict(required=[], optional=[])
@@ -568,8 +557,7 @@
                 # Check passed without error: New email address seems good.
             except RegistrationError, e:
                 # Always warn about issues.
-                chrome.add_warning(
-                    req, Markup(gettext(e.message)))
+                chrome.add_warning(req, e)
                 # Look, if the issue existed before.
                 attributes = get_user_attribute(self.env, req.authname,
                                                 attribute='email')
@@ -588,10 +576,9 @@
                          href=req.href.verify_email()
                    )
             # TRANSLATOR: ... verify your email address
-            chrome.add_warning(req, Markup(tag.span(Markup(_(
+            chrome.add_warning(req, tag_(
                 "Your permissions have been limited until you %(link)s.",
-                link=link))))
-            )
+                link=link))
             req.perm = perm.PermissionCache(self.env, 'anonymous')
         return handler
 
@@ -625,10 +612,9 @@
                 link = tag.a(_("verify your new email address"),
                              href=req.href.verify_email())
                 # TRANSLATOR: ... verify your new email address
-                chrome.add_notice(req, Markup(tag.span(Markup(_(
+                chrome.add_notice(req, tag_(
                     "An email has been sent to <%(email)s> with a token to "
-                    "%(link)s.", email=tag(email), link=link))))
-                )
+                    "%(link)s.", email=tag(email), link=link))
         return template, data, content_type
 
     # IRequestHandler methods
@@ -638,9 +624,8 @@
 
     def process_request(self, req):
         if not req.session.authenticated:
-            chrome.add_warning(req, Markup(tag.span(tag_(
-                "Please log in to finish email verification procedure.")))
-            )
+            chrome.add_warning(req, tag_(
+                "Please log in to finish email verification procedure."))
             req.redirect(req.href.login())
         if 'email_verification_token' not in req.session:
             chrome.add_notice(req, _("Your email is already verified."))
Index: acct_mgr/web_ui.py
===================================================================
--- acct_mgr/web_ui.py	(revision 15206)
+++ acct_mgr/web_ui.py	(working copy)
@@ -14,7 +14,6 @@
 import time
 
 from datetime import timedelta
-from genshi.core import Markup
 from genshi.builder import tag
 
 from trac import perm, util
@@ -162,11 +161,11 @@
     def process_request(self, req):
         data = dict(_dgettext=dgettext)
         if req.authname and req.authname != 'anonymous':
-            add_notice(req, Markup(tag_(
+            add_notice(req, tag_(
                 "You're already logged in. If you need to change your "
                 "password please use the %(prefs_href)s page.",
                 prefs_href=tag.a(_("Account Preferences"),
-                                 href=req.href.prefs('account')))))
+                                 href=req.href.prefs('account'))))
             data['authenticated'] = True
         if req.method == 'POST':
             self._do_reset_password(req)
@@ -193,10 +192,10 @@
             elif action == 'delete' and delete_enabled:
                 self._do_delete(req)
         if force_change_password:
-            add_warning(req, Markup(_(
+            add_warning(req, tag_(
                 "You are required to change password because of a recent "
                 "password change request. %(invitation)s",
-                invitation=tag.b(_("Please change your password now.")))))
+                invitation=tag.b(_("Please change your password now."))))
         return data
 
     def _do_change_password(self, req):
@@ -472,11 +471,11 @@
         else:
             n_plural=req.args.get('failed_logins')
             if n_plural > 0:
-                add_warning(req, Markup(tag.span(tag(ngettext(
+                add_warning(req, tag(ngettext(
                     "Login after %(attempts)s failed attempt",
                     "Login after %(attempts)s failed attempts",
                     n_plural, attempts=n_plural
-                )))))
+                )))
         return auth.LoginModule.process_request(self, req)
 
     # overrides
