changeset 2039:12961b623cb6 gae

merged default branch into gae branch
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Wed, 20 Mar 2013 01:25:01 +0100
parents 9ed8069eea05 (current diff) 3217a345d20a (diff)
children 089f0f9c21d6
files MoinMoin/app.py MoinMoin/apps/admin/templates/admin/sysitems_upgrade.html MoinMoin/apps/frontend/views.py MoinMoin/config/default.py MoinMoin/constants/keys.py MoinMoin/converter/rst_in.py MoinMoin/items/content.py MoinMoin/log.py MoinMoin/mail/sendmail.py MoinMoin/script/__init__.py MoinMoin/script/maint/modified_systemitems.py MoinMoin/storage/middleware/indexing.py MoinMoin/themes/__init__.py docs/admin/requirements.rst moin.py setup.cfg setup.py wikiconfig.py
diffstat 266 files changed, 6392 insertions(+), 5031 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/_tests/__init__.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/_tests/__init__.py	Wed Mar 20 01:25:01 2013 +0100
@@ -8,23 +8,21 @@
 """
 
 
-import os, shutil
-import socket, errno
+import socket
 from StringIO import StringIO
 
-from flask import current_app as app
 from flask import g as flaskg
 
-from MoinMoin import config, security, user
-from MoinMoin.config import NAME, CONTENTTYPE
+from MoinMoin.constants.contenttypes import CHARSET
+from MoinMoin.constants.keys import NAME, CONTENTTYPE
 from MoinMoin.items import Item
 from MoinMoin.util.crypto import random_string
-from MoinMoin.storage.error import ItemAlreadyExistsError
 
 # Promoting the test user -------------------------------------------
 # Usually the tests run as anonymous user, but for some stuff, you
 # need more privs...
 
+
 def become_valid(username=u"ValidUser"):
     """ modify flaskg.user to make the user valid.
         Note that a valid user will only be in ACL special group "Known", if
@@ -49,7 +47,7 @@
 def update_item(name, meta, data):
     """ creates or updates an item  """
     if isinstance(data, unicode):
-        data = data.encode(config.charset)
+        data = data.encode(CHARSET)
     item = flaskg.storage[name]
 
     meta = meta.copy()
@@ -60,11 +58,13 @@
     rev = item.store_revision(meta, StringIO(data), return_rev=True)
     return rev
 
+
 def create_random_string_list(length=14, count=10):
     """ creates a list of random strings """
     chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
     return [u"{0}".format(random_string(length, chars)) for counter in range(count)]
 
+
 def nuke_item(name):
     """ complete destroys an item """
     item = Item.create(name)
--- a/MoinMoin/_tests/_test_template.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/_tests/_test_template.py	Wed Mar 20 01:25:01 2013 +0100
@@ -45,6 +45,7 @@
     )
 
     from MoinMoin._tests import wikiconfig
+
     class Config(wikiconfig.Config):
         foo = 'bar'  # we want to have this non-default setting
 
--- a/MoinMoin/_tests/ldap_testbase.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/_tests/ldap_testbase.py	Wed Mar 20 01:25:01 2013 +0100
@@ -39,14 +39,21 @@
 SLAPD_EXECUTABLE = 'slapd'  # filename of LDAP server executable - if it is not
                             # in your PATH, you have to give full path/filename.
 
-import os, shutil, tempfile, time, base64
+import os
+import shutil
+import tempfile
+import time
+import base64
 from StringIO import StringIO
 import signal
 import subprocess
 import hashlib
 
 try:
-    import ldap, ldif, ldap.modlist  # needs python-ldap
+    # needs python-ldap
+    import ldap
+    import ldap.modlist
+    import ldif
 except ImportError:
     ldap = None
 
@@ -77,20 +84,21 @@
 
 class Slapd(object):
     """ Manage a slapd process for testing purposes """
-    def __init__(self,
-                 config=None,  # config filename for -f
-                 executable=SLAPD_EXECUTABLE,
-                 debug_flags='', # None,  # for -d stats,acl,args,trace,sync,config
-                 proto='ldap', ip='127.0.0.1', port=3890,  # use -h proto://ip:port
-                 service_name=''  # defaults to -n executable:port, use None to not use -n
-                ):
+    def __init__(
+        self,
+        config=None,  # config filename for -f
+        executable=SLAPD_EXECUTABLE,
+        debug_flags='',  # None,  # for -d stats,acl,args,trace,sync,config
+        proto='ldap', ip='127.0.0.1', port=3890,  # use -h proto://ip:port
+        service_name='',  # defaults to -n executable:port, use None to not use -n
+    ):
         self.executable = executable
         self.config = config
         self.debug_flags = debug_flags
         self.proto = proto
         self.ip = ip
         self.port = port
-        self.url = '{0}://{1}:{2}'.format(proto, ip, port) # can be used for ldap.initialize() call
+        self.url = '{0}://{1}:{2}'.format(proto, ip, port)  # can be used for ldap.initialize() call
         if service_name == '':
             self.service_name = '{0}:{1}'.format(executable, port)
         else:
@@ -109,7 +117,7 @@
         started = None
         if timeout:
             lo = ldap.initialize(self.url)
-            ldap.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3) # ldap v2 is outdated
+            ldap.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3)  # ldap v2 is outdated
             started = False
             wait_until = time.time() + timeout
             while time.time() < wait_until:
@@ -146,14 +154,15 @@
 #set_tas_spins 0
 """
 
-    def __init__(self,
-                 basedn,
-                 rootdn, rootpw,
-                 instance=0,  # use different values when running multiple LdapEnvironments
-                 schema_dir='/etc/ldap/schema',  # directory with schemas
-                 coding='utf-8',  # coding used for config files
-                 timeout=10,  # how long to wait for slapd starting [s]
-                ):
+    def __init__(
+        self,
+        basedn,
+        rootdn, rootpw,
+        instance=0,  # use different values when running multiple LdapEnvironments
+        schema_dir='/etc/ldap/schema',  # directory with schemas
+        coding='utf-8',  # coding used for config files
+        timeout=10,  # how long to wait for slapd starting [s]
+    ):
         self.basedn = basedn
         self.rootdn = rootdn
         self.rootpw = rootpw
@@ -200,14 +209,14 @@
 
     def start_slapd(self):
         """ start a slapd and optionally wait until it talks with us """
-        self.slapd = Slapd(config=self.slapd_conf, port=3890+self.instance)
+        self.slapd = Slapd(config=self.slapd_conf, port=3890 + self.instance)
         started = self.slapd.start(timeout=self.timeout)
         return started
 
     def load_directory(self, ldif_content):
         """ load the directory with the ldif_content (str) """
         lo = ldap.initialize(self.slapd.url)
-        ldap.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3) # ldap v2 is outdated
+        ldap.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3)  # ldap v2 is outdated
         lo.simple_bind_s(self.rootdn, self.rootpw)
 
         class LDIFLoader(ldif.LDIFParser):
@@ -228,7 +237,7 @@
 try:
     import pytest
 
-    class LDAPTstBase:
+    class LDAPTstBase(object):
         """ Test base class for pytest based tests which need a LDAP server to talk to.
 
             Inherit your test class from this base class to test LDAP stuff.
@@ -248,7 +257,7 @@
             started = self.ldap_env.start_slapd()
             if not started:
                 pytest.skip("Failed to start {0} process, please see your syslog / log files"
-                             " (and check if stopping apparmor helps, in case you use it).".format(SLAPD_EXECUTABLE))
+                            " (and check if stopping apparmor helps, in case you use it).".format(SLAPD_EXECUTABLE))
             self.ldap_env.load_directory(ldif_content=self.ldif_content)
 
         def teardown_class(self):
--- a/MoinMoin/_tests/test_error.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/_tests/test_error.py	Wed Mar 20 01:25:01 2013 +0100
@@ -8,8 +8,6 @@
 """
 
 
-import pytest
-
 from MoinMoin import error
 
 
@@ -48,6 +46,7 @@
         err = error.Error(test)
         assert '%(message)s' % dict(message=err) == test
 
+
 class TestCompositeError(object):
 
     def setup_method(self, method):
@@ -74,4 +73,5 @@
         expected = ['This is a fatal Error']
         assert result == expected
 
+
 coverage_modules = ['MoinMoin.error']
--- a/MoinMoin/_tests/test_forms.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/_tests/test_forms.py	Wed Mar 20 01:25:01 2013 +0100
@@ -10,6 +10,7 @@
 
 from MoinMoin.forms import DateTimeUNIX
 
+
 def test_datetimeunix():
     dt = datetime.datetime(2012, 12, 21, 23, 45, 59)
     timestamp = timegm(dt.timetuple())
--- a/MoinMoin/_tests/test_test_environ.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/_tests/test_test_environ.py	Wed Mar 20 01:25:01 2013 +0100
@@ -7,17 +7,14 @@
 
 from StringIO import StringIO
 
-import pytest
-
 from flask import current_app as app
 from flask import g as flaskg
 
-from MoinMoin.conftest import init_test_app, deinit_test_app
-from MoinMoin.config import NAME, CURRENT, CONTENTTYPE, IS_SYSITEM, SYSITEM_VERSION
-from MoinMoin.storage.error import NoSuchItemError
+from MoinMoin.constants.keys import NAME, CONTENTTYPE
 
 from MoinMoin._tests import wikiconfig
 
+
 class TestStorageEnvironWithoutConfig(object):
     def setup_method(self, method):
         self.class_level_value = 123
@@ -33,17 +30,18 @@
         itemname = u"this item shouldn't exist yet"
         assert not storage.has_item(itemname)
         item = storage[itemname]
-        new_rev = item.store_revision({NAME: [itemname, ], CONTENTTYPE: u'text/plain'}, StringIO(''))
+        new_rev = item.store_revision({NAME: [itemname, ], CONTENTTYPE: u'text/plain;charset=utf-8'}, StringIO(''))
         assert storage.has_item(itemname)
 
 
 CONTENT_ACL = dict(
-        before="+All:write", # need to write to sys pages
-        default="All:read,write,admin,create,destroy",
-        after="Me:create",
-        hierarchic=False,
+    before="+All:write",  # need to write to sys pages
+    default="All:read,write,admin,create,destroy",
+    after="Me:create",
+    hierarchic=False,
 )
 
+
 class TestStorageEnvironWithConfig(object):
 
     class Config(wikiconfig.Config):
--- a/MoinMoin/_tests/test_user.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/_tests/test_user.py	Wed Mar 20 01:25:01 2013 +0100
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 # Copyright: 2003-2004 by Juergen Hermann <jh@web.de>
 # Copyright: 2009 by ReimarBauer
-# Copyright: 2013 by ThomasWaldmann
+# Copyright: 2011-2013 by ThomasWaldmann
 # License: GNU GPL v2 (or any later version), see LICENSE.txt for details.
 
 """
@@ -9,13 +9,9 @@
 """
 
 
-import pytest
-
-from flask import current_app as app
 from flask import g as flaskg
 
 from MoinMoin import user
-from MoinMoin.util import crypto
 
 
 class TestSimple(object):
@@ -71,7 +67,7 @@
     def testUnicodePassword(self):
         """ user: login with non-ascii password """
         # Create test user
-        name = u'__שם משתמש לא קיים__' # Hebrew
+        name = u'__שם משתמש לא קיים__'  # Hebrew
         password = name
         self.createUser(name, password)
 
@@ -91,7 +87,7 @@
         assert theUser.valid
 
         # invalidate the stored password (hash)
-        theUser.set_password("") # emptry str or None means "invalidate"
+        theUser.set_password("")  # emptry str or None means "invalidate"
         theUser.save()
 
         # Try to "login" with previous password
@@ -132,7 +128,7 @@
         # Login - this should replace the old password in the user file
         theUser = user.User(name=name, password=password)
         theUser.subscribe(pagename)
-        assert theUser.is_subscribed_to([pagename]) # list(!) of pages to check
+        assert theUser.is_subscribed_to([pagename])  # list(!) of pages to check
 
     def testSubscriptionSubPage(self):
         """ user: tests is_subscribed_to on a subpage """
@@ -144,7 +140,7 @@
         # Login - this should replace the old password in the user file
         theUser = user.User(name=name, password=password)
         theUser.subscribe(pagename)
-        assert not theUser.is_subscribed_to([testPagename]) # list(!) of pages to check
+        assert not theUser.is_subscribed_to([testPagename])  # list(!) of pages to check
 
     # Bookmarks -------------------------------------------------------
 
@@ -292,18 +288,18 @@
             u' User Name',
             u'User Name ',
             u'User   Name',
-            )
+        )
         for test in cases:
             assert not user.isValidName(test)
 
     def testValid(self):
         """ user: isValidName: accept names in any language, with spaces """
         cases = (
-            u'Jürgen Hermann', # German
-            u'ניר סופר', # Hebrew
-            u'CamelCase', # Good old camel case
-            u'가각간갇갈 갉갊감 갬갯걀갼' # Hangul (gibberish)
-            )
+            u'Jürgen Hermann',  # German
+            u'ניר סופר',  # Hebrew
+            u'CamelCase',  # Good old camel case
+            u'가각간갇갈 갉갊감 갬갯걀갼'  # Hangul (gibberish)
+        )
         for test in cases:
             assert user.isValidName(test)
 
--- a/MoinMoin/_tests/test_wikiutil.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/_tests/test_wikiutil.py	Wed Mar 20 01:25:01 2013 +0100
@@ -1,5 +1,5 @@
 # Copyright: 2003-2004 by Juergen Hermann <jh@web.de>
-# Copyright: 2007 by MoinMoin:ThomasWaldmann
+# Copyright: 2007-2013 by MoinMoin:ThomasWaldmann
 # License: GNU GPL v2 (or any later version), see LICENSE.txt for details.
 
 """
@@ -11,19 +11,20 @@
 
 from flask import current_app as app
 
-from MoinMoin import config, wikiutil
-from MoinMoin._tests import wikiconfig
+from MoinMoin.constants.chartypes import CHARS_SPACES
+from MoinMoin import wikiutil
 
 from werkzeug import MultiDict
 
 
 class TestCleanInput(object):
     def testCleanInput(self):
-        tests = [(u"", u""), # empty
-                 (u"aaa\r\n\tbbb", u"aaa   bbb"), # ws chars -> blanks
-                 (u"aaa\x00\x01bbb", u"aaabbb"), # strip weird chars
-                 (u"a"*500, u""), # too long
-                ]
+        tests = [
+            (u"", u""),  # empty
+            (u"aaa\r\n\tbbb", u"aaa   bbb"),  # ws chars -> blanks
+            (u"aaa\x00\x01bbb", u"aaabbb"),  # strip weird chars
+            (u"a" * 500, u""),  # too long
+        ]
         for instr, outstr in tests:
             assert wikiutil.clean_input(instr) == outstr
 
@@ -56,13 +57,14 @@
         (('MainPage', '/SubPage1'), 'MainPage/SubPage1'),
         (('MainPage', '/SubPage1/SubPage2'), 'MainPage/SubPage1/SubPage2'),
         (('MainPage/SubPage1', '/SubPage2/SubPage3'), 'MainPage/SubPage1/SubPage2/SubPage3'),
-        (('', '/OtherMainPage'), 'OtherMainPage'), # strange
+        (('', '/OtherMainPage'), 'OtherMainPage'),  # strange
         # PARENT_PREFIX
         (('MainPage/SubPage', '../SisterPage'), 'MainPage/SisterPage'),
         (('MainPage/SubPage1/SubPage2', '../SisterPage'), 'MainPage/SubPage1/SisterPage'),
         (('MainPage/SubPage1/SubPage2', '../../SisterPage'), 'MainPage/SisterPage'),
-        (('MainPage', '../SisterPage'), 'SisterPage'), # strange
+        (('MainPage', '../SisterPage'), 'SisterPage'),  # strange
     ]
+
     def test_abs_pagename(self):
         for (current_page, relative_page), absolute_page in self.tests:
             yield self._check_abs_pagename, current_page, relative_page, absolute_page
@@ -98,7 +100,7 @@
             (u'a/', u'a'),
             (u'a/////b/////c', u'a/b/c'),
             (u'a b/////c d/////e f', u'a b/c d/e f'),
-            )
+        )
         for test, expected in cases:
             result = wikiutil.normalize_pagename(test, app.cfg)
             assert result == expected
@@ -112,8 +114,8 @@
             (u'a     b     c', u'a b c'),
             (u'a   b  /  c    d  /  e   f', u'a b/c d/e f'),
             # All 30 unicode spaces
-            (config.chars_spaces, u''),
-            )
+            (CHARS_SPACES, u''),
+        )
         for test, expected in cases:
             result = wikiutil.normalize_pagename(test, app.cfg)
             assert result == expected
@@ -130,11 +132,12 @@
             (u'a  ', u'a'),
             (u'a  b  c', u'a b c'),
             (u'a  b  /  c  d  /  e  f', u'a b/c d/e f'),
-            )
+        )
         for test, expected in cases:
             result = wikiutil.normalize_pagename(test, app.cfg)
             assert result == expected
 
+
 class TestGroupItems(object):
 
     def testNormalizeGroupName(self):
@@ -147,7 +150,7 @@
             (u'Name,:Group', u'NameGroup'),
             # remove than normalize spaces
             (u'Name ! @ # $ % ^ & * ( ) + Group', u'Name Group'),
-            )
+        )
         for test, expected in cases:
             # validate we are testing valid group names
             if wikiutil.isGroupItem(test):
@@ -159,22 +162,24 @@
     # with no parent
     result = wikiutil.ParentItemName(u'itemname')
     expected = u''
-    assert result == expected, ('Expected "%(expected)s" but got "%(result)s"')
+    assert result == expected, 'Expected "%(expected)s" but got "%(result)s"' % locals()
     # with a parent
     result = wikiutil.ParentItemName(u'some/parent/itemname')
     expected = u'some/parent'
     assert result == expected
 
+
 def testdrawing2fname():
-    # with extension not in config.drawing_extensions
+    # with extension not in DRAWING_EXTENSIONS
     result = wikiutil.drawing2fname('Moin_drawing.txt')
     expected = 'Moin_drawing.txt.tdraw'
     assert result == expected
-    # with extension in config.drawing_extensions
+    # with extension in DRAWING_EXTENSIONS
     result = wikiutil.drawing2fname('Moindir.Moin_drawing.jpg')
     expected = 'Moindir.Moin_drawing.jpg'
     assert result == expected
 
+
 def testgetUnicodeIndexGroup():
     result = wikiutil.getUnicodeIndexGroup(['moin-2', 'MoinMoin'])
     expected = 'MOIN-2'
@@ -183,6 +188,7 @@
     with pytest.raises(IndexError):
         result = wikiutil.getUnicodeIndexGroup('')
 
+
 def testis_URL():
     sample_schemes = ['http', 'https', 'ftp', 'ssh']
     for scheme in sample_schemes:
@@ -196,6 +202,7 @@
     result = wikiutil.is_URL('invalid_scheme:MoinMoin')
     assert not result
 
+
 def testcontainsConflictMarker():
     # text with conflict marker
     result = wikiutil.containsConflictMarker("/!\\ '''Edit conflict - Conflict marker is present")
@@ -205,6 +212,7 @@
     result = wikiutil.containsConflictMarker('No conflict marker')
     assert not result
 
+
 def testsplit_anchor():
     """
     TODO: add the test for for split_anchor when we have better
@@ -222,15 +230,16 @@
     expected = ['#MoinMoin', '']
     assert result == expected
 
+
 def testfile_headers():
     test_headers = [
-                #test_file, content_type
-                ('imagefile.gif', 'image/gif'),
-                ('testfile.txt', 'text/plain'),
-                ('pdffile.pdf', 'application/pdf'),
-                ('docfile.doc', 'application/msword'),
-                (None, 'application/octet-stream')
-                ]
+        # test_file, content_type
+        ('imagefile.gif', 'image/gif'),
+        ('testfile.txt', 'text/plain'),
+        ('pdffile.pdf', 'application/pdf'),
+        ('docfile.doc', 'application/msword'),
+        (None, 'application/octet-stream'),
+    ]
 
     for test_file, content_type in test_headers:
         result = wikiutil.file_headers(test_file, None, 10)
@@ -242,4 +251,5 @@
     expected = [('Content-Type', 'text/plain')]
     assert result == expected
 
+
 coverage_modules = ['MoinMoin.wikiutil']
--- a/MoinMoin/_tests/wikiconfig.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/_tests/wikiconfig.py	Wed Mar 20 01:25:01 2013 +0100
@@ -1,4 +1,5 @@
 # Copyright: 2000-2004 by Juergen Hermann <jh@web.de>
+# Copyright: 2011-2013 by MoinMoin:ThomasWaldmann
 # License: GNU GPL v2 (or any later version), see LICENSE.txt for details.
 
 """
@@ -13,12 +14,17 @@
 
 import os
 from os.path import abspath, dirname, join
+
 from MoinMoin.config.default import DefaultConfig
 
+
 class Config(DefaultConfig):
+    """
+    default configuration for the unit tests
+    """
     _here = abspath(dirname(__file__))
     _root = abspath(join(_here, '..', '..'))
-    data_dir = join(_here, 'wiki', 'data') # needed for plugins package TODO
+    data_dir = join(_here, 'wiki', 'data')  # needed for plugins package TODO
     index_storage = 'FileStorage', (join(_here, 'wiki', 'index'), ), {}
     content_acl = None
     item_root = 'FrontPage'
--- a/MoinMoin/app.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/app.py	Wed Mar 20 01:25:01 2013 +0100
@@ -28,6 +28,7 @@
 from MoinMoin import log
 logging = log.getLogger(__name__)
 
+from MoinMoin.constants.misc import ANON
 from MoinMoin.i18n import i18n_init
 from MoinMoin.i18n import _, L_, N_
 
@@ -46,8 +47,7 @@
 
 
 def create_app_ext(flask_config_file=None, flask_config_dict=None,
-                   moin_config_class=None, warn_default=True, **kwargs
-                  ):
+                   moin_config_class=None, warn_default=True, **kwargs):
     """
     Factory for moin wsgi apps
 
@@ -110,8 +110,6 @@
 
             Rule('/<itemname:wikipage>')
             Rule('/<itemname:wikipage>/edit')
-
-        :param map: the :class:`Map`.
         """
         regex = '[^/]+?(/[^/]+?)*'
         weight = 200
@@ -226,7 +224,7 @@
 
     # if we still have no user obj, create a dummy:
     if not userobj:
-        userobj = user.User(name=u'anonymous', auth_method='invalid')
+        userobj = user.User(name=ANON, auth_method='invalid')
     # if we have a valid user we store it in the session
     if userobj.valid:
         session['user.itemid'] = userobj.itemid
--- a/MoinMoin/apps/admin/_tests/test_admin.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/apps/admin/_tests/test_admin.py	Wed Mar 20 01:25:01 2013 +0100
@@ -7,6 +7,7 @@
 
 from flask import url_for
 
+
 class TestAdmin(object):
     def _test_view_get(self, url, status='200 OK', data=('<html>', '</html>')):
         with self.app.test_client() as c:
--- a/MoinMoin/apps/admin/templates/admin/index.html	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/apps/admin/templates/admin/index.html	Wed Mar 20 01:25:01 2013 +0100
@@ -3,7 +3,6 @@
 <h1>{{ _("Admin Menu") }}</h1>
 <ul>
     <li><a href="{{ url_for('admin.userbrowser') }}">{{ _("Users") }}</a></li>
-    <li><a href="{{ url_for('admin.sysitems_upgrade') }}">{{ _("Upgrade System Items") }}</a></li>
     <li><a href="{{ url_for('admin.wikiconfig') }}">{{ _("Show Wiki Configuration") }}</a></li>
     <li><a href="{{ url_for('admin.wikiconfighelp') }}">{{ _("Wiki Configuration Help") }}</a></li>
 </ul>
--- a/MoinMoin/apps/admin/templates/admin/sysitems_upgrade.html	Tue Mar 19 20:32:47 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-{% extends theme("layout.html") %}
-{% block content %}
-<h1>{{ _("Upgrade System Items") }}</h1>
-<p>
-{{ _("You can upgrade your system items by uploading an xml file with new items below.") }}
-</p>
-<form action="{{ url_for('admin.sysitems_upgrade') }}" method="POST" enctype="multipart/form-data">
-<fieldset>
-    <label for="xmlfile">System items XML file:</label><input type="file" id="xmlfile" name="xmlfile" />
-    <input type="submit" name="submit" value="{{ _("Upgrade system items") }}" />
-</fieldset>
-</form>
-{% endblock %}
--- a/MoinMoin/apps/admin/templates/admin/userbrowser.html	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/apps/admin/templates/admin/userbrowser.html	Wed Mar 20 01:25:01 2013 +0100
@@ -18,7 +18,7 @@
             {% endif %}
         </td>
         <td>
-            <form action="{{ url_for('admin.userprofile', user_name=u.name) }}" method="GET">
+            <form action="{{ url_for('admin.userprofile', user_name=u.name[0]) }}" method="POST">
                 <input type="hidden" name="key" value="disabled" />
                 <input type="hidden" name="val" value="{{ u.disabled and "0" or "1" }}" />
                 <input type="submit" name="userprofile" value="{{ u.disabled and _("Enable user") or _("Disable user") }}" />
--- a/MoinMoin/apps/admin/templates/admin/wikiconfig.html	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/apps/admin/templates/admin/wikiconfig.html	Wed Mar 20 01:25:01 2013 +0100
@@ -30,6 +30,6 @@
 </td>
 </tr>
 {% endfor %}
-</tdbody>
+</tbody>
 </table>
 {% endblock %}
--- a/MoinMoin/apps/admin/views.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/apps/admin/views.py	Wed Mar 20 01:25:01 2013 +0100
@@ -20,16 +20,17 @@
 from MoinMoin.themes import render_template
 from MoinMoin.apps.admin import admin
 from MoinMoin import user
-from MoinMoin.storage.error import NoSuchRevisionError
-from MoinMoin.config import NAME, ITEMID, SIZE, EMAIL
-from MoinMoin.config import SUPERUSER
+from MoinMoin.constants.keys import NAME, ITEMID, SIZE, EMAIL, DISABLED
+from MoinMoin.constants.rights import SUPERUSER
 from MoinMoin.security import require_permission
 
+
 @admin.route('/superuser')
 @require_permission(SUPERUSER)
 def index():
     return render_template('admin/index.html', title_name=_(u"Admin"))
 
+
 @admin.route('/user')
 def index_user():
     return render_template('user/index_user.html', title_name=_(u"User"))
@@ -42,14 +43,13 @@
     User Account Browser
     """
     groups = flaskg.groups
-    revs = user.search_users() # all users
+    revs = user.search_users()  # all users
     user_accounts = [dict(uid=rev.meta[ITEMID],
                           name=rev.meta[NAME],
                           email=rev.meta[EMAIL],
-                          disabled=False,  # TODO: add to index
+                          disabled=rev.meta[DISABLED],
                           groups=[groupname for groupname in groups if rev.meta[NAME] in groups[groupname]],
-                     )
-                     for rev in revs]
+                     ) for rev in revs]
     return render_template('admin/userbrowser.html', user_accounts=user_accounts, title_name=_(u"Users"))
 
 
@@ -70,9 +70,9 @@
         ok = False
         if hasattr(u, key):
             ok = True
-            oldval = getattr(u, key)
+            oldval = u.profile[key]
             if isinstance(oldval, bool):
-                val = bool(val)
+                val = bool(int(val))
             elif isinstance(oldval, int):
                 val = int(val)
             elif isinstance(oldval, unicode):
@@ -80,7 +80,7 @@
             else:
                 ok = False
         if ok:
-            setattr(u, key, val)
+            u.profile[key] = val
             u.save()
             flash(u'{0}.{1}: {2} -> {3}'.format(user_name, key, unicode(oldval), unicode(val), ), "info")
         else:
@@ -97,29 +97,9 @@
     return redirect(url_for('.userbrowser'))
 
 
-@admin.route('/sysitems_upgrade', methods=['GET', 'POST', ])
-@require_permission(SUPERUSER)
-def sysitems_upgrade():
-    from MoinMoin.storage.backends import upgrade_sysitems
-    from MoinMoin.storage.error import BackendError
-    if request.method == 'GET':
-        action = 'syspages_upgrade'
-        label = 'Upgrade System Pages'
-        return render_template('admin/sysitems_upgrade.html',
-                               title_name=_(u"System items upgrade"))
-    if request.method == 'POST':
-        xmlfile = request.files.get('xmlfile')
-        try:
-            upgrade_sysitems(xmlfile)
-        except BackendError as e:
-            flash(_('System items upgrade failed due to the following error: %(error)s.', error=e), 'error')
-        else:
-            flash(_('System items have been upgraded successfully!'))
-        return redirect(url_for('.index'))
+from MoinMoin.config import default as defaultconfig
 
 
-from MoinMoin.config import default as defaultconfig
-
 @admin.route('/wikiconfig', methods=['GET', ])
 @require_permission(SUPERUSER)
 def wikiconfig():
@@ -198,11 +178,12 @@
 def highlighterhelp():
     """display a table with list of available Pygments lexers"""
     import pygments.lexers
-    headings = [_('Lexer description'),
-                _('Lexer names'),
-                _('File patterns'),
-                _('Mimetypes'),
-               ]
+    headings = [
+        _('Lexer description'),
+        _('Lexer names'),
+        _('File patterns'),
+        _('Mimetypes'),
+    ]
     lexers = pygments.lexers.get_all_lexers()
     rows = sorted([[desc, ' '.join(names), ' '.join(patterns), ' '.join(mimetypes), ]
                    for desc, names, patterns, mimetypes in lexers])
@@ -215,9 +196,10 @@
 @admin.route('/interwikihelp', methods=['GET', ])
 def interwikihelp():
     """display a table with list of known interwiki names / urls"""
-    headings = [_('InterWiki name'),
-                _('URL'),
-               ]
+    headings = [
+        _('InterWiki name'),
+        _('URL'),
+    ]
     rows = sorted(app.cfg.interwiki_map.items())
     return render_template('user/interwikihelp.html',
                            title_name=_(u"Interwiki Names"),
@@ -228,9 +210,10 @@
 @admin.route('/itemsize', methods=['GET', ])
 def itemsize():
     """display a table with item sizes"""
-    headings = [_('Size'),
-                _('Item name'),
-               ]
+    headings = [
+        _('Size'),
+        _('Item name'),
+    ]
     rows = [(rev.meta[SIZE], rev.name)
             for rev in flaskg.storage.documents(wikiname=app.cfg.interwikiname)]
     rows = sorted(rows, reverse=True)
--- a/MoinMoin/apps/feed/_tests/test_feed.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/apps/feed/_tests/test_feed.py	Wed Mar 20 01:25:01 2013 +0100
@@ -7,10 +7,10 @@
 
 from flask import url_for
 
-from MoinMoin.items import Item
-from MoinMoin.config import CONTENTTYPE, COMMENT
+from MoinMoin.constants.keys import COMMENT
 from MoinMoin._tests import update_item, wikiconfig
 
+
 class TestFeeds(object):
     class Config(wikiconfig.Config):
         """
--- a/MoinMoin/apps/feed/views.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/apps/feed/views.py	Wed Mar 20 01:25:01 2013 +0100
@@ -14,7 +14,6 @@
 from flask import request, Response
 from flask import current_app as app
 from flask import g as flaskg
-from flask import url_for
 
 from werkzeug.contrib.atom import AtomFeed
 from jinja2 import Markup
@@ -26,14 +25,13 @@
 
 from MoinMoin.i18n import _, L_, N_
 from MoinMoin.apps.feed import feed
-from MoinMoin.config import (NAME, NAME_EXACT, WIKINAME, ACL, ACTION, ADDRESS,
-                            HOSTNAME, USERID, COMMENT, MTIME, REVID, ALL_REVS,
-                            PARENTID, LATEST_REVS)
+from MoinMoin.constants.keys import NAME, NAME_EXACT, WIKINAME, COMMENT, MTIME, REVID, ALL_REVS, PARENTID, LATEST_REVS
 from MoinMoin.themes import get_editor_info, render_template
 from MoinMoin.items import Item
 from MoinMoin.util.crypto import cache_key
 from MoinMoin.util.interwiki import url_for_item
 
+
 @feed.route('/atom/<itemname:item_name>')
 @feed.route('/atom', defaults=dict(item_name=''))
 def atom(item_name):
@@ -78,7 +76,8 @@
                     content = hl_item.content._render_data_diff_atom(previous_rev, this_rev)
                 else:
                     # full html rendering for new items
-                    content = render_template('atom.html', get='first_revision', rev=this_rev, content=Markup(hl_item.content._render_data()), revision=this_revid)
+                    content = render_template('atom.html', get='first_revision', rev=this_rev,
+                                              content=Markup(hl_item.content._render_data()), revision=this_revid)
                 content_type = 'html'
             except Exception as e:
                 logging.exception("content rendering crashed")
@@ -89,7 +88,8 @@
             if rev_comment:
                 # Trim down extremely long revision comment
                 if len(rev_comment) > 80:
-                    content = render_template('atom.html', get='comment_cont_merge', comment=rev_comment[79:], content=Markup(content))
+                    content = render_template('atom.html', get='comment_cont_merge', comment=rev_comment[79:],
+                                              content=Markup(content))
                     rev_comment = u"{0}...".format(rev_comment[:79])
                 feed_title = u"{0} - {1}".format(author.get(NAME, ''), rev_comment)
             else:
@@ -101,7 +101,7 @@
                      author=author,
                      url=url_for_item(name, rev=this_revid, _external=True),
                      updated=datetime.fromtimestamp(rev.meta[MTIME]),
-                    )
+            )
         content = feed.to_string()
         # Hack to add XSLT stylesheet declaration since AtomFeed doesn't allow this
         content = content.split("\n")
--- a/MoinMoin/apps/frontend/_tests/test_frontend.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/apps/frontend/_tests/test_frontend.py	Wed Mar 20 01:25:01 2013 +0100
@@ -8,16 +8,12 @@
 
 from StringIO import StringIO
 
-import pytest
-
 from flask import url_for
 from flask import g as flaskg
 from werkzeug import ImmutableMultiDict, FileStorage
 
 from MoinMoin.apps.frontend import views
 from MoinMoin import user
-from MoinMoin.util import crypto
-from MoinMoin._tests import wikiconfig
 
 
 class TestFrontend(object):
@@ -56,33 +52,33 @@
         self._test_view_post('frontend.ajaxdelete', status='200 OK', content_types=['application/json', ], data=['{', '}'], form=dict(
             comment='Test',
             itemnames='["DoesntExist"]',
-            ), viewopts=dict(item_name='DoesntExist'))
+        ), viewopts=dict(item_name='DoesntExist'))
 
     def test_ajaxdelete_no_item_name_route(self):
         self._test_view_post('frontend.ajaxdelete', status='200 OK', content_types=['application/json', ], data=['{', '}'], form=dict(
             comment='Test',
             itemnames='["DoesntExist"]',
-            ))
+        ))
 
     def test_ajaxdestroy_item_name_route(self):
         self._test_view_post('frontend.ajaxdestroy', status='200 OK', content_types=['application/json', ], data=['{', '}'], form=dict(
             comment='Test',
             itemnames='["DoesntExist"]',
-            ), viewopts=dict(item_name='DoesntExist'))
+        ), viewopts=dict(item_name='DoesntExist'))
 
     def test_ajaxdestroy_no_item_name_route(self):
         self._test_view_post('frontend.ajaxdestroy', status='200 OK', content_types=['application/json', ], data=['{', '}'], form=dict(
             comment='Test',
             itemnames='["DoesntExist"]',
-            ))
+        ))
 
     def test_ajaxmodify(self):
         self._test_view_post('frontend.ajaxmodify', status='404 NOT FOUND', viewopts=dict(item_name='DoesntExist'))
 
     def test_jfu_server(self):
         self._test_view_post('frontend.jfu_server', status='200 OK', data=['{', '}'], form=dict(
-            data_file=FileStorage(StringIO("Hello, world"), filename='C:\\fakepath\\DoesntExist.txt', content_type='text/plain'),
-            ), viewopts=dict(item_name='WillBeCreated'), content_types=['application/json', ])
+            data_file=FileStorage(StringIO("Hello, world"), filename='C:\\fakepath\\DoesntExist.txt', content_type='text/plain; charset=utf-8'),
+        ), viewopts=dict(item_name='WillBeCreated'), content_types=['application/json', ])
 
     def test_show_item(self):
         self._test_view('frontend.show_item', status='404 NOT FOUND', viewopts=dict(item_name='DoesntExist'))
@@ -205,7 +201,7 @@
 
     def test_favicon(self):
         rv = self._test_view('frontend.favicon', content_types=['image/x-icon', 'image/vnd.microsoft.icon', ], data=[])
-        assert rv.data.startswith('\x00\x00') # "reserved word, should always be 0"
+        assert rv.data.startswith('\x00\x00')  # "reserved word, should always be 0"
 
     def test_global_tags(self):
         self._test_view('frontend.global_tags')
@@ -240,28 +236,28 @@
         flaskg.user = user.User(name=u'moin', password=u'Xiwejr622')
         form = self.fillPasswordChangeForm(u'Xiwejr622', u'Woodoo645', u'Woodoo645')
         valid = form.validate()
-        assert valid # form data is valid
+        assert valid  # form data is valid
 
     def test_user_unicode_password_change(self):
         name = u'moin'
-        password = u'__שם משתמש לא קיים__' # Hebrew
+        password = u'__שם משתמש לא קיים__'  # Hebrew
 
         self.createUser(name, password)
         flaskg.user = user.User(name=name, password=password)
         form = self.fillPasswordChangeForm(password, u'Woodoo645', u'Woodoo645')
         valid = form.validate()
-        assert valid # form data is valid
+        assert valid  # form data is valid
 
     def test_user_password_change_to_unicode_pw(self):
         name = u'moin'
         password = u'Xiwejr622'
-        new_password = u'__שם משתמש לא קיים__' # Hebrew
+        new_password = u'__שם משתמש לא קיים__'  # Hebrew
 
         self.createUser(name, password)
         flaskg.user = user.User(name=name, password=password)
         form = self.fillPasswordChangeForm(password, new_password, new_password)
         valid = form.validate()
-        assert valid # form data is valid
+        assert valid  # form data is valid
 
     def test_fail_user_password_change_pw_mismatch(self):
         self.createUser(u'moin', u'Xiwejr622')
@@ -285,14 +281,12 @@
         """ helper to fill UserSettingsPasswordForm form
         """
         FormClass = views.UserSettingsPasswordForm
-        request_form = ImmutableMultiDict(
-           [
-              ('usersettings_password_password_current', current_password),
-              ('usersettings_password_password1', password1),
-              ('usersettings_password_password2', password2),
-              ('usersettings_password_submit', u'Save')
-           ]
-        )
+        request_form = ImmutableMultiDict([
+            ('usersettings_password_password_current', current_password),
+            ('usersettings_password_password1', password1),
+            ('usersettings_password_password2', password2),
+            ('usersettings_password_submit', u'Save')
+        ])
         form = FormClass.from_flat(request_form)
         return form
 
--- a/MoinMoin/apps/frontend/views.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/apps/frontend/views.py	Wed Mar 20 01:25:01 2013 +0100
@@ -21,17 +21,16 @@
 import mimetypes
 import json
 from datetime import datetime
-from itertools import chain
 from collections import namedtuple
 from functools import wraps, partial
 
-from flask import request, url_for, flash, Response, make_response, redirect, session, abort, jsonify
+from flask import request, url_for, flash, Response, make_response, redirect, abort, jsonify
 from flask import current_app as app
 from flask import g as flaskg
 from flask.ext.babel import format_date
 from flask.ext.themes import get_themes_list
 
-from flatland import Form, Enum, List
+from flatland import Form, List
 from flatland.validation import Validator
 
 from jinja2 import Markup
@@ -45,18 +44,20 @@
 logging = log.getLogger(__name__)
 
 from MoinMoin.i18n import _, L_, N_
-from MoinMoin.themes import render_template, get_editor_info, contenttype_to_class
+from MoinMoin.themes import render_template, contenttype_to_class
 from MoinMoin.apps.frontend import frontend
-from MoinMoin.forms import OptionalText, RequiredText, URL, YourOpenID, YourEmail, RequiredPassword, Checkbox, InlineCheckbox, Select, Names, Tags, Natural, Submit, Hidden, MultiSelect
+from MoinMoin.forms import (OptionalText, RequiredText, URL, YourOpenID, YourEmail, RequiredPassword, Checkbox,
+                            InlineCheckbox, Select, Names, Tags, Natural, Hidden, MultiSelect, Enum)
 from MoinMoin.items import BaseChangeForm, Item, NonExistent
 from MoinMoin.items.content import content_registry
-from MoinMoin import config, user, util
+from MoinMoin import user, util
 from MoinMoin.constants.keys import *
+from MoinMoin.constants.itemtypes import ITEMTYPE_DEFAULT
+from MoinMoin.constants.chartypes import CHARS_UPPER, CHARS_LOWER
 from MoinMoin.util import crypto
 from MoinMoin.util.interwiki import url_for_item
-from MoinMoin.search import SearchForm, ValidSearch
-from MoinMoin.security.textcha import TextCha, TextChaizedForm, TextChaValid
-from MoinMoin.storage.error import NoSuchItemError, NoSuchRevisionError
+from MoinMoin.search import SearchForm
+from MoinMoin.security.textcha import TextCha, TextChaizedForm
 from MoinMoin.signalling import item_displayed, item_modified
 from MoinMoin.storage.middleware.protecting import AccessDenied
 
@@ -76,6 +77,7 @@
     item_name = app.cfg.item_root
     return redirect(url_for_item(item_name))
 
+
 @frontend.route('/robots.txt')
 def robots():
     return app.send_static_file('robots.txt')
@@ -100,7 +102,7 @@
     refs = OptionalText.using(label='refs')
     tags = Tags.using(optional=True).using(label='tags')
     history = InlineCheckbox.using(label=L_('search also in non-current revisions'))
-    submit = Submit.using(default=L_('Lookup'))
+    submit_label = L_('Lookup')
 
 
 @frontend.route('/+lookup', methods=['GET', 'POST'])
@@ -128,7 +130,6 @@
     # TAGS might be there multiple times, thus we need multi:
     lookup_form = LookupForm.from_flat(request.values.items(multi=True))
     valid = lookup_form.validate()
-    lookup_form['submit'].set_default() # XXX from_flat() kills all values
     if valid:
         history = bool(request.values.get('history'))
         idx_name = ALL_REVS if history else LATEST_REVS
@@ -169,7 +170,7 @@
                                            title_name=title_name,
                                            lookup_form=lookup_form,
                                            results=results,
-                                          )
+                    )
                     flaskg.clock.stop('lookup render')
                     if not num_results:
                         status = 404
@@ -177,7 +178,7 @@
     html = render_template('lookup.html',
                            title_name=title_name,
                            lookup_form=lookup_form,
-                          )
+    )
     return Response(html, status)
 
 
@@ -189,7 +190,7 @@
     with flaskg.storage.indexer.ix[LATEST_REVS].searcher() as searcher:
         # The search process should be as fast as possible so use
         # the indexer low-level documents instead of high-level Revisions.
-        doc = searcher.document(name_exact=item_name)
+        doc = searcher.document(**{NAME_EXACT: item_name})
         if not doc:
             return set()
         transcluded_names = set(doc[ITEMTRANSCLUSIONS])
@@ -198,12 +199,12 @@
             transcluded_names.update(transclusions)
         return transcluded_names
 
+
 @frontend.route('/+search/<itemname:item_name>', methods=['GET', 'POST'])
 @frontend.route('/+search', defaults=dict(item_name=u''), methods=['GET', 'POST'])
 def search(item_name):
     search_form = SearchForm.from_flat(request.values)
     valid = search_form.validate()
-    search_form['submit'].set_default() # XXX from_flat() kills all values
     query = search_form['q'].value
     if valid:
         history = bool(request.values.get('history'))
@@ -212,7 +213,7 @@
         q = qp.parse(query)
 
         _filter = None
-        if item_name: # Only search this item and subitems
+        if item_name:  # Only search this item and subitems
             prefix_name = item_name + u'/'
             terms = [Term(NAME_EXACT, item_name), Prefix(NAME_EXACT, prefix_name), ]
 
@@ -243,33 +244,26 @@
             flaskg.clock.start('search')
             results = searcher.search(q, filter=_filter, limit=100)
             flaskg.clock.stop('search')
-            # XXX if found that calling key_terms like you see below is 1000..10000x
-            # slower than the search itself, so we better don't do that right now.
-            key_terms_is_fast = False
-            if key_terms_is_fast:
-                flaskg.clock.start('search suggestions')
-                name_suggestions = u', '.join([word for word, score in results.key_terms(NAME, docs=20, numterms=10)])
-                content_suggestions = u', '.join([word for word, score in results.key_terms(CONTENT, docs=20, numterms=10)])
-                flaskg.clock.stop('search suggestions')
-            else:
-                name_suggestions = u''
-                content_suggestions = u''
+            flaskg.clock.start('search suggestions')
+            name_suggestions = [word for word, score in results.key_terms(NAME, docs=20, numterms=10)]
+            content_suggestions = [word for word, score in results.key_terms(CONTENT, docs=20, numterms=10)]
+            flaskg.clock.stop('search suggestions')
             flaskg.clock.start('search render')
             html = render_template('search.html',
                                    results=results,
-                                   name_suggestions=name_suggestions,
-                                   content_suggestions=content_suggestions,
+                                   name_suggestions=u', '.join(name_suggestions),
+                                   content_suggestions=u', '.join(content_suggestions),
                                    query=query,
                                    medium_search_form=search_form,
                                    item_name=item_name,
-                                  )
+            )
             flaskg.clock.stop('search render')
     else:
         html = render_template('search.html',
                                query=query,
                                medium_search_form=search_form,
                                item_name=item_name,
-                              )
+        )
     return html
 
 
@@ -337,7 +331,7 @@
         status = 200
     content = render_template('dom.xml',
                               data_xml=Markup(item.content._render_data_xml()),
-                             )
+    )
     return Response(content, status, mimetype='text/xml')
 
 
@@ -360,13 +354,13 @@
     return render_template('highlight.html',
                            item=item, item_name=item.name,
                            data_text=Markup(item.content._render_data_highlight()),
-                          )
+    )
 
 
 @presenter('meta', add_trail=True)
 def show_item_meta(item):
     show_revision = request.view_args['rev'] != CURRENT
-    show_navigation = False # TODO
+    show_navigation = False  # TODO
     first_rev = None
     last_rev = None
     if show_navigation:
@@ -383,17 +377,13 @@
                            meta_rendered=Markup(item._render_meta()),
                            show_revision=show_revision,
                            show_navigation=show_navigation,
-                          )
+    )
+
 
 @frontend.route('/+content/+<rev>/<itemname:item_name>')
 @frontend.route('/+content/<itemname:item_name>', defaults=dict(rev=CURRENT))
 def content_item(item_name, rev):
     """ same as show_item, but we only show the content """
-    # first check whether we have a valid search query:
-    search_form = SearchForm.from_flat(request.values)
-    if search_form.validate():
-        return _search(search_form, item_name)
-    search_form['submit'].set_default() # XXX from_flat() kills all values
     item_displayed.send(app._get_current_object(),
                         item_name=item_name)
     try:
@@ -407,15 +397,18 @@
                            data_rendered=Markup(item.content._render_data()),
                            )
 
+
 @presenter('get')
 def get_item(item):
     return item.content.do_get()
 
+
 @presenter('download')
 def download_item(item):
     mimetype = request.values.get("mimetype")
     return item.content.do_get(force_attachment=True, mimetype=mimetype)
 
+
 @frontend.route('/+convert/<itemname:item_name>')
 def convert_item(item_name):
     """
@@ -438,7 +431,7 @@
     item_name_converted = item_name + 'converted'
     try:
         # TODO implement Content.create and use it here
-        converted_item = Item.create(item_name_converted, itemtype=u'default', contenttype=contenttype)
+        converted_item = Item.create(item_name_converted, itemtype=ITEMTYPE_DEFAULT, contenttype=contenttype)
     except AccessDenied:
         abort(403)
     return converted_item.content._convert(item.content.internal_representation())
@@ -453,7 +446,7 @@
     After successful POST, redirects to the page.
     """
     # XXX drawing applets don't send itemtype
-    itemtype = request.values.get('itemtype', u'default')
+    itemtype = request.values.get('itemtype', ITEMTYPE_DEFAULT)
     contenttype = request.values.get('contenttype')
     try:
         item = Item.create(item_name, itemtype=itemtype, contenttype=contenttype)
@@ -467,15 +460,19 @@
 class TargetChangeForm(BaseChangeForm):
     target = RequiredText.using(label=L_('Target')).with_properties(placeholder=L_("The name of the target item"))
 
+
 class RevertItemForm(BaseChangeForm):
     name = 'revert_item'
 
+
 class DeleteItemForm(BaseChangeForm):
     name = 'delete_item'
 
+
 class DestroyItemForm(BaseChangeForm):
     name = 'destroy_item'
 
+
 class RenameItemForm(TargetChangeForm):
     name = 'rename_item'
 
@@ -503,7 +500,7 @@
                            item=item, item_name=item_name,
                            rev_id=rev,
                            form=form,
-                          )
+    )
 
 
 @frontend.route('/+rename/<itemname:item_name>', methods=['GET', 'POST'])
@@ -531,7 +528,7 @@
     return render_template(item.rename_template,
                            item=item, item_name=item_name,
                            form=form,
-                          )
+    )
 
 
 @frontend.route('/+delete/<itemname:item_name>', methods=['GET', 'POST'])
@@ -560,7 +557,8 @@
     return render_template(item.delete_template,
                            item=item, item_name=item_name,
                            form=form,
-                          )
+    )
+
 
 @frontend.route('/+ajaxdelete/<itemname:item_name>', methods=['POST'])
 @frontend.route('/+ajaxdelete', defaults=dict(item_name=''), methods=['POST'])
@@ -587,6 +585,7 @@
 
     return jsonify(response)
 
+
 @frontend.route('/+ajaxdestroy/<itemname:item_name>', methods=['POST'])
 @frontend.route('/+ajaxdestroy', defaults=dict(item_name=''), methods=['POST'])
 def ajaxdestroy(item_name):
@@ -630,7 +629,7 @@
 def destroy_item(item_name, rev):
     if rev is None:
         # no revision given
-        _rev = CURRENT # for item creation
+        _rev = CURRENT  # for item creation
         destroy_item = True
     else:
         _rev = rev
@@ -660,7 +659,7 @@
                            item=item, item_name=item_name,
                            rev_id=rev,
                            form=form,
-                          )
+    )
 
 
 @frontend.route('/+jfu-server/<itemname:item_name>', methods=['POST'])
@@ -670,7 +669,7 @@
     """
     data_file = request.files.get('data_file')
     subitem_name = data_file.filename
-    contenttype = data_file.content_type # guess by browser, based on file name
+    contenttype = data_file.content_type  # guess by browser, based on file name
     data = data_file.stream
     if item_name:
         subitem_prefix = item_name + u'/'
@@ -686,28 +685,30 @@
                        size=size,
                        url=url_for('.show_item', item_name=item_name, rev=revid),
                        contenttype=contenttype_to_class(contenttype),
-                      )
+        )
     except AccessDenied:
         abort(403)
 
 
-contenttype_groups = content_registry.group_names[:]
-contenttype_group_descriptions = {}
-for g in contenttype_groups:
-    contenttype_group_descriptions[g] = ', '.join([e.display_name for e in content_registry.groups[g]])
-contenttype_groups.append('unknown items')
+def contenttype_selects_gen():
+    for g in content_registry.group_names:
+        description = u', '.join([e.display_name for e in content_registry.groups[g]])
+        yield g, None, description
+    yield u'unknown items', None, u'Items of contenttype unknown to MoinMoin'
 
-ContenttypeGroup = MultiSelect.of(Enum.using(valid_values=contenttype_groups).with_properties(descriptions=contenttype_group_descriptions)).using(optional=True)
+ContenttypeGroup = MultiSelect.of(Enum.out_of(contenttype_selects_gen())).using(optional=True)
+
 
 class IndexForm(Form):
     contenttype = ContenttypeGroup
-    submit = Submit.using(default=L_('Filter'))
+    submit_label = L_('Filter')
+
 
 @frontend.route('/+index/', defaults=dict(item_name=''), methods=['GET', 'POST'])
 @frontend.route('/+index/<itemname:item_name>', methods=['GET', 'POST'])
 def index(item_name):
     try:
-        item = Item.create(item_name) # when item_name='', it gives toplevel index
+        item = Item.create(item_name)  # when item_name='', it gives toplevel index
     except AccessDenied:
         abort(403)
 
@@ -717,9 +718,8 @@
     # values, eg. calling items with multi=True. See Werkzeug documentation for
     # more.
     form = IndexForm.from_flat(request.args.items(multi=True))
-    form['submit'].set_default() # XXX from_flat() kills all values
     if not form['contenttype']:
-        form['contenttype'].set(contenttype_groups)
+        form['contenttype'].set(ContenttypeGroup.member_schema.valid_values)
 
     selected_groups = form['contenttype'].value
     startswith = request.values.get("startswith")
@@ -738,7 +738,7 @@
                            initials=initials,
                            startswith=startswith,
                            form=form,
-                          )
+    )
 
 
 @frontend.route('/+mychanges')
@@ -753,7 +753,7 @@
                            title_name=_(u'My Changes'),
                            headline=_(u'My Changes'),
                            item_names=my_changes
-                          )
+    )
 
 
 def _mychanges(userid):
@@ -784,7 +784,7 @@
                            item_name=item_name,
                            headline=_(u"Items which refer to '%(item_name)s'", item_name=item_name),
                            item_names=refs_here
-                          )
+    )
 
 
 def _backrefs(item_name):
@@ -821,10 +821,10 @@
     history = [dict((k, v) for k, v in rev.meta.iteritems() if k != CONTENT) for rev in revs]
     history_page = util.getPageContent(history, offset, results_per_page)
     return render_template('history.html',
-                           item_name=item_name, # XXX no item here
+                           item_name=item_name,  # XXX no item here
                            history_page=history_page,
                            bookmark_time=bookmark_time,
-                          )
+    )
 
 
 @frontend.route('/+history')
@@ -860,7 +860,8 @@
                            history=history,
                            current_timestamp=current_timestamp,
                            bookmark_time=bookmark_time,
-                          )
+    )
+
 
 def _compute_item_sets():
     """
@@ -942,7 +943,7 @@
         # Try to unsubscribe
         if not u.unsubscribe(item_name):
             msg = _("Can't remove regular expression subscription!") + u' ' + \
-                  _("Edit the subscription regular expressions in your settings."), "error"
+                _("Edit the subscription regular expressions in your settings."), "error"
     else:
         # Try to subscribe
         if not u.subscribe(item_name):
@@ -964,8 +965,8 @@
             return False
         if element['password1'].value != element['password2'].value:
             return self.note_error(element, state, 'passwords_mismatch_msg')
+        return True
 
-        return True
 
 class RegistrationForm(TextChaizedForm):
     """a simple user registration form"""
@@ -976,7 +977,7 @@
     password2 = RequiredPassword.with_properties(placeholder=L_("Repeat the same password"))
     email = YourEmail
     openid = YourOpenID.using(optional=True)
-    submit = Submit.using(default=L_('Register'))
+    submit_label = L_('Register')
 
     validators = [ValidRegistration()]
 
@@ -989,6 +990,7 @@
 
     openid = YourOpenID
 
+
 def _using_moin_auth():
     """Check if MoinAuth is being used for authentication.
 
@@ -1061,8 +1063,9 @@
                     if is_ok:
                         flash(_('Account verification required, please see the email we sent to your address.'), "info")
                     else:
-                        flash(_('An error occurred while sending the verification email: "%(message)s" Please contact an administrator to activate your account.',
-                            message=msg), "error")
+                        flash(_('An error occurred while sending the verification email: "%(message)s" '
+                                'Please contact an administrator to activate your account.',
+                                message=msg), "error")
                 else:
                     flash(_('Account created, please log in now.'), "info")
                 return redirect(url_for('.show_root'))
@@ -1070,21 +1073,21 @@
     return render_template(template,
                            title_name=title_name,
                            form=form,
-                          )
+    )
 
 
 @frontend.route('/+verifyemail', methods=['GET'])
 def verifyemail():
-    u = None
+    u = token = None
     if 'username' in request.values and 'token' in request.values:
         u = user.User(auth_username=request.values['username'])
         token = request.values['token']
-    if u and u.disabled and u.validate_recovery_token(token):
+    if u and u.disabled and token and u.validate_recovery_token(token):
         u.profile[DISABLED] = False
         u.save()
         flash(_("Your account has been activated, you can log in now."), "info")
     else:
-        flash(_('Your token is invalid!'), "error")
+        flash(_('Your username and/or token is invalid!'), "error")
     return redirect(url_for('.show_root'))
 
 
@@ -1108,7 +1111,7 @@
 
     username = OptionalText.using(label=L_('Name')).with_properties(placeholder=L_("Your login name"))
     email = YourEmail.using(optional=True)
-    submit = Submit.using(default=L_('Recover password'))
+    submit_label = L_('Recover password')
 
     validators = [ValidLostPassword()]
 
@@ -1143,7 +1146,8 @@
     return render_template('lostpass.html',
                            title_name=title_name,
                            form=form,
-                          )
+    )
+
 
 class ValidPasswordRecovery(Validator):
     """Validator for a valid password recovery form
@@ -1163,15 +1167,19 @@
 
         return True
 
+
 class PasswordRecoveryForm(Form):
     """a simple password recovery form"""
     name = 'recoverpass'
 
     username = RequiredText.using(label=L_('Name')).with_properties(placeholder=L_("Your login name"))
-    token = RequiredText.using(label=L_('Recovery token')).with_properties(placeholder=L_("The recovery token that has been sent to you"))
-    password1 = RequiredPassword.using(label=L_('New password')).with_properties(placeholder=L_("The login password you want to use"))
-    password2 = RequiredPassword.using(label=L_('New password (repeat)')).with_properties(placeholder=L_("Repeat the same password"))
-    submit = Submit.using(default=L_('Change password'))
+    token = RequiredText.using(label=L_('Recovery token')).with_properties(
+        placeholder=L_("The recovery token that has been sent to you"))
+    password1 = RequiredPassword.using(label=L_('New password')).with_properties(
+        placeholder=L_("The login password you want to use"))
+    password2 = RequiredPassword.using(label=L_('New password (repeat)')).with_properties(
+        placeholder=L_("Repeat the same password"))
+    submit_label = L_('Change password')
 
     validators = [ValidPasswordRecovery()]
 
@@ -1199,7 +1207,7 @@
     return render_template('recoverpass.html',
                            title_name=title_name,
                            form=form,
-                          )
+    )
 
 
 class ValidLogin(Validator):
@@ -1237,7 +1245,10 @@
     username = RequiredText.using(label=L_('Name'), optional=False).with_properties(autofocus=True)
     password = RequiredPassword
     openid = YourOpenID.using(optional=True)
-    submit = Submit.using(default=L_('Log in'))
+    # This field results in a login_submit field in the POST form, which is in
+    # turn looked for by setup_user() in app.py as marker for login requests.
+    submit = Hidden.using(default='1')
+    submit_label = L_('Log in')
 
     validators = [ValidLogin()]
 
@@ -1269,7 +1280,7 @@
                            title_name=title_name,
                            login_inputs=app.cfg.auth_login_inputs,
                            form=form,
-                          )
+    )
 
 
 @frontend.route('/+logout')
@@ -1308,21 +1319,27 @@
     name = 'usersettings_password'
     validators = [ValidChangePass()]
 
-    password_current = RequiredPassword.using(label=L_('Current Password')).with_properties(placeholder=L_("Your current login password"))
-    password1 = RequiredPassword.using(label=L_('New password')).with_properties(placeholder=L_("The login password you want to use"))
-    password2 = RequiredPassword.using(label=L_('New password (repeat)')).with_properties(placeholder=L_("Repeat the same password"))
-    submit = Submit.using(default=L_('Change password'))
+    password_current = RequiredPassword.using(label=L_('Current Password')).with_properties(
+        placeholder=L_("Your current login password"))
+    password1 = RequiredPassword.using(label=L_('New password')).with_properties(
+        placeholder=L_("The login password you want to use"))
+    password2 = RequiredPassword.using(label=L_('New password (repeat)')).with_properties(
+        placeholder=L_("Repeat the same password"))
+    submit_label = L_('Change password')
+
 
 class UserSettingsNotificationForm(Form):
     name = 'usersettings_notification'
     email = YourEmail
-    submit = Submit.using(default=L_('Save'))
+    submit_label = L_('Save')
 
 
 class UserSettingsNavigationForm(Form):
     name = 'usersettings_navigation'
+    # XXX Flatland insists a form having at least one element
+    dummy = Hidden
     # TODO: find a good way to handle quicklinks here
-    submit = Submit.using(default=L_('Save'))
+    submit_label = L_('Save')
 
 
 class UserSettingsOptionsForm(Form):
@@ -1332,7 +1349,7 @@
     scroll_page_after_edit = Checkbox.using(label=L_('Scroll page after edit'))
     show_comments = Checkbox.using(label=L_('Show comment sections'))
     disabled = Checkbox.using(label=L_('Disable this account forever'))
-    submit = Submit.using(default=L_('Save'))
+    submit_label = L_('Save')
 
 
 @frontend.route('/+usersettings', methods=['GET', 'POST'])
@@ -1342,30 +1359,30 @@
 
     # these forms can't be global because we need app object, which is only available within a request:
     class UserSettingsPersonalForm(Form):
-        name = 'usersettings_personal' # "name" is duplicate
+        name = 'usersettings_personal'  # "name" is duplicate
         name = Names.using(label=L_('Names')).with_properties(placeholder=L_("The login names you want to use"))
-        display_name = OptionalText.using(label=L_('Display-Name')).with_properties(placeholder=L_("Your display name (informational)"))
+        display_name = OptionalText.using(label=L_('Display-Name')).with_properties(
+            placeholder=L_("Your display name (informational)"))
         openid = YourOpenID.using(optional=True)
-        #timezones_keys = sorted(Locale('en').time_zones.keys())
-        timezones_keys = [unicode(tz) for tz in pytz.common_timezones]
-        timezone = Select.using(label=L_('Timezone')).valued(*timezones_keys)
-        supported_locales = [Locale('en')] + app.babel_instance.list_translations()
-        locales_available = sorted([(unicode(l), l.display_name) for l in supported_locales],
-                                   key=lambda x: x[1])
-        locales_keys = [l[0] for l in locales_available]
-        locale = Select.using(label=L_('Locale')).with_properties(labels=dict(locales_available)).valued(*locales_keys)
-        submit = Submit.using(default=L_('Save'))
+        #_timezones_keys = sorted(Locale('en').time_zones.keys())
+        _timezones_keys = [unicode(tz) for tz in pytz.common_timezones]
+        timezone = Select.using(label=L_('Timezone')).out_of((e, e) for e in _timezones_keys)
+        _supported_locales = [Locale('en')] + app.babel_instance.list_translations()
+        locale = Select.using(label=L_('Locale')).out_of(
+            ((unicode(l), l.display_name) for l in _supported_locales), sort_by=1)
+        submit_label = L_('Save')
 
     class UserSettingsUIForm(Form):
         name = 'usersettings_ui'
-        themes_available = sorted([(unicode(t.identifier), t.name) for t in get_themes_list()],
-                                  key=lambda x: x[1])
-        themes_keys = [t[0] for t in themes_available]
-        theme_name = Select.using(label=L_('Theme name')).with_properties(labels=dict(themes_available)).valued(*themes_keys)
-        css_url = URL.using(label=L_('User CSS URL'), optional=True).with_properties(placeholder=L_("Give the URL of your custom CSS (optional)"))
-        edit_rows = Natural.using(label=L_('Editor size')).with_properties(placeholder=L_("Editor textarea height (0=auto)"))
-        results_per_page = Natural.using(label=L_('History results per page')).with_properties(placeholder=L_("Number of results per page (0=no paging)"))
-        submit = Submit.using(default=L_('Save'))
+        theme_name = Select.using(label=L_('Theme name')).out_of(
+            ((unicode(t.identifier), t.name) for t in get_themes_list()), sort_by=1)
+        css_url = URL.using(label=L_('User CSS URL'), optional=True).with_properties(
+            placeholder=L_("Give the URL of your custom CSS (optional)"))
+        edit_rows = Natural.using(label=L_('Editor size')).with_properties(
+            placeholder=L_("Editor textarea height (0=auto)"))
+        results_per_page = Natural.using(label=L_('History results per page')).with_properties(
+            placeholder=L_("Number of results per page (0=no paging)"))
+        submit_label = L_('Save')
 
     form_classes = dict(
         personal=UserSettingsPersonalForm,
@@ -1410,44 +1427,50 @@
                     response['flash'].append((_("Your password has been changed."), "info"))
                 else:
                     if part == 'personal':
-                        if form['openid'].value and form['openid'].value != flaskg.user.openid and user.search_users(openid=form['openid'].value):
+                        if (form['openid'].value and form['openid'].value != flaskg.user.openid and
+                            user.search_users(openid=form['openid'].value)):
                             # duplicate openid
                             response['flash'].append((_("This openid is already in use."), "error"))
                             success = False
                         if set(form['name'].value) != set(flaskg.user.name):
                             new_names = set(form['name'].value) - set(flaskg.user.name)
                             for name in new_names:
-                                if user.search_users(name_exact=name):
+                                if user.search_users(**{NAME_EXACT: name}):
                                     # duplicate name
-                                    response['flash'].append((_("The username %(name)r is already in use.", name=name), "error"))
+                                    response['flash'].append((_("The username %(name)r is already in use.", name=name),
+                                                              "error"))
                                     success = False
                     if part == 'notification':
                         if (form['email'].value != flaskg.user.email and
-                            user.search_users(email=form['email'].value) and app.cfg.user_email_unique):
+                            user.search_users(**{EMAIL: form['email'].value}) and app.cfg.user_email_unique):
                             # duplicate email
                             response['flash'].append((_('This email is already in use'), 'error'))
                             success = False
                     if success:
                         user_old_email = flaskg.user.email
                         d = dict(form.value)
-                        d.pop('submit')
                         for k, v in d.items():
                             flaskg.user.profile[k] = v
-                        if part == 'notification' and app.cfg.user_email_verification and form['email'].value != user_old_email:
+                        if (part == 'notification' and app.cfg.user_email_verification and
+                            form['email'].value != user_old_email):
                             # disable account
                             flaskg.user.profile[DISABLED] = True
                             # send verification mail
                             is_ok, msg = flaskg.user.mail_email_verification()
                             if is_ok:
                                 flaskg.user.logout_session()
-                                response['flash'].append((_('Your account has been disabled because you changed your email address. Please see the email we sent to your address to reactivate it.'), "info"))
+                                response['flash'].append((_('Your account has been disabled because you changed your '
+                                                            'email address. Please see the email we sent to your '
+                                                            'address to reactivate it.'), "info"))
                                 response['redirect'] = url_for('.show_root')
                             else:
                                 # sending the verification email didn't work. reset email change and alert the user.
                                 flaskg.user.profile[DISABLED] = False
                                 flaskg.user.profile[EMAIL] = user_old_email
                                 flaskg.user.save()
-                                response['flash'].append((_('Your email address was not changed because sending the verification email failed. Please try again later.'), "error"))
+                                response['flash'].append((_('Your email address was not changed because sending the '
+                                                            'verification email failed. Please try again later.'),
+                                                          "error"))
                         else:
                             flaskg.user.save()
 
@@ -1466,7 +1489,7 @@
                 response['form'] = render_template('usersettings_ajax.html',
                                                    part=part,
                                                    form=form,
-                                                  )
+                )
                 return jsonify(**response)
             else:
                 # if it is not a XHR request but there is an redirect pending, we use a normal HTTP redirect
@@ -1485,7 +1508,7 @@
     return render_template('usersettings.html',
                            title_name=title_name,
                            form_objs=forms,
-                          )
+    )
 
 
 @frontend.route('/+bookmark')
@@ -1596,7 +1619,7 @@
                            last_rev_id=rev_ids[-1],
                            oldrev=oldrev,
                            newrev=newrev,
-                          )
+    )
 
 
 def _diff_raw(item, revid1, revid2):
@@ -1632,7 +1655,7 @@
                 item_names.append(name)
     return render_template("link_list_item_panel.html",
                            headline=_("Items with similar names to '%(item_name)s'", item_name=item_name),
-                           item_name=item_name, # XXX no item
+                           item_name=item_name,  # XXX no item
                            item_names=item_names)
 
 
@@ -1685,11 +1708,9 @@
     :returns: start, end, matches dict
     """
     if start_re is None:
-        start_re = re.compile(u'([{0}][{1}]+)'.format(config.chars_upper,
-                                                     config.chars_lower))
+        start_re = re.compile(u'([{0}][{1}]+)'.format(CHARS_UPPER, CHARS_LOWER))
     if end_re is None:
-        end_re = re.compile(u'([{0}][{1}]+)$'.format(config.chars_upper,
-                                                    config.chars_lower))
+        end_re = re.compile(u'([{0}][{1}]+)$'.format(CHARS_UPPER, CHARS_LOWER))
 
     # If we don't get results with wiki words matching, fall back to
     # simple first word and last word, using spaces.
@@ -1765,18 +1786,18 @@
     if not flaskg.storage[item_name]:
         abort(404, item_name)
     sitemap = NestedItemListBuilder().recurse_build([item_name])
-    del sitemap[0] # don't show current item name as sole toplevel list item
+    del sitemap[0]  # don't show current item name as sole toplevel list item
     return render_template('sitemap.html',
-                           item_name=item_name, # XXX no item
+                           item_name=item_name,  # XXX no item
                            sitemap=sitemap,
-                          )
+    )
 
 
 class NestedItemListBuilder(object):
     def __init__(self):
         self.children = set()
         self.numnodes = 0
-        self.maxnodes = 35 # approx. max count of nodes, not strict
+        self.maxnodes = 35  # approx. max count of nodes, not strict
 
     def recurse_build(self, names):
         result = []
@@ -1835,10 +1856,11 @@
             scale = weight_max / 2
         else:
             scale = weight_max / (count_max - count_min)
+
         def cls(count):
             # return the css class for this tag
             weight = scale * (count - count_min)
-            return "weight{0}".format(int(weight)) # weight0, ..., weight9
+            return "weight{0}".format(int(weight))  # weight0, ..., weight9
         tags = [(cls(count), tag) for tag, count in tags_counts]
     else:
         tags = []
--- a/MoinMoin/apps/misc/_tests/test_misc.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/apps/misc/_tests/test_misc.py	Wed Mar 20 01:25:01 2013 +0100
@@ -9,6 +9,7 @@
 
 from MoinMoin._tests import wikiconfig
 
+
 class TestMisc(object):
     class Config(wikiconfig.Config):
         """
--- a/MoinMoin/apps/misc/views.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/apps/misc/views.py	Wed Mar 20 01:25:01 2013 +0100
@@ -15,11 +15,9 @@
 
 from MoinMoin.apps.misc import misc
 
-from MoinMoin.config import NAME, MTIME
+from MoinMoin.constants.keys import MTIME
 from MoinMoin.themes import render_template
-from MoinMoin import wikiutil
 
-SITEMAP_HAS_SYSTEM_ITEMS = True
 
 @misc.route('/sitemap')
 def sitemap():
@@ -34,16 +32,9 @@
     for rev in flaskg.storage.documents(wikiname=app.cfg.interwikiname):
         name = rev.name
         mtime = rev.meta[MTIME]
-        if False: # was: wikiutil.isSystemItem(name)   XXX add back later, when we have that in the index
-            if not SITEMAP_HAS_SYSTEM_ITEMS:
-                continue
-            # system items are rather boring
-            changefreq = "yearly"
-            priority = "0.1"
-        else:
-            # these are the content items:
-            changefreq = "daily"
-            priority = "0.5"
+        # these are the content items:
+        changefreq = "daily"
+        priority = "0.5"
         sitemap.append((name, format_timestamp(mtime), changefreq, priority))
     # add an entry for root url
     root_item = app.cfg.item_root
--- a/MoinMoin/apps/serve/_tests/test_serve.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/apps/serve/_tests/test_serve.py	Wed Mar 20 01:25:01 2013 +0100
@@ -7,6 +7,7 @@
 
 from flask import url_for
 
+
 class TestServe(object):
     def test_index(self):
         with self.app.test_client() as c:
--- a/MoinMoin/auth/__init__.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/auth/__init__.py	Wed Mar 20 01:25:01 2013 +0100
@@ -177,21 +177,25 @@
         self.multistage = multistage
         self.redirect_to = redirect_to
 
+
 class ContinueLogin(LoginReturn):
     """ ContinueLogin - helper for auth method login that just continues """
     def __init__(self, user_obj, message=None):
         LoginReturn.__init__(self, user_obj, True, message=message)
 
+
 class CancelLogin(LoginReturn):
     """ CancelLogin - cancel login showing a message """
     def __init__(self, message):
         LoginReturn.__init__(self, None, False, message=message)
 
+
 class MultistageFormLogin(LoginReturn):
     """ MultistageFormLogin - require user to fill in another form """
     def __init__(self, multistage):
         LoginReturn.__init__(self, None, False, multistage=multistage)
 
+
 class MultistageRedirectLogin(LoginReturn):
     """ MultistageRedirectLogin - redirect user to another site before continuing login """
     def __init__(self, url):
@@ -202,22 +206,28 @@
     name = None
     login_inputs = []
     logout_possible = False
+
     def __init__(self, trusted=False, **kw):
         self.trusted = trusted
         if kw:
             raise TypeError("got unexpected arguments %r" % kw)
+
     def login(self, user_obj, **kw):
         return ContinueLogin(user_obj)
+
     def request(self, user_obj, **kw):
         return user_obj, True
+
     def logout(self, user_obj, **kw):
         if self.name and user_obj and user_obj.auth_method == self.name:
             logging.debug("{0}: logout - invalidating user {1!r}".format(self.name, user_obj.name))
             user_obj.valid = False
         return user_obj, True
+
     def login_hint(self):
         return None
 
+
 class MoinAuth(BaseAuth):
     """ handle login from moin login form """
     def __init__(self, **kw):
@@ -267,7 +277,7 @@
         Alternatively you can directly give a fixed user name (user_name)
         that will be considered as authenticated.
     """
-    name = 'given' # was 'http' in 1.8.x and before
+    name = 'given'  # was 'http' in 1.8.x and before
 
     def __init__(self,
                  env_var=None,  # environment variable we want to read (default: REMOTE_USER)
@@ -279,7 +289,7 @@
                  remove_blanks=False,  # Joe Doe -> JoeDoe
                  coding='utf-8',  # for decoding REMOTE_USER correctly
                  **kw
-                ):
+    ):
         super(GivenAuth, self).__init__(**kw)
         self.env_var = env_var
         self.user_name = user_name
@@ -352,7 +362,7 @@
             u.create_or_update()
         if u and u.valid:
             logging.debug("returning valid user {0!r}".format(u))
-            return u, True # True to get other methods called, too
+            return u, True  # True to get other methods called, too
         else:
             logging.debug("returning {0!r}".format(user_obj))
             return user_obj, True
@@ -371,7 +381,7 @@
               'openid': kw.get('login_openid'),
               'multistage': (stage and True) or None,
               'attended': True
-             }
+    }
     # add the other parameters from the form
     for param in kw.keys():
         params[param] = kw.get(param)
@@ -407,6 +417,7 @@
 
     return userobj
 
+
 def handle_logout(userobj):
     """ Logout the passed user from every configured authentication method. """
     if userobj is None:
@@ -419,6 +430,7 @@
             break
     return userobj
 
+
 def handle_request(userobj):
     """ Handle the per-request callbacks of the configured authentication methods. """
     for authmethod in app.cfg.auth:
@@ -427,6 +439,7 @@
             break
     return userobj
 
+
 def setup_from_session():
     userobj = None
     if 'user.itemid' in session:
--- a/MoinMoin/auth/_tests/test_auth.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/auth/_tests/test_auth.py	Wed Mar 20 01:25:01 2013 +0100
@@ -5,15 +5,14 @@
 Test for auth.__init__
 """
 
-from flask import current_app as app
 from flask import g as flaskg
 
-import pytest
-
 from MoinMoin._tests import wikiconfig
+from MoinMoin.constants.misc import ANON
 from MoinMoin.auth import GivenAuth, handle_login, get_multistage_continuation_url
 from MoinMoin.user import create_user
 
+
 class TestConfiguredGivenAuth(object):
     """ Test: configured GivenAuth """
     class Config(wikiconfig.Config):
@@ -54,13 +53,14 @@
         assert test_user.valid
         assert test_user.name == [u'Test_User', ]
 
+
 def test_handle_login():
     # no messages in the beginning
     assert not flaskg._login_messages
     test_user1 = handle_login(flaskg.user, login_username='test_user', login_password='test_password', stage='moin')
     test_login_message = [u'Invalid username or password.']
     assert flaskg._login_messages == test_login_message
-    assert test_user1.name0 == u'anonymous'
+    assert test_user1.name0 == ANON
     assert not test_user1.valid
     # pop the message
     flaskg._login_messages.pop()
@@ -75,8 +75,10 @@
     assert test_user2.name == [u'Test_User', ]
     assert test_user2.valid
 
+
 def test_get_multistage_continuation_url():
-    test_url = get_multistage_continuation_url('test_auth_name', extra_fields={'password': 'test_pass', 'test_key': 'test_value'})
+    test_url = get_multistage_continuation_url('test_auth_name',
+                                               extra_fields={'password': 'test_pass', 'test_key': 'test_value'})
     assert 'test_key=test_value' in test_url
     assert 'password=test_pass' in test_url
     assert 'stage=test_auth_name' in test_url
--- a/MoinMoin/auth/_tests/test_http.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/auth/_tests/test_http.py	Wed Mar 20 01:25:01 2013 +0100
@@ -10,7 +10,8 @@
 
 from MoinMoin.user import create_user
 from MoinMoin.auth.http import HTTPAuthMoin
-import pytest
+from MoinMoin.constants.misc import ANON
+
 
 class TestHTTPAuthMoin(object):
     """ Test: HTTPAuthMoin """
@@ -41,4 +42,4 @@
         flaskg.user.auth_method = 'invalid'
         test_user, bool_val = httpauthmoin_obj.request(flaskg.user)
         assert not test_user.valid
-        assert test_user.name0 == u'anonymous'
+        assert test_user.name0 == ANON
--- a/MoinMoin/auth/_tests/test_ldap_login.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/auth/_tests/test_ldap_login.py	Wed Mar 20 01:25:01 2013 +0100
@@ -23,6 +23,7 @@
 
 import ldap
 
+
 class TestLDAPServer(LDAPTstBase):
     basedn = BASEDN
     rootdn = ROOTDN
@@ -35,13 +36,14 @@
         server_uri = self.ldap_env.slapd.url
         base_dn = self.ldap_env.basedn
         lo = ldap.initialize(server_uri)
-        ldap.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3) # ldap v2 is outdated
+        ldap.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3)  # ldap v2 is outdated
         lo.simple_bind_s('', '')
         lusers = lo.search_st(base_dn, ldap.SCOPE_SUBTREE, '(uid=*)')
         uids = [ldap_dict['uid'][0] for dn, ldap_dict in lusers]
         assert 'usera' in uids
         assert 'userb' in uids
 
+
 class TestMoinLDAPLogin(LDAPTstBase):
     basedn = BASEDN
     rootdn = ROOTDN
@@ -132,6 +134,7 @@
         u2 = handle_login(None, username='usera', password='wrong')
         assert u2 is None
 
+
 class TestTwoLdapServers(object):
     basedn = BASEDN
     rootdn = ROOTDN
@@ -148,7 +151,7 @@
             started = ldap_env.start_slapd()
             if not started:
                 pytest.skip("Failed to start {0} process, please see your syslog / log files"
-                             " (and check if stopping apparmor helps, in case you use it).".format(SLAPD_EXECUTABLE))
+                            " (and check if stopping apparmor helps, in case you use it).".format(SLAPD_EXECUTABLE))
             ldap_env.load_directory(ldif_content=self.ldif_content)
             self.ldap_envs.append(ldap_env)
 
@@ -164,7 +167,7 @@
             server_uri = ldap_env.slapd.url
             base_dn = ldap_env.basedn
             lo = ldap.initialize(server_uri)
-            ldap.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3) # ldap v2 is outdated
+            ldap.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3)  # ldap v2 is outdated
             lo.simple_bind_s('', '')
             lusers = lo.search_st(base_dn, ldap.SCOPE_SUBTREE, '(uid=*)')
             uids = [ldap_dict['uid'][0] for dn, ldap_dict in lusers]
@@ -188,7 +191,7 @@
             started = ldap_env.start_slapd()
             if not started:
                 pytest.skip("Failed to start {0} process, please see your syslog / log files"
-                             " (and check if stopping apparmor helps, in case you use it).".format(SLAPD_EXECUTABLE))
+                            " (and check if stopping apparmor helps, in case you use it).".format(SLAPD_EXECUTABLE))
             ldap_env.load_directory(ldif_content=self.ldif_content)
             self.ldap_envs.append(ldap_env)
 
@@ -198,13 +201,13 @@
         server_uri = 'ldap://127.0.0.1:3891'
         base_dn = 'ou=testing,dc=example,dc=org'
         ldap_auth1 = LDAPAuth(server_uri=server_uri, base_dn=base_dn,
-                             name="ldap1", autocreate=True,
-                             timeout=1)
+                              name="ldap1", autocreate=True,
+                              timeout=1)
         # short timeout, faster testing
         server_uri = 'ldap://127.0.0.1:3892'
         ldap_auth2 = LDAPAuth(server_uri=server_uri, base_dn=base_dn,
-                             name="ldap2", autocreate=True,
-                             timeout=1)
+                              name="ldap2", autocreate=True,
+                              timeout=1)
 
         auth = [ldap_auth1, ldap_auth2]
 
@@ -214,7 +217,7 @@
             try:
                 ldap_env.stop_slapd()
             except:
-                pass # one will fail, because it is already stopped
+                pass  # one will fail, because it is already stopped
             ldap_env.destroy_env()
 
     def testMoinLDAPFailOver(self):
--- a/MoinMoin/auth/_tests/test_log.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/auth/_tests/test_log.py	Wed Mar 20 01:25:01 2013 +0100
@@ -8,9 +8,11 @@
 from MoinMoin import log
 logging = log.getLogger(__name__)
 
+from flask import g as flaskg
+
 from MoinMoin.auth.log import AuthLog
-from flask import g as flaskg
-import pytest
+from MoinMoin.constants.misc import ANON
+
 
 class TestAuthLog(object):
     """ Test: TestAuthLog """
@@ -19,13 +21,13 @@
         result = authlog_obj.login(flaskg.user)
         assert result.continue_flag
         test_user_obj = result.user_obj
-        assert test_user_obj.name0 == u'anonymous'
+        assert test_user_obj.name0 == ANON
 
     def test_request(self):
         authlog_obj = AuthLog()
         result = authlog_obj.request(flaskg.user)
         test_user, bool_value = result
-        assert test_user.name0 == u'anonymous'
+        assert test_user.name0 == ANON
         assert not test_user.valid
         assert bool_value
 
@@ -33,6 +35,6 @@
         authlog_obj = AuthLog()
         result = authlog_obj.logout(flaskg.user)
         test_user, bool_value = result
-        assert test_user.name0 == u'anonymous'
+        assert test_user.name0 == ANON
         assert not test_user.valid
         assert bool_value
--- a/MoinMoin/auth/http.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/auth/http.py	Wed Mar 20 01:25:01 2013 +0100
@@ -22,7 +22,7 @@
 
 from flask import request
 
-from MoinMoin import config, user
+from MoinMoin import user
 from MoinMoin.i18n import _, L_, N_
 from MoinMoin.auth import BaseAuth, GivenAuth
 
@@ -48,7 +48,8 @@
 
         auth = request.authorization
         if auth and auth.username and auth.password is not None:
-            logging.debug("http basic auth, received username: {0!r} password: {1!r}".format(auth.username, auth.password))
+            logging.debug("http basic auth, received username: {0!r} password: {1!r}".format(
+                auth.username, auth.password))
             u = user.User(name=auth.username.decode(self.coding),
                           password=auth.password.decode(self.coding),
                           auth_method=self.name, auth_attribs=[], trusted=self.trusted)
@@ -66,7 +67,7 @@
             u.create_or_update()
         if u and u.valid:
             logging.debug("returning valid user {0!r}".format(u))
-            return u, True # True to get other methods called, too
+            return u, True  # True to get other methods called, too
         else:
             logging.debug("returning {0!r}".format(user_obj))
             return user_obj, True
--- a/MoinMoin/auth/ldap_login.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/auth/ldap_login.py	Wed Mar 20 01:25:01 2013 +0100
@@ -41,7 +41,8 @@
     logout_possible = True
     name = 'ldap'
 
-    def __init__(self,
+    def __init__(
+        self,
         server_uri='ldap://localhost',  # ldap / active directory server URI
                                         # use ldaps://server:636 url for ldaps,
                                         # use  ldap://server for ldap without tls (and set start_tls to 0),
@@ -60,34 +61,34 @@
         bind_pw='',
         base_dn='',  # base DN we use for searching
                      #base_dn = 'ou=SOMEUNIT,dc=example,dc=org'
-        scope=ldap.SCOPE_SUBTREE, # scope of the search we do (2 == ldap.SCOPE_SUBTREE)
-        referrals=0, # LDAP REFERRALS (0 needed for AD)
+        scope=ldap.SCOPE_SUBTREE,  # scope of the search we do (2 == ldap.SCOPE_SUBTREE)
+        referrals=0,  # LDAP REFERRALS (0 needed for AD)
         search_filter='(uid=%(username)s)',  # ldap filter used for searching:
                                              #search_filter = '(sAMAccountName=%(username)s)' # (AD)
                                              #search_filter = '(uid=%(username)s)' # (OpenLDAP)
                                              # you can also do more complex filtering like:
                                              # "(&(cn=%(username)s)(memberOf=CN=WikiUsers,OU=Groups,DC=example,DC=org))"
         # some attribute names we use to extract information from LDAP:
-        givenname_attribute=None, # ('givenName') ldap attribute we get the first name from
-        surname_attribute=None, # ('sn') ldap attribute we get the family name from
-        displayname_attribute=None, # ('displayName') ldap attribute we get the display_name from
-        email_attribute=None, # ('mail') ldap attribute we get the email address from
-        email_callback=None, # called to make up email address
-        name_callback=None, # called to use a Wiki name different from the login name
-        coding='utf-8', # coding used for ldap queries and result values
-        timeout=10, # how long we wait for the ldap server [s]
-        start_tls=0, # 0 = No, 1 = Try, 2 = Required
+        givenname_attribute=None,  # ('givenName') ldap attribute we get the first name from
+        surname_attribute=None,  # ('sn') ldap attribute we get the family name from
+        displayname_attribute=None,  # ('displayName') ldap attribute we get the display_name from
+        email_attribute=None,  # ('mail') ldap attribute we get the email address from
+        email_callback=None,  # called to make up email address
+        name_callback=None,  # called to use a Wiki name different from the login name
+        coding='utf-8',  # coding used for ldap queries and result values
+        timeout=10,  # how long we wait for the ldap server [s]
+        start_tls=0,  # 0 = No, 1 = Try, 2 = Required
         tls_cacertdir=None,
         tls_cacertfile=None,
         tls_certfile=None,
         tls_keyfile=None,
-        tls_require_cert=0, # 0 == ldap.OPT_X_TLS_NEVER (needed for self-signed certs)
-        bind_once=False, # set to True to only do one bind - useful if configured to bind as the user on the first attempt
-        autocreate=False, # set to True if you want to autocreate user profiles
-        name='ldap', # use e.g. 'ldap_pdc' and 'ldap_bdc' (or 'ldap1' and 'ldap2') if you auth against 2 ldap servers
-        report_invalid_credentials=True, # whether to emit "invalid username or password" msg at login time or not
+        tls_require_cert=0,  # 0 == ldap.OPT_X_TLS_NEVER (needed for self-signed certs)
+        bind_once=False,  # set to True to only do one bind - useful if configured to bind as the user on first attempt
+        autocreate=False,  # set to True if you want to autocreate user profiles
+        name='ldap',  # use e.g. 'ldap_pdc' and 'ldap_bdc' (or 'ldap1' and 'ldap2') if you auth against 2 ldap servers
+        report_invalid_credentials=True,  # whether to emit "invalid username or password" msg at login time or not
         **kw
-        ):
+    ):
         super(LDAPAuth, self).__init__(**kw)
         self.server_uri = server_uri
         self.bind_dn = bind_dn
@@ -133,9 +134,10 @@
             try:
                 u = None
                 dn = None
+                server = self.server_uri
                 coding = self.coding
                 logging.debug("Setting misc. ldap options...")
-                ldap.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3) # ldap v2 is outdated
+                ldap.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3)  # ldap v2 is outdated
                 ldap.set_option(ldap.OPT_REFERRALS, self.referrals)
                 ldap.set_option(ldap.OPT_NETWORK_TIMEOUT, self.timeout)
 
@@ -152,7 +154,6 @@
                         if value is not None:
                             ldap.set_option(option, value)
 
-                server = self.server_uri
                 logging.debug("Trying to initialize {0!r}.".format(server))
                 l = ldap.initialize(server)
                 logging.debug("Connected to LDAP server {0!r}.".format(server))
@@ -176,11 +177,11 @@
                 filterstr = self.search_filter % locals()
                 logging.debug("Searching {0!r}".format(filterstr))
                 attrs = [getattr(self, attr) for attr in [
-                                         'email_attribute',
-                                         'displayname_attribute',
-                                         'surname_attribute',
-                                         'givenname_attribute',
-                                         ] if getattr(self, attr) is not None]
+                    'email_attribute',
+                    'displayname_attribute',
+                    'surname_attribute',
+                    'givenname_attribute',
+                ] if getattr(self, attr) is not None]
                 lusers = l.search_st(self.base_dn, self.scope, filterstr.encode(coding),
                                      attrlist=attrs, timeout=self.timeout)
                 # we remove entries with dn == None to get the real result list:
@@ -193,7 +194,8 @@
                 result_length = len(lusers)
                 if result_length != 1:
                     if result_length > 1:
-                        logging.warning("Search found more than one ({0}) matches for {1!r}.".format(result_length, filterstr))
+                        logging.warning("Search found more than one ({0}) matches for {1!r}.".format(
+                            result_length, filterstr))
                     if result_length == 0:
                         logging.debug("Search found no matches for {0!r}.".format(filterstr, ))
                     if self.report_invalid_credentials:
@@ -233,18 +235,22 @@
                     username = self.name_callback(ldap_dict)
 
                 if email:
-                    u = user.User(auth_username=username, auth_method=self.name, auth_attribs=('name', 'password', 'email', 'mailto_author', ),
+                    u = user.User(auth_username=username, auth_method=self.name,
+                                  auth_attribs=('name', 'password', 'email', 'mailto_author', ),
                                   trusted=self.trusted)
                     u.email = email
                 else:
-                    u = user.User(auth_username=username, auth_method=self.name, auth_attribs=('name', 'password', 'mailto_author', ),
+                    u = user.User(auth_username=username, auth_method=self.name,
+                                  auth_attribs=('name', 'password', 'mailto_author', ),
                                   trusted=self.trusted)
                 u.name = username
                 u.display_name = display_name
-                logging.debug("creating user object with name {0!r} email {1!r} display name {2!r}".format(username, email, display_name))
+                logging.debug("creating user object with name {0!r} email {1!r} display name {2!r}".format(
+                    username, email, display_name))
 
             except ldap.INVALID_CREDENTIALS as err:
-                logging.debug("invalid credentials (wrong password?) for dn {0!r} (username: {1!r})".format(dn, username))
+                logging.debug("invalid credentials (wrong password?) for dn {0!r} (username: {1!r})".format(
+                    dn, username))
                 return CancelLogin(_("Invalid username or password."))
 
             if u and self.autocreate:
--- a/MoinMoin/auth/log.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/auth/log.py	Wed Mar 20 01:25:01 2013 +0100
@@ -14,6 +14,7 @@
 
 from MoinMoin.auth import BaseAuth, ContinueLogin
 
+
 class AuthLog(BaseAuth):
     """ just log the call, do nothing else """
     name = "log"
--- a/MoinMoin/auth/openidrp.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/auth/openidrp.py	Wed Mar 20 01:25:01 2013 +0100
@@ -20,7 +20,7 @@
 from flask import current_app as app
 from MoinMoin.auth import BaseAuth, get_multistage_continuation_url
 from MoinMoin.auth import ContinueLogin, CancelLogin, MultistageFormLogin, MultistageRedirectLogin
-from MoinMoin.config import ITEMID
+from MoinMoin.constants.keys import ITEMID
 from MoinMoin import user
 from MoinMoin.i18n import _, L_, N_
 
@@ -99,7 +99,7 @@
                                                            _external=True,
                                                            openid_openid=identity,
                                                            openid_submit='1'
-                                                          ))
+                    ))
 
             # not trusted
             return ContinueLogin(None, _('This OpenID provider is not trusted.'))
--- a/MoinMoin/auth/smb_mount.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/auth/smb_mount.py	Wed Mar 20 01:25:01 2013 +0100
@@ -16,26 +16,28 @@
 
 from MoinMoin.auth import BaseAuth, CancelLogin, ContinueLogin
 
+
 class SMBMount(BaseAuth):
     """ auth plugin for (un)mounting an smb share,
         this is a wrapper around mount.cifs -o <options> //server/share mountpoint
 
         See man mount.cifs for details.
     """
-    def __init__(self,
-        server, # mount.cifs //server/share
-        share, # mount.cifs //server/share
-        mountpoint_fn, # function of username to determine the mountpoint, e.g.:
-                       # lambda username: u'/mnt/wiki/%s' % username
-        dir_user, # username to get the uid that is used for mount.cifs -o uid=... (e.g. 'www-data')
-        domain, # mount.cifs -o domain=...
-        dir_mode='0700', # mount.cifs -o dir_mode=...
-        file_mode='0600', # mount.cifs -o file_mode=...
-        iocharset='utf-8', # mount.cifs -o iocharset=... (try 'iso8859-1' if default does not work)
-        coding='utf-8', # encoding used for username/password/cmdline (try 'iso8859-1' if default does not work)
-        log='/dev/null', # logfile for mount.cifs output
+    def __init__(
+        self,
+        server,  # mount.cifs //server/share
+        share,  # mount.cifs //server/share
+        mountpoint_fn,  # function of username to determine the mountpoint, e.g.:
+                        # lambda username: u'/mnt/wiki/%s' % username
+        dir_user,  # username to get the uid that is used for mount.cifs -o uid=... (e.g. 'www-data')
+        domain,  # mount.cifs -o domain=...
+        dir_mode='0700',  # mount.cifs -o dir_mode=...
+        file_mode='0600',  # mount.cifs -o file_mode=...
+        iocharset='utf-8',  # mount.cifs -o iocharset=... (try 'iso8859-1' if default does not work)
+        coding='utf-8',  # encoding used for username/password/cmdline (try 'iso8859-1' if default does not work)
+        log='/dev/null',  # logfile for mount.cifs output
         **kw
-        ):
+    ):
         super(SMBMount, self).__init__(**kw)
         self.server = server
         self.share = share
@@ -51,13 +53,16 @@
     def do_smb(self, username, password, login):
         logging.debug("login={0} logout={1}: got name={2!r}".format(login, not login, username))
 
-        import os, pwd, subprocess
+        import os
+        import pwd
+        import subprocess
         web_username = self.dir_user
-        web_uid = pwd.getpwnam(web_username)[2] # XXX better just use current uid?
+        web_uid = pwd.getpwnam(web_username)[2]  # XXX better just use current uid?
 
         mountpoint = self.mountpoint_fn(username)
         if login:
-            cmd = u"sudo mount -t cifs -o user=%(user)s,domain=%(domain)s,uid=%(uid)d,dir_mode=%(dir_mode)s,file_mode=%(file_mode)s,iocharset=%(iocharset)s //%(server)s/%(share)s %(mountpoint)s >>%(log)s 2>&1"
+            cmd = (u"sudo mount -t cifs -o user=%(user)s,domain=%(domain)s,uid=%(uid)d,dir_mode=%(dir_mode)s,file_mode="
+                   u"%(file_mode)s,iocharset=%(iocharset)s //%(server)s/%(share)s %(mountpoint)s >>%(log)s 2>&1")
         else:
             cmd = u"sudo umount %(mountpoint)s >>%(log)s 2>&1"
 
@@ -77,7 +82,7 @@
         if login:
             try:
                 if not os.path.exists(mountpoint):
-                    os.makedirs(mountpoint) # the dir containing the mountpoint must be writeable for us!
+                    os.makedirs(mountpoint)  # the dir containing the mountpoint must be writeable for us!
             except OSError:
                 pass
             env['PASSWD'] = password.encode(self.coding)
--- a/MoinMoin/config/__init__.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/config/__init__.py	Wed Mar 20 01:25:01 2013 +0100
@@ -1,13 +1,4 @@
-# Copyright: 2011 MoinMoin:ThomasWaldmann
+# Copyright: 2011-2013 MoinMoin:ThomasWaldmann
 # License: GNU GPL v2 (or any later version), see LICENSE.txt for details.
 
-"""
-MoinMoin - configuration defaults and support code
-"""
-
-# provide compatibility for stuff not using MoinMoin.constants yet
-from MoinMoin.constants.rights import *
-from MoinMoin.constants.chartypes import *
-from MoinMoin.constants.contenttypes import *
-from MoinMoin.constants.keys import *
-from MoinMoin.constants.misc import *
+# Nothing to see here any more, please do direct imports from MoinMoin.constants.*
--- a/MoinMoin/config/_tests/test_defaultconfig.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/config/_tests/test_defaultconfig.py	Wed Mar 20 01:25:01 2013 +0100
@@ -10,22 +10,24 @@
 
 from flask import current_app as app
 
+
 class TestPasswordChecker(object):
     username = u"SomeUser"
     tests_builtin = [
-        (u'', False), # empty
-        (u'1966', False), # too short
-        (u'asdfghjk', False), # keyboard sequence
-        (u'QwertZuiop', False), # german keyboard sequence, with uppercase
-        (u'mnbvcx', False), # reverse keyboard sequence
-        (u'12345678', False), # keyboard sequence, too easy
-        (u'aaaaaaaa', False), # not enough different chars
-        (u'BBBaaaddd', False), # not enough different chars
-        (username, False), # username == password
-        (username[1:-1], False), # password in username
-        (u"XXX{0}XXX".format(username), False), # username in password
-        (u'Moin-2007', True), # this should be OK
+        (u'', False),  # empty
+        (u'1966', False),  # too short
+        (u'asdfghjk', False),  # keyboard sequence
+        (u'QwertZuiop', False),  # german keyboard sequence, with uppercase
+        (u'mnbvcx', False),  # reverse keyboard sequence
+        (u'12345678', False),  # keyboard sequence, too easy
+        (u'aaaaaaaa', False),  # not enough different chars
+        (u'BBBaaaddd', False),  # not enough different chars
+        (username, False),  # username == password
+        (username[1:-1], False),  # password in username
+        (u"XXX{0}XXX".format(username), False),  # username in password
+        (u'Moin-2007', True),  # this should be OK
     ]
+
     def testBuiltinPasswordChecker(self):
         pw_checker = app.cfg.password_checker
         if not pw_checker:
@@ -36,4 +38,5 @@
                 print "{0!r}: {1}".format(pw, pw_error)
                 assert result == (pw_error is None)
 
+
 coverage_modules = ['MoinMoin.config.default']
--- a/MoinMoin/config/default.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/config/default.py	Wed Mar 20 01:25:01 2013 +0100
@@ -20,7 +20,9 @@
 logging = log.getLogger(__name__)
 
 from MoinMoin.i18n import _, L_, N_
-from MoinMoin import config, error
+from MoinMoin import error
+from MoinMoin.constants.rights import ACL_RIGHTS_CONTENTS, ACL_RIGHTS_FUNCTIONS
+from MoinMoin.constants.keys import *
 from MoinMoin import datastruct
 from MoinMoin.auth import MoinAuth
 from MoinMoin.util import plugins
@@ -76,10 +78,10 @@
 
         plugins._loadPluginModule(self)
 
-        if self.user_defaults['timezone'] is None:
-            self.user_defaults['timezone'] = self.timezone_default
-        if self.user_defaults['theme_name'] is None:
-            self.user_defaults['theme_name'] = self.theme_default
+        if self.user_defaults[TIMEZONE] is None:
+            self.user_defaults[TIMEZONE] = self.timezone_default
+        if self.user_defaults[THEME_NAME] is None:
+            self.user_defaults[THEME_NAME] = self.theme_default
         # Note: do not assign user_defaults['locale'] = locale_default
         # to give browser language detection a chance.
         try:
@@ -113,22 +115,28 @@
         self.mail_enabled = self.mail_enabled and True or False
 
         if self.namespace_mapping is None:
-            raise error.ConfigurationError("No storage configuration specified! You need to define a namespace_mapping. "
-                                           "For further reference, please see HelpOnStorageConfiguration.")
+            raise error.ConfigurationError(
+                "No storage configuration specified! You need to define a namespace_mapping. "
+                "For further reference, please see HelpOnStorageConfiguration.")
 
         if self.backend_mapping is None:
-            raise error.ConfigurationError("No storage configuration specified! You need to define a backend_mapping. " +
-                                           "For further reference, please see HelpOnStorageConfiguration.")
+            raise error.ConfigurationError(
+                "No storage configuration specified! You need to define a backend_mapping. " +
+                "For further reference, please see HelpOnStorageConfiguration.")
 
         if self.acl_mapping is None:
-            raise error.ConfigurationError("No acl configuration specified! You need to define a acl_mapping. "
-                                           "For further reference, please see HelpOnStorageConfiguration.")
+            raise error.ConfigurationError(
+                "No acl configuration specified! You need to define a acl_mapping. "
+                "For further reference, please see HelpOnStorageConfiguration.")
 
         if self.secrets is None:  # admin did not setup a real secret
-            raise error.ConfigurationError("No secret configured! You need to set secrets = 'somelongsecretstring' in your wiki config.")
+            raise error.ConfigurationError(
+                "No secret configured! You need to set secrets = 'somelongsecretstring' in your wiki config.")
 
         if self.interwikiname is None:  # admin did not setup a real interwikiname
-            raise error.ConfigurationError("No interwikiname configured! You need to set interwikiname = u'YourUniqueStableInterwikiName' in your wiki config.")
+            raise error.ConfigurationError(
+                "No interwikiname configured! "
+                "You need to set interwikiname = u'YourUniqueStableInterwikiName' in your wiki config.")
 
         secret_key_names = ['security/ticket', ]
         if self.textchas:
@@ -137,8 +145,9 @@
         secret_min_length = 10
         if isinstance(self.secrets, str):
             if len(self.secrets) < secret_min_length:
-                raise error.ConfigurationError("The secrets = '...' wiki config setting is a way too short string (minimum length is {0} chars)!".format(
-                    secret_min_length))
+                raise error.ConfigurationError(
+                    "The secrets = '...' wiki config setting is a way too short string "
+                    "(minimum length is {0} chars)!".format(secret_min_length))
             # for lazy people: set all required secrets to same value
             secrets = {}
             for key in secret_key_names:
@@ -152,7 +161,8 @@
                 if len(secret) < secret_min_length:
                     raise ValueError
             except (KeyError, ValueError):
-                raise error.ConfigurationError("You must set a (at least {0} chars long) secret string for secrets['{1}']!".format(
+                raise error.ConfigurationError(
+                    "You must set a (at least {0} chars long) secret string for secrets['{1}']!".format(
                     secret_min_length, secret_key_name))
 
         from passlib.context import CryptContext
@@ -172,9 +182,9 @@
         error message with unknown names.
         """
         unknown = ['"{0}"'.format(name) for name in dir(self)
-                  if not name.startswith('_') and
-                  name not in DefaultConfig.__dict__ and
-                  not isinstance(getattr(self, name), (type(sys), type(DefaultConfig)))]
+                   if not name.startswith('_') and
+                   name not in DefaultConfig.__dict__ and
+                   not isinstance(getattr(self, name), (type(re), type(DefaultConfig)))]
         if unknown:
             msg = """
 Unknown configuration options: {0}.
@@ -276,9 +286,9 @@
        username_lower in password_lower or password_lower in username_lower:
         return _("Password is too easy to guess (password contains name or name contains password).")
 
-    keyboards = (ur"`1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./", # US kbd
-                 ur"^1234567890ß´qwertzuiopü+asdfghjklöä#yxcvbnm,.-", # german kbd
-                ) # add more keyboards!
+    keyboards = (ur"`1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./",  # US kbd
+                 ur"^1234567890ß´qwertzuiopü+asdfghjklöä#yxcvbnm,.-",  # german kbd
+    )  # TODO add more keyboards!
     for kbd in keyboards:
         rev_kbd = kbd[::-1]
         if password in kbd or password in rev_kbd or \
@@ -299,236 +309,222 @@
 # information on the layout of this structure.
 #
 options_no_group_name = {
-  # ==========================================================================
-  'datastruct': ('Datastruct', None, (
-    #('dicts', lambda cfg: datastruct.ConfigDicts({}),
-    ('dicts', lambda cfg: datastruct.WikiDicts(),
-     "function f(cfg) that returns a backend which is used to access dicts definitions."),
-    #('groups', lambda cfg: datastruct.ConfigGroups({}),
-    ('groups', lambda cfg: datastruct.WikiGroups(),
-     "function f(cfg) that returns a backend which is used to access groups definitions."),
-  )),
-  # ==========================================================================
-  'auth': ('Authentication / Authorization / Security', None, (
-    ('auth', DefaultExpression('[MoinAuth()]'),
-     "list of auth objects, to be called in this order (see HelpOnAuthentication)"),
-    ('secrets', None, """Either a long shared secret string used for multiple purposes or a dict {"purpose": "longsecretstring", ...} for setting up different shared secrets for different purposes."""),
-    ('SecurityPolicy',
-     DefaultSecurityPolicy,
-     "Class object hook for implementing security restrictions or relaxations"),
-    ('endpoints_excluded',
-     [],
-     "Exclude unwanted endpoints (list of strings)"),
-
-    ('password_checker', DefaultExpression('_default_password_checker'),
-     'checks whether a password is acceptable (default check is length >= 6, at least 4 different chars, no keyboard sequence, not username used somehow (you can switch this off by using `None`)'),
-
-    ('passlib_crypt_context', dict(
-        # schemes we want to support (or deprecated schemes for which we still have
-        # hashes in our storage).
-        # note about bcrypt: it needs additional code (that is not pure python and
-        # thus either needs compiling or installing platform-specific binaries)
-        schemes=["sha512_crypt", ],
-        # default scheme for creating new pw hashes (if not given, passlib uses first from schemes)
-        #default="sha512_crypt",
-        # deprecated schemes get auto-upgraded to the default scheme at login
-        # time or when setting a password (including doing a moin account pwreset).
-        #deprecated=["auto"],
-        # vary rounds parameter randomly when creating new hashes...
-        #all__vary_rounds=0.1,
-     ),
-     "passlib CryptContext arguments, see passlib docs"),
-  )),
-  # ==========================================================================
-  'spam_leech_dos': ('Anti-Spam / Leech / DOS',
-  'These settings help limiting ressource usage and avoiding abuse.',
-  (
-    ('textchas', None,
-     "Spam protection setup using site-specific questions/answers, see HelpOnSpam."),
-    ('textchas_expiry_time', 600,
-     "Time [s] for a !TextCha to expire."),
-  )),
-  # ==========================================================================
-  'style': ('Style / Theme / UI',
-  'These settings control how the wiki user interface will look like.',
-  (
-    ('sitename', u'Untitled Wiki',
-     "Short description of your wiki site, displayed below the logo on each page, and used in RSS documents as the channel title [Unicode]"),
-    ('interwikiname', None, "unique, stable and required InterWiki name (prefix, moniker) of the site [Unicode]"),
-    ('html_pagetitle', None, "Allows you to set a specific HTML page title (if None, it defaults to the value of `sitename`) [Unicode]"),
-    ('navi_bar', [
-        ('wikilink', 'frontend.show_root', dict(), L_('Home'), L_('Home Page')),
-        ('wikilink', 'frontend.global_history', dict(), L_('History'), L_('Global History')),
-        ('wikilink', 'frontend.index', dict(), L_('Index'), L_('Global Index')),
-        ('wikilink', 'frontend.global_tags', dict(), L_('Tags'), L_('Global Tags Index')),
-        ('wikilink', 'admin.index_user', dict(), L_('User'), L_('User')),
-        ('wikilink', 'admin.index', dict(), L_('Admin'), L_('Administration & Docs')),
-     ],
-     'Data to create the navi_bar from. Users can add more items in their quick links in user preferences. You need to configure a list of tuples (css_class, endpoint, args, label, title). Use L_() for translating. [list of tuples]'),
-
-    ('theme_default', u'modernized', "Default theme."),
-
-    ('serve_files', {},
-     """
-     Dictionary of name: filesystem_path for static file resources to serve
-     from the filesystem as url .../+serve/<name>/...
-     """),
-
-    ('supplementation_item_names', [u'Discussion', ],
-     "List of names of the supplementation (sub)items [Unicode]"),
-
-    ('interwiki_preferred', [], "In dialogues, show those wikis at the top of the list [list of Unicode]."),
-    ('sistersites', [], "list of tuples `('WikiName', 'sisterpagelist_fetch_url')`"),
-
-    ('trail_size', 5,
-     "Number of items in the trail of recently visited items"),
-
-    ('item_views', [
-        # (endpointname, label, check_item_exists
-        ('frontend.show_item', L_('Show'), L_('Show'), False, ),
-        ('frontend.download_item', L_('Download'), L_('Download'), True, ),
-        ('frontend.history', L_('History'), L_('Revision History'), True, ),
-        # note: when rendering a non-existing item, you'll be offered to
-        # create it (in the content area), so we do not offer "Modify":
-        ('frontend.modify_item', L_('Modify'), L_('Edit or Upload'), True, ),
-        ('special.supplementation', None, None, False, ),
-        ('frontend.index', L_('Index'), L_('List sub-items'), False, ),
-        ('special.comments', L_('Comments'), L_('Hide comments'), True, ),
-        ('special.transclusions', L_('Transclusions'), L_('Show transclusions'), True, ),
-        ('frontend.highlight_item', L_('Highlight'), L_('Show with Syntax-Highlighting'), True, ),
-        ('frontend.show_item_meta', L_('Meta'), L_('Display Metadata'), True, ),
-        ('frontend.quicklink_item', None, L_('Create or remove a navigation link to this item'), False, ),
-        ('frontend.subscribe_item', None, L_('Switch notifications about item changes on or off'), False, ),
-        ('frontend.rename_item', L_('Rename'), L_('Rename this item'), True, ),
-        ('frontend.delete_item', L_('Delete'), L_('Delete this item'), True, ),
-        ('frontend.destroy_item', L_('Destroy'), L_('Completely destroy this item'), True, ),
-        ('frontend.backrefs', L_('Referrers'), L_('What refers here?'), False, ),
-        ('frontend.sitemap', L_('Site Map'), L_('Local Site Map of this item'), True, ),
-        ('frontend.similar_names', L_('Similar'), L_('Items with similar names'), False, ),
-     ],
-     'list of edit bar entries (list of tuples (endpoint, label))'),
+    # ==========================================================================
+    'datastruct': ('Datastruct', None, (
+        # ('dicts', lambda cfg: datastruct.ConfigDicts({}),
+        ('dicts', lambda cfg: datastruct.WikiDicts(),
+         "function f(cfg) that returns a backend which is used to access dicts definitions."),
+        # ('groups', lambda cfg: datastruct.ConfigGroups({}),
+        ('groups', lambda cfg: datastruct.WikiGroups(),
+         "function f(cfg) that returns a backend which is used to access groups definitions."),
+    )),
+    # ==========================================================================
+    'auth': ('Authentication / Authorization / Security', None, (
+        ('auth', DefaultExpression('[MoinAuth()]'),
+         "list of auth objects, to be called in this order (see HelpOnAuthentication)"),
+        ('secrets', None, """Either a long shared secret string used for multiple purposes or a dict {"purpose": "longsecretstring", ...} for setting up different shared secrets for different purposes."""),
+        ('SecurityPolicy',
+         DefaultSecurityPolicy,
+         "Class object hook for implementing security restrictions or relaxations"),
+        ('endpoints_excluded',
+         [],
+         "Exclude unwanted endpoints (list of strings)"),
+        ('password_checker', DefaultExpression('_default_password_checker'),
+         'checks whether a password is acceptable (default check is length >= 6, at least 4 different chars, no keyboard sequence, not username used somehow (you can switch this off by using `None`)'),
 
-    ('show_hosts', True,
-     "if True, show host names and IPs. Set to False to hide them."),
-    ('show_interwiki', False,
-     "if True, let the theme display your interwiki name"),
-    ('show_names', True,
-     "if True, show user names in the revision history and on Recent``Changes. Set to False to hide them."),
-    ('show_section_numbers', False,
-     'show section numbers in headings by default'),
-    ('show_rename_redirect', False, "if True, offer creation of redirect pages when renaming wiki pages"),
-
-    ('template_dirs', [], "list of directories with templates that will override theme and base templates."),
-  )),
-  # ==========================================================================
-  'editor': ('Editor', None, (
-    ('item_license', u'', 'if set, show the license item within the editor. [Unicode]'),
-    #('edit_locking', 'warn 10', "Editor locking policy: `None`, `'warn <timeout in minutes>'`, or `'lock <timeout in minutes>'`"),
-    ('edit_ticketing', True, None),
-  )),
-  # ==========================================================================
-  'paging': ('Paging', None, (
-    ('results_per_page', 50, "Number of results to be shown on a single page in pagination"),
-  )),
-  # ==========================================================================
-  'data': ('Data Storage', None, (
-    ('data_dir', './data/', "Path to the data directory."),
-    ('plugin_dirs', [], "Plugin directories."),
-
-    ('interwiki_map', {},
-     "Dictionary of wiki_name -> wiki_url"),
-    ('namespace_mapping', None,
-    "A list of tuples, each tuple containing: Namespace identifier, backend name. " +
-    "E.g.: [('', 'default')), ]. Please see HelpOnStorageConfiguration for further reference."),
-    ('backend_mapping', None,
-    "A dictionary that maps backend names to backends. " +
-    "E.g.: {'default': Backend(), }. Please see HelpOnStorageConfiguration for further reference."),
-    ('acl_mapping', None,
-    "This needs to point to a list of tuples, each tuple containing: name prefix, acl protection to be applied to matching items. " +
-    "E.g.: [('', dict(default='All:read,write,create')), ]. Please see HelpOnStorageConfiguration for further reference."),
-    ('create_storage', False, "Create (initialize) the storage backends before trying to use them."),
-    ('create_index', False, "Create (initialize) the index before trying to use them."),
-    ('destroy_storage', False, "Destroy (empty) the storage backends after using them."),
-    ('destroy_index', False, "Destroy (empty) the index after using it."),
-  )),
-  # ==========================================================================
-  'items': ('Special Item Names', None, (
-    ('item_root', u'Home', "Name of the root item (aka 'front page'). [Unicode]"),
+        ('passlib_crypt_context', dict(
+            # schemes we want to support (or deprecated schemes for which we still have
+            # hashes in our storage).
+            # note about bcrypt: it needs additional code (that is not pure python and
+            # thus either needs compiling or installing platform-specific binaries)
+            schemes=["sha512_crypt", ],
+            # default scheme for creating new pw hashes (if not given, passlib uses first from schemes)
+            #default="sha512_crypt",
+            # deprecated schemes get auto-upgraded to the default scheme at login
+            # time or when setting a password (including doing a moin account pwreset).
+            #deprecated=["auto"],
+            # vary rounds parameter randomly when creating new hashes...
+            #all__vary_rounds=0.1,
+        ), "passlib CryptContext arguments, see passlib docs"),
+    )),
+    # ==========================================================================
+    'spam_leech_dos': ('Anti-Spam / Leech / DOS', 'These settings help limiting ressource usage and avoiding abuse.', (
+        ('textchas', None,
+         "Spam protection setup using site-specific questions/answers, see HelpOnSpam."),
+        ('textchas_expiry_time', 600,
+         "Time [s] for a !TextCha to expire."),
+    )),
+    # ==========================================================================
+    'style': ('Style / Theme / UI', 'These settings control how the wiki user interface will look like.', (
+        ('sitename', u'Untitled Wiki',
+         "Short description of your wiki site, displayed below the logo on each page, and used in RSS documents as the channel title [Unicode]"),
+        ('interwikiname', None, "unique, stable and required InterWiki name (prefix, moniker) of the site [Unicode]"),
+        ('html_pagetitle', None, "Allows you to set a specific HTML page title (if None, it defaults to the value of `sitename`) [Unicode]"),
+        ('navi_bar', [
+            ('wikilink', 'frontend.show_root', dict(), L_('Home'), L_('Home Page')),
+            ('wikilink', 'frontend.global_history', dict(), L_('History'), L_('Global History')),
+            ('wikilink', 'frontend.index', dict(), L_('Index'), L_('Global Index')),
+            ('wikilink', 'frontend.global_tags', dict(), L_('Tags'), L_('Global Tags Index')),
+            ('wikilink', 'admin.index_user', dict(), L_('User'), L_('User')),
+            ('wikilink', 'admin.index', dict(), L_('Admin'), L_('Administration & Docs')),
+        ], 'Data to create the navi_bar from. Users can add more items in their quick links in user preferences. You need to configure a list of tuples (css_class, endpoint, args, label, title). Use L_() for translating. [list of tuples]'),
 
-    # the following regexes should match the complete name when used in free text
-    # the group 'all' shall match all, while the group 'key' shall match the key only
-    # e.g. FooGroup -> group 'all' ==  FooGroup, group 'key' == Foo
-    # moin's code will add ^ / $ at beginning / end when needed
-    ('item_dict_regex', ur'(?P<all>(?P<key>\S+)Dict)',
-     'Item names exactly matching this regex are regarded as items containing variable dictionary definitions [Unicode]'),
-    ('item_group_regex', ur'(?P<all>(?P<key>\S+)Group)',
-     'Item names exactly matching this regex are regarded as items containing group definitions [Unicode]'),
-  )),
-  # ==========================================================================
-  'user': ('User Preferences', None, (
-    ('user_defaults',
-      dict(
-        name=[],
-        display_name=None,
-        email=None,
-        openid=None,
-        css_url=None,
-        mailto_author=False,
-        edit_on_doubleclick=True,
-        scroll_page_after_edit=True,
-        show_comments=False,
-        want_trivial=False,
-        enc_password=u'',  # empty value == invalid hash
-        disabled=False,
-        bookmarks={},
-        quicklinks=[],
-        subscribed_items=[],
-        email_subscribed_events=[
-            # XXX PageChangedEvent.__name__
-            # XXX PageRenamedEvent.__name__
-            # XXX PageDeletedEvent.__name__
-            # XXX PageCopiedEvent.__name__
-            # XXX PageRevertedEvent.__name__
-        ],
-        theme_name=None, # None -> use cfg.theme_default
-        edit_rows=0,
-        results_per_page=0,
-        locale=None, # None -> do browser language detection, otherwise just use this locale
-        timezone=None, # None -> use cfg.timezone_default
-      ),
-     'Default attributes of the user object'),
-  )),
-  # ==========================================================================
-  'various': ('Various', None, (
-    ('bang_meta', True, 'if True, enable {{{!NoWikiName}}} markup'),
+        ('theme_default', u'modernized', "Default theme."),
 
-    ('config_check_enabled', False, "if True, check configuration for unknown settings."),
-
-    ('timezone_default', u'UTC', "Default time zone."),
-    ('locale_default', u'en_US', "Default locale for user interface and content."),
-
-    ('log_remote_addr', True,
-     "if True, log the remote IP address (and maybe hostname)."),
-    ('log_reverse_dns_lookups', True,
-     "if True, do a reverse DNS lookup on page SAVE. If your DNS is broken, set this to False to speed up SAVE."),
+        ('serve_files', {},
+         """
+         Dictionary of name: filesystem_path for static file resources to serve
+         from the filesystem as url .../+serve/<name>/...
+         """),
 
-    # some dangerous mimetypes (we don't use "content-disposition: inline" for them when a user
-    # downloads such data, because the browser might execute e.g. Javascript contained
-    # in the HTML and steal your moin session cookie or do other nasty stuff)
-    ('mimetypes_xss_protect',
-     [
-       'text/html',
-       'application/x-shockwave-flash',
-       'application/xhtml+xml',
-     ],
-     '"content-disposition: inline" is not used for downloads of such data'),
+        ('supplementation_item_names', [u'Discussion', ],
+         "List of names of the supplementation (sub)items [Unicode]"),
 
-    ('refresh', None,
-     "refresh = (minimum_delay_s, targets_allowed) enables use of `#refresh 5 PageName` processing instruction, targets_allowed must be either `'internal'` or `'external'`"),
+        ('interwiki_preferred', [], "In dialogues, show those wikis at the top of the list [list of Unicode]."),
+        ('sistersites', [], "list of tuples `('WikiName', 'sisterpagelist_fetch_url')`"),
 
-    ('siteid', 'MoinMoin', None), # XXX just default to some existing module name to
-                                  # make plugin loader etc. work for now
-  )),
+        ('trail_size', 5,
+         "Number of items in the trail of recently visited items"),
+
+        ('item_views', [
+            # (endpointname, label, check_item_exists
+            ('frontend.show_item', L_('Show'), L_('Show'), False, ),
+            ('frontend.download_item', L_('Download'), L_('Download'), True, ),
+            ('frontend.history', L_('History'), L_('Revision History'), True, ),
+            # note: when rendering a non-existing item, you'll be offered to
+            # create it (in the content area), so we do not offer "Modify":
+            ('frontend.modify_item', L_('Modify'), L_('Edit or Upload'), True, ),
+            ('special.supplementation', None, None, False, ),
+            ('frontend.index', L_('Index'), L_('List sub-items'), False, ),
+            ('special.comments', L_('Comments'), L_('Hide comments'), True, ),
+            ('special.transclusions', L_('Transclusions'), L_('Show transclusions'), True, ),
+            ('frontend.highlight_item', L_('Highlight'), L_('Show with Syntax-Highlighting'), True, ),
+            ('frontend.show_item_meta', L_('Meta'), L_('Display Metadata'), True, ),
+            ('frontend.quicklink_item', None, L_('Create or remove a navigation link to this item'), False, ),
+            ('frontend.subscribe_item', None, L_('Switch notifications about item changes on or off'), False, ),
+            ('frontend.rename_item', L_('Rename'), L_('Rename this item'), True, ),
+            ('frontend.delete_item', L_('Delete'), L_('Delete this item'), True, ),
+            ('frontend.destroy_item', L_('Destroy'), L_('Completely destroy this item'), True, ),
+            ('frontend.backrefs', L_('Referrers'), L_('What refers here?'), False, ),
+            ('frontend.sitemap', L_('Site Map'), L_('Local Site Map of this item'), True, ),
+            ('frontend.similar_names', L_('Similar'), L_('Items with similar names'), False, ),
+        ], 'list of edit bar entries (list of tuples (endpoint, label))'),
+
+        ('show_hosts', True,
+         "if True, show host names and IPs. Set to False to hide them."),
+        ('show_interwiki', False,
+         "if True, let the theme display your interwiki name"),
+        ('show_names', True,
+         "if True, show user names in the revision history and on Recent``Changes. Set to False to hide them."),
+        ('show_section_numbers', False,
+         'show section numbers in headings by default'),
+        ('show_rename_redirect', False, "if True, offer creation of redirect pages when renaming wiki pages"),
+
+        ('template_dirs', [], "list of directories with templates that will override theme and base templates."),
+    )),
+    # ==========================================================================
+    'editor': ('Editor', None, (
+        ('item_license', u'', 'if set, show the license item within the editor. [Unicode]'),
+        #('edit_locking', 'warn 10', "Editor locking policy: `None`, `'warn <timeout in minutes>'`, or `'lock <timeout in minutes>'`"),
+        ('edit_ticketing', True, None),
+    )),
+    # ==========================================================================
+    'paging': ('Paging', None, (
+        ('results_per_page', 50, "Number of results to be shown on a single page in pagination"),
+    )),
+    # ==========================================================================
+    'data': ('Data Storage', None, (
+        ('data_dir', './data/', "Path to the data directory."),
+        ('plugin_dirs', [], "Plugin directories."),
+
+        ('interwiki_map', {},
+         "Dictionary of wiki_name -> wiki_url"),
+        ('namespace_mapping', None,
+         "A list of tuples, each tuple containing: Namespace identifier, backend name. " +
+         "E.g.: [('', 'default')), ]. Please see HelpOnStorageConfiguration for further reference."),
+        ('backend_mapping', None,
+         "A dictionary that maps backend names to backends. " +
+         "E.g.: {'default': Backend(), }. Please see HelpOnStorageConfiguration for further reference."),
+        ('acl_mapping', None,
+         "This needs to point to a list of tuples, each tuple containing: name prefix, acl protection to be applied to matching items. " +
+         "E.g.: [('', dict(default='All:read,write,create')), ]. Please see HelpOnStorageConfiguration for further reference."),
+        ('create_storage', False, "Create (initialize) the storage backends before trying to use them."),
+        ('create_index', False, "Create (initialize) the index before trying to use them."),
+        ('destroy_storage', False, "Destroy (empty) the storage backends after using them."),
+        ('destroy_index', False, "Destroy (empty) the index after using it."),
+    )),
+    # ==========================================================================
+    'items': ('Special Item Names', None, (
+        ('item_root', u'Home', "Name of the root item (aka 'front page'). [Unicode]"),
+
+        # the following regexes should match the complete name when used in free text
+        # the group 'all' shall match all, while the group 'key' shall match the key only
+        # e.g. FooGroup -> group 'all' ==  FooGroup, group 'key' == Foo
+        # moin's code will add ^ / $ at beginning / end when needed
+        ('item_dict_regex', ur'(?P<all>(?P<key>\S+)Dict)',
+         'Item names exactly matching this regex are regarded as items containing variable dictionary definitions [Unicode]'),
+        ('item_group_regex', ur'(?P<all>(?P<key>\S+)Group)',
+         'Item names exactly matching this regex are regarded as items containing group definitions [Unicode]'),
+    )),
+    # ==========================================================================
+    'user': ('User Preferences', None, (
+        ('user_defaults', {
+            NAME: [],
+            DISPLAY_NAME: None,
+            EMAIL: None,
+            OPENID: None,
+            CSS_URL: None,
+            MAILTO_AUTHOR: False,
+            EDIT_ON_DOUBLECLICK: True,
+            SCROLL_PAGE_AFTER_EDIT: True,
+            SHOW_COMMENTS: False,
+            WANT_TRIVIAL: False,
+            ENC_PASSWORD: u'',  # empty value == invalid hash
+            DISABLED: False,
+            BOOKMARKS: {},
+            QUICKLINKS: [],
+            SUBSCRIBED_ITEMS: [],
+            EMAIL_SUBSCRIBED_EVENTS: [
+                # XXX PageChangedEvent.__name__
+                # XXX PageRenamedEvent.__name__
+                # XXX PageDeletedEvent.__name__
+                # XXX PageCopiedEvent.__name__
+                # XXX PageRevertedEvent.__name__
+            ],
+            THEME_NAME: None,  # None -> use cfg.theme_default
+            EDIT_ROWS: 0,
+            RESULTS_PER_PAGE: 0,
+            LOCALE: None,  # None -> do browser language detection, otherwise just use this locale
+            TIMEZONE: None,  # None -> use cfg.timezone_default
+        }, 'Default attributes of the user object'),
+    )),
+    # ==========================================================================
+    'various': ('Various', None, (
+        ('bang_meta', True, 'if True, enable {{{!NoWikiName}}} markup'),
+
+        ('config_check_enabled', False, "if True, check configuration for unknown settings."),
+
+        ('timezone_default', u'UTC', "Default time zone."),
+        ('locale_default', u'en_US', "Default locale for user interface and content."),
+
+        ('log_remote_addr', True,
+         "if True, log the remote IP address (and maybe hostname)."),
+        ('log_reverse_dns_lookups', True,
+         "if True, do a reverse DNS lookup on page SAVE. If your DNS is broken, set this to False to speed up SAVE."),
+
+        # some dangerous mimetypes (we don't use "content-disposition: inline" for them when a user
+        # downloads such data, because the browser might execute e.g. Javascript contained
+        # in the HTML and steal your moin session cookie or do other nasty stuff)
+        ('mimetypes_xss_protect', [
+            'text/html',
+            'application/x-shockwave-flash',
+            'application/xhtml+xml',
+        ], '"content-disposition: inline" is not used for downloads of such data'),
+
+        ('refresh', None, "refresh = (minimum_delay_s, targets_allowed) enables use of `#refresh 5 PageName` processing instruction, targets_allowed must be either `'internal'` or `'external'`"),
+        ('siteid', 'MoinMoin', None),  # XXX just default to some existing module name to
+                                       # make plugin loader etc. work for now
+    )),
 }
 
 #
@@ -555,48 +551,42 @@
 #
 #
 options = {
-    'acl': ('Access Control Lists',
-    'ACLs control who may do what.',
-    (
-      ('functions', u'',
-       'Access Control List for functions.'),
-      ('rights_contents', config.ACL_RIGHTS_CONTENTS,
-       'Valid tokens for right sides of content ACL entries.'),
-      ('rights_functions', config.ACL_RIGHTS_FUNCTIONS,
-       'Valid tokens for right sides of function ACL entries.'),
+    'acl': ('Access Control Lists', 'ACLs control who may do what.', (
+        ('functions', u'', 'Access Control List for functions.'),
+        ('rights_contents', ACL_RIGHTS_CONTENTS, 'Valid tokens for right sides of content ACL entries.'),
+        ('rights_functions', ACL_RIGHTS_FUNCTIONS, 'Valid tokens for right sides of function ACL entries.'),
     )),
 
     'ns': ('Storage Namespaces',
     "Storage namespaces can be defined for all sorts of data. All items sharing a common namespace as prefix" +
     "are then stored within the same backend. The common prefix for all data is ''.",
     (
-      ('content', '/', "All content is by default stored below /, hence the prefix is ''."),  # Not really necessary. Just for completeness.
-      ('user_profile', 'UserProfile/', 'User profiles (i.e. user data, not their homepage) are stored in this namespace.'),
-      ('user_homepage', 'User/', 'All user homepages are stored below this namespace.'),
+        ('content', '/', "All content is by default stored below /, hence the prefix is ''."),  # Not really necessary. Just for completeness.
+        ('user_profile', 'UserProfile/', 'User profiles (i.e. user data, not their homepage) are stored in this namespace.'),
+        ('user_homepage', 'User/', 'All user homepages are stored below this namespace.'),
     )),
 
     'user': ('User', None, (
-      ('email_unique', True,
-       "if True, check email addresses for uniqueness and don't accept duplicates."),
-      ('email_verification', False,
-       "if True, require a new user to verify his or her email address before the first login."),
+        ('email_unique', True,
+         "if True, check email addresses for uniqueness and don't accept duplicates."),
+        ('email_verification', False,
+         "if True, require a new user to verify his or her email address before the first login."),
 
-      ('homewiki', u'Self',
-       "interwiki name of the wiki where the user home pages are located [Unicode] - useful if you have ''many'' users. You could even link to nonwiki \"user pages\" if the wiki username is in the target URL."),
-      ('use_gravatar', False, "if True, gravatar.com will be used to find User's avatar")
+        ('homewiki', u'Self',
+         "interwiki name of the wiki where the user home pages are located [Unicode] - useful if you have ''many'' users. You could even link to nonwiki \"user pages\" if the wiki username is in the target URL."),
+        ('use_gravatar', False, "if True, gravatar.com will be used to find User's avatar")
     )),
 
-    'mail': ('Mail',
-        'These settings control outgoing and incoming email from and to the wiki.',
-    (
-      ('from', None, "Used as From: address for generated mail. [Unicode]"),
-      ('username', None, "Username for SMTP server authentication (None = don't use auth)."),
-      ('password', None, "Password for SMTP server authentication (None = don't use auth)."),
-      ('smarthost', None, "Address of SMTP server to use for sending mail (None = don't use SMTP server)."),
-      ('sendmail', None, "sendmail command to use for sending mail (None = don't use sendmail)"),
+    'mail': ('Mail', 'These settings control outgoing and incoming email from and to the wiki.', (
+        ('from', None, "Used as From: address for generated mail. [Unicode]"),
+        ('username', None, "Username for SMTP server authentication (None = don't use auth)."),
+        ('password', None, "Password for SMTP server authentication (None = don't use auth)."),
+        ('smarthost', None, "Address of SMTP server to use for sending mail (None = don't use SMTP server)."),
+        ('sendmail', None, "sendmail command to use for sending mail (None = don't use sendmail)"),
     )),
 }
 
+
 def _add_options_to_defconfig(opts, addgroup=True):
     for groupname in opts:
         group_short, group_doc, group_opts = opts[groupname]
--- a/MoinMoin/conftest.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/conftest.py	Wed Mar 20 01:25:01 2013 +0100
@@ -19,10 +19,11 @@
 from __future__ import absolute_import, division
 
 # exclude some directories from py.test test discovery, pathes relative to this file
-collect_ignore = ['static',  # same
-                  '../wiki', # no tests there
-                  '../instance', # tw likes to use this for wiki data (non-revisioned)
-                 ]
+collect_ignore = [
+    'static',  # same
+    '../wiki',  # no tests there
+    '../instance',  # tw likes to use this for wiki data (non-revisioned)
+]
 import atexit
 import os
 import sys
@@ -32,8 +33,7 @@
 import py
 import MoinMoin.log
 
-""" Logging for tests to avoid useless output like timing information on stderr on test failures
-"""
+# Logging for tests to avoid useless output like timing information on stderr on test failures
 Moindir = py.path.local(__file__).dirname
 config_file = Moindir + '/_tests/test_logging.conf'
 MoinMoin.log.load_config(config_file)
@@ -50,10 +50,10 @@
         namespace_mapping=namespace_mapping,
         backend_mapping=backend_mapping,
         acl_mapping=acl_mapping,
-        create_storage=True, # create a fresh storage at each app start
-        destroy_storage=True, # kill all storage contents at app shutdown
-        create_index=True, # create a fresh index at each app start
-        destroy_index=True, # kill index contents at app shutdown
+        create_storage=True,  # create a fresh storage at each app start
+        destroy_storage=True,  # kill all storage contents at app shutdown
+        create_index=True,  # create a fresh index at each app start
+        destroy_index=True,  # kill index contents at app shutdown
     )
     app = create_app_ext(flask_config_dict=dict(SECRET_KEY='foobarfoobar'),
                          moin_config_class=given_config,
@@ -63,6 +63,7 @@
     before_wiki()
     return app, ctx
 
+
 def deinit_test_app(app, ctx):
     teardown_wiki('')
     ctx.pop()
@@ -74,6 +75,7 @@
 prev_ctx = None
 prev_cfg = None
 
+
 class MoinTestFunction(pytest.collect.Function):
     def setup(self):
         global prev_app, prev_ctx, prev_cfg
@@ -109,10 +111,12 @@
 def pytest_pycollect_makemodule(path, parent):
     return Module(path, parent=parent)
 
+
 def pytest_pycollect_makeitem(__multicall__, collector, name, obj):
     if collector.funcnamefilter(name) and inspect.isfunction(obj):
         return MoinTestFunction(name, parent=collector)
 
+
 def pytest_pyfunc_call(pyfuncitem):
     """hook to intercept generators and run them as a single test items"""
     if inspect.isgeneratorfunction(pyfuncitem.obj):
@@ -120,9 +124,11 @@
             kwarg = item[1:]
             item[0](*kwarg)
 
+
 def pytest_report_header(config):
     return "The tests here are implemented only for pytest-2"
 
+
 class Module(pytest.collect.Module):
     def run(self, *args, **kwargs):
         if coverage is not None:
--- a/MoinMoin/constants/chartypes.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/constants/chartypes.py	Wed Mar 20 01:25:01 2013 +0100
@@ -1,8 +1,8 @@
-
-chars_upper = u"\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004a\u004b\u004c\u004d\u004e\u004f\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057\u0058\u0059\u005a\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u00d0\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d8\u00d9\u00da\u00db\u00dc\u00dd\u00de\u0100\u0102\u0104\u0106\u0108\u010a\u010c\u010e\u0110\u0112\u0114\u0116\u0118\u011a\u011c\u011e\u0120\u0122\u0124\u0126\u0128\u012a\u012c\u012e\u0130\u0132\u0134\u0136\u0139\u013b\u013d\u013f\u0141\u0143\u0145\u0147\u014a\u014c\u014e\u0150\u0152\u0154\u0156\u0158\u015a\u015c\u015e\u0160\u0162\u0164\u0166\u0168\u016a\u016c\u016e\u0170\u0172\u0174\u0176\u0178\u0179\u017b\u017d\u0181\u0182\u0184\u0186\u0187\u0189\u018a\u018b\u018e\u018f\u0190\u0191\u0193\u0194\u0196\u0197\u0198\u019c\u019d\u019f\u01a0\u01a2\u01a4\u01a6\u01a7\u01a9\u01ac\u01ae\u01af\u01b1\u01b2\u01b3\u01b5\u01b7\u01b8\u01bc\u01c4\u01c7\u01ca\u01cd\u01cf\u01d1\u01d3\u01d5\u01d7\u01d9\u01db\u01de\u01e0\u01e2\u01e4\u01e6\u01e8\u01ea\u01ec\u01ee\u01f1\u01f4\u01f6\u01f7\u01f8\u01fa\u01fc\u01fe\u0200\u0202\u0204\u0206\u0208\u020a\u020c\u020e\u0210\u0212\u0214\u0216\u0218\u021a\u021c\u021e\u0220\u0222\u0224\u0226\u0228\u022a\u022c\u022e\u0230\u0232\u0386\u0388\u0389\u038a\u038c\u038e\u038f\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab\u03d2\u03d3\u03d4\u03d8\u03da\u03dc\u03de\u03e0\u03e2\u03e4\u03e6\u03e8\u03ea\u03ec\u03ee\u03f4\u0400\u0401\u0402\u0403\u0404\u0405\u0406\u0407\u0408\u0409\u040a\u040b\u040c\u040d\u040e\u040f\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0460\u0462\u0464\u0466\u0468\u046a\u046c\u046e\u0470\u0472\u0474\u0476\u0478\u047a\u047c\u047e\u0480\u048a\u048c\u048e\u0490\u0492\u0494\u0496\u0498\u049a\u049c\u049e\u04a0\u04a2\u04a4\u04a6\u04a8\u04aa\u04ac\u04ae\u04b0\u04b2\u04b4\u04b6\u04b8\u04ba\u04bc\u04be\u04c0\u04c1\u04c3\u04c5\u04c7\u04c9\u04cb\u04cd\u04d0\u04d2\u04d4\u04d6\u04d8\u04da\u04dc\u04de\u04e0\u04e2\u04e4\u04e6\u04e8\u04ea\u04ec\u04ee\u04f0\u04f2\u04f4\u04f8\u0500\u0502\u0504\u0506\u0508\u050a\u050c\u050e\u0531\u0532\u0533\u0534\u0535\u0536\u0537\u0538\u0539\u053a\u053b\u053c\u053d\u053e\u053f\u0540\u0541\u0542\u0543\u0544\u0545\u0546\u0547\u0548\u0549\u054a\u054b\u054c\u054d\u054e\u054f\u0550\u0551\u0552\u0553\u0554\u0555\u0556\u10a0\u10a1\u10a2\u10a3\u10a4\u10a5\u10a6\u10a7\u10a8\u10a9\u10aa\u10ab\u10ac\u10ad\u10ae\u10af\u10b0\u10b1\u10b2\u10b3\u10b4\u10b5\u10b6\u10b7\u10b8\u10b9\u10ba\u10bb\u10bc\u10bd\u10be\u10bf\u10c0\u10c1\u10c2\u10c3\u10c4\u10c5\u1e00\u1e02\u1e04\u1e06\u1e08\u1e0a\u1e0c\u1e0e\u1e10\u1e12\u1e14\u1e16\u1e18\u1e1a\u1e1c\u1e1e\u1e20\u1e22\u1e24\u1e26\u1e28\u1e2a\u1e2c\u1e2e\u1e30\u1e32\u1e34\u1e36\u1e38\u1e3a\u1e3c\u1e3e\u1e40\u1e42\u1e44\u1e46\u1e48\u1e4a\u1e4c\u1e4e\u1e50\u1e52\u1e54\u1e56\u1e58\u1e5a\u1e5c\u1e5e\u1e60\u1e62\u1e64\u1e66\u1e68\u1e6a\u1e6c\u1e6e\u1e70\u1e72\u1e74\u1e76\u1e78\u1e7a\u1e7c\u1e7e\u1e80\u1e82\u1e84\u1e86\u1e88\u1e8a\u1e8c\u1e8e\u1e90\u1e92\u1e94\u1ea0\u1ea2\u1ea4\u1ea6\u1ea8\u1eaa\u1eac\u1eae\u1eb0\u1eb2\u1eb4\u1eb6\u1eb8\u1eba\u1ebc\u1ebe\u1ec0\u1ec2\u1ec4\u1ec6\u1ec8\u1eca\u1ecc\u1ece\u1ed0\u1ed2\u1ed4\u1ed6\u1ed8\u1eda\u1edc\u1ede\u1ee0\u1ee2\u1ee4\u1ee6\u1ee8\u1eea\u1eec\u1eee\u1ef0\u1ef2\u1ef4\u1ef6\u1ef8\u1f08\u1f09\u1f0a\u1f0b\u1f0c\u1f0d\u1f0e\u1f0f\u1f18\u1f19\u1f1a\u1f1b\u1f1c\u1f1d\u1f28\u1f29\u1f2a\u1f2b\u1f2c\u1f2d\u1f2e\u1f2f\u1f38\u1f39\u1f3a\u1f3b\u1f3c\u1f3d\u1f3e\u1f3f\u1f48\u1f49\u1f4a\u1f4b\u1f4c\u1f4d\u1f59\u1f5b\u1f5d\u1f5f\u1f68\u1f69\u1f6a\u1f6b\u1f6c\u1f6d\u1f6e\u1f6f\u1fb8\u1fb9\u1fba\u1fbb\u1fc8\u1fc9\u1fca\u1fcb\u1fd8\u1fd9\u1fda\u1fdb\u1fe8\u1fe9\u1fea\u1feb\u1fec\u1ff8\u1ff9\u1ffa\u1ffb\u2102\u2107\u210b\u210c\u210d\u2110\u2111\u2112\u2115\u2119\u211a\u211b\u211c\u211d\u2124\u2126\u2128\u212a\u212b\u212c\u212d\u2130\u2131\u2133\u213e\u213f\u2145\uff21\uff22\uff23\uff24\uff25\uff26\uff27\uff28\uff29\uff2a\uff2b\uff2c\uff2d\uff2e\uff2f\uff30\uff31\uff32\uff33\uff34\uff35\uff36\uff37\uff38\uff39\uff3a"
 
-chars_lower = u"\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068\u0069\u006a\u006b\u006c\u006d\u006e\u006f\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077\u0078\u0079\u007a\u00aa\u00b5\u00ba\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u00f0\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u00fe\u00ff\u0101\u0103\u0105\u0107\u0109\u010b\u010d\u010f\u0111\u0113\u0115\u0117\u0119\u011b\u011d\u011f\u0121\u0123\u0125\u0127\u0129\u012b\u012d\u012f\u0131\u0133\u0135\u0137\u0138\u013a\u013c\u013e\u0140\u0142\u0144\u0146\u0148\u0149\u014b\u014d\u014f\u0151\u0153\u0155\u0157\u0159\u015b\u015d\u015f\u0161\u0163\u0165\u0167\u0169\u016b\u016d\u016f\u0171\u0173\u0175\u0177\u017a\u017c\u017e\u017f\u0180\u0183\u0185\u0188\u018c\u018d\u0192\u0195\u0199\u019a\u019b\u019e\u01a1\u01a3\u01a5\u01a8\u01aa\u01ab\u01ad\u01b0\u01b4\u01b6\u01b9\u01ba\u01bd\u01be\u01bf\u01c6\u01c9\u01cc\u01ce\u01d0\u01d2\u01d4\u01d6\u01d8\u01da\u01dc\u01dd\u01df\u01e1\u01e3\u01e5\u01e7\u01e9\u01eb\u01ed\u01ef\u01f0\u01f3\u01f5\u01f9\u01fb\u01fd\u01ff\u0201\u0203\u0205\u0207\u0209\u020b\u020d\u020f\u0211\u0213\u0215\u0217\u0219\u021b\u021d\u021f\u0223\u0225\u0227\u0229\u022b\u022d\u022f\u0231\u0233\u0250\u0251\u0252\u0253\u0254\u0255\u0256\u0257\u0258\u0259\u025a\u025b\u025c\u025d\u025e\u025f\u0260\u0261\u0262\u0263\u0264\u0265\u0266\u0267\u0268\u0269\u026a\u026b\u026c\u026d\u026e\u026f\u0270\u0271\u0272\u0273\u0274\u0275\u0276\u0277\u0278\u0279\u027a\u027b\u027c\u027d\u027e\u027f\u0280\u0281\u0282\u0283\u0284\u0285\u0286\u0287\u0288\u0289\u028a\u028b\u028c\u028d\u028e\u028f\u0290\u0291\u0292\u0293\u0294\u0295\u0296\u0297\u0298\u0299\u029a\u029b\u029c\u029d\u029e\u029f\u02a0\u02a1\u02a2\u02a3\u02a4\u02a5\u02a6\u02a7\u02a8\u02a9\u02aa\u02ab\u02ac\u02ad\u0390\u03ac\u03ad\u03ae\u03af\u03b0\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\u03ca\u03cb\u03cc\u03cd\u03ce\u03d0\u03d1\u03d5\u03d6\u03d7\u03d9\u03db\u03dd\u03df\u03e1\u03e3\u03e5\u03e7\u03e9\u03eb\u03ed\u03ef\u03f0\u03f1\u03f2\u03f3\u03f5\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u0450\u0451\u0452\u0453\u0454\u0455\u0456\u0457\u0458\u0459\u045a\u045b\u045c\u045d\u045e\u045f\u0461\u0463\u0465\u0467\u0469\u046b\u046d\u046f\u0471\u0473\u0475\u0477\u0479\u047b\u047d\u047f\u0481\u048b\u048d\u048f\u0491\u0493\u0495\u0497\u0499\u049b\u049d\u049f\u04a1\u04a3\u04a5\u04a7\u04a9\u04ab\u04ad\u04af\u04b1\u04b3\u04b5\u04b7\u04b9\u04bb\u04bd\u04bf\u04c2\u04c4\u04c6\u04c8\u04ca\u04cc\u04ce\u04d1\u04d3\u04d5\u04d7\u04d9\u04db\u04dd\u04df\u04e1\u04e3\u04e5\u04e7\u04e9\u04eb\u04ed\u04ef\u04f1\u04f3\u04f5\u04f9\u0501\u0503\u0505\u0507\u0509\u050b\u050d\u050f\u0561\u0562\u0563\u0564\u0565\u0566\u0567\u0568\u0569\u056a\u056b\u056c\u056d\u056e\u056f\u0570\u0571\u0572\u0573\u0574\u0575\u0576\u0577\u0578\u0579\u057a\u057b\u057c\u057d\u057e\u057f\u0580\u0581\u0582\u0583\u0584\u0585\u0586\u0587\u1e01\u1e03\u1e05\u1e07\u1e09\u1e0b\u1e0d\u1e0f\u1e11\u1e13\u1e15\u1e17\u1e19\u1e1b\u1e1d\u1e1f\u1e21\u1e23\u1e25\u1e27\u1e29\u1e2b\u1e2d\u1e2f\u1e31\u1e33\u1e35\u1e37\u1e39\u1e3b\u1e3d\u1e3f\u1e41\u1e43\u1e45\u1e47\u1e49\u1e4b\u1e4d\u1e4f\u1e51\u1e53\u1e55\u1e57\u1e59\u1e5b\u1e5d\u1e5f\u1e61\u1e63\u1e65\u1e67\u1e69\u1e6b\u1e6d\u1e6f\u1e71\u1e73\u1e75\u1e77\u1e79\u1e7b\u1e7d\u1e7f\u1e81\u1e83\u1e85\u1e87\u1e89\u1e8b\u1e8d\u1e8f\u1e91\u1e93\u1e95\u1e96\u1e97\u1e98\u1e99\u1e9a\u1e9b\u1ea1\u1ea3\u1ea5\u1ea7\u1ea9\u1eab\u1ead\u1eaf\u1eb1\u1eb3\u1eb5\u1eb7\u1eb9\u1ebb\u1ebd\u1ebf\u1ec1\u1ec3\u1ec5\u1ec7\u1ec9\u1ecb\u1ecd\u1ecf\u1ed1\u1ed3\u1ed5\u1ed7\u1ed9\u1edb\u1edd\u1edf\u1ee1\u1ee3\u1ee5\u1ee7\u1ee9\u1eeb\u1eed\u1eef\u1ef1\u1ef3\u1ef5\u1ef7\u1ef9\u1f00\u1f01\u1f02\u1f03\u1f04\u1f05\u1f06\u1f07\u1f10\u1f11\u1f12\u1f13\u1f14\u1f15\u1f20\u1f21\u1f22\u1f23\u1f24\u1f25\u1f26\u1f27\u1f30\u1f31\u1f32\u1f33\u1f34\u1f35\u1f36\u1f37\u1f40\u1f41\u1f42\u1f43\u1f44\u1f45\u1f50\u1f51\u1f52\u1f53\u1f54\u1f55\u1f56\u1f57\u1f60\u1f61\u1f62\u1f63\u1f64\u1f65\u1f66\u1f67\u1f70\u1f71\u1f72\u1f73\u1f74\u1f75\u1f76\u1f77\u1f78\u1f79\u1f7a\u1f7b\u1f7c\u1f7d\u1f80\u1f81\u1f82\u1f83\u1f84\u1f85\u1f86\u1f87\u1f90\u1f91\u1f92\u1f93\u1f94\u1f95\u1f96\u1f97\u1fa0\u1fa1\u1fa2\u1fa3\u1fa4\u1fa5\u1fa6\u1fa7\u1fb0\u1fb1\u1fb2\u1fb3\u1fb4\u1fb6\u1fb7\u1fbe\u1fc2\u1fc3\u1fc4\u1fc6\u1fc7\u1fd0\u1fd1\u1fd2\u1fd3\u1fd6\u1fd7\u1fe0\u1fe1\u1fe2\u1fe3\u1fe4\u1fe5\u1fe6\u1fe7\u1ff2\u1ff3\u1ff4\u1ff6\u1ff7\u2071\u207f\u210a\u210e\u210f\u2113\u212f\u2134\u2139\u213d\u2146\u2147\u2148\u2149\ufb00\ufb01\ufb02\ufb03\ufb04\ufb05\ufb06\ufb13\ufb14\ufb15\ufb16\ufb17\uff41\uff42\uff43\uff44\uff45\uff46\uff47\uff48\uff49\uff4a\uff4b\uff4c\uff4d\uff4e\uff4f\uff50\uff51\uff52\uff53\uff54\uff55\uff56\uff57\uff58\uff59\uff5a\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u00b2\u00b3\u00b9\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u0966\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u09e6\u09e7\u09e8\u09e9\u09ea\u09eb\u09ec\u09ed\u09ee\u09ef\u0a66\u0a67\u0a68\u0a69\u0a6a\u0a6b\u0a6c\u0a6d\u0a6e\u0a6f\u0ae6\u0ae7\u0ae8\u0ae9\u0aea\u0aeb\u0aec\u0aed\u0aee\u0aef\u0b66\u0b67\u0b68\u0b69\u0b6a\u0b6b\u0b6c\u0b6d\u0b6e\u0b6f\u0be7\u0be8\u0be9\u0bea\u0beb\u0bec\u0bed\u0bee\u0bef\u0c66\u0c67\u0c68\u0c69\u0c6a\u0c6b\u0c6c\u0c6d\u0c6e\u0c6f\u0ce6\u0ce7\u0ce8\u0ce9\u0cea\u0ceb\u0cec\u0ced\u0cee\u0cef\u0d66\u0d67\u0d68\u0d69\u0d6a\u0d6b\u0d6c\u0d6d\u0d6e\u0d6f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0ed0\u0ed1\u0ed2\u0ed3\u0ed4\u0ed5\u0ed6\u0ed7\u0ed8\u0ed9\u0f20\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\u0f29\u1040\u1041\u1042\u1043\u1044\u1045\u1046\u1047\u1048\u1049\u1369\u136a\u136b\u136c\u136d\u136e\u136f\u1370\u1371\u17e0\u17e1\u17e2\u17e3\u17e4\u17e5\u17e6\u17e7\u17e8\u17e9\u1810\u1811\u1812\u1813\u1814\u1815\u1816\u1817\u1818\u1819\u2070\u2074\u2075\u2076\u2077\u2078\u2079\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089\u2460\u2461\u2462\u2463\u2464\u2465\u2466\u2467\u2468\u2474\u2475\u2476\u2477\u2478\u2479\u247a\u247b\u247c\u2488\u2489\u248a\u248b\u248c\u248d\u248e\u248f\u2490\u24ea\u24f5\u24f6\u24f7\u24f8\u24f9\u24fa\u24fb\u24fc\u24fd\u2776\u2777\u2778\u2779\u277a\u277b\u277c\u277d\u277e\u2780\u2781\u2782\u2783\u2784\u2785\u2786\u2787\u2788\u278a\u278b\u278c\u278d\u278e\u278f\u2790\u2791\u2792\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19"
+CHARS_UPPER = u"\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004a\u004b\u004c\u004d\u004e\u004f\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057\u0058\u0059\u005a\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u00d0\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d8\u00d9\u00da\u00db\u00dc\u00dd\u00de\u0100\u0102\u0104\u0106\u0108\u010a\u010c\u010e\u0110\u0112\u0114\u0116\u0118\u011a\u011c\u011e\u0120\u0122\u0124\u0126\u0128\u012a\u012c\u012e\u0130\u0132\u0134\u0136\u0139\u013b\u013d\u013f\u0141\u0143\u0145\u0147\u014a\u014c\u014e\u0150\u0152\u0154\u0156\u0158\u015a\u015c\u015e\u0160\u0162\u0164\u0166\u0168\u016a\u016c\u016e\u0170\u0172\u0174\u0176\u0178\u0179\u017b\u017d\u0181\u0182\u0184\u0186\u0187\u0189\u018a\u018b\u018e\u018f\u0190\u0191\u0193\u0194\u0196\u0197\u0198\u019c\u019d\u019f\u01a0\u01a2\u01a4\u01a6\u01a7\u01a9\u01ac\u01ae\u01af\u01b1\u01b2\u01b3\u01b5\u01b7\u01b8\u01bc\u01c4\u01c7\u01ca\u01cd\u01cf\u01d1\u01d3\u01d5\u01d7\u01d9\u01db\u01de\u01e0\u01e2\u01e4\u01e6\u01e8\u01ea\u01ec\u01ee\u01f1\u01f4\u01f6\u01f7\u01f8\u01fa\u01fc\u01fe\u0200\u0202\u0204\u0206\u0208\u020a\u020c\u020e\u0210\u0212\u0214\u0216\u0218\u021a\u021c\u021e\u0220\u0222\u0224\u0226\u0228\u022a\u022c\u022e\u0230\u0232\u0386\u0388\u0389\u038a\u038c\u038e\u038f\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab\u03d2\u03d3\u03d4\u03d8\u03da\u03dc\u03de\u03e0\u03e2\u03e4\u03e6\u03e8\u03ea\u03ec\u03ee\u03f4\u0400\u0401\u0402\u0403\u0404\u0405\u0406\u0407\u0408\u0409\u040a\u040b\u040c\u040d\u040e\u040f\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0460\u0462\u0464\u0466\u0468\u046a\u046c\u046e\u0470\u0472\u0474\u0476\u0478\u047a\u047c\u047e\u0480\u048a\u048c\u048e\u0490\u0492\u0494\u0496\u0498\u049a\u049c\u049e\u04a0\u04a2\u04a4\u04a6\u04a8\u04aa\u04ac\u04ae\u04b0\u04b2\u04b4\u04b6\u04b8\u04ba\u04bc\u04be\u04c0\u04c1\u04c3\u04c5\u04c7\u04c9\u04cb\u04cd\u04d0\u04d2\u04d4\u04d6\u04d8\u04da\u04dc\u04de\u04e0\u04e2\u04e4\u04e6\u04e8\u04ea\u04ec\u04ee\u04f0\u04f2\u04f4\u04f8\u0500\u0502\u0504\u0506\u0508\u050a\u050c\u050e\u0531\u0532\u0533\u0534\u0535\u0536\u0537\u0538\u0539\u053a\u053b\u053c\u053d\u053e\u053f\u0540\u0541\u0542\u0543\u0544\u0545\u0546\u0547\u0548\u0549\u054a\u054b\u054c\u054d\u054e\u054f\u0550\u0551\u0552\u0553\u0554\u0555\u0556\u10a0\u10a1\u10a2\u10a3\u10a4\u10a5\u10a6\u10a7\u10a8\u10a9\u10aa\u10ab\u10ac\u10ad\u10ae\u10af\u10b0\u10b1\u10b2\u10b3\u10b4\u10b5\u10b6\u10b7\u10b8\u10b9\u10ba\u10bb\u10bc\u10bd\u10be\u10bf\u10c0\u10c1\u10c2\u10c3\u10c4\u10c5\u1e00\u1e02\u1e04\u1e06\u1e08\u1e0a\u1e0c\u1e0e\u1e10\u1e12\u1e14\u1e16\u1e18\u1e1a\u1e1c\u1e1e\u1e20\u1e22\u1e24\u1e26\u1e28\u1e2a\u1e2c\u1e2e\u1e30\u1e32\u1e34\u1e36\u1e38\u1e3a\u1e3c\u1e3e\u1e40\u1e42\u1e44\u1e46\u1e48\u1e4a\u1e4c\u1e4e\u1e50\u1e52\u1e54\u1e56\u1e58\u1e5a\u1e5c\u1e5e\u1e60\u1e62\u1e64\u1e66\u1e68\u1e6a\u1e6c\u1e6e\u1e70\u1e72\u1e74\u1e76\u1e78\u1e7a\u1e7c\u1e7e\u1e80\u1e82\u1e84\u1e86\u1e88\u1e8a\u1e8c\u1e8e\u1e90\u1e92\u1e94\u1ea0\u1ea2\u1ea4\u1ea6\u1ea8\u1eaa\u1eac\u1eae\u1eb0\u1eb2\u1eb4\u1eb6\u1eb8\u1eba\u1ebc\u1ebe\u1ec0\u1ec2\u1ec4\u1ec6\u1ec8\u1eca\u1ecc\u1ece\u1ed0\u1ed2\u1ed4\u1ed6\u1ed8\u1eda\u1edc\u1ede\u1ee0\u1ee2\u1ee4\u1ee6\u1ee8\u1eea\u1eec\u1eee\u1ef0\u1ef2\u1ef4\u1ef6\u1ef8\u1f08\u1f09\u1f0a\u1f0b\u1f0c\u1f0d\u1f0e\u1f0f\u1f18\u1f19\u1f1a\u1f1b\u1f1c\u1f1d\u1f28\u1f29\u1f2a\u1f2b\u1f2c\u1f2d\u1f2e\u1f2f\u1f38\u1f39\u1f3a\u1f3b\u1f3c\u1f3d\u1f3e\u1f3f\u1f48\u1f49\u1f4a\u1f4b\u1f4c\u1f4d\u1f59\u1f5b\u1f5d\u1f5f\u1f68\u1f69\u1f6a\u1f6b\u1f6c\u1f6d\u1f6e\u1f6f\u1fb8\u1fb9\u1fba\u1fbb\u1fc8\u1fc9\u1fca\u1fcb\u1fd8\u1fd9\u1fda\u1fdb\u1fe8\u1fe9\u1fea\u1feb\u1fec\u1ff8\u1ff9\u1ffa\u1ffb\u2102\u2107\u210b\u210c\u210d\u2110\u2111\u2112\u2115\u2119\u211a\u211b\u211c\u211d\u2124\u2126\u2128\u212a\u212b\u212c\u212d\u2130\u2131\u2133\u213e\u213f\u2145\uff21\uff22\uff23\uff24\uff25\uff26\uff27\uff28\uff29\uff2a\uff2b\uff2c\uff2d\uff2e\uff2f\uff30\uff31\uff32\uff33\uff34\uff35\uff36\uff37\uff38\uff39\uff3a"
 
-chars_digits = u"\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u00b2\u00b3\u00b9\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u0966\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u09e6\u09e7\u09e8\u09e9\u09ea\u09eb\u09ec\u09ed\u09ee\u09ef\u0a66\u0a67\u0a68\u0a69\u0a6a\u0a6b\u0a6c\u0a6d\u0a6e\u0a6f\u0ae6\u0ae7\u0ae8\u0ae9\u0aea\u0aeb\u0aec\u0aed\u0aee\u0aef\u0b66\u0b67\u0b68\u0b69\u0b6a\u0b6b\u0b6c\u0b6d\u0b6e\u0b6f\u0be7\u0be8\u0be9\u0bea\u0beb\u0bec\u0bed\u0bee\u0bef\u0c66\u0c67\u0c68\u0c69\u0c6a\u0c6b\u0c6c\u0c6d\u0c6e\u0c6f\u0ce6\u0ce7\u0ce8\u0ce9\u0cea\u0ceb\u0cec\u0ced\u0cee\u0cef\u0d66\u0d67\u0d68\u0d69\u0d6a\u0d6b\u0d6c\u0d6d\u0d6e\u0d6f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0ed0\u0ed1\u0ed2\u0ed3\u0ed4\u0ed5\u0ed6\u0ed7\u0ed8\u0ed9\u0f20\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\u0f29\u1040\u1041\u1042\u1043\u1044\u1045\u1046\u1047\u1048\u1049\u1369\u136a\u136b\u136c\u136d\u136e\u136f\u1370\u1371\u17e0\u17e1\u17e2\u17e3\u17e4\u17e5\u17e6\u17e7\u17e8\u17e9\u1810\u1811\u1812\u1813\u1814\u1815\u1816\u1817\u1818\u1819\u2070\u2074\u2075\u2076\u2077\u2078\u2079\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089\u2460\u2461\u2462\u2463\u2464\u2465\u2466\u2467\u2468\u2474\u2475\u2476\u2477\u2478\u2479\u247a\u247b\u247c\u2488\u2489\u248a\u248b\u248c\u248d\u248e\u248f\u2490\u24ea\u24f5\u24f6\u24f7\u24f8\u24f9\u24fa\u24fb\u24fc\u24fd\u2776\u2777\u2778\u2779\u277a\u277b\u277c\u277d\u277e\u2780\u2781\u2782\u2783\u2784\u2785\u2786\u2787\u2788\u278a\u278b\u278c\u278d\u278e\u278f\u2790\u2791\u2792\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19"
+CHARS_LOWER = u"\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068\u0069\u006a\u006b\u006c\u006d\u006e\u006f\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077\u0078\u0079\u007a\u00aa\u00b5\u00ba\u00df\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u00f0\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u00fe\u00ff\u0101\u0103\u0105\u0107\u0109\u010b\u010d\u010f\u0111\u0113\u0115\u0117\u0119\u011b\u011d\u011f\u0121\u0123\u0125\u0127\u0129\u012b\u012d\u012f\u0131\u0133\u0135\u0137\u0138\u013a\u013c\u013e\u0140\u0142\u0144\u0146\u0148\u0149\u014b\u014d\u014f\u0151\u0153\u0155\u0157\u0159\u015b\u015d\u015f\u0161\u0163\u0165\u0167\u0169\u016b\u016d\u016f\u0171\u0173\u0175\u0177\u017a\u017c\u017e\u017f\u0180\u0183\u0185\u0188\u018c\u018d\u0192\u0195\u0199\u019a\u019b\u019e\u01a1\u01a3\u01a5\u01a8\u01aa\u01ab\u01ad\u01b0\u01b4\u01b6\u01b9\u01ba\u01bd\u01be\u01bf\u01c6\u01c9\u01cc\u01ce\u01d0\u01d2\u01d4\u01d6\u01d8\u01da\u01dc\u01dd\u01df\u01e1\u01e3\u01e5\u01e7\u01e9\u01eb\u01ed\u01ef\u01f0\u01f3\u01f5\u01f9\u01fb\u01fd\u01ff\u0201\u0203\u0205\u0207\u0209\u020b\u020d\u020f\u0211\u0213\u0215\u0217\u0219\u021b\u021d\u021f\u0223\u0225\u0227\u0229\u022b\u022d\u022f\u0231\u0233\u0250\u0251\u0252\u0253\u0254\u0255\u0256\u0257\u0258\u0259\u025a\u025b\u025c\u025d\u025e\u025f\u0260\u0261\u0262\u0263\u0264\u0265\u0266\u0267\u0268\u0269\u026a\u026b\u026c\u026d\u026e\u026f\u0270\u0271\u0272\u0273\u0274\u0275\u0276\u0277\u0278\u0279\u027a\u027b\u027c\u027d\u027e\u027f\u0280\u0281\u0282\u0283\u0284\u0285\u0286\u0287\u0288\u0289\u028a\u028b\u028c\u028d\u028e\u028f\u0290\u0291\u0292\u0293\u0294\u0295\u0296\u0297\u0298\u0299\u029a\u029b\u029c\u029d\u029e\u029f\u02a0\u02a1\u02a2\u02a3\u02a4\u02a5\u02a6\u02a7\u02a8\u02a9\u02aa\u02ab\u02ac\u02ad\u0390\u03ac\u03ad\u03ae\u03af\u03b0\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\u03ca\u03cb\u03cc\u03cd\u03ce\u03d0\u03d1\u03d5\u03d6\u03d7\u03d9\u03db\u03dd\u03df\u03e1\u03e3\u03e5\u03e7\u03e9\u03eb\u03ed\u03ef\u03f0\u03f1\u03f2\u03f3\u03f5\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u0450\u0451\u0452\u0453\u0454\u0455\u0456\u0457\u0458\u0459\u045a\u045b\u045c\u045d\u045e\u045f\u0461\u0463\u0465\u0467\u0469\u046b\u046d\u046f\u0471\u0473\u0475\u0477\u0479\u047b\u047d\u047f\u0481\u048b\u048d\u048f\u0491\u0493\u0495\u0497\u0499\u049b\u049d\u049f\u04a1\u04a3\u04a5\u04a7\u04a9\u04ab\u04ad\u04af\u04b1\u04b3\u04b5\u04b7\u04b9\u04bb\u04bd\u04bf\u04c2\u04c4\u04c6\u04c8\u04ca\u04cc\u04ce\u04d1\u04d3\u04d5\u04d7\u04d9\u04db\u04dd\u04df\u04e1\u04e3\u04e5\u04e7\u04e9\u04eb\u04ed\u04ef\u04f1\u04f3\u04f5\u04f9\u0501\u0503\u0505\u0507\u0509\u050b\u050d\u050f\u0561\u0562\u0563\u0564\u0565\u0566\u0567\u0568\u0569\u056a\u056b\u056c\u056d\u056e\u056f\u0570\u0571\u0572\u0573\u0574\u0575\u0576\u0577\u0578\u0579\u057a\u057b\u057c\u057d\u057e\u057f\u0580\u0581\u0582\u0583\u0584\u0585\u0586\u0587\u1e01\u1e03\u1e05\u1e07\u1e09\u1e0b\u1e0d\u1e0f\u1e11\u1e13\u1e15\u1e17\u1e19\u1e1b\u1e1d\u1e1f\u1e21\u1e23\u1e25\u1e27\u1e29\u1e2b\u1e2d\u1e2f\u1e31\u1e33\u1e35\u1e37\u1e39\u1e3b\u1e3d\u1e3f\u1e41\u1e43\u1e45\u1e47\u1e49\u1e4b\u1e4d\u1e4f\u1e51\u1e53\u1e55\u1e57\u1e59\u1e5b\u1e5d\u1e5f\u1e61\u1e63\u1e65\u1e67\u1e69\u1e6b\u1e6d\u1e6f\u1e71\u1e73\u1e75\u1e77\u1e79\u1e7b\u1e7d\u1e7f\u1e81\u1e83\u1e85\u1e87\u1e89\u1e8b\u1e8d\u1e8f\u1e91\u1e93\u1e95\u1e96\u1e97\u1e98\u1e99\u1e9a\u1e9b\u1ea1\u1ea3\u1ea5\u1ea7\u1ea9\u1eab\u1ead\u1eaf\u1eb1\u1eb3\u1eb5\u1eb7\u1eb9\u1ebb\u1ebd\u1ebf\u1ec1\u1ec3\u1ec5\u1ec7\u1ec9\u1ecb\u1ecd\u1ecf\u1ed1\u1ed3\u1ed5\u1ed7\u1ed9\u1edb\u1edd\u1edf\u1ee1\u1ee3\u1ee5\u1ee7\u1ee9\u1eeb\u1eed\u1eef\u1ef1\u1ef3\u1ef5\u1ef7\u1ef9\u1f00\u1f01\u1f02\u1f03\u1f04\u1f05\u1f06\u1f07\u1f10\u1f11\u1f12\u1f13\u1f14\u1f15\u1f20\u1f21\u1f22\u1f23\u1f24\u1f25\u1f26\u1f27\u1f30\u1f31\u1f32\u1f33\u1f34\u1f35\u1f36\u1f37\u1f40\u1f41\u1f42\u1f43\u1f44\u1f45\u1f50\u1f51\u1f52\u1f53\u1f54\u1f55\u1f56\u1f57\u1f60\u1f61\u1f62\u1f63\u1f64\u1f65\u1f66\u1f67\u1f70\u1f71\u1f72\u1f73\u1f74\u1f75\u1f76\u1f77\u1f78\u1f79\u1f7a\u1f7b\u1f7c\u1f7d\u1f80\u1f81\u1f82\u1f83\u1f84\u1f85\u1f86\u1f87\u1f90\u1f91\u1f92\u1f93\u1f94\u1f95\u1f96\u1f97\u1fa0\u1fa1\u1fa2\u1fa3\u1fa4\u1fa5\u1fa6\u1fa7\u1fb0\u1fb1\u1fb2\u1fb3\u1fb4\u1fb6\u1fb7\u1fbe\u1fc2\u1fc3\u1fc4\u1fc6\u1fc7\u1fd0\u1fd1\u1fd2\u1fd3\u1fd6\u1fd7\u1fe0\u1fe1\u1fe2\u1fe3\u1fe4\u1fe5\u1fe6\u1fe7\u1ff2\u1ff3\u1ff4\u1ff6\u1ff7\u2071\u207f\u210a\u210e\u210f\u2113\u212f\u2134\u2139\u213d\u2146\u2147\u2148\u2149\ufb00\ufb01\ufb02\ufb03\ufb04\ufb05\ufb06\ufb13\ufb14\ufb15\ufb16\ufb17\uff41\uff42\uff43\uff44\uff45\uff46\uff47\uff48\uff49\uff4a\uff4b\uff4c\uff4d\uff4e\uff4f\uff50\uff51\uff52\uff53\uff54\uff55\uff56\uff57\uff58\uff59\uff5a\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u00b2\u00b3\u00b9\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u0966\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u09e6\u09e7\u09e8\u09e9\u09ea\u09eb\u09ec\u09ed\u09ee\u09ef\u0a66\u0a67\u0a68\u0a69\u0a6a\u0a6b\u0a6c\u0a6d\u0a6e\u0a6f\u0ae6\u0ae7\u0ae8\u0ae9\u0aea\u0aeb\u0aec\u0aed\u0aee\u0aef\u0b66\u0b67\u0b68\u0b69\u0b6a\u0b6b\u0b6c\u0b6d\u0b6e\u0b6f\u0be7\u0be8\u0be9\u0bea\u0beb\u0bec\u0bed\u0bee\u0bef\u0c66\u0c67\u0c68\u0c69\u0c6a\u0c6b\u0c6c\u0c6d\u0c6e\u0c6f\u0ce6\u0ce7\u0ce8\u0ce9\u0cea\u0ceb\u0cec\u0ced\u0cee\u0cef\u0d66\u0d67\u0d68\u0d69\u0d6a\u0d6b\u0d6c\u0d6d\u0d6e\u0d6f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0ed0\u0ed1\u0ed2\u0ed3\u0ed4\u0ed5\u0ed6\u0ed7\u0ed8\u0ed9\u0f20\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\u0f29\u1040\u1041\u1042\u1043\u1044\u1045\u1046\u1047\u1048\u1049\u1369\u136a\u136b\u136c\u136d\u136e\u136f\u1370\u1371\u17e0\u17e1\u17e2\u17e3\u17e4\u17e5\u17e6\u17e7\u17e8\u17e9\u1810\u1811\u1812\u1813\u1814\u1815\u1816\u1817\u1818\u1819\u2070\u2074\u2075\u2076\u2077\u2078\u2079\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089\u2460\u2461\u2462\u2463\u2464\u2465\u2466\u2467\u2468\u2474\u2475\u2476\u2477\u2478\u2479\u247a\u247b\u247c\u2488\u2489\u248a\u248b\u248c\u248d\u248e\u248f\u2490\u24ea\u24f5\u24f6\u24f7\u24f8\u24f9\u24fa\u24fb\u24fc\u24fd\u2776\u2777\u2778\u2779\u277a\u277b\u277c\u277d\u277e\u2780\u2781\u2782\u2783\u2784\u2785\u2786\u2787\u2788\u278a\u278b\u278c\u278d\u278e\u278f\u2790\u2791\u2792\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19"
 
-chars_spaces = u"\u0009\u000a\u000b\u000c\u000d\u001c\u001d\u001e\u001f\u0020\u0085\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000"
+CHARS_DIGITS = u"\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u00b2\u00b3\u00b9\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9\u0966\u0967\u0968\u0969\u096a\u096b\u096c\u096d\u096e\u096f\u09e6\u09e7\u09e8\u09e9\u09ea\u09eb\u09ec\u09ed\u09ee\u09ef\u0a66\u0a67\u0a68\u0a69\u0a6a\u0a6b\u0a6c\u0a6d\u0a6e\u0a6f\u0ae6\u0ae7\u0ae8\u0ae9\u0aea\u0aeb\u0aec\u0aed\u0aee\u0aef\u0b66\u0b67\u0b68\u0b69\u0b6a\u0b6b\u0b6c\u0b6d\u0b6e\u0b6f\u0be7\u0be8\u0be9\u0bea\u0beb\u0bec\u0bed\u0bee\u0bef\u0c66\u0c67\u0c68\u0c69\u0c6a\u0c6b\u0c6c\u0c6d\u0c6e\u0c6f\u0ce6\u0ce7\u0ce8\u0ce9\u0cea\u0ceb\u0cec\u0ced\u0cee\u0cef\u0d66\u0d67\u0d68\u0d69\u0d6a\u0d6b\u0d6c\u0d6d\u0d6e\u0d6f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0ed0\u0ed1\u0ed2\u0ed3\u0ed4\u0ed5\u0ed6\u0ed7\u0ed8\u0ed9\u0f20\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\u0f29\u1040\u1041\u1042\u1043\u1044\u1045\u1046\u1047\u1048\u1049\u1369\u136a\u136b\u136c\u136d\u136e\u136f\u1370\u1371\u17e0\u17e1\u17e2\u17e3\u17e4\u17e5\u17e6\u17e7\u17e8\u17e9\u1810\u1811\u1812\u1813\u1814\u1815\u1816\u1817\u1818\u1819\u2070\u2074\u2075\u2076\u2077\u2078\u2079\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089\u2460\u2461\u2462\u2463\u2464\u2465\u2466\u2467\u2468\u2474\u2475\u2476\u2477\u2478\u2479\u247a\u247b\u247c\u2488\u2489\u248a\u248b\u248c\u248d\u248e\u248f\u2490\u24ea\u24f5\u24f6\u24f7\u24f8\u24f9\u24fa\u24fb\u24fc\u24fd\u2776\u2777\u2778\u2779\u277a\u277b\u277c\u277d\u277e\u2780\u2781\u2782\u2783\u2784\u2785\u2786\u2787\u2788\u278a\u278b\u278c\u278d\u278e\u278f\u2790\u2791\u2792\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19"
+
+CHARS_SPACES = u"\u0009\u000a\u000b\u000c\u000d\u001c\u001d\u001e\u001f\u0020\u0085\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000"
--- a/MoinMoin/constants/contenttypes.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/constants/contenttypes.py	Wed Mar 20 01:25:01 2013 +0100
@@ -8,12 +8,14 @@
 # Charset - we support only 'utf-8'. While older encodings might work,
 # we don't have the resources to test them, and there is no real
 # benefit for the user. IMPORTANT: use only lowercase 'utf-8'!
-charset = 'utf-8'
+CHARSET = 'utf-8'
 
 # Parser to use mimetype text
-parser_text_mimetype = ('plain', 'csv', 'rst', 'docbook', 'latex', 'tex', 'html', 'css',
-                       'xml', 'python', 'perl', 'php', 'ruby', 'javascript',
-                       'cplusplus', 'java', 'pascal', 'diff', 'gettext', 'xslt', 'creole', )
+PARSER_TEXT_MIMETYPE = [
+    'plain', 'csv', 'rst', 'docbook', 'latex', 'tex', 'html', 'css',
+    'xml', 'python', 'perl', 'php', 'ruby', 'javascript',
+    'cplusplus', 'java', 'pascal', 'diff', 'gettext', 'xslt', 'creole',
+]
 
 CONTENTTYPE_USER = u'application/x.moin.userprofile'
 CONTENTTYPE_DEFAULT = u'application/octet-stream'
@@ -27,3 +29,5 @@
 GROUP_VIDEO = 'video items'
 GROUP_DRAWING = 'drawing items'
 GROUP_OTHER = 'other items'
+
+DRAWING_EXTENSIONS = ['.tdraw', '.adraw', '.svg', '.png', '.jpg', '.jpeg', '.gif', ]
--- a/MoinMoin/constants/forms.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/constants/forms.py	Wed Mar 20 01:25:01 2013 +0100
@@ -7,7 +7,7 @@
 
 # Widget types
 
-WIDGET_TEXT = u'text' # single-line text
+WIDGET_TEXT = u'text'  # single-line text
 WIDGET_MULTILINE_TEXT = u'multiline_text'
 WIDGET_URL = u'url'
 WIDGET_EMAIL = u'email'
@@ -24,6 +24,7 @@
 WIDGET_HIDDEN = u'hidden'
 
 WIDGET_SELECT = u'select'
+WIDGET_SELECT_SUBMIT = u'select_submit'
 WIDGET_MULTI_SELECT = u'multi_select'
 
 WIDGET_READONLY_STRING_LIST = u'readonly_string_list'
--- a/MoinMoin/constants/keys.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/constants/keys.py	Wed Mar 20 01:25:01 2013 +0100
@@ -20,11 +20,6 @@
 # some metadata key constants:
 ACL = "acl"
 
-# This says: I am a system item
-IS_SYSITEM = "is_syspage"
-# This says: original sysitem as contained in release: <release>
-SYSITEM_VERSION = "syspage_version"
-
 # keys for storing group and dict information
 # group of user names, e.g. for ACLs:
 USERGROUP = "usergroup"
@@ -53,7 +48,7 @@
 # data. meta[HASH_ALGORITHM] = hash(rev_data, HASH_ALGORITHM)
 # some backends may use this also for other purposes.
 HASH_ALGORITHM = 'sha1'
-HASH_LEN = 40 # length of hex str representation of hash value
+HASH_LEN = 40  # length of hex str representation of hash value
 
 # some field names for whoosh index schema / documents in index:
 NAME_EXACT = "name_exact"
@@ -88,6 +83,8 @@
 CSS_URL = "css_url"
 EDIT_ROWS = "edit_rows"
 RESULTS_PER_PAGE = "results_per_page"
+WANT_TRIVIAL = "want_trivial"
+EMAIL_SUBSCRIBED_EVENTS = "email_subscribed_events"
 DISABLED = "disabled"
 GAE_USER_ID = "gae_user_id"
 
--- a/MoinMoin/constants/misc.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/constants/misc.py	Wed Mar 20 01:25:01 2013 +0100
@@ -7,9 +7,11 @@
 
 import re
 
+ANON = u'anonymous'
+
 # Invalid characters - invisible characters that should not be in page
 # names. Prevent user confusion and wiki abuse, e.g u'\u202aFrontPage'.
-page_invalid_chars_regex = re.compile(
+ITEM_INVALID_CHARS_REGEX = re.compile(
     ur"""
     \u0000 | # NULL
 
@@ -21,26 +23,26 @@
     \u202E   # RLM
     """,
     re.UNICODE | re.VERBOSE
-    )
+)
 
-clean_input_translation_map = {
+CLEAN_INPUT_TRANSLATION_MAP = {
     # these chars will be replaced by blanks
     ord(u'\t'): u' ',
     ord(u'\r'): u' ',
     ord(u'\n'): u' ',
 }
-for c in u'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0e\x0f' \
-          '\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f':
+for c in u'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f':
     # these chars will be removed
-    clean_input_translation_map[ord(c)] = None
+    CLEAN_INPUT_TRANSLATION_MAP[ord(c)] = None
 del c
 
 # Other stuff
-uri_schemes = ['http', 'https', 'ftp', 'file',
-               'mailto', 'nntp', 'news',
-               'ssh', 'telnet', 'irc', 'ircs', 'xmpp', 'mumble',
-               'webcal', 'ed2k', 'apt', 'rootz',
-               'gopher',
-               'notes',
-               'rtp', 'rtsp', 'rtcp',
-              ]
+URI_SCHEMES = [
+    'http', 'https', 'ftp', 'file',
+    'mailto', 'nntp', 'news',
+    'ssh', 'telnet', 'irc', 'ircs', 'xmpp', 'mumble',
+    'webcal', 'ed2k', 'apt', 'rootz',
+    'gopher',
+    'notes',
+    'rtp', 'rtsp', 'rtcp',
+]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/constants/namespaces.py	Wed Mar 20 01:25:01 2013 +0100
@@ -0,0 +1,9 @@
+# Copyright: 2013 MoinMoin:CheerXiao
+# License: GNU GPL v2 (or any later version), see LICENSE.txt for details.
+
+"""
+MoinMoin - namespaces related constants
+"""
+
+NAMESPACE_DEFAULT = u''
+NAMESPACE_USERPROFILES = u'userprofiles'
--- a/MoinMoin/constants/tools/chartypes_create.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/constants/tools/chartypes_create.py	Wed Mar 20 01:25:01 2013 +0100
@@ -25,18 +25,18 @@
             space.append(str)
 
     chars_upper = u''.join(uppercase)
-    chars_lower = u''.join(lowercase+digits)
+    chars_lower = u''.join(lowercase + digits)
     chars_digits = u''.join(digits)
     chars_spaces = u''.join(space)
 
     print """
-chars_upper = u"%(chars_upper)s"
+CHARS_UPPER = u"%(chars_upper)s"
 
-chars_lower = u"%(chars_lower)s"
+CHARS_LOWER = u"%(chars_lower)s"
 
-chars_digits = u"%(chars_digits)s"
+CHARS_DIGITS = u"%(chars_digits)s"
 
-chars_spaces = u"%(chars_spaces)s"
+CHARS_SPACES = u"%(chars_spaces)s"
 
 
 """ % locals()
--- a/MoinMoin/converter/_args.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_args.py	Wed Mar 20 01:25:01 2013 +0100
@@ -37,8 +37,7 @@
         return len(self.positional) + len(self.keyword)
 
     def __repr__(self):
-        return '<{0}({1!r}, {2!r})>'.format(self.__class__.__name__,
-                self.positional, self.keyword)
+        return '<{0}({1!r}, {2!r})>'.format(self.__class__.__name__, self.positional, self.keyword)
 
     def items(self):
         """
--- a/MoinMoin/converter/_args_wiki.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_args_wiki.py	Wed Mar 20 01:25:01 2013 +0100
@@ -32,6 +32,7 @@
 '''
 _parse_re = re.compile(_parse_rules, re.X)
 
+
 def parse(input):
     """
     Parse <input> for positional and keyword arguments, with value quoting and
@@ -57,6 +58,7 @@
 _unparse_rules = r'''^[-\w]+$'''
 _unparse_re = re.compile(_unparse_rules, re.X)
 
+
 def unparse(args):
     """
     Generate a argument string from a Argument instance <args>.
--- a/MoinMoin/converter/_table.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_table.py	Wed Mar 20 01:25:01 2013 +0100
@@ -13,6 +13,7 @@
 
 WORDBREAK_LEN = 30
 
+
 class TableMixin(object):
     """
     Mixin to support building a DOM table.
--- a/MoinMoin/converter/_tests/test__args.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test__args.py	Wed Mar 20 01:25:01 2013 +0100
@@ -10,6 +10,7 @@
 
 from MoinMoin.converter._args import *
 
+
 def test_Arguments___init__():
     positional = []
     keyword = {}
@@ -21,6 +22,7 @@
     assert keyword == a.keyword
     assert keyword is not a.keyword
 
+
 def test_Arguments___contains__():
     positional = ['positional', 'both']
     keyword = {'keyword': None, 'both': None}
@@ -32,6 +34,7 @@
     assert 'both' in a
     assert 'none' not in a
 
+
 def test_Arguments___getitem__():
     positional = ['positional', 'both']
     keyword = {'keyword': None, 'both': None}
@@ -47,6 +50,7 @@
     pytest.raises(IndexError, a.__getitem__, 2)
     pytest.raises(KeyError, a.__getitem__, 'none')
 
+
 def test_Arguments___len__():
     positional = ['positional', 'both']
     keyword = {'keyword': None, 'both': None}
@@ -55,6 +59,7 @@
 
     assert len(a) == 4
 
+
 def test_Arguments_items():
     positional = ['positional', 'both']
     keyword = {'keyword': True, 'both': False}
@@ -69,6 +74,7 @@
     assert ('keyword', True) in l
     assert ('both', False) in l
 
+
 def test_Arguments_keys():
     positional = ['positional', 'both']
     keyword = {'keyword': True, 'both': False}
@@ -81,6 +87,7 @@
     assert 'keyword' in l
     assert 'both' in l
 
+
 def test_Arguments_values():
     positional = ['positional', 'both']
     keyword = {'keyword': True, 'both': False}
--- a/MoinMoin/converter/_tests/test__args_wiki.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test__args_wiki.py	Wed Mar 20 01:25:01 2013 +0100
@@ -6,31 +6,32 @@
 """
 
 
-import pytest
+from MoinMoin.converter._args_wiki import *
 
-from MoinMoin.converter._args_wiki import *
 
 def test():
     yield (do,
-        ur'both positional both=foo keyword=bar',
-        [u'both', u'positional'],
-        {u'both': u'foo', u'keyword': u'bar'})
+           ur'both positional both=foo keyword=bar',
+           [u'both', u'positional'],
+           {u'both': u'foo', u'keyword': u'bar'})
 
     yield (do,
-        ur'a-b a_b a-c=foo a_c=bar',
-        [u'a-b', u'a_b'],
-        {u'a-c': u'foo', u'a_c': u'bar'})
+           ur'a-b a_b a-c=foo a_c=bar',
+           [u'a-b', u'a_b'],
+           {u'a-c': u'foo', u'a_c': u'bar'})
 
     yield (do,
-        ur'''"a b\tc\nd" k="a b\tc\nd"''',
-        [u'a b\tc\nd'],
-        {u'k': u'a b\tc\nd'})
+           ur'''"a b\tc\nd" k="a b\tc\nd"''',
+           [u'a b\tc\nd'],
+           {u'k': u'a b\tc\nd'})
+
 
 def test_parse():
     a = parse(ur''''a b\tc\nd',k="a b\tc\nd"''')
     assert a.positional == [u'a b\tc\nd']
     assert a.keyword == {u'k': u'a b\tc\nd'}
 
+
 def do(wiki, positional, keyword):
     a = parse(wiki)
     assert a.positional == positional
--- a/MoinMoin/converter/_tests/test__wiki_macro.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test__wiki_macro.py	Wed Mar 20 01:25:01 2013 +0100
@@ -6,7 +6,6 @@
 """
 
 
-import pytest
 import re
 
 from MoinMoin.converter._args import Arguments
--- a/MoinMoin/converter/_tests/test_creole_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test_creole_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -6,8 +6,6 @@
 """
 
 
-import pytest
-
 import re
 
 from MoinMoin.util.tree import moin_page, xlink
@@ -223,15 +221,15 @@
                 '<page><body><p><code>nowiki</code> <code>nowiki</code></p></body></page>'),
             # XXX: Is <page> correct?
             (u'{{{\n#!\nwiki\n}}}',
-               '<page><body><page><body><p>wiki</p></body></page></body></page>'),
+                '<page><body><page><body><p>wiki</p></body></page></body></page>'),
             (u'{{{\n#!(style="background-color: red")\nwiki\n}}}',
-               '<page><body><page><body style="background-color: red"><p>wiki</p></body></page></body></page>'),
+                '<page><body><page><body style="background-color: red"><p>wiki</p></body></page></body></page>'),
             (u'{{{\n#!creole\nwiki\n}}}',
-               '<page><body><page><body><p>wiki</p></body></page></body></page>'),
+                '<page><body><page><body><p>wiki</p></body></page></body></page>'),
             (u'{{{\n#!creole(style="background-color: red")\nwiki\n}}}',
-               '<page><body><page><body style="background-color: red"><p>wiki</p></body></page></body></page>'),
+                '<page><body><page><body style="background-color: red"><p>wiki</p></body></page></body></page>'),
             (u'{{{\n#!text/plain\ntext\n}}}',
-               u'<page><body><part content-type="text/plain"><body>text</body></part></body></page>'),
+                u'<page><body><part content-type="text/plain"><body>text</body></part></body></page>'),
         ]
         for i in data:
             yield (self.do, ) + i
--- a/MoinMoin/converter/_tests/test_docbook_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test_docbook_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -11,10 +11,8 @@
 import StringIO
 
 import pytest
-try:
-    from lxml import etree
-except:
-    pytest.skip("lxml module required to run test for docbook_in converter.")
+
+etree = pytest.importorskip('lxml.etree')
 
 from emeraldtree.tree import *
 
@@ -23,6 +21,7 @@
 
 from MoinMoin.converter.docbook_in import *
 
+
 class Base(object):
     input_namespaces = ns_all = u'xmlns="{0}" xmlns:xlink="{1}"'.format(docbook.namespace, xlink.namespace)
     output_namespaces = {
@@ -65,6 +64,7 @@
         tree = etree.parse(StringIO.StringIO(string_to_parse))
         assert (tree.xpath(xpath_query, namespaces=self.namespaces_xpath))
 
+
 class TestConverter(Base):
     def setup_class(self):
         self.conv = Converter()
@@ -72,37 +72,37 @@
     def test_base(self):
         data = [
             ('<article><para>Test</para></article>',
-              # <page><body><div html:class="db-article"><p>Test</p></div></body></page>
-             '/page/body/div[@html:class="db-article"][p="Test"]'),
+                # <page><body><div html:class="db-article"><p>Test</p></div></body></page>
+                '/page/body/div[@html:class="db-article"][p="Test"]'),
             ('<article><simpara>Test</simpara></article>',
-            # <page><body><div html:class="article"><p>Test</p></div></body></page>
-             '/page/body/div[p="Test"]'),
+                # <page><body><div html:class="article"><p>Test</p></div></body></page>
+                '/page/body/div[p="Test"]'),
             ('<article><formalpara><title>Title</title><para>Test</para></formalpara></article>',
-            # <page><body><div html:class="article"><p html:title="Title">Test</p></div></body></page>
-            '/page/body/div/p[text()="Test"][@html:title="Title"]'),
+                # <page><body><div html:class="article"><p html:title="Title">Test</p></div></body></page>
+                '/page/body/div/p[text()="Test"][@html:title="Title"]'),
             ('<article><sect1><title>Heading 1</title> <para>First Paragraph</para></sect1></article>',
-            # <page><body><div html:class="article"><h outline-level="1">Heading 1</h><p>First Paragraph</p></div></body></page>
-             '/page/body/div[./h[@outline-level="1"][text()="Heading 1"]][./p[text()="First Paragraph"]]'),
+                # <page><body><div html:class="article"><h outline-level="1">Heading 1</h><p>First Paragraph</p></div></body></page>
+                '/page/body/div[./h[@outline-level="1"][text()="Heading 1"]][./p[text()="First Paragraph"]]'),
             # Test for conversion with unicode char
             (u'<article><para>안녕 유빈</para></article>',
-            # <page><body><div html:class="article"><p>안녕 유빈</p></div></body></page>
-             u'/page/body/div[p="안녕 유빈"]'),
+                # <page><body><div html:class="article"><p>안녕 유빈</p></div></body></page>
+                u'/page/body/div[p="안녕 유빈"]'),
             # Ignored tags
             ('<article><info><title>Title</title><author>Author</author></info><para>text</para></article>',
-            # <page><body><div html:class="article"><p>text</p></div></body></page>
-            '/page/body/div[p="text"]'),
+                # <page><body><div html:class="article"><p>text</p></div></body></page>
+                '/page/body/div[p="text"]'),
             # XML attributes: We support all the xml standard attributes
             ('<article><para xml:base="http://base.tld" xml:id="id" xml:lang="en">Text</para></article>',
-            # <page><body><div html:class="article"><p xml:base="http://base.tld" xml:id="id" xml:lang="en">Text</p></div></body></page>
-            '/page/body/div/p[@xml:base="http://base.tld"][@xml:id="id"][@xml:lang="en"][text()="Text"]'),
+                # <page><body><div html:class="article"><p xml:base="http://base.tld" xml:id="id" xml:lang="en">Text</p></div></body></page>
+                '/page/body/div/p[@xml:base="http://base.tld"][@xml:id="id"][@xml:lang="en"][text()="Text"]'),
             # ANCHOR --> SPAN
             ('<article><para>bla bla<anchor xml:id="point_1" />bla bla</para></article>',
-            # <page><body><div html:class="article"><p>bla bla<span class="db-anchor" xml:id="point_1" />bla bla</p></div></body></page>
-            '/page/body/div/p/span[@html:class="db-anchor"][@xml:id="point_1"]'),
+                # <page><body><div html:class="article"><p>bla bla<span class="db-anchor" xml:id="point_1" />bla bla</p></div></body></page>
+                '/page/body/div/p/span[@html:class="db-anchor"][@xml:id="point_1"]'),
             # BOOK Document
             ('<book><para>Test</para></book>',
-            # <page><body><div html:class="db-book"><p>Test</p></div></body></page>
-            '/page/body/div[@html:class="db-book"][p="Test"]'),
+                # <page><body><div html:class="db-book"><p>Test</p></div></body></page>
+                '/page/body/div[@html:class="db-book"][p="Test"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -111,15 +111,15 @@
         data = [
             # Test simple numbered section conversion into headings.
             ('<article><sect1><title>Heading 1</title> <para>First</para><sect2><title>Heading 2</title><para>Second</para></sect2></sect1></article>',
-            # <page><body><table-of-content><div html:class="article"><h outline-level="1">Heading 1</h><p>First</p><h outline-level="2">Heading 2</h><p>Second</p></div></body></page>
-             '/page/body[table-of-content]/div[h[1][@outline-level="1"][text()="Heading 1"]][p[1][text()="First"]][h[2][@outline-level="2"][text()="Heading 2"]][p[2][text()="Second"]]'),
+                # <page><body><table-of-content><div html:class="article"><h outline-level="1">Heading 1</h><p>First</p><h outline-level="2">Heading 2</h><p>Second</p></div></body></page>
+                '/page/body[table-of-content]/div[h[1][@outline-level="1"][text()="Heading 1"]][p[1][text()="First"]][h[2][@outline-level="2"][text()="Heading 2"]][p[2][text()="Second"]]'),
             ('<article><section><title>Heading 1</title> <para>First</para><section><title>Heading 2</title><para>Second</para></section></section></article>',
-            # <page><body><table-of-content><div html:class="article"><h outline-level="1">Heading 1</h><p>First</p><h outline-level="2">Heading 2</h><p>Second</p></div></body></page>
-             '/page/body[table-of-content]/div[h[1][@outline-level="1"][text()="Heading 1"]][p[1][text()="First"]][h[2][@outline-level="2"][text()="Heading 2"]][p[2][text()="Second"]]'),
+                # <page><body><table-of-content><div html:class="article"><h outline-level="1">Heading 1</h><p>First</p><h outline-level="2">Heading 2</h><p>Second</p></div></body></page>
+                '/page/body[table-of-content]/div[h[1][@outline-level="1"][text()="Heading 1"]][p[1][text()="First"]][h[2][@outline-level="2"][text()="Heading 2"]][p[2][text()="Second"]]'),
             # Test complex recursive section conversion into headings.
             ('<article><section><title>Heading 1 A</title><para>First</para><section><title>Heading 2 A</title><para>Second</para><section><title>Heading 3 A</title><para>Third</para></section></section></section><section><title>Heading 1 B</title><para>Fourth</para></section></article>',
-            # <page><body><table-of-content /><div html:class="article"><h outline-level="1">Heading 1 A</h><p>First</p><h outline-level="2">Heading 2 A</h><p>Second</p><h outline-level="3">Heading 3 A</h><p>Third</p><h outline-level="1">Heading 1 B</h><p>Fourth</p></div></body></page>
-             '/page/body[table-of-content]/div[h[1][@outline-level="1"][text()="Heading 1 A"]][p[1][text()="First"]][h[2][@outline-level="2"][text()="Heading 2 A"]][p[2][text()="Second"]][h[3][@outline-level="3"][text()="Heading 3 A"]][p[3][text()="Third"]][h[4][@outline-level="1"][text()="Heading 1 B"]][p[4][text()="Fourth"]]'),
+                # <page><body><table-of-content /><div html:class="article"><h outline-level="1">Heading 1 A</h><p>First</p><h outline-level="2">Heading 2 A</h><p>Second</p><h outline-level="3">Heading 3 A</h><p>Third</p><h outline-level="1">Heading 1 B</h><p>Fourth</p></div></body></page>
+                '/page/body[table-of-content]/div[h[1][@outline-level="1"][text()="Heading 1 A"]][p[1][text()="First"]][h[2][@outline-level="2"][text()="Heading 2 A"]][p[2][text()="Second"]][h[3][@outline-level="3"][text()="Heading 3 A"]][p[3][text()="Third"]][h[4][@outline-level="1"][text()="Heading 1 B"]][p[4][text()="Fourth"]]'),
         ]
 
         for i in data:
@@ -129,64 +129,63 @@
         data = [
             # ITEMIZED LIST --> unordered list
             ('<article><itemizedlist><listitem>Unordered Item 1</listitem><listitem>Unordered Item 2</listitem></itemizedlist></article>',
-            # <page><body><div html:class="article"><list item-label-generate="unordered"><list-item><list-item-body>Unordered Item 1</list-item-body></list-item><list-item><list-item-body>Unordered Item 2</list-item-body></list-item></list></div></body></page>
-             '/page/body/div/list[@item-label-generate="unordered"][list-item[1]/list-item-body[text()="Unordered Item 1"]][list-item[2]/list-item-body[text()="Unordered Item 2"]]'),
+                # <page><body><div html:class="article"><list item-label-generate="unordered"><list-item><list-item-body>Unordered Item 1</list-item-body></list-item><list-item><list-item-body>Unordered Item 2</list-item-body></list-item></list></div></body></page>
+                '/page/body/div/list[@item-label-generate="unordered"][list-item[1]/list-item-body[text()="Unordered Item 1"]][list-item[2]/list-item-body[text()="Unordered Item 2"]]'),
             # ORDERED LIST --> ordered list
             ('<article><orderedlist><listitem>Ordered Item 1</listitem><listitem>Ordered Item 2</listitem></orderedlist></article>',
-            # <page><body><div html:class="article"><list item-label-generate="ordered"><list-item><list-item-body>Ordered Item 1</list-item-body></list-item><list-item><list-item-body>Ordered Item 2</list-item-body></list-item></list></div></body></page>
-             '/page/body/div/list[@item-label-generate="ordered"][list-item[1]/list-item-body[text()="Ordered Item 1"]][list-item[2]/list-item-body[text()="Ordered Item 2"]]'),
+                # <page><body><div html:class="article"><list item-label-generate="ordered"><list-item><list-item-body>Ordered Item 1</list-item-body></list-item><list-item><list-item-body>Ordered Item 2</list-item-body></list-item></list></div></body></page>
+                '/page/body/div/list[@item-label-generate="ordered"][list-item[1]/list-item-body[text()="Ordered Item 1"]][list-item[2]/list-item-body[text()="Ordered Item 2"]]'),
             # ORDERED LIST with upperalpha numeration --> ordered list with upper-alpha list-style-type
             ('<article><orderedlist numeration="upperalpha"><listitem>Ordered Item 1</listitem><listitem>Ordered Item 2</listitem></orderedlist></article>',
-
             # <page><body><div html:class="article"><list item-label-generage="ordered" list-style-type="upper-alpha"><list-item><list-item-body>Ordered Item 1</list-item-body></list-item><list-item><list-item-body>Ordered Item 2</list-item-body></list-item></list></div></body></page>
-             '/page/body/div/list[@item-label-generate="ordered"][@list-style-type="upper-alpha"][list-item[1]/list-item-body[text()="Ordered Item 1"]][list-item[2]/list-item-body[text()="Ordered Item 2"]]'),
+                '/page/body/div/list[@item-label-generate="ordered"][@list-style-type="upper-alpha"][list-item[1]/list-item-body[text()="Ordered Item 1"]][list-item[2]/list-item-body[text()="Ordered Item 2"]]'),
             # ORDERED LIST with loweralpha numeration --> ordered list with lower-alpha list-style-type
             ('<article><orderedlist numeration="loweralpha"><listitem>Ordered Item 1</listitem><listitem>Ordered Item 2</listitem></orderedlist></article>',
-            # <page><body><div html:class="article"><list item-label-generage="ordered" list-style-type="lower-alpha"><list-item><list-item-body>Ordered Item 1</list-item-body></list-item><list-item><list-item-body>Ordered Item 2</list-item-body></list-item></list></div></body></page>
-             '/page/body/div/list[@item-label-generate="ordered"][@list-style-type="lower-alpha"][list-item[1]/list-item-body[text()="Ordered Item 1"]][list-item[2]/list-item-body[text()="Ordered Item 2"]]'),
+                # <page><body><div html:class="article"><list item-label-generage="ordered" list-style-type="lower-alpha"><list-item><list-item-body>Ordered Item 1</list-item-body></list-item><list-item><list-item-body>Ordered Item 2</list-item-body></list-item></list></div></body></page>
+                '/page/body/div/list[@item-label-generate="ordered"][@list-style-type="lower-alpha"][list-item[1]/list-item-body[text()="Ordered Item 1"]][list-item[2]/list-item-body[text()="Ordered Item 2"]]'),
             # ORDERED LIST with upperroman numeration --> ordered list with upper-roman list-style-type
             ('<article><orderedlist numeration="upperroman"><listitem>Ordered Item 1</listitem><listitem>Ordered Item 2</listitem></orderedlist></article>',
-            # <page><body><div html:class="article"><list item-label-generage="ordered" list-style-type="upper-roman"><list-item><list-item-body>Ordered Item 1</list-item-body></list-item><list-item><list-item-body>Ordered Item 2</list-item-body></list-item></list></div></body></page>
-             '/page/body/div/list[@item-label-generate="ordered"][@list-style-type="upper-roman"][list-item[1]/list-item-body[text()="Ordered Item 1"]][list-item[2]/list-item-body[text()="Ordered Item 2"]]'),
+                # <page><body><div html:class="article"><list item-label-generage="ordered" list-style-type="upper-roman"><list-item><list-item-body>Ordered Item 1</list-item-body></list-item><list-item><list-item-body>Ordered Item 2</list-item-body></list-item></list></div></body></page>
+                '/page/body/div/list[@item-label-generate="ordered"][@list-style-type="upper-roman"][list-item[1]/list-item-body[text()="Ordered Item 1"]][list-item[2]/list-item-body[text()="Ordered Item 2"]]'),
             # ORDERED LIST with lowerroman numeration --> ordered list with lower-roman list-style-type
             ('<article><orderedlist numeration="lowerroman"><listitem>Ordered Item 1</listitem><listitem>Ordered Item 2</listitem></orderedlist></article>',
-            # <page><body><div html:class="article"><list item-label-generage="ordered" list-style-type="lower-roman"><list-item><list-item-body>Ordered Item 1</list-item-body></list-item><list-item><list-item-body>Ordered Item 2</list-item-body></list-item></list></div></body></page>
-             '/page/body/div/list[@item-label-generate="ordered"][@list-style-type="lower-roman"][list-item[1]/list-item-body[text()="Ordered Item 1"]][list-item[2]/list-item-body[text()="Ordered Item 2"]]'),
+                # <page><body><div html:class="article"><list item-label-generage="ordered" list-style-type="lower-roman"><list-item><list-item-body>Ordered Item 1</list-item-body></list-item><list-item><list-item-body>Ordered Item 2</list-item-body></list-item></list></div></body></page>
+                '/page/body/div/list[@item-label-generate="ordered"][@list-style-type="lower-roman"][list-item[1]/list-item-body[text()="Ordered Item 1"]][list-item[2]/list-item-body[text()="Ordered Item 2"]]'),
             # VARIABLE LIST --> list
             ('<article><variablelist><varlistentry><term>Term 1</term><listitem>Definition 1</listitem></varlistentry><varlistentry><term>Term 2</term><listitem>Definition 2</listitem></varlistentry></variablelist></article>',
-            # <page><body><div html:class="article"><list><list-item><list-item-label>Termm 1</list-item-label><list-item-body>Definition 1</list-item-body></list-item><list-item><list-item-label>Term 2</list-item-label><list-item-body>Definition 2</list-item-body></list-item></list></div></body></page>
-            '/page/body/div/list[list-item[1][list-item-label="Term 1"][list-item-body="Definition 1"]][list-item[2][list-item-label="Term 2"][list-item-body="Definition 2"]]'),
+                # <page><body><div html:class="article"><list><list-item><list-item-label>Termm 1</list-item-label><list-item-body>Definition 1</list-item-body></list-item><list-item><list-item-label>Term 2</list-item-label><list-item-body>Definition 2</list-item-body></list-item></list></div></body></page>
+                '/page/body/div/list[list-item[1][list-item-label="Term 1"][list-item-body="Definition 1"]][list-item[2][list-item-label="Term 2"][list-item-body="Definition 2"]]'),
             # PROCEDURE --> ordered list (with arabic numeration)
             ('<article><procedure><step>First Step</step><step>Second Step</step></procedure></article>',
-            # <page><body><div html:class="article"><list item-label-generate="ordered"><list-item><list-item-body>First Step</list-item-body></list-item><list-item><list-item-body>Second Step</list-item-body></list-item></list></div></body></page>
-             '/page/body/div/list[@item-label-generate="ordered"][list-item[1]/list-item-body[text()="First Step"]][list-item[2]/list-item-body[text()="Second Step"]]'),
+                # <page><body><div html:class="article"><list item-label-generate="ordered"><list-item><list-item-body>First Step</list-item-body></list-item><list-item><list-item-body>Second Step</list-item-body></list-item></list></div></body></page>
+                '/page/body/div/list[@item-label-generate="ordered"][list-item[1]/list-item-body[text()="First Step"]][list-item[2]/list-item-body[text()="Second Step"]]'),
             # PROCEDURE --> ordered list (with arabic numeration) (with stepalternative)
             ('<article><procedure><step>First Step</step><stepalternatives>Second Step</stepalternatives></procedure></article>',
-            # <page><body><div html:class="article"><list item-label-generate="ordered"><list-item><list-item-body>First Step</list-item-body></list-item><list-item><list-item-body>Second Step</list-item-body></list-item></list></div></body></page>
-             '/page/body/div/list[@item-label-generate="ordered"][list-item[1]/list-item-body[text()="First Step"]][list-item[2]/list-item-body[text()="Second Step"]]'),
+                # <page><body><div html:class="article"><list item-label-generate="ordered"><list-item><list-item-body>First Step</list-item-body></list-item><list-item><list-item-body>Second Step</list-item-body></list-item></list></div></body></page>
+                '/page/body/div/list[@item-label-generate="ordered"][list-item[1]/list-item-body[text()="First Step"]][list-item[2]/list-item-body[text()="Second Step"]]'),
             # PROCEDURE with SUBSTEPS
             ('<article><procedure><step>First Step</step><substeps><step>Second Step</step></substeps></procedure></article>',
-            # <page><body><div html:class="article"><list item-label-generate="ordered"><list-item><list-item-body>First Step</list-item-body></list-item><list-item><list-item-body><list item-label-generate="ordered">Second Step</list-item-body></list-item></list></list></div></body></page>
-             '/page/body/div/list[@item-label-generate="ordered"][list-item[1]/list-item-body[text()="First Step"]][list[@item-label-generate="ordered"]/list-item/list-item-body[text()="Second Step"]]'),
+                # <page><body><div html:class="article"><list item-label-generate="ordered"><list-item><list-item-body>First Step</list-item-body></list-item><list-item><list-item-body><list item-label-generate="ordered">Second Step</list-item-body></list-item></list></list></div></body></page>
+                '/page/body/div/list[@item-label-generate="ordered"][list-item[1]/list-item-body[text()="First Step"]][list[@item-label-generate="ordered"]/list-item/list-item-body[text()="Second Step"]]'),
             # GLOSS LIST --> Definition list
             ('<article><glosslist><glossentry><glossterm>Term 1</glossterm><glossdef><para>Definition 1</para></glossdef></glossentry><glossentry><glossterm>Term 2</glossterm><glossdef><para>Definition 2</para></glossdef></glossentry></glosslist></article>',
-            # <page><body><div html:class="article"><list><list-item><list-item-label>Termm 1</list-item-label><list-item-body>Definition 1</list-item-body></list-item><list-item><list-item-label>Term 2</list-item-label><list-item-body>Definition 2</list-item-body></list-item></list></div></body></page>
-            '/page/body/div/list[list-item[1][list-item-label="Term 1"][list-item-body[p="Definition 1"]]][list-item[2][list-item-label="Term 2"][list-item-body[p="Definition 2"]]]'),
+                # <page><body><div html:class="article"><list><list-item><list-item-label>Termm 1</list-item-label><list-item-body>Definition 1</list-item-body></list-item><list-item><list-item-label>Term 2</list-item-label><list-item-body>Definition 2</list-item-body></list-item></list></div></body></page>
+                '/page/body/div/list[list-item[1][list-item-label="Term 1"][list-item-body[p="Definition 1"]]][list-item[2][list-item-label="Term 2"][list-item-body[p="Definition 2"]]]'),
             # SEGMENTED LIST --> Definition List
             ('<article><segmentedlist><segtitle>Term 1</segtitle><segtitle>Term 2</segtitle><segtitle>Term 3</segtitle><seglistitem><seg>Def 1:1</seg><seg>Def 1:2</seg><seg>Def 1:3</seg></seglistitem><seglistitem><seg>Def 2:1</seg><seg>Def 2:2</seg><seg>Def 2:3</seg></seglistitem></segmentedlist></article>',
-              '/page/body/div/list[list-item[1][list-item-label="Term 1"][list-item-body="Def 1:1"]][list-item[2][list-item-label="Term 2"][list-item-body="Def 1:2"]][list-item[3][list-item-label="Term 3"][list-item-body="Def 1:3"]][list-item[4][list-item-label="Term 1"][list-item-body="Def 2:1"]][list-item[5][list-item-label="Term 2"][list-item-body="Def 2:2"]][list-item[6][list-item-label="Term 3"][list-item-body="Def 2:3"]]'),
+                '/page/body/div/list[list-item[1][list-item-label="Term 1"][list-item-body="Def 1:1"]][list-item[2][list-item-label="Term 2"][list-item-body="Def 1:2"]][list-item[3][list-item-label="Term 3"][list-item-body="Def 1:3"]][list-item[4][list-item-label="Term 1"][list-item-body="Def 2:1"]][list-item[5][list-item-label="Term 2"][list-item-body="Def 2:2"]][list-item[6][list-item-label="Term 3"][list-item-body="Def 2:3"]]'),
             # SIMPLE LIST --> unordered list
             ('<article><simplelist><member>Item 1</member><member>Item 2</member></simplelist></article>',
-            # <page><body><div html:class="article"><list item-label-generate="unordered"><list-item><list-item-body>Unordered Item 1</list-item-body></list-item><list-item><list-item-body>Unordered Item 2</list-item-body></list-item></list></div></body></page>
-             '/page/body/div/list[@item-label-generate="unordered"][list-item[1]/list-item-body[text()="Item 1"]][list-item[2]/list-item-body[text()="Item 2"]]'),
+                # <page><body><div html:class="article"><list item-label-generate="unordered"><list-item><list-item-body>Unordered Item 1</list-item-body></list-item><list-item><list-item-body>Unordered Item 2</list-item-body></list-item></list></div></body></page>
+                '/page/body/div/list[@item-label-generate="unordered"][list-item[1]/list-item-body[text()="Item 1"]][list-item[2]/list-item-body[text()="Item 2"]]'),
             # Q and A set with defaultlabel = number --> ordered list
             ("<article><qandaset defaultlabel='number'><qandaentry><question><para>Question 1</para></question><answer><para>Answer 1</para></answer></qandaentry><qandaentry><question><para>Question 2</para></question><answer><para>Answer 2</para></answer></qandaentry></qandaset></article> ",
-            # <page><body><div html:class="article"><list item-label-generate="ordered"><list-item><list-item-body><p>Question1</p><p>Answer 1</p></list-item-body></list-item><list-item><list-item-body><p>Question 2</p><p>Answer 2</p></list-item-body></list-item></div></body></page>
-             '/page/body/div/list[@item-label-generate="ordered"][list-item[1]/list-item-body[p[1][text()="Question 1"]][p[2][text()="Answer 1"]]][list-item[2]/list-item-body[p[1][text()="Question 2"]][p[2][text()="Answer 2"]]]'),
+                # <page><body><div html:class="article"><list item-label-generate="ordered"><list-item><list-item-body><p>Question1</p><p>Answer 1</p></list-item-body></list-item><list-item><list-item-body><p>Question 2</p><p>Answer 2</p></list-item-body></list-item></div></body></page>
+                '/page/body/div/list[@item-label-generate="ordered"][list-item[1]/list-item-body[p[1][text()="Question 1"]][p[2][text()="Answer 1"]]][list-item[2]/list-item-body[p[1][text()="Question 2"]][p[2][text()="Answer 2"]]]'),
             # Q and A set with defaultlabel = qanda --> definition list, with Q: and A: for the label
             ("<article><qandaset defaultlabel='qanda'><qandaentry><question><para>Question 1</para></question><answer><para>Answer 1</para></answer></qandaentry><qandaentry><question><para>Question 2</para></question><answer><para>Answer 2</para></answer></qandaentry></qandaset></article> ",
-            # <page><body><div html:class="article"><list><list-item><list-item-label>Q: </list-item-label><list-item-body>Question 1</list-item-body></list-item><list-item><list-item-label>A: </list-item-label><list-item-body>Answer 1</list-item-body></list-item><list-item><list-item-label>Q: </list-item-label><list-item-body>Question 2</list-item-body></list-item><list-item><list-item-label>A: </list-item-label><list-item-body>Answer 2</list-item-body></list-item>
-              '/page/body/div/list[list-item[1][list-item-label="Q:"][list-item-body="Question 1"]][list-item[2][list-item-label="A:"][list-item-body="Answer 1"]][list-item[3][list-item-label="Q:"][list-item-body="Question 2"]][list-item[4][list-item-label="A:"][list-item-body="Answer 2"]]'),
+                # <page><body><div html:class="article"><list><list-item><list-item-label>Q: </list-item-label><list-item-body>Question 1</list-item-body></list-item><list-item><list-item-label>A: </list-item-label><list-item-body>Answer 1</list-item-body></list-item><list-item><list-item-label>Q: </list-item-label><list-item-body>Question 2</list-item-body></list-item><list-item><list-item-label>A: </list-item-label><list-item-body>Answer 2</list-item-body></list-item>
+                '/page/body/div/list[list-item[1][list-item-label="Q:"][list-item-body="Question 1"]][list-item[2][list-item-label="A:"][list-item-body="Answer 1"]][list-item[3][list-item-label="Q:"][list-item-body="Question 2"]][list-item[4][list-item-label="A:"][list-item-body="Answer 2"]]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -194,22 +193,22 @@
     def test_table(self):
         data = [
             ('<article><table><thead><tr><td>Header</td></tr></thead><tfoot><tr><td>Footer</td></tr></tfoot><tbody><tr><td>Cell</td></tr></tbody></table></article>',
-            # <page><body><div html:class="article"><table><table-header><table-row><table-cell>Header</table-cell></table-row></table-header><table-footer><table-row><table-cell>Footer</table-cell></table-row></table-footer><table-body><table-row><table-cell>Cell</table-row></table-cell></table></div></body></page>
-             '/page/body/div/table[./table-header/table-row[table-cell="Header"]][./table-footer/table-row[table-cell="Footer"]][./table-body/table-row[table-cell="Cell"]]'),
+                # <page><body><div html:class="article"><table><table-header><table-row><table-cell>Header</table-cell></table-row></table-header><table-footer><table-row><table-cell>Footer</table-cell></table-row></table-footer><table-body><table-row><table-cell>Cell</table-row></table-cell></table></div></body></page>
+                '/page/body/div/table[./table-header/table-row[table-cell="Header"]][./table-footer/table-row[table-cell="Footer"]][./table-body/table-row[table-cell="Cell"]]'),
             ('<article><table><tbody><tr><td colspan="2">Cell</td></tr></tbody></table></article>',
-            # <page><body><div html:class="article"><table><table-body><table-row><table-cell number-columns-spanned="2">Cell</table-cell></table-row></table-body></table></div></body></page>
-             '/page/body/div/table/table-body/table-row/table-cell[text()="Cell"][@number-columns-spanned="2"]'),
+                # <page><body><div html:class="article"><table><table-body><table-row><table-cell number-columns-spanned="2">Cell</table-cell></table-row></table-body></table></div></body></page>
+                '/page/body/div/table/table-body/table-row/table-cell[text()="Cell"][@number-columns-spanned="2"]'),
             ('<article><table><tbody><tr><td rowspan="2">Cell</td></tr></tbody></table></article>',
-            # <page><body><div html:class="article"><table><table-body><table-row><table-cell number-rows-spanned="2">Cell</table-cell></table-row></table-body></table></div></body></page>
-             '/page/body/div/table/table-body/table-row/table-cell[text()="Cell"][@number-rows-spanned="2"]'),
+                # <page><body><div html:class="article"><table><table-body><table-row><table-cell number-rows-spanned="2">Cell</table-cell></table-row></table-body></table></div></body></page>
+                '/page/body/div/table/table-body/table-row/table-cell[text()="Cell"][@number-rows-spanned="2"]'),
             # Simple db.cals.table
             ('<article><table xml:id="ex.calstable"><tgroup cols="2"><thead><row><entry>a1</entry><entry>a2</entry></row></thead><tfoot><row><entry>f1</entry><entry>f2</entry></row></tfoot><tbody><row><entry>b1</entry><entry>b2</entry></row></tbody></tgroup></table></article>',
-            # <page><body><div html:class="article"><table><table-header><table-row><table-cell>a1</table-cell><table-cell>a2</table-cell></table-row></table-header><table-footer><table-row><table-cell>f1</table-cell><table-cell>f2</table-cell></table-row></table-footer><table-body><table-row><table-cell>b1</table-row><table-cell>b2</table-row></table-cell></table></div></body></page>
-             '/page/body/div/table[./table-header/table-row[table-cell="a1"][table-cell="a2"]][./table-footer/table-row[table-cell="f1"][table-cell="f2"]][./table-body/table-row[table-cell="b1"][table-cell="b2"]]'),
+                # <page><body><div html:class="article"><table><table-header><table-row><table-cell>a1</table-cell><table-cell>a2</table-cell></table-row></table-header><table-footer><table-row><table-cell>f1</table-cell><table-cell>f2</table-cell></table-row></table-footer><table-body><table-row><table-cell>b1</table-row><table-cell>b2</table-row></table-cell></table></div></body></page>
+                '/page/body/div/table[./table-header/table-row[table-cell="a1"][table-cell="a2"]][./table-footer/table-row[table-cell="f1"][table-cell="f2"]][./table-body/table-row[table-cell="b1"][table-cell="b2"]]'),
             # db.cals.table with entry table.
             ('<article><table xml:id="ex.calstable"><tgroup cols="1"><thead><row><entry>a1</entry></row></thead><tfoot><row><entry>f1</entry></row></tfoot><tbody><row><entrytbl cols="1"><tbody><row><entry>s1</entry></row></tbody></entrytbl></row></tbody></tgroup></table></article>',
-            # <page><body><div html:class="article"><table><table-header><table-row><table-cell>a1</table-cell></table-row></table-header><table-footer><table-row><table-cell>f1</table-cell></table-row></table-footer><table-body><table-row><table-cell><table><table-body><table-row><table-cell>s1</table-cell></table-row></table-body></table></table-row></table-cell></table></div></body></page>
-             '/page/body/div/table[./table-header/table-row[table-cell="a1"]][./table-footer/table-row[table-cell="f1"]][./table-body/table-row[table-cell/table/table-body/table-row[table-cell="s1"]]]'),
+                # <page><body><div html:class="article"><table><table-header><table-row><table-cell>a1</table-cell></table-row></table-header><table-footer><table-row><table-cell>f1</table-cell></table-row></table-footer><table-body><table-row><table-cell><table><table-body><table-row><table-cell>s1</table-cell></table-row></table-body></table></table-row></table-cell></table></div></body></page>
+                '/page/body/div/table[./table-header/table-row[table-cell="a1"]][./table-footer/table-row[table-cell="f1"]][./table-body/table-row[table-cell/table/table-body/table-row[table-cell="s1"]]]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -217,39 +216,39 @@
     def test_misc(self):
         data = [
             ('<article><para>Text Para<footnote><para>Text Footnote</para></footnote></para></article>',
-            # <page><body><div html:class="article"><p>Text Para<note note-class="footnote"><note-body><p>Text Footnote</p></note-body></note></p></div></body></page>
-             '/page/body/div/p[text()="Text Para"]/note[@note-class="footnote"]/note-body/p[text()="Text Footnote"]'),
+                # <page><body><div html:class="article"><p>Text Para<note note-class="footnote"><note-body><p>Text Footnote</p></note-body></note></p></div></body></page>
+                '/page/body/div/p[text()="Text Para"]/note[@note-class="footnote"]/note-body/p[text()="Text Footnote"]'),
             ('<article><para><quote>text</quote></para></article>',
-            # <page><body><div html:class="article"><p><quote>text</quote></para></article>
-            '/page/body/div/p[quote="text"]'),
+                # <page><body><div html:class="article"><p><quote>text</quote></para></article>
+                '/page/body/div/p[quote="text"]'),
             # Test span for inline element
             ('<article><para><abbrev>ABBREV</abbrev></para></article>',
-            # <page><body><div html:class="article"><p><span class="db-abbrev">ABBREV</span></p></div></body></page>
-             '/page/body/div/p/span[@html:class="db-abbrev"][text()="ABBREV"]'),
+                # <page><body><div html:class="article"><p><span class="db-abbrev">ABBREV</span></p></div></body></page>
+                '/page/body/div/p/span[@html:class="db-abbrev"][text()="ABBREV"]'),
             # Test div for block element
             ('<article><acknowledgements><para>Text</para></acknowledgements></article>',
-            # <page><body><div html:class="article"><div html:class="db-acknowledgements"><p>Text</p></div></div></body></page>
-            '/page/body/div/div[@html:class="db-acknowledgements"][p="Text"]'),
+                # <page><body><div html:class="article"><div html:class="db-acknowledgements"><p>Text</p></div></div></body></page>
+                '/page/body/div/div[@html:class="db-acknowledgements"][p="Text"]'),
             # Test for <informalequation>
             ('<article><informalequation><para>E = mc^2</para></informalequation></article>',
-            # <page><body><div html:class="article"><div html:class="db-equation"><p>E = mc^2</p></div></div></body></page>
-             '/page/body/div/div[@html:class="db-equation"][p="E = mc^2"]'),
+                # <page><body><div html:class="article"><div html:class="db-equation"><p>E = mc^2</p></div></div></body></page>
+                '/page/body/div/div[@html:class="db-equation"][p="E = mc^2"]'),
             # Test for <informalexample>
             ('<article><informalexample><para>example</para></informalexample></article>',
-            # <page><body><div html:class="article"><div html:class="db-example"><p>example</p></div></div></body></page>
-             '/page/body/div/div[@html:class="db-example"][p="example"]'),
+                # <page><body><div html:class="article"><div html:class="db-example"><p>example</p></div></div></body></page>
+                '/page/body/div/div[@html:class="db-example"][p="example"]'),
             # Test for <sbr />
             ('<article><cmdsynopsis><para>Line 1<sbr />Line 2</para></cmdsynopsis></article>',
-            # <page><body><div html:class="article"><div html:class="db-cmdsynopsis"><p>Line 1<line-break />Line 2</p></div></div></body></page>
-            '/page/body/div/div[@html:class="db-cmdsynopsis"]/p/line-break'),
+                # <page><body><div html:class="article"><div html:class="db-cmdsynopsis"><p>Line 1<line-break />Line 2</p></div></div></body></page>
+                '/page/body/div/div[@html:class="db-cmdsynopsis"]/p/line-break'),
             # Test for <tag> element with class and namespace attribute
             ('<article><para><tag class="attribute" namespace="namespace">TAG</tag></para></article>',
-            # <page><body><div html:class="article"><p><span class="db-tag-attribute">{namespace}TAG</span></p></div></article>
-            '/page/body/div/p/span[@html:class="db-tag-attribute"][text()="{namespace}TAG"]'),
+                # <page><body><div html:class="article"><p><span class="db-tag-attribute">{namespace}TAG</span></p></div></article>
+                '/page/body/div/p/span[@html:class="db-tag-attribute"][text()="{namespace}TAG"]'),
             # Test for <tag> element without class and namespace attribute
             ('<article><para><tag>TAG</tag></para></article>',
-            # <page><body><div html:class="article"><p><span class="db-tag">TAG</span></p></div></article>
-            '/page/body/div/p/span[@html:class="db-tag"][text()="TAG"]'),
+                # <page><body><div html:class="article"><p><span class="db-tag">TAG</span></p></div></article>
+                '/page/body/div/p/span[@html:class="db-tag"][text()="TAG"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -258,24 +257,24 @@
         data = [
             # Normal link, with conversion of all the xlink attributes
             ('<article><para><link xlink:href="uri:test" xlink:title="title">link</link></para></article>',
-            # <page><body><div html:class="article"><p><a xlink:href="uri:test" xlink:title="title">link</a></p></div></body></page>
-             '/page/body/div/p/a[@xlink:href="uri:test"][@xlink:title="title"][text()="link"]'),
+                # <page><body><div html:class="article"><p><a xlink:href="uri:test" xlink:title="title">link</a></p></div></body></page>
+                '/page/body/div/p/a[@xlink:href="uri:test"][@xlink:title="title"][text()="link"]'),
             # Old link from DocBook v.4.X for backward compatibility
             ('<article><para><ulink url="url:test">link</ulink></para></article>',
-            # <page><body><div html:class="article"><p><a xlink:href="url:test">link</a></p></div></body></page>
-             '/page/body/div/p/a[@xlink:href="url:test"][text()="link"]'),
+                # <page><body><div html:class="article"><p><a xlink:href="url:test">link</a></p></div></body></page>
+                '/page/body/div/p/a[@xlink:href="url:test"][text()="link"]'),
             # Normal link, with linkend attribute
             ('<article><para><link linkend="anchor">link</link></para></article>',
-            # <page><body><div html:class="article"><p><a xlink:href="#anchor">link</a></p></div></body></page>
-             '/page/body/div/p/a[@xlink:href="#anchor"][text()="link"]'),
+                # <page><body><div html:class="article"><p><a xlink:href="#anchor">link</a></p></div></body></page>
+                '/page/body/div/p/a[@xlink:href="#anchor"][text()="link"]'),
             # OLINK
             ('<article><para><olink targetdoc="uri" targetptr="anchor">link</olink></para></article>',
-            # <page><body><div html:class="article"><para><a xlink:href="uri#anchor">link</a></para></div></body></page>
-             '/page/body/div/p/a[@xlink:href="uri#anchor"][text()="link"]'),
+                # <page><body><div html:class="article"><para><a xlink:href="uri#anchor">link</a></para></div></body></page>
+                '/page/body/div/p/a[@xlink:href="uri#anchor"][text()="link"]'),
             # Link w/ javascript: scheme
             ('<article><para><ulink url="javascript:alert(\'xss\')">link</ulink></para></article>',
-            # <page><body><div html:class="article"><p><a xlink:href="url:test">link</a></p></div></body></page>
-             '/page/body/div/p/a[@xlink:href=""][text()="link"]'),
+                # <page><body><div html:class="article"><p><a xlink:href="url:test">link</a></p></div></body></page>
+                '/page/body/div/p/a[@xlink:href=""][text()="link"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -283,39 +282,39 @@
     def test_code(self):
         data = [
             ('<article><screen>Text</screen></article>',
-            # <page><body><div html:class="article"><blockcode>Text</blockcode></div></body></page>
-             '/page/body/div[blockcode="Text"]'),
+                # <page><body><div html:class="article"><blockcode>Text</blockcode></div></body></page>
+                '/page/body/div[blockcode="Text"]'),
             # Test for <screen> with CDATA
             ('<article><screen><![CDATA[Text]]></screen></article>',
-            # <page><body><div html:class="article"><blockcode>Text</blockcode></div></body></page>
-             '/page/body/div[blockcode="Text"]'),
+                # <page><body><div html:class="article"><blockcode>Text</blockcode></div></body></page>
+                '/page/body/div[blockcode="Text"]'),
             # PROGRAMLISTING --> BLOCKCODE
             ('<article><programlisting>Text</programlisting></article>',
-            # <page><body><div html:class="article"><blockcode>Text</blockcode></div></body></page>
-             '/page/body/div[blockcode="Text"]'),
+                # <page><body><div html:class="article"><blockcode>Text</blockcode></div></body></page>
+                '/page/body/div[blockcode="Text"]'),
             # LITERAL --> CODE
             ('<article><para>text<literal>literal</literal></para></article>',
-            # <page><body><div html:class="article"><p>text<code>literal</code></p></div></body></page>
-             '/page/body/div/p[text()="text"][code="literal"]'),
+                # <page><body><div html:class="article"><p>text<code>literal</code></p></div></body></page>
+                '/page/body/div/p[text()="text"][code="literal"]'),
             ('<article><blockquote><attribution>author</attribution>text</blockquote></article>',
-            # <page><body><div html:class="article"><blockquote source="author">text</blockquote></div></body></page>
-            '/page/body/div/blockquote[@source="author"][text()="text"]'),
+                # <page><body><div html:class="article"><blockquote source="author">text</blockquote></div></body></page>
+                '/page/body/div/blockquote[@source="author"][text()="text"]'),
             # CODE --> CODE
             ('<article><para><code>Text</code></para></article>',
-            # <page><body><div html:class="article"><p><code>Text</code></p></article>
-            '/page/body/div/p[code="Text"]'),
+                # <page><body><div html:class="article"><p><code>Text</code></p></article>
+                '/page/body/div/p[code="Text"]'),
             # COMPUTEROUTPUT --> CODE
             ('<article><para><computeroutput>Text</computeroutput></para></article>',
-            # <page><body><div html:class="article"><p><code>Text</code></p></article>
-            '/page/body/div/p[code="Text"]'),
+                # <page><body><div html:class="article"><p><code>Text</code></p></article>
+                '/page/body/div/p[code="Text"]'),
             # MARKUP --> CODE
             ('<article><para><markup>Text</markup></para></article>',
-            # <page><body><div html:class="article"><p><code>Text</code></p></article>
-            '/page/body/div/p[code="Text"]'),
+                # <page><body><div html:class="article"><p><code>Text</code></p></article>
+                '/page/body/div/p[code="Text"]'),
             # LITERALLAYOUT --> BLOCKCODE
             ('<article><literallayout>Text</literallayout></article>',
-             # <page><body><div html:class="article"><blockcode html:class="db-literallayout">Text</blockcode></div></body></page>
-             '/page/body/div/blockcode[text()="Text"][@html:class="db-literallayout"]'),
+                # <page><body><div html:class="article"><blockcode html:class="db-literallayout">Text</blockcode></div></body></page>
+                '/page/body/div/blockcode[text()="Text"][@html:class="db-literallayout"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -324,20 +323,20 @@
         data = [
             # Test for image object
             ('<article><para><inlinemediaobject><imageobject><imagedata fileref="test.png"/></imageobject></inlinemediaobject></para></article>',
-            # <page><body><div html:class="article"><p><object xlink:href="test.png" type='image/' /></p></div></body></page>
-            '/page/body/div/p/span[@html:class="db-inlinemediaobject"]/object[@xlink:href="test.png"][@type="image/"]'),
+                # <page><body><div html:class="article"><p><object xlink:href="test.png" type='image/' /></p></div></body></page>
+                '/page/body/div/p/span[@html:class="db-inlinemediaobject"]/object[@xlink:href="test.png"][@type="image/"]'),
             # Test for audio object
             ('<article><para><inlinemediaobject><audioobject><audiodata fileref="test.wav"/></audioobject></inlinemediaobject></para></article>',
-            # <page><body><div html:class="article"><p><object xlink:href="test.wav" type='audio/' /></p></div></body></page>
-            '/page/body/div/p/span[@html:class="db-inlinemediaobject"]/object[@xlink:href="test.wav"][@type="audio/"]'),
+                # <page><body><div html:class="article"><p><object xlink:href="test.wav" type='audio/' /></p></div></body></page>
+                '/page/body/div/p/span[@html:class="db-inlinemediaobject"]/object[@xlink:href="test.wav"][@type="audio/"]'),
             # Test for video object
             ('<article><para><mediaobject><videoobject><videodata fileref="test.avi"/></videoobject></mediaobject></para></article>',
-            # <page><body><div html:class="article"><p><object xlink:href="test.avi" type='video/' /></p></div></body></page>
-             '/page/body/div/p/div[@html:class="db-mediaobject"]/object[@xlink:href="test.avi"][@type="video/"]'),
+                # <page><body><div html:class="article"><p><object xlink:href="test.avi" type='video/' /></p></div></body></page>
+                '/page/body/div/p/div[@html:class="db-mediaobject"]/object[@xlink:href="test.avi"][@type="video/"]'),
             # Test for image object with different imagedata
             ('<article><mediaobject><imageobject><imagedata fileref="figures/eiffeltower.eps" format="EPS"/></imageobject><imageobject><imagedata fileref="figures/eiffeltower.png" format="PNG"/></imageobject><textobject><phrase>The Eiffel Tower</phrase> </textobject><caption><para>Designed by Gustave Eiffel in 1889, The Eiffel Tower is one of the most widely recognized buildings in the world.</para>  </caption></mediaobject></article>',
-            # <page><body><div html:class="article"><div html:class="db-mediaobject"><object xlink:href="figures/eiffeltowe.png" /></div></div></body></page>
-            '/page/body/div/div[@html:class="db-mediaobject"]/object[@xlink:href="figures/eiffeltower.png"][@type="image/png"]'),
+                # <page><body><div html:class="article"><div html:class="db-mediaobject"><object xlink:href="figures/eiffeltowe.png" /></div></div></body></page>
+                '/page/body/div/div[@html:class="db-mediaobject"]/object[@xlink:href="figures/eiffeltower.png"][@type="image/png"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -346,24 +345,24 @@
         data = [
             # EMPHASIS --> EMPHASIS
             ('<article><para>text<emphasis>emphasis</emphasis></para></article>',
-            # <page><body><div html:class="article"><p>text<emphasis>emphasis</emphasis></p></div></body></page>
-             '/page/body/div/p[text()="text"][emphasis="emphasis"]'),
+                # <page><body><div html:class="article"><p>text<emphasis>emphasis</emphasis></p></div></body></page>
+                '/page/body/div/p[text()="text"][emphasis="emphasis"]'),
             # EMPHASIS role='strong' --> STRONG
             ('<article><para>text<emphasis role="strong">strong</emphasis></para></article>',
-            # <page><body><div html:class="article"><p>text<strong>strong</strong></p></div></body></page>
-             '/page/body/div/p[text()="text"][strong="strong"]'),
+                # <page><body><div html:class="article"><p>text<strong>strong</strong></p></div></body></page>
+                '/page/body/div/p[text()="text"][strong="strong"]'),
             # SUBSCRIPT --> SPAN baseline-shift = 'sub'
             ('<article><para><subscript>sub</subscript>script</para></article>',
-            # <page><body><div html:class="article"><p>script<span baseline-shift="sub">sub</span></p></div></body></page>
-             '/page/body/div/p[text()="script"]/span[@baseline-shift="sub"][text()="sub"]'),
+                # <page><body><div html:class="article"><p>script<span baseline-shift="sub">sub</span></p></div></body></page>
+                '/page/body/div/p[text()="script"]/span[@baseline-shift="sub"][text()="sub"]'),
             # SUPERSCRIPT --> SPAN baseline-shift = 'super'
             ('<article><para><superscript>super</superscript>script</para></article>',
-            # <page><body><div html:class="article"><p>script<span baseline-shift="super">super</span></p></div></body></page>
-             '/page/body/div/p[text()="script"]/span[@baseline-shift="super"][text()="super"]'),
+                # <page><body><div html:class="article"><p>script<span baseline-shift="super">super</span></p></div></body></page>
+                '/page/body/div/p[text()="script"]/span[@baseline-shift="super"][text()="super"]'),
             # PHRASE --> SPAN
             ('<article><para><phrase>text</phrase></para></article>',
-            # <page><body><div html:class="article"><p><span>text</span></p></div></body></page>
-             '/page/body/div/p[span="text"]'),
+                # <page><body><div html:class="article"><p><span>text</span></p></div></body></page>
+                '/page/body/div/p[span="text"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -372,24 +371,24 @@
         data = [
             # Test for caution admonition
             ('<article><caution><para>text</para></caution></article>',
-            # <page><body><div html:class="article"><admonition type='caution'><p>text<p></admonition></div></body></page>
-            '/page/body/div/admonition[@type="caution"][p="text"]'),
+                # <page><body><div html:class="article"><admonition type='caution'><p>text<p></admonition></div></body></page>
+                '/page/body/div/admonition[@type="caution"][p="text"]'),
             # Test for important admonition
             ('<article><important><para>text</para></important></article>',
-            # <page><body><div html:class="article"><admonition type='important'><p>text<p></admonition></div></body></page>
-            '/page/body/div/admonition[@type="important"][p="text"]'),
+                # <page><body><div html:class="article"><admonition type='important'><p>text<p></admonition></div></body></page>
+                '/page/body/div/admonition[@type="important"][p="text"]'),
             # Test for note admonition
             ('<article><note><para>text</para></note></article>',
-            # <page><body><div html:class="article"><admonition type='note'><p>text<p></admonition></div></body></page>
-            '/page/body/div/admonition[@type="note"][p="text"]'),
+                # <page><body><div html:class="article"><admonition type='note'><p>text<p></admonition></div></body></page>
+                '/page/body/div/admonition[@type="note"][p="text"]'),
             # Test for tip admonition
             ('<article><tip><para>text</para></tip></article>',
-            # <page><body><div html:class="article"><admonition type='tip'><p>text<p></admonition></div></body></page>
-            '/page/body/div/admonition[@type="tip"][p="text"]'),
+                # <page><body><div html:class="article"><admonition type='tip'><p>text<p></admonition></div></body></page>
+                '/page/body/div/admonition[@type="tip"][p="text"]'),
             # Test for warning admonition
             ('<article><warning><para>text</para></warning></article>',
-            # <page><body><div html:class="article"><admonition type='warning'><p>text<p></admonition></div></body></page>
-            '/page/body/div/admonition[@type="warning"][p="text"]'),
+                # <page><body><div html:class="article"><admonition type='warning'><p>text<p></admonition></div></body></page>
+                '/page/body/div/admonition[@type="warning"][p="text"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -397,14 +396,14 @@
     def test_trademark(self):
         data = [
             ('<article><para><trademark class="copyright">MoinMoin</trademark></para></article>',
-             # <page><body><div html:class="article"><p><span class="db-trademark">MoinMoin&copy;</span></p></div></body></page>
-             '/page/body/div/p/span[@html:class="db-trademark"][text()="MoinMoin&copy;"]'),
+                # <page><body><div html:class="article"><p><span class="db-trademark">MoinMoin&copy;</span></p></div></body></page>
+                '/page/body/div/p/span[@html:class="db-trademark"][text()="MoinMoin&copy;"]'),
             ('<article><para><trademark class="service">MoinMoin</trademark></para></article>',
-             # <page><body><div html:class="article"><p><span class="db-trademark">MoinMoin<span baseline-shift="super">SM</span></span></p></div></body></page>
-             '/page/body/div/p/span[@html:class="db-trademark"][text()="MoinMoin"]/span[@baseline-shift="super"][text()="SM"]'),
+                # <page><body><div html:class="article"><p><span class="db-trademark">MoinMoin<span baseline-shift="super">SM</span></span></p></div></body></page>
+                '/page/body/div/p/span[@html:class="db-trademark"][text()="MoinMoin"]/span[@baseline-shift="super"][text()="SM"]'),
             ('<article><para><trademark>MoinMoin</trademark></para></article>',
-             # <page><body><div html:class="article"><p><span class="db-trademark">MoinMoin</span></p></div></body></page>
-             '/page/body/div/p/span[@html:class="db-trademark"][text()="MoinMoin"]'),
+                # <page><body><div html:class="article"><p><span class="db-trademark">MoinMoin</span></p></div></body></page>
+                '/page/body/div/p/span[@html:class="db-trademark"][text()="MoinMoin"]'),
         ]
         for i in data:
             yield(self.do, ) + i
@@ -413,10 +412,10 @@
         data = [
             # Error: Xml not correctly formatted
             ('<article><para>Text</para>',
-             '/page/body/part/error'),
+                '/page/body/part/error'),
             # Error: Root Element is not correct
             ('<link xlink:href="uri">link</link>',
-             '/page/body/part/error'),
+                '/page/body/part/error'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -425,7 +424,7 @@
         data = [
             # Error: Missing namespace
             ('<article><para>Text</para></article>',
-             '/page/body/part/error'),
+                '/page/body/part/error'),
         ]
         for i in data:
             yield (self.do_nonamespace, ) + i
--- a/MoinMoin/converter/_tests/test_docbook_out.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test_docbook_out.py	Wed Mar 20 01:25:01 2013 +0100
@@ -10,10 +10,8 @@
 import StringIO
 
 import pytest
-try:
-    from lxml import etree
-except:
-    pytest.skip("lxml module required to run test for docbook_out converter.")
+
+etree = pytest.importorskip('lxml.etree')
 
 from emeraldtree.tree import *
 
@@ -22,6 +20,7 @@
 
 from MoinMoin.converter.docbook_out import *
 
+
 class Base(object):
     input_namespaces = ns_all = 'xmlns="{0}" xmlns:page="{1}" xmlns:html="{2}" xmlns:xlink="{3}" xmlns:xml="{4}"'.format(moin_page.namespace, moin_page.namespace, html.namespace, xlink.namespace, xml.namespace)
     output_namespaces = {
@@ -55,32 +54,33 @@
         tree = etree.parse(StringIO.StringIO(string_to_parse))
         assert (tree.xpath(xpath, namespaces=self.namespaces_xpath))
 
+
 class TestConverter(Base):
     def setup_class(self):
         self.conv = Converter()
 
     def test_base(self):
         data = [
-           # NB: All the output contain the <info> section, but for a better
-           #     readability, I did not wrote it in the snippet except this one
-           ('<page><body><p>Test</p></body></page>',
-            # <article><info><title>Untitled</title></info><simpara>Test</simpara></article>
-              '/article[./info[title="Untitled"]][simpara="Test"]'),
-           # ADMONITION type --> type
-           ('<page><body><admonition page:type="warning"><p>Text</p></admonition></body></page>',
-            # <article><warning><simpara>Text</simpara></warning></article>
-            '/article/warning[simpara="Text"]'),
-           # Unknown admonition
-           ('<page><body><admonition page:type="none"><p>Text</p></admonition></body></page>',
-            '/article[simpara="Text"]'),
-           # XML attributes: we support all the xml standard attributes
-           ('<page><body><p xml:base="http://base.tld" xml:id="id" xml:lang="en">Text</p></body></page>',
-            # <article><simpara xml:base="http://base.tld" xml:id="id" xml:lang="en">Text</p></body></page>
-            '/article/simpara[@xml:base="http://base.tld"][@xml:id="id"][@xml:lang="en"][text()="Text"]'),
-           # Para with title
-           ('<page><body><p html:title="Title">Text</p></body></page>',
-            # <article><simpara xml:base="http://base.tld" xml:id="id" xml:lang="en">Text</p></body></page>
-            '/article/para[text()="Text"][title="Title"]'),
+            # NB: All the output contain the <info> section, but for a better
+            #     readability, I did not wrote it in the snippet except this one
+            ('<page><body><p>Test</p></body></page>',
+                # <article><info><title>Untitled</title></info><simpara>Test</simpara></article>
+                '/article[./info[title="Untitled"]][simpara="Test"]'),
+            # ADMONITION type --> type
+            ('<page><body><admonition page:type="warning"><p>Text</p></admonition></body></page>',
+                # <article><warning><simpara>Text</simpara></warning></article>
+                '/article/warning[simpara="Text"]'),
+            # Unknown admonition
+            ('<page><body><admonition page:type="none"><p>Text</p></admonition></body></page>',
+                '/article[simpara="Text"]'),
+            # XML attributes: we support all the xml standard attributes
+            ('<page><body><p xml:base="http://base.tld" xml:id="id" xml:lang="en">Text</p></body></page>',
+                # <article><simpara xml:base="http://base.tld" xml:id="id" xml:lang="en">Text</p></body></page>
+                '/article/simpara[@xml:base="http://base.tld"][@xml:id="id"][@xml:lang="en"][text()="Text"]'),
+            # Para with title
+            ('<page><body><p html:title="Title">Text</p></body></page>',
+                # <article><simpara xml:base="http://base.tld" xml:id="id" xml:lang="en">Text</p></body></page>
+                '/article/para[text()="Text"][title="Title"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -88,7 +88,7 @@
     def test_title(self):
         data = [
             ('<page><body><h page:outline-level="1">Heading 1</h><p>First</p><h page:outline-level="2">Heading 2</h><p>Second</p></body></page>',
-             '/article/sect1[title="Heading 1"][simpara="First"]/sect2[title="Heading 2"][simpara="Second"]'),
+                '/article/sect1[title="Heading 1"][simpara="First"]/sect2[title="Heading 2"][simpara="Second"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -97,32 +97,32 @@
         data = [
             # Simple unordered list
             ('<page><body><list page:item-label-generate="unordered"><list-item><list-item-body>Item 1</list-item-body></list-item><list-item><list-item-body>Item 2</list-item-body></list-item></list></body></page>',
-             # <article><itemizedlist><listitem><simpara>Item 1</simpara></listitem><listitem><simpara>Item 2</simpara></listitem></itemizedlist></article>
-             '/article/itemizedlist[listitem[1]/simpara[text()="Item 1"]][listitem[2]/simpara[text()="Item 2"]]'),
+                # <article><itemizedlist><listitem><simpara>Item 1</simpara></listitem><listitem><simpara>Item 2</simpara></listitem></itemizedlist></article>
+                '/article/itemizedlist[listitem[1]/simpara[text()="Item 1"]][listitem[2]/simpara[text()="Item 2"]]'),
             # Simple ordered list (use default arabic numeration)
             ('<page><body><list page:item-label-generate="ordered"><list-item><list-item-body>Item 1</list-item-body></list-item><list-item><list-item-body>Item 2</list-item-body></list-item></list></body></page>',
-             # <article><orderedlist numeration="arabic"><listitem><simpara>Item 1</simpara></listitem><listitem><simpara>Item 2</simpara></listitem></orderedlist></article>
-             '/article/orderedlist[@numeration="arabic"][listitem[1]/simpara[text()="Item 1"]][listitem[2]/simpara[text()="Item 2"]]'),
+                # <article><orderedlist numeration="arabic"><listitem><simpara>Item 1</simpara></listitem><listitem><simpara>Item 2</simpara></listitem></orderedlist></article>
+                '/article/orderedlist[@numeration="arabic"][listitem[1]/simpara[text()="Item 1"]][listitem[2]/simpara[text()="Item 2"]]'),
             # Simple ordered list with upper-alpha numeration
             ('<page><body><list page:item-label-generate="ordered" page:list-style-type="upper-alpha"><list-item><list-item-body>Item 1</list-item-body></list-item><list-item><list-item-body>Item 2</list-item-body></list-item></list></body></page>',
-             # <article><orderedlist numeration="upperalpha"><listitem><simpara>Item 1</simpara></listitem><listitem><simpara>Item 2</simpara></listitem></orderedlist></article>
-             '/article/orderedlist[@numeration="upperalpha"][listitem[1]/simpara[text()="Item 1"]][listitem[2]/simpara[text()="Item 2"]]'),
+                # <article><orderedlist numeration="upperalpha"><listitem><simpara>Item 1</simpara></listitem><listitem><simpara>Item 2</simpara></listitem></orderedlist></article>
+                '/article/orderedlist[@numeration="upperalpha"][listitem[1]/simpara[text()="Item 1"]][listitem[2]/simpara[text()="Item 2"]]'),
             # Simple ordered list with lower-alpha numeration
             ('<page><body><list page:item-label-generate="ordered" page:list-style-type="lower-alpha"><list-item><list-item-body>Item 1</list-item-body></list-item><list-item><list-item-body>Item 2</list-item-body></list-item></list></body></page>',
-             # <article><orderedlist numeration="loweralpha"><listitem><simpara>Item 1</simpara></listitem><listitem><simpara>Item 2</simpara></listitem></orderedlist></article>
-             '/article/orderedlist[@numeration="loweralpha"][listitem[1]/simpara[text()="Item 1"]][listitem[2]/simpara[text()="Item 2"]]'),
+                # <article><orderedlist numeration="loweralpha"><listitem><simpara>Item 1</simpara></listitem><listitem><simpara>Item 2</simpara></listitem></orderedlist></article>
+                '/article/orderedlist[@numeration="loweralpha"][listitem[1]/simpara[text()="Item 1"]][listitem[2]/simpara[text()="Item 2"]]'),
             # Simple ordered list with upper-roman numeration
             ('<page><body><list page:item-label-generate="ordered" page:list-style-type="upper-roman"><list-item><list-item-body>Item 1</list-item-body></list-item><list-item><list-item-body>Item 2</list-item-body></list-item></list></body></page>',
-             # <article><orderedlist numeration="upperroman"><listitem><simpara>Item 1</simpara></listitem><listitem><simpara>Item 2</simpara></listitem></orderedlist></article>
-             '/article/orderedlist[@numeration="upperroman"][listitem[1]/simpara[text()="Item 1"]][listitem[2]/simpara[text()="Item 2"]]'),
+                # <article><orderedlist numeration="upperroman"><listitem><simpara>Item 1</simpara></listitem><listitem><simpara>Item 2</simpara></listitem></orderedlist></article>
+                '/article/orderedlist[@numeration="upperroman"][listitem[1]/simpara[text()="Item 1"]][listitem[2]/simpara[text()="Item 2"]]'),
             # Simple ordered list with lower-roman numeration
             ('<page><body><list page:item-label-generate="ordered" page:list-style-type="lower-roman"><list-item><list-item-body>Item 1</list-item-body></list-item><list-item><list-item-body>Item 2</list-item-body></list-item></list></body></page>',
-             # <article><orderedlist numeration="lowerroman"><listitem><simpara>Item 1</simpara></listitem><listitem><simpara>Item 2</simpara></listitem></orderedlist></article>
-             '/article/orderedlist[@numeration="lowerroman"][listitem[1]/simpara[text()="Item 1"]][listitem[2]/simpara[text()="Item 2"]]'),
+                # <article><orderedlist numeration="lowerroman"><listitem><simpara>Item 1</simpara></listitem><listitem><simpara>Item 2</simpara></listitem></orderedlist></article>
+                '/article/orderedlist[@numeration="lowerroman"][listitem[1]/simpara[text()="Item 1"]][listitem[2]/simpara[text()="Item 2"]]'),
             # Simple definition list
             ('<page><body><list><list-item><list-item-label>First Term</list-item-label><list-item-body>First Definition</list-item-body></list-item><list-item><list-item-label>Second Term</list-item-label><list-item-body>Second Definition</list-item-body></list-item></list></body></page>',
-             # <article><variablelist><varlistentry><term>First Term</term><listitem><simpara>First Definition</simpara></listitem></varlistentry><varlistentry><term>Second term</term><listitem><simpara>Second Definition</simpara></listitem></varlistentry></variablelist></article>
-             '/article/variablelist[varlistentry[1][./term[text()="First Term"]][./listitem/simpara[text()="First Definition"]]][varlistentry[2][./term[text()="Second Term"]][./listitem/simpara[text()="Second Definition"]]]')
+                # <article><variablelist><varlistentry><term>First Term</term><listitem><simpara>First Definition</simpara></listitem></varlistentry><varlistentry><term>Second term</term><listitem><simpara>Second Definition</simpara></listitem></varlistentry></variablelist></article>
+                '/article/variablelist[varlistentry[1][./term[text()="First Term"]][./listitem/simpara[text()="First Definition"]]][varlistentry[2][./term[text()="Second Term"]][./listitem/simpara[text()="Second Definition"]]]')
         ]
 
         for i in data:
@@ -133,16 +133,16 @@
             # All the table output caption, just wrote a test and snippet
             # for the two first tests.
             ('<page><body><table><table-header><table-row><table-cell>Header</table-cell></table-row></table-header><table-footer><table-row><table-cell>Footer</table-cell></table-row></table-footer><table-body><table-row><table-cell>Cell</table-cell></table-row></table-body></table></body></page>',
-            # <article><table><caption>Table 0</caption><thead><tr><td>Header</td></tr></thead><tfoot><tr><td>Footer</td></tr></tfoot><tbody><tr><td>Cell</td></tr></tbody></table>
+                # <article><table><caption>Table 0</caption><thead><tr><td>Header</td></tr></thead><tfoot><tr><td>Footer</td></tr></tfoot><tbody><tr><td>Cell</td></tr></tbody></table>
                 '/article/table[caption="Table 0"][thead/tr[td="Header"]][tfoot/tr[td="Footer"]][tbody/tr[td="Cell"]]'),
             ('<page><body><table html:title="Title"><table-header><table-row><table-cell>Header</table-cell></table-row></table-header><table-footer><table-row><table-cell>Footer</table-cell></table-row></table-footer><table-body><table-row><table-cell>Cell</table-cell></table-row></table-body></table></body></page>',
-            # <article><table><caption>Title</caption><thead><tr><td>Header</td></tr></thead><tfoot><tr><td>Footer</td></tr></tfoot><tbody><tr><td>Cell</td></tr></tbody></table>
+                # <article><table><caption>Title</caption><thead><tr><td>Header</td></tr></thead><tfoot><tr><td>Footer</td></tr></tfoot><tbody><tr><td>Cell</td></tr></tbody></table>
                 '/article/table[caption="Title"][thead/tr[td="Header"]][tfoot/tr[td="Footer"]][tbody/tr[td="Cell"]]'),
             ('<page><body><table><table-body><table-row><table-cell page:number-columns-spanned="2">Cell</table-cell></table-row></table-body></table></body></page>',
-             # <article><table><tbody><tr><td colspan="2">Cell</td></tr></tbody></table></article>
+                # <article><table><tbody><tr><td colspan="2">Cell</td></tr></tbody></table></article>
                 '/article/table/tbody/tr/td[@colspan="2"][text()="Cell"]'),
             ('<page><body><table><table-body><table-row><table-cell page:number-rows-spanned="2">Cell</table-cell></table-row></table-body></table></body></page>',
-            # <article><table><tbody><tr><td rowspan="2">Cell</td></tr></tbody></table></article>
+                # <article><table><tbody><tr><td rowspan="2">Cell</td></tr></tbody></table></article>
                 '/article/table/tbody/tr/td[@rowspan="2"][text()="Cell"]'),
         ]
         for i in data:
@@ -152,53 +152,52 @@
         data = [
             # Footnote conversion
             ('<page><body><p>Text simpara<note page:note-class="footnote"><note-body>Text Footnote</note-body></note></p></body></page>',
-             # <article><simpara>Text simpara<footnote>Text Footnote</footnote></simpara></article>
-             '/article/simpara[text()="Text simpara"]/footnote[simpara="Text Footnote"]'),
+                # <article><simpara>Text simpara<footnote>Text Footnote</footnote></simpara></article>
+                '/article/simpara[text()="Text simpara"]/footnote[simpara="Text Footnote"]'),
             # Link conversion
             ('<page><body><p><a xlink:href="uri:test" xlink:title="title">link</a></p></body></page>',
-              # <article><simpara><link xlink:href="uri:test" xlink:title="title">link</link></simpara></article>
-              '/article/simpara/link[@xlink:href="uri:test"][@xlink:title="title"][text()="link"]'),
+                # <article><simpara><link xlink:href="uri:test" xlink:title="title">link</link></simpara></article>
+                '/article/simpara/link[@xlink:href="uri:test"][@xlink:title="title"][text()="link"]'),
             # Blockcode conversion into <screen> with CDATA
             ('<page><body><blockcode>Text</blockcode></body></page>',
-              # <article><screen><![CDATA[Text]]></screen></article>
-             '/article[screen="<![CDATA[Text]]>"]'),
+                # <article><screen><![CDATA[Text]]></screen></article>
+                '/article[screen="<![CDATA[Text]]>"]'),
             # Code conversion into <literal>
             ('<page><body><p><code>Text</code></p></body></page>',
-              # <article><simpara><literal>Text</literal></simpara></article>
-             '/article/simpara[literal="Text"]'),
+                # <article><simpara><literal>Text</literal></simpara></article>
+                '/article/simpara[literal="Text"]'),
             # SPAN --> PHRASE
             ('<page><body><p><span>Text</span></p></body></page>',
-              # <article><simpara><phrase>Text</phrase></simpara></article>
-             '/article/simpara[phrase="Text"]'),
+                # <article><simpara><phrase>Text</phrase></simpara></article>
+                '/article/simpara[phrase="Text"]'),
             # SPAN baseline-shift=sub --> subscript
             ('<page><body><p>sub<span page:baseline-shift="sub">sub</span>script</p></body></page>',
-             # <article><simpara>script<subscript>sub</subscript></simpara></article>
-             '/article/simpara[text()="script"][subscript="sub"]'),
+                # <article><simpara>script<subscript>sub</subscript></simpara></article>
+                '/article/simpara[text()="script"][subscript="sub"]'),
             # SPAN baseline-shift=super --> superscript
             ('<page><body><p>sub<span page:baseline-shift="super">super</span>script</p></body></page>',
-             # <article><simpara>script</simpara><superscript>super</superscript></article>
-             '/article/simpara[text()="script"][superscript="super"]'),
+                # <article><simpara>script</simpara><superscript>super</superscript></article>
+                '/article/simpara[text()="script"][superscript="super"]'),
             # STRONG --> EMPHASIS role='strong'
             ('<page><body><p>text<strong>strong</strong></p></body></page>',
-             # <article><simpara>text<emphasis role="strong">strong</emphasis></simpara>
-             '/article/simpara[text()="text"]/emphasis[@role="strong"][text()="strong"]'),
+                # <article><simpara>text<emphasis role="strong">strong</emphasis></simpara>
+                '/article/simpara[text()="text"]/emphasis[@role="strong"][text()="strong"]'),
             # EMPHASIS --> EMPHASIS
             ('<page><body><p>text<emphasis>emphasis</emphasis></p></body></page>',
-             # <article><simpara>text<emphasis>emphasis</emphasis></simpara>
-             '/article/simpara[text()="text"][emphasis="emphasis"]'),
+                # <article><simpara>text<emphasis>emphasis</emphasis></simpara>
+                '/article/simpara[text()="text"][emphasis="emphasis"]'),
             # LINE-BREAK --> SBR
             ('<page><body><p>Line 1<line-break />Line 2</p></body></page>',
-             #<article><simpara>Line 1<sbr />Line 2</simpara></article>
-             '/article/simpara[text()="Line 1"]/sbr'),
+                # <article><simpara>Line 1<sbr />Line 2</simpara></article>
+                '/article/simpara[text()="Line 1"]/sbr'),
             # QUOTE --> QUOTE
             ('<page><body><p>Text<quote>quotation</quote></p></body></page>',
-             # <article><simpara>Text<quote>quotation</quote></simpara></body></page>
-             '/article/simpara[text()="Text"][quote="quotation"]'),
+                # <article><simpara>Text<quote>quotation</quote></simpara></body></page>
+                '/article/simpara[text()="Text"][quote="quotation"]'),
             # BLOCKQUOTE --> BLOCKQUOTE
             ('<page><body><blockquote page:source="Socrates">One thing only I know, and that is that I know nothing.</blockquote></body></page>',
-             # <article><blockquote><attribution>Socrates</attribution><simpara>One thing ... nothing</simpara></blockquote></article>
-             '/article/blockquote[attribution="Socrates"][simpara="One thing only I know, and that is that I know nothing."]'),
-
+                # <article><blockquote><attribution>Socrates</attribution><simpara>One thing ... nothing</simpara></blockquote></article>
+                '/article/blockquote[attribution="Socrates"][simpara="One thing only I know, and that is that I know nothing."]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -206,14 +205,14 @@
     def test_object(self):
         data = [
             ('<page><body><p><object xlink:href="pics.png" page:type="image/" /></p></body></page>',
-             # <article><simpara><inlinemediaobject><imageobject><imagedata fileref="pics.png"></imageobject></inlinemediaobject></simpara></article>
-             '/article/simpara/inlinemediaobject/imageobject/imagedata[@fileref="pics.png"]'),
+                # <article><simpara><inlinemediaobject><imageobject><imagedata fileref="pics.png"></imageobject></inlinemediaobject></simpara></article>
+                '/article/simpara/inlinemediaobject/imageobject/imagedata[@fileref="pics.png"]'),
             ('<page><body><p><object xlink:href="sound.wav" page:type="audio/" /></p></body></page>',
-             # <article><simpara><inlinemediaobject><audioobject><audiodata fileref="sound.wav"></audioobject></inlinemediaobject></simpara></article>
-             '/article/simpara/inlinemediaobject/audioobject/audiodata[@fileref="sound.wav"]'),
+                # <article><simpara><inlinemediaobject><audioobject><audiodata fileref="sound.wav"></audioobject></inlinemediaobject></simpara></article>
+                '/article/simpara/inlinemediaobject/audioobject/audiodata[@fileref="sound.wav"]'),
             ('<page><body><p><object xlink:href="video.ogg" page:type="video/" /></p></body></page>',
-             # <article><simpara><inlinemediaobject><videoobject><videodata fileref="video.ogg"></videoobject></inlinemediaobject></simpara></article>
-             '/article/simpara/inlinemediaobject/videoobject/videodata[@fileref="video.ogg"]'),
+                # <article><simpara><inlinemediaobject><videoobject><videodata fileref="video.ogg"></videoobject></inlinemediaobject></simpara></article>
+                '/article/simpara/inlinemediaobject/videoobject/videodata[@fileref="video.ogg"]'),
         ]
         for i in data:
             yield (self.do, ) + i
--- a/MoinMoin/converter/_tests/test_html_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test_html_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -10,10 +10,8 @@
 import StringIO
 
 import pytest
-try:
-    from lxml import etree
-except:
-    pytest.skip("lxml module required to run test for html_in converter.")
+
+etree = pytest.importorskip('lxml.etree')
 
 from emeraldtree.tree import *
 
@@ -21,6 +19,7 @@
 logging = log.getLogger(__name__)
 from MoinMoin.converter.html_in import *
 
+
 class Base(object):
     namespaces = {
         moin_page.namespace: '',
@@ -49,6 +48,7 @@
         tree = etree.parse(StringIO.StringIO(string_to_parse))
         assert (tree.xpath(path, namespaces=self.namespaces_xpath))
 
+
 class TestConverter(Base):
     def setup_class(self):
         self.conv = Converter()
@@ -70,12 +70,12 @@
             ('<div><p>Test</p></div>',
              # <page><body><p>Test</p></page></body>
              '/page/body[p="Test"]'),
-             # Test attributes conversion
-             ('<div><p class="class text" style="style text" title="title text">Test</p></div>',
+            # Test attributes conversion
+            ('<div><p class="class text" style="style text" title="title text">Test</p></div>',
              # <page><body><p html:class="class text" html:style="style text" html:title="title text">Test</p></body></page>
              '/page/body/p[@html:class="class text"][@html:style="style text"][@html:title="title text"][text()="Test"]'),
-             # Test id
-             ('<div><p id="first">Text<strong id="second">strong</strong></p></div>',
+            # Test id
+            ('<div><p id="first">Text<strong id="second">strong</strong></p></div>',
              # <page><body><p xml:id="first">Text<strong xml:id="second">strong</strong></p></div>
              '/page/body/p[@xml:id="first"][text()="Text"]/strong[@xml:id="second"][text()="strong"]'),
         ]
@@ -85,11 +85,11 @@
     def test_title(self):
         data = [
             ('<html><h2>Test</h2></html>',
-            # <page><body><h outline-level="2">Test</h></body></page>
-              '/page/body/h[text()="Test"][@outline-level=2]'),
+                # <page><body><h outline-level="2">Test</h></body></page>
+                '/page/body/h[text()="Test"][@outline-level=2]'),
             ('<html><h6>Test</h6></html>',
-            # <page><body><h outline-level="6">Test</h></body></page>
-              '/page/body/h[text()="Test"][@outline-level=6]'),
+                # <page><body><h outline-level="6">Test</h></body></page>
+                '/page/body/h[text()="Test"][@outline-level=6]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -97,17 +97,17 @@
     def test_basic_style(self):
         data = [
             ('<html><p><em>Test</em></p></html>',
-             # <page><body><p><emphasis>Test</emphasis></body></page>
-              '/page/body/p[emphasis="Test"]'),
+                # <page><body><p><emphasis>Test</emphasis></body></page>
+                '/page/body/p[emphasis="Test"]'),
             ('<html><p><i>Test</i></p></html>',
-             # <page><body><p><emphasis>Test</emphasis></body></page>
-              '/page/body/p[emphasis="Test"]'),
+                # <page><body><p><emphasis>Test</emphasis></body></page>
+                '/page/body/p[emphasis="Test"]'),
             ('<html><p><strong>Test</strong></p></html>',
-             # <page><body><p><strong>Test</strong></p></body></page>
-              '/page/body/p[strong="Test"]'),
+                # <page><body><p><strong>Test</strong></p></body></page>
+                '/page/body/p[strong="Test"]'),
             ('<html><p><b>Test</b></p></html>',
-             # <page><body><p><strong>Test</strong></p></body></page>
-              '/page/body/p[strong="Test"]'),
+                # <page><body><p><strong>Test</strong></p></body></page>
+                '/page/body/p[strong="Test"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -115,32 +115,32 @@
     def test_span(self):
         data = [
             ('<html><p><sub>sub</sub>script</p></html>',
-             # <page><body><p><span baseline-shift="sub">sub</span></p></body></page>
-             '/page/body/p/span[text()="sub"][@baseline-shift="sub"]'),
+                # <page><body><p><span baseline-shift="sub">sub</span></p></body></page>
+                '/page/body/p/span[text()="sub"][@baseline-shift="sub"]'),
             ('<html><p><sup>super</sup>script</p></html>',
-             # <page><body><p><span baseline-shift="super">super</span></p></body></page>
-             '/page/body/p/span[text()="super"][@baseline-shift="super"]'),
+                # <page><body><p><span baseline-shift="super">super</span></p></body></page>
+                '/page/body/p/span[text()="super"][@baseline-shift="super"]'),
             ('<html><p><u>underline</u></p></html>',
-             # <page><body><p><span text-decoration="underline">underline</span></p></body></page>
-             '/page/body/p/span[text()="underline"][@text-decoration="underline"]'),
+                # <page><body><p><span text-decoration="underline">underline</span></p></body></page>
+                '/page/body/p/span[text()="underline"][@text-decoration="underline"]'),
             ('<html><p><big>Test</big></p></html>',
-             # <page><body><p><span font-size="120%">Test</span></p></body></page>
-              '/page/body/p/span[text()="Test"][@font-size="120%"]'),
+                # <page><body><p><span font-size="120%">Test</span></p></body></page>
+                '/page/body/p/span[text()="Test"][@font-size="120%"]'),
             ('<html><p><small>Test</small></p></html>',
-             # <page><body><p><span font-size="85%">Test</span></p></body></page>
-              '/page/body/p/span[text()="Test"][@font-size="85%"]'),
+                # <page><body><p><span font-size="85%">Test</span></p></body></page>
+                '/page/body/p/span[text()="Test"][@font-size="85%"]'),
             ('<html><p><ins>underline</ins></p></html>',
-             # <page><body><p><span text-decoration="underline">underline</span></p></body></page>
-             '/page/body/p/span[text()="underline"][@text-decoration="underline"]'),
+                # <page><body><p><span text-decoration="underline">underline</span></p></body></page>
+                '/page/body/p/span[text()="underline"][@text-decoration="underline"]'),
             ('<html><p><del>Test</del></p></html>',
-             # <page><body><p><span text-decoration="line-through">Test</span></p></body></page>
-             '/page/body/p/span[text()="Test"][@text-decoration="line-through"]'),
+                # <page><body><p><span text-decoration="line-through">Test</span></p></body></page>
+                '/page/body/p/span[text()="Test"][@text-decoration="line-through"]'),
             ('<html><p><s>Test</s></p></html>',
-             # <page><body><p><span text-decoration="line-through">Test</span></p></body></page>
-             '/page/body/p/span[text()="Test"][@text-decoration="line-through"]'),
+                # <page><body><p><span text-decoration="line-through">Test</span></p></body></page>
+                '/page/body/p/span[text()="Test"][@text-decoration="line-through"]'),
             ('<html><p><strike>Test</strike></p></html>',
-             # <page><body><p><span text-decoration="line-through">Test</span></p></body></page>
-             '/page/body/p/span[text()="Test"][@text-decoration="line-through"]'),
+                # <page><body><p><span text-decoration="line-through">Test</span></p></body></page>
+                '/page/body/p/span[text()="Test"][@text-decoration="line-through"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -148,20 +148,20 @@
     def test_span_html_element(self):
         data = [
             ('<html><p><abbr>Text</abbr></p></html>',
-             # <page><body><span html:class="html-abbr">Text</span></body></page>
-             '/page/body/p/span[text()="Text"][@html:class="html-abbr"]'),
+                # <page><body><span html:class="html-abbr">Text</span></body></page>
+                '/page/body/p/span[text()="Text"][@html:class="html-abbr"]'),
             ('<html><p><acronym>Text</acronym></p></html>',
-             # <page><body><span html:class="html-acronym">Text</span></body></page>
-             '/page/body/p/span[text()="Text"][@html:class="html-acronym"]'),
+                # <page><body><span html:class="html-acronym">Text</span></body></page>
+                '/page/body/p/span[text()="Text"][@html:class="html-acronym"]'),
             ('<html><p><address>Text</address></p></html>',
-             # <page><body><span html:class="html-address">Text</span></body></page>
-             '/page/body/p/span[text()="Text"][@html:class="html-address"]'),
+                # <page><body><span html:class="html-address">Text</span></body></page>
+                '/page/body/p/span[text()="Text"][@html:class="html-address"]'),
             ('<html><p><dfn>Text</dfn></p></html>',
-             # <page><body><span html:class="html-dfn">Text</span></body></page>
-             '/page/body/p/span[text()="Text"][@html:class="html-dfn"]'),
+                # <page><body><span html:class="html-dfn">Text</span></body></page>
+                '/page/body/p/span[text()="Text"][@html:class="html-dfn"]'),
             ('<html><p><kbd>Text</kbd></p></html>',
-             # <page><body><span html:class="html-kbd">Text</span></body></page>
-             '/page/body/p/span[text()="Text"][@html:class="html-kbd"]'),
+                # <page><body><span html:class="html-kbd">Text</span></body></page>
+                '/page/body/p/span[text()="Text"][@html:class="html-kbd"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -169,13 +169,13 @@
     def test_link(self):
         data = [
             ('<html><p><a href="uri:test">Test</a></p></html>',
-              # <page><body><p><a xlink:href>Test</a></p></body></page>
-              '/page/body/p/a[text()="Test"][@xlink:href="uri:test"]'),
+                # <page><body><p><a xlink:href>Test</a></p></body></page>
+                '/page/body/p/a[text()="Test"][@xlink:href="uri:test"]'),
             ('<html><base href="http://www.base-url.com/" /><body><div><p><a href="myPage.html">Test</a></p></div></body></html>',
-              # <page><body><div><p><a xlink:href="http://www.base-url.com/myPage.html">Test</a></p></div></body></page>
-              '/page/body/div/p/a[@xlink:href="http://www.base-url.com/myPage.html"]'),
+                # <page><body><div><p><a xlink:href="http://www.base-url.com/myPage.html">Test</a></p></div></body></page>
+                '/page/body/div/p/a[@xlink:href="http://www.base-url.com/myPage.html"]'),
             ('<html><p><a href="javascript:alert(\'hi\')">Test</a></p></html>',
-              # <page><body><p>Test</p></body></page>
+                # <page><body><p>Test</p></body></page>
                 '/page/body/p/[text()="Test"]'),
         ]
         for i in data:
@@ -184,17 +184,17 @@
     def test_code(self):
         data = [
             ('<html><div><code>Code</code></div></html>',
-             # <page><body><div><code>Code</code></div></body></page>
-             '/page/body/div[code="Code"]'),
+                # <page><body><div><code>Code</code></div></body></page>
+                '/page/body/div[code="Code"]'),
             ('<html><div><samp>Code</samp></div></html>',
-             # <page><body><div><code>Code</code></div></body></page>
-             '/page/body/div[code="Code"]'),
+                # <page><body><div><code>Code</code></div></body></page>
+                '/page/body/div[code="Code"]'),
             ('<html><pre>Code</pre></html>',
-             # <page><body><blockcode>Code</blockcode></body></page>
-              '/page/body[blockcode="Code"]'),
+                # <page><body><blockcode>Code</blockcode></body></page>
+                '/page/body[blockcode="Code"]'),
             ('<html><p><tt>Code</tt></p></html>',
-             # <page><body><p><code>Code</code></p></body></page>
-              '/page/body/p[code="Code"]'),
+                # <page><body><p><code>Code</code></p></body></page>
+                '/page/body/p[code="Code"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -202,11 +202,11 @@
     def test_quote(self):
         data = [
             ('<html><div><p><quote>Inline quote</quote></p></div></html>',
-            # <page><body><div><p><quote>Inline quote</quote></p></body></page>
-             '/page/body/div/p[quote="Inline quote"]'),
+                # <page><body><div><p><quote>Inline quote</quote></p></body></page>
+                '/page/body/div/p[quote="Inline quote"]'),
             ('<html><div><blockquote>Block quote</blockquote></div></html>',
-            # <page><body><div><blockquote>Block quote</blockquote></body></page>
-             '/page/body/div[blockquote="Block quote"]'),
+                # <page><body><div><blockquote>Block quote</blockquote></body></page>
+                '/page/body/div[blockquote="Block quote"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -214,32 +214,32 @@
     def test_list(self):
         data = [
             ('<html><div><ul><li>Item</li></ul></div></html>',
-            # <page><body><div><list item-label-generate="unordered"><list-item><list-item-body>Item</list-item-body></list-item></list></div></page></body></page>
-              '/page/body/div/list[@item-label-generate="unordered"]/list-item[list-item-body="Item"]'),
+                # <page><body><div><list item-label-generate="unordered"><list-item><list-item-body>Item</list-item-body></list-item></list></div></page></body></page>
+                '/page/body/div/list[@item-label-generate="unordered"]/list-item[list-item-body="Item"]'),
             ('<html><div><ol><li>Item</li></ol></div></html>',
-            # <page><body><div><list item-label-generate="ordered"><list-item><list-item-body>Item</list-item-body></list-item></list></div></page></body></page>
-              '/page/body/div/list[@item-label-generate="ordered"]/list-item[list-item-body="Item"]'),
+                # <page><body><div><list item-label-generate="ordered"><list-item><list-item-body>Item</list-item-body></list-item></list></div></page></body></page>
+                '/page/body/div/list[@item-label-generate="ordered"]/list-item[list-item-body="Item"]'),
             ('<html><div><ol type="A"><li>Item</li></ol></div></html>',
-            # <page><body><div><list item-label-generate="ordered" list-style-type="upper-alpha"><list-item><list-item-body>Item</list-item-body></list-item></list></div></page></body></page>
-              '/page/body/div/list[@item-label-generate="ordered" and @list-style-type="upper-alpha"]/list-item[list-item-body="Item"]'),
+                # <page><body><div><list item-label-generate="ordered" list-style-type="upper-alpha"><list-item><list-item-body>Item</list-item-body></list-item></list></div></page></body></page>
+                '/page/body/div/list[@item-label-generate="ordered" and @list-style-type="upper-alpha"]/list-item[list-item-body="Item"]'),
             ('<html><div><ol type="I"><li>Item</li></ol></div></html>',
-            # <page><body><div><list item-label-generate="ordered" list-style-type="upper-roman"><list-item><list-item-body>Item</list-item-body></list-item></list></div></page></body></page>
-              '/page/body/div/list[@item-label-generate="ordered" and @list-style-type="upper-roman"]/list-item[list-item-body="Item"]'),
+                # <page><body><div><list item-label-generate="ordered" list-style-type="upper-roman"><list-item><list-item-body>Item</list-item-body></list-item></list></div></page></body></page>
+                '/page/body/div/list[@item-label-generate="ordered" and @list-style-type="upper-roman"]/list-item[list-item-body="Item"]'),
             ('<html><div><ol type="a"><li>Item</li></ol></div></html>',
-            # <page><body><div><list item-label-generate="ordered" list-style-type="lower-alpha"><list-item><list-item-body>Item</list-item-body></list-item></list></div></page></body></page>
-              '/page/body/div/list[@item-label-generate="ordered" and @list-style-type="lower-alpha"]/list-item[list-item-body="Item"]'),
+                # <page><body><div><list item-label-generate="ordered" list-style-type="lower-alpha"><list-item><list-item-body>Item</list-item-body></list-item></list></div></page></body></page>
+                '/page/body/div/list[@item-label-generate="ordered" and @list-style-type="lower-alpha"]/list-item[list-item-body="Item"]'),
             ('<html><div><ol type="i"><li>Item</li></ol></div></html>',
-            # <page><body><div><list item-label-generate="ordered" list-style-type="lower-roman"><list-item><list-item-body>Item</list-item-body></list-item></list></div></page></body></page>
-              '/page/body/div/list[@item-label-generate="ordered" and @list-style-type="lower-roman"]/list-item[list-item-body="Item"]'),
+                # <page><body><div><list item-label-generate="ordered" list-style-type="lower-roman"><list-item><list-item-body>Item</list-item-body></list-item></list></div></page></body></page>
+                '/page/body/div/list[@item-label-generate="ordered" and @list-style-type="lower-roman"]/list-item[list-item-body="Item"]'),
             ('<html><div><dl><dt>Label</dt><dd>Item</dd></dl></div></html>',
-            # <page><body><div><list><list-item><list-item-label>Label</list-item-label><list-item-body>Item</list-item-body></list-item></list></div></body></page>
-             '/page/body/div/list/list-item[list-item-label="Label"][list-item-body="Item"]'),
+                # <page><body><div><list><list-item><list-item-label>Label</list-item-label><list-item-body>Item</list-item-body></list-item></list></div></body></page>
+                '/page/body/div/list/list-item[list-item-label="Label"][list-item-body="Item"]'),
             ('<html><div><dir><li>Item</li></dir></div></html>',
-            # <page><body><div><list item-label-generate="unordered"><list-item><list-item-body>Item</list-item-body></list-item></list></div></page></body></page>
-              '/page/body/div/list[@item-label-generate="unordered"]/list-item[list-item-body="Item"]'),
+                # <page><body><div><list item-label-generate="unordered"><list-item><list-item-body>Item</list-item-body></list-item></list></div></page></body></page>
+                '/page/body/div/list[@item-label-generate="unordered"]/list-item[list-item-body="Item"]'),
             ('<div><ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul></div>',
-            # <page><body><div><list item-label-generate="unordered"><list-item><list-item-body>Item 1</list-item-body></list-item><list-item><list-item-body>Item 2</list-item-body></list-item><list-item><list-item-body>Item 3</list-item-body></list-item></list></div></page></body></page>
-             '/page/body/list[@item-label-generate="unordered"][list-item[1]/list-item-body[text()="Item 1"]][list-item[2]/list-item-body[text()="Item 2"]][list-item[3]/list-item-body[text()="Item 3"]]'),
+                # <page><body><div><list item-label-generate="unordered"><list-item><list-item-body>Item 1</list-item-body></list-item><list-item><list-item-body>Item 2</list-item-body></list-item><list-item><list-item-body>Item 3</list-item-body></list-item></list></div></page></body></page>
+                '/page/body/list[@item-label-generate="unordered"][list-item[1]/list-item-body[text()="Item 1"]][list-item[2]/list-item-body[text()="Item 2"]][list-item[3]/list-item-body[text()="Item 3"]]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -247,11 +247,11 @@
     def test_object(self):
         data = [
             ('<html><div><img src="uri:test" /></div></html>',
-             # <page><body><div><object xlink:href="uri:test" /></div></body></page>
-              '/page/body/div/object/@xlink:href="uri:test"'),
+                # <page><body><div><object xlink:href="uri:test" /></div></body></page>
+                '/page/body/div/object/@xlink:href="uri:test"'),
             ('<html><div><object data="href"></object></div></html>',
-             # <page><body><div><object xlink:href="href" /></div></body></page>
-              '/page/body/div/object/@xlink:href="href"'),
+                # <page><body><div><object xlink:href="href" /></div></body></page>
+                '/page/body/div/object/@xlink:href="href"'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -259,14 +259,14 @@
     def test_table(self):
         data = [
             ('<html><div><table><thead><tr><td>Header</td></tr></thead><tfoot><tr><td>Footer</td></tr></tfoot><tbody><tr><td>Cell</td></tr></tbody></table></div></html>',
-            # <page><body><div><table><table-header><table-row><table-cell>Header</table-cell></table-row></table-header><table-footer><table-row><table-cell>Footer</table-cell></table-row></table-footer><table-body><table-row><table-cell>Cell</table-cell></table-row></table-body></table></div></body></page>
-             '/page/body/div/table[./table-header/table-row[table-cell="Header"]][./table-footer/table-row[table-cell="Footer"]][./table-body/table-row[table-cell="Cell"]]'),
+                # <page><body><div><table><table-header><table-row><table-cell>Header</table-cell></table-row></table-header><table-footer><table-row><table-cell>Footer</table-cell></table-row></table-footer><table-body><table-row><table-cell>Cell</table-cell></table-row></table-body></table></div></body></page>
+                '/page/body/div/table[./table-header/table-row[table-cell="Header"]][./table-footer/table-row[table-cell="Footer"]][./table-body/table-row[table-cell="Cell"]]'),
             ('<html><div><table><tbody><tr><td colspan="2">Cell</td></tr></tbody></table></div></html>',
-            # <page><body><div><table><table-body><table-row><table-cell number-columns-spanned="2">Cell</table-cell></table-row></table-body></table></body></page>
-             '/page/body/div/table/table-body/table-row/table-cell[text()="Cell"][@number-columns-spanned="2"]'),
+                # <page><body><div><table><table-body><table-row><table-cell number-columns-spanned="2">Cell</table-cell></table-row></table-body></table></body></page>
+                '/page/body/div/table/table-body/table-row/table-cell[text()="Cell"][@number-columns-spanned="2"]'),
             ('<html><div><table><tbody><tr><td rowspan="2">Cell</td></tr></tbody></table></div></html>',
-            # <page><body><div><table><table-body><table-row><table-cell number-rows-spanned="2">Cell</table-cell></table-row></table-body></table></body></page>
-             '/page/body/div/table/table-body/table-row/table-cell[text()="Cell"][@number-rows-spanned="2"]'),
+                # <page><body><div><table><table-body><table-row><table-cell number-rows-spanned="2">Cell</table-cell></table-row></table-body></table></body></page>
+                '/page/body/div/table/table-body/table-row/table-cell[text()="Cell"][@number-rows-spanned="2"]'),
         ]
         for i in data:
             yield (self.do, ) + i
--- a/MoinMoin/converter/_tests/test_html_in_out.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test_html_in_out.py	Wed Mar 20 01:25:01 2013 +0100
@@ -13,10 +13,8 @@
 import re
 
 import pytest
-try:
-    from lxml import etree
-except:
-    pytest.skip("lxml module required to run test for html_in_out converter.")
+
+etree = pytest.importorskip('lxml.etree')
 
 from MoinMoin import log
 logging = log.getLogger(__name__)
@@ -25,6 +23,7 @@
 from MoinMoin.converter.html_out import Converter as HTML_OUT
 from MoinMoin.util.tree import html, moin_page, xlink
 
+
 class Base(object):
 
     namespaces = {
@@ -51,6 +50,7 @@
         tree = etree.parse(StringIO.StringIO(string_to_parse))
         assert (tree.xpath(path))
 
+
 class TestConverter(Base):
     def setup_class(self):
         self.conv_html_dom = HTML_IN()
@@ -85,13 +85,13 @@
     def test_basic_style(self):
         data = [
             ('<html><p><em>Test</em></p></html>',
-              '/div/p[em="Test"]'),
+                '/div/p[em="Test"]'),
             ('<html><p><i>Test</i></p></html>',
-              '/div/p[em="Test"]'),
+                '/div/p[em="Test"]'),
             ('<html><p><strong>Test</strong></p></html>',
-              '/div/p[strong="Test"]'),
+                '/div/p[strong="Test"]'),
             ('<html><p><b>Test</b></p></html>',
-              '/div/p[strong="Test"]'),
+                '/div/p[strong="Test"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -99,23 +99,23 @@
     def test_span(self):
         data = [
             ('<html><p><sub>sub</sub>script</p></html>',
-             '/div/p[sub="sub"]'),
+                '/div/p[sub="sub"]'),
             ('<html><p><sup>super</sup>script</p></html>',
-             '/div/p[sup="super"]'),
+                '/div/p[sup="super"]'),
             ('<html><p><u>underline</u></p></html>',
-             '/div/p[ins="underline"]'),
+                '/div/p[ins="underline"]'),
             ('<html><p><big>Test</big></p></html>',
-              '/div/p/span[@class="moin-big"][text()="Test"]'),
+                '/div/p/span[@class="moin-big"][text()="Test"]'),
             ('<html><p><small>Test</small></p></html>',
-              '/div/p/span[@class="moin-small"][text()="Test"]'),
+                '/div/p/span[@class="moin-small"][text()="Test"]'),
             ('<html><p><ins>underline</ins></p></html>',
-             '/div/p[ins="underline"]'),
+                '/div/p[ins="underline"]'),
             ('<html><p><del>Test</del></p></html>',
-             '/div/p[del="Test"]'),
+                '/div/p[del="Test"]'),
             ('<html><p><s>Test</s></p></html>',
-             '/div/p[del="Test"]'),
+                '/div/p[del="Test"]'),
             ('<html><p><strike>Test</strike></p></html>',
-             '/div/p[del="Test"]'),
+                '/div/p[del="Test"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -123,15 +123,15 @@
     def test_span_html_element(self):
         data = [
             ('<html><p><abbr>Text</abbr></p></html>',
-             '/div/p/span[@class="html-abbr"][text()="Text"]'),
+                '/div/p/span[@class="html-abbr"][text()="Text"]'),
             ('<html><p><acronym>Text</acronym></p></html>',
-             '/div/p/span[@class="html-acronym"][text()="Text"]'),
+                '/div/p/span[@class="html-acronym"][text()="Text"]'),
             ('<html><p><address>Text</address></p></html>',
-             '/div/p/span[@class="html-address"][text()="Text"]'),
+                '/div/p/span[@class="html-address"][text()="Text"]'),
             ('<html><p><dfn>Text</dfn></p></html>',
-             '/div/p/span[@class="html-dfn"][text()="Text"]'),
+                '/div/p/span[@class="html-dfn"][text()="Text"]'),
             ('<html><p><kbd>Text</kbd></p></html>',
-             '/div/p/span[@class="html-kbd"][text()="Text"]'),
+                '/div/p/span[@class="html-kbd"][text()="Text"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -139,7 +139,7 @@
     def test_link(self):
         data = [
             ('<html><p><a href="uri:test">Test</a></p></html>',
-              '/div/p/a[text()="Test"][@href="uri:test"]'),
+                '/div/p/a[text()="Test"][@href="uri:test"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -147,13 +147,13 @@
     def test_code(self):
         data = [
             ('<html><div><code>Code</code></div></html>',
-             '/div/div[code="Code"]'),
+                '/div/div[code="Code"]'),
             ('<html><div><samp>Code</samp></div></html>',
-             '/div/div[code="Code"]'),
+                '/div/div[code="Code"]'),
             ('<html><pre>Code</pre></html>',
-              '/div[pre="Code"]'),
+                '/div[pre="Code"]'),
             ('<html><p><tt>Code</tt></p></html>',
-              '/div/p[code="Code"]'),
+                '/div/p[code="Code"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -161,28 +161,28 @@
     def test_list(self):
         data = [
             ('<html><div><ul><li>Item</li></ul></div></html>',
-              '/div/div/ul[li="Item"]'),
+                '/div/div/ul[li="Item"]'),
             ('<html><div><ol><li>Item</li></ol></div></html>',
-              '/div/div/ol[li="Item"]'),
+                '/div/div/ol[li="Item"]'),
             ('<html><div><ol type="A"><li>Item</li></ol></div></html>',
-              '/div/div/ol[@class="moin-upperalpha-list"][li="Item"]'),
+                '/div/div/ol[@class="moin-upperalpha-list"][li="Item"]'),
             ('<html><div><ol type="I"><li>Item</li></ol></div></html>',
-              '/div/div/ol[@class="moin-upperroman-list"][li="Item"]'),
+                '/div/div/ol[@class="moin-upperroman-list"][li="Item"]'),
             ('<html><div><ol type="a"><li>Item</li></ol></div></html>',
-              '/div/div/ol[@class="moin-loweralpha-list"][li="Item"]'),
+                '/div/div/ol[@class="moin-loweralpha-list"][li="Item"]'),
             ('<html><div><ol type="i"><li>Item<li></ol></div></html>',
-              '/div/div/ol[@class="moin-lowerroman-list"][li="Item"]'),
+                '/div/div/ol[@class="moin-lowerroman-list"][li="Item"]'),
             ('<html><div><dl><dt>Label</dt><dd>Item</dd></dl></div></html>',
-             '/div/div/dl[dt="Label"][dd="Item"]'),
+                '/div/div/dl[dt="Label"][dd="Item"]'),
             ('<html><div><dir><li>Item</li></dir></div></html>',
-              '/div/div/ul[li="Item"]'),
+                '/div/div/ul[li="Item"]'),
             ('<div><ul><li>Item 1</li><p>Pouet</p><li>Item 2</li><li>Item 3</li></ul></div>',
-             '/div/ul[li[1]="Item 1"][li[2]="Item 2"][li[3]="Item 3"]'),
-             #Test for bug with line return and spaces
+                '/div/ul[li[1]="Item 1"][li[2]="Item 2"][li[3]="Item 3"]'),
+            #Test for bug with line return and spaces
             ('<div><ul><li>\n Item 1</li>\n<li>\n Item 2</li>\n<li>\n Item 3</li>\n</ul></div>',
-             '/div/ul[li[1]="\n Item 1"][li[2]="\n Item 2"][li[3]="\n Item 3"]'),
+                '/div/ul[li[1]="\n Item 1"][li[2]="\n Item 2"][li[3]="\n Item 3"]'),
             ('<div><ol><li>\n Item 1</li>\n<li>\n Item 2</li>\n<li>\n Item 3</li>\n</ol></div>',
-             '/div/ol[li[1]="\n Item 1"][li[2]="\n Item 2"][li[3]="\n Item 3"]'),
+                '/div/ol[li[1]="\n Item 1"][li[2]="\n Item 2"][li[3]="\n Item 3"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -192,7 +192,7 @@
             #('<html><div><img src="uri:test" /></div></html>',
             #  '/page/body/div/object/@xlink:href="uri:test"'),
             ('<html><div><object data="href"></object></div></html>',
-              '/div/div/div/object[@data="href"]'),
+                '/div/div/div/object[@data="href"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -200,14 +200,14 @@
     def test_table(self):
         data = [
             ('<html><div><table><thead><tr><td>Header</td></tr></thead><tfoot><tr><td>Footer</td></tr></tfoot><tbody><tr><td>Cell</td></tr></tbody></table></div></html>',
-             '/div/div/table[./thead/tr[td="Header"]][./tfoot/tr[td="Footer"]][./tbody/tr[td="Cell"]]'),
+                '/div/div/table[./thead/tr[td="Header"]][./tfoot/tr[td="Footer"]][./tbody/tr[td="Cell"]]'),
             ('<html><div><table><tbody><tr><td colspan="2">Cell</td></tr></tbody></table></div></html>',
-             '/div/div/table/tbody/tr/td[text()="Cell"][@colspan="2"]'),
+                '/div/div/table/tbody/tr/td[text()="Cell"][@colspan="2"]'),
             ('<html><div><table><tbody><tr><td rowspan="2">Cell</td></tr></tbody></table></div></html>',
-             '/div/div/table/tbody/tr/td[text()="Cell"][@rowspan="2"]'),
+                '/div/div/table/tbody/tr/td[text()="Cell"][@rowspan="2"]'),
             # Test for bug with newline between cell
             ('<div><table>\n<tbody>\n<tr>\n<td>\n Cell 1:1</td>\n<td>\n Cell 1:2</td>\n</tr>\n<tr>\n<td>\n Cell 2:1</td>\n<td>\n Cell 2:2</td>\n</tr>\n</tbody>\n</table></div>',
-              '/div/table/tbody[tr[1][td[1]="\n Cell 1:1"][td[2]="\n Cell 1:2"]][tr[2][td[1]="\n Cell 2:1"][td[2]="\n Cell 2:2"]]'),
+                '/div/table/tbody[tr[1][td[1]="\n Cell 1:1"][td[2]="\n Cell 1:2"]][tr[2][td[1]="\n Cell 2:1"][td[2]="\n Cell 2:2"]]'),
         ]
         for i in data:
             yield (self.do, ) + i
--- a/MoinMoin/converter/_tests/test_html_out.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test_html_out.py	Wed Mar 20 01:25:01 2013 +0100
@@ -11,10 +11,8 @@
 import StringIO
 
 import pytest
-try:
-    from lxml import etree
-except:
-    pytest.skip("lxml module required to run test for html_out converter.")
+
+etree = pytest.importorskip('lxml.etree')
 
 from emeraldtree.tree import *
 
@@ -23,6 +21,7 @@
 
 from MoinMoin.converter.html_out import *
 
+
 class Base(object):
     input_namespaces = ns_all = 'xmlns="{0}" xmlns:page="{1}" xmlns:html="{2}" xmlns:xlink="{3}" xmlns:xml="{4}"'.format(moin_page.namespace, moin_page.namespace, html.namespace, xlink.namespace, xml.namespace)
     output_namespaces = {
@@ -51,6 +50,7 @@
         tree = etree.parse(StringIO.StringIO(string_to_parse))
         assert (tree.xpath(xpath))
 
+
 class TestConverter(Base):
     def setup_class(self):
         self.conv = Converter()
@@ -105,10 +105,10 @@
         data = [
             # Basic Links
             ('<page:page><page:body><page:a xlink:href="uri:test">Test</page:a></page:body></page:page>',
-              '/div/a[text()="Test"][@href="uri:test"]'),
+                '/div/a[text()="Test"][@href="uri:test"]'),
             # Links with xml:base
             ('<page xml:base="http://base.tld/"><body><p><a xlink:href="page.html">Test</a></p></body></page>',
-              '/div/p/a[@href="http://base.tld/page.html"][text()="Test"]'),
+                '/div/p/a[@href="http://base.tld/page.html"][text()="Test"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -180,7 +180,7 @@
             ('<page><body><object xlink:href="href.png" page:type="image/png"/></body></page>',
                 '/div/img[@src="href.png"]'),
             ('<page xml:base="http://base.tld/"><body><object xlink:href="href.png" page:type="image/png"/></body></page>',
-              '/div/img[@src="http://base.tld/href.png"]'),
+                '/div/img[@src="http://base.tld/href.png"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -202,9 +202,9 @@
     def test_style(self):
         data = [
             ('<page><body><p style="font-size: 1em">Text</p></body></page>',
-              '/div/p[@style="font-size: 1em"][text()="Text"]'),
+                '/div/p[@style="font-size: 1em"][text()="Text"]'),
             ('<page><body><p style="color: black; font-size: 1em">Text</p></body></page>',
-              '/div/p[@style="color: black; font-size: 1em"][text()="Text"]'),
+                '/div/p[@style="color: black; font-size: 1em"][text()="Text"]'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -229,6 +229,7 @@
         for i in data:
             yield (self.do, ) + i
 
+
 class TestConverterPage(Base):
     def setup_class(self):
         self.conv = ConverterPage()
--- a/MoinMoin/converter/_tests/test_include.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test_include.py	Wed Mar 20 01:25:01 2013 +0100
@@ -6,13 +6,12 @@
 """
 
 
-import pytest
-
 from MoinMoin.converter.include import *
 from MoinMoin.items import Item
-from MoinMoin.config import CONTENTTYPE
+from MoinMoin.constants.keys import CONTENTTYPE
 from MoinMoin._tests import wikiconfig, update_item
 
+
 class TestInclude(object):
     class Config(wikiconfig.Config):
         """
@@ -65,10 +64,10 @@
 
     def test_IncludeHandlesCircularRecursion(self):
         # detect circular recursion and create error message
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'{{page2}}')
-        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u'{{page3}}')
-        update_item(u'page3', {CONTENTTYPE: u'text/x.moin.wiki'}, u'{{page4}}')
-        update_item(u'page4', {CONTENTTYPE: u'text/x.moin.wiki'}, u'{{page2}}')
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'{{page2}}')
+        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'{{page3}}')
+        update_item(u'page3', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'{{page4}}')
+        update_item(u'page4', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'{{page2}}')
         page1 = Item.create(u'page1')
         rendered = page1.content._render_data()
         # an error message will follow strong tag
@@ -76,88 +75,90 @@
 
     def test_ExternalInclude(self):
         # external include
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'{{http://moinmo.in}}')
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'{{http://moinmo.in}}')
         rendered = Item.create(u'page1').content._render_data()
         assert '<object class="moin-http moin-transclusion" data="http://moinmo.in" data-href="http://moinmo.in">http://moinmo.in</object>' in rendered
         # external include embedded within text (object is an inline tag)
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'before {{http://moinmo.in}} after')
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'before {{http://moinmo.in}} after')
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>before <object class="moin-http moin-transclusion" data="http://moinmo.in" data-href="http://moinmo.in">http://moinmo.in</object> after</p>' in rendered
         # external include embedded within text italic and bold markup (object is an inline tag)
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u"before ''italic '''bold {{http://moinmo.in}} bold''' italic'' normal")
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"before ''italic '''bold {{http://moinmo.in}} bold''' italic'' normal")
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>before <em>italic <strong>bold <object class="moin-http moin-transclusion" data="http://moinmo.in" data-href="http://moinmo.in">http://moinmo.in</object> bold</strong> italic</em> normal</p>' in rendered
 
     def test_InlineInclude(self):
 
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'before {{page2}} after')
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'before {{page2}} after')
         # transclude single paragraph as inline
-        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u'Single line')
+        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'Single line')
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>before <span class="moin-transclusion" data-href="/page2">Single line</span> after</p>' in rendered
         # transclude multiple paragraphs as block
-        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u'Two\n\nParagraphs')
+        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'Two\n\nParagraphs')
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>before </p><div class="moin-transclusion" data-href="/page2"><p>Two</p><p>Paragraphs</p></div><p> after</p></div>' in rendered
         # transclude single paragraph with internal markup as inline
-        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u"this text contains ''italic'' string")
+        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"this text contains ''italic'' string")
         rendered = Item.create(u'page1').content._render_data()
         assert 'before <span class="moin-transclusion" data-href="/page2">this text contains <em>italic</em>' in rendered
         # transclude single paragraph as only content within a paragraph
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'Content of page2 is\n\n{{page2}}')
-        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u"Single Line")
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'Content of page2 is\n\n{{page2}}')
+        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"Single Line")
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>Content of page2 is</p><p><span class="moin-transclusion" data-href="/page2">Single Line</span></p>' in rendered
         # transclude single row table within a paragraph, block element forces paragraph to be split into 2 parts
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'before {{page2}} after')
-        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u"|| table || cell ||")
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'before {{page2}} after')
+        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"|| table || cell ||")
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>before </p><div class="moin-transclusion" data-href="/page2"><table' in rendered
         assert '</table></div><p> after</p>' in rendered
         assert rendered.count('<table>') == 1
         # transclude two row table within a paragraph, block element forces paragraph to be split into 2 parts
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'before {{page2}} after')
-        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u"|| this || has ||\n|| two || rows ||")
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'before {{page2}} after')
+        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"|| this || has ||\n|| two || rows ||")
         rendered = Item.create(u'page1').content._render_data()
         # inclusion of block item within a paragraph results in a before and after p
         assert '<p>before </p><div class="moin-transclusion" data-href="/page2"><table' in rendered
         assert '</table></div><p> after</p>' in rendered
         assert rendered.count('<table>') == 1
         # transclude nonexistent item
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'before {{nonexistent}} after')
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'before {{nonexistent}} after')
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>before <span class="moin-transclusion" data-href="/nonexistent"><a href="/+modify/nonexistent">' in rendered
         assert '</a></span> after</p>' in rendered
         # transclude empty item
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'text {{page2}} text')
-        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u"")
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'text {{page2}} text')
+        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"")
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>text <span class="moin-transclusion" data-href="/page2"></span> text</p>' in rendered
+
     def test_InlineIncludeCreole(self):
         # transclude single paragraph as inline using creole parser
         update_item(u'creole', {CONTENTTYPE: u'text/x.moin.creole;charset=utf-8'}, u'creole item')
         update_item(u'page1', {CONTENTTYPE: u'text/x.moin.creole;charset=utf-8'}, u'before {{creole}} after')
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>before <span class="moin-transclusion" data-href="/creole">creole item</span> after</p>' in rendered
+
     def test_InlineIncludeWithinMarkup(self):
         # transclude single line item within italic and bold markup
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u"Normal ''italic '''bold {{page2}} bold''' italic'' normal")
-        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u"Single Line")
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"Normal ''italic '''bold {{page2}} bold''' italic'' normal")
+        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"Single Line")
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>Normal <em>italic <strong>bold <span class="moin-transclusion" data-href="/page2">Single Line</span> bold</strong> italic</em> normal</p>' in rendered
         # transclude double line item within italic and bold markup
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u"Normal ''italic '''bold {{page2}} bold''' italic'' normal")
-        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u"Double\n\nLine")
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"Normal ''italic '''bold {{page2}} bold''' italic'' normal")
+        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"Double\n\nLine")
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>Normal <em>italic <strong>bold </strong></em></p><div class="moin-transclusion" data-href="/page2"><p>Double</p><p>Line</p></div><p><em><strong> bold</strong> italic</em> normal</p>' in rendered
         # transclude single line item within comment
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u"comment /* before {{page2}} after */")
-        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u"Single Line")
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"comment /* before {{page2}} after */")
+        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"Single Line")
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>comment <span class="comment">before <span class="moin-transclusion" data-href="/page2">Single Line</span> after</span></p>' in rendered
         # transclude double line item within comment
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u"comment /* before {{page2}} after */")
-        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u"Double\n\nLine")
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"comment /* before {{page2}} after */")
+        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"Double\n\nLine")
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>comment <span class="comment">before </span></p><div class="comment moin-transclusion" data-href="/page2"><p>Double</p><p>Line</p></div><p><span class="comment"> after</span></p>' in rendered
 
@@ -165,22 +166,22 @@
         # the 3rd parameter, u'',  should be a binary string defining a png image, but it is not needed for this simple test
         update_item(u'logo.png', {CONTENTTYPE: u'image/png'}, u'')
         # simple transclusion
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'{{logo.png}}')
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'{{logo.png}}')
         rendered = Item.create(u'page1').content._render_data()
         assert '<p><span class="moin-transclusion" data-href="/logo.png"><img alt="logo.png" src=' in rendered
         assert '/logo.png" /></span></p>' in rendered
         # within paragraph
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'text {{logo.png}} text')
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'text {{logo.png}} text')
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>text <span class="moin-transclusion" data-href="/logo.png"><img alt="logo.png" src=' in rendered
         assert '/logo.png" /></span> text</p>' in rendered
         # within markup
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u"Normal ''italic '''bold {{logo.png}} bold''' italic'' normal")
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"Normal ''italic '''bold {{logo.png}} bold''' italic'' normal")
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>Normal <em>italic <strong>bold <span class="moin-transclusion" data-href="/logo.png"><img alt="logo.png" src=' in rendered
         assert '/logo.png" /></span> bold</strong> italic</em> normal</p>' in rendered
         # multiple transclusions
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'{{logo.png}}{{logo.png}}')
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'{{logo.png}}{{logo.png}}')
         rendered = Item.create(u'page1').content._render_data()
         assert '<p><span class="moin-transclusion" data-href="/logo.png"><img alt="logo.png" src=' in rendered
         assert '/logo.png" /></span><span class="moin-transclusion" data-href="/logo.png"><img alt="logo.png" src=' in rendered
@@ -190,41 +191,41 @@
 
     def test_IncludeAsLinkAlternate(self):
         # image as link alternate
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u"text [[page2|{{logo.png}}]] text")
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"text [[page2|{{logo.png}}]] text")
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>text <a href="/page2"><span class="moin-transclusion" data-href="/logo.png"><img alt="logo.png" src="' in rendered
         assert '/logo.png" /></span></a> text</p>' in rendered
         # link alternate with image embedded in markup
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u"text [[page2|plain '''bold {{logo.png}} bold''' plain]] text")
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"text [[page2|plain '''bold {{logo.png}} bold''' plain]] text")
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>text <a href="/page2">plain <strong>bold <span class="moin-transclusion" data-href="/logo.png"><img alt="logo.png" src="' in rendered
         assert '/logo.png" /></span> bold</strong> plain</a> text</p>' in rendered
         # nonexistent image used in link alternate
         # XXX html validation errora: A inside A - the image alternate turns into an A-tag to create the non-existant image.  Error is easily seen.
         # IE9, Firefox, Chrome, Safari, and Opera display this OK;  the only usable hyperlink is to create the missing image.
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u"text [[page2|{{logoxxx.png}}]] text")
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"text [[page2|{{logoxxx.png}}]] text")
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>text <a href="/page2"><span class="moin-transclusion" data-href="/logoxxx.png"><a href="/+modify/logoxxx.png">' in rendered
         assert '</a></span></a> text</p>' in rendered
         # image used as alternate to nonexistent page
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u"text [[page2xxx|{{logo.png}}]] text")
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"text [[page2xxx|{{logo.png}}]] text")
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>text <a class="moin-nonexistent" href="/page2xxx"><span class="moin-transclusion" data-href="/logo.png"><img alt="logo.png" src="' in rendered
         assert '/logo.png" /></span></a> text</p>' in rendered
         # transclude block elem as link alternate to nonexistent page
         # XXX html validation errors, block element inside A.
         # IE9, Firefox, Chrome, Safari, and Opera display this OK;  the hyperlink is the entire div enclosing the block elem
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'text [[MyPage|{{page2}}]] text')
-        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u"Double\n\nLine")
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'text [[MyPage|{{page2}}]] text')
+        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"Double\n\nLine")
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>text <a class="moin-nonexistent" href="/MyPage"><div class="moin-transclusion" data-href="/page2"><p>Double</p><p>Line</p></div></a> text</p>' in rendered
         # transclude empty item as link alternate to nonexistent page
         # hyperlink will be empty span and invisible
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'text [[MyPage|{{page2}}]] text')
-        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki'}, u"")
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'text [[MyPage|{{page2}}]] text')
+        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u"")
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>text <a class="moin-nonexistent" href="/MyPage"><span class="moin-transclusion" data-href="/page2"></span></a> text</p>' in rendered
         # transclude external page as link alternate to nonexistent page
-        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki'}, u'text [[MyPage|{{http://moinmo.in}}]] text')
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'text [[MyPage|{{http://moinmo.in}}]] text')
         rendered = Item.create(u'page1').content._render_data()
         assert '<p>text <a class="moin-nonexistent" href="/MyPage"><object class="moin-http moin-transclusion" data="http://moinmo.in" data-href="http://moinmo.in">http://moinmo.in</object></a> text</p>' in rendered
--- a/MoinMoin/converter/_tests/test_link.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test_link.py	Wed Mar 20 01:25:01 2013 +0100
@@ -15,6 +15,7 @@
 from MoinMoin.converter.link import *
 from MoinMoin.util.iri import Iri
 
+
 class TestConverterExternOutput(object):
     def setup_class(self):
         self.conv = ConverterExternOutput()
--- a/MoinMoin/converter/_tests/test_moinwiki19_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test_moinwiki19_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -32,7 +32,7 @@
                 '<page><body><p><a xlink:href="mailto:foo@bar.baz">mailto:foo@bar.baz</a></p></body></page>'),
             (u'foo@bar.baz',
                 '<page><body><p><a xlink:href="mailto:foo@bar.baz">foo@bar.baz</a></p></body></page>'),
-            (u'foo@bar', # 1.9 requires domain
+            (u'foo@bar',  # 1.9 requires domain
                 '<page><body><p>foo@bar</p></body></page>'),
         ]
         for i in data:
--- a/MoinMoin/converter/_tests/test_moinwiki_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test_moinwiki_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -91,7 +91,7 @@
 
     def test_heading(self):
         data = [
-            (u'=Not_a_Heading=', # this is for better moin 1.x compatibility
+            (u'=Not_a_Heading=',  # this is for better moin 1.x compatibility
                 '<page><body><p>=Not_a_Heading=</p></body></page>'),
             (u'= Heading 1 =',
                 '<page><body><h outline-level="1">Heading 1</h></body></page>'),
@@ -257,20 +257,20 @@
                 '<page><body><p /></body></page>'),
             # XXX: Is <page> correct?
             (u'{{{#!\nwiki\n}}}',
-               '<page><body><page><body><p>wiki</p></body></page></body></page>'),
+                '<page><body><page><body><p>wiki</p></body></page></body></page>'),
             (u'{{{#!(style="background-color: red")\nwiki\n}}}',
-               '<page><body><page><body style="background-color: red"><p>wiki</p></body></page></body></page>'),
+                '<page><body><page><body style="background-color: red"><p>wiki</p></body></page></body></page>'),
             (u'{{{#!wiki\nwiki\n}}}',
-               '<page><body><page><body><p>wiki</p></body></page></body></page>'),
+                '<page><body><page><body><p>wiki</p></body></page></body></page>'),
             (u'{{{#!wiki(style="background-color: red")\nwiki\n}}}',
-               '<page><body><page><body style="background-color: red"><p>wiki</p></body></page></body></page>'),
+                '<page><body><page><body style="background-color: red"><p>wiki</p></body></page></body></page>'),
             # TODO: Backward compatibility
             (u'{{{#!wiki red/solid\nwiki\n}}}',
-               '<page><body><page><body class="red solid"><p>wiki</p></body></page></body></page>'),
+                '<page><body><page><body class="red solid"><p>wiki</p></body></page></body></page>'),
             (u'{{{#!text/plain\ntext\n}}}',
-               u'<page><body><part content-type="text/plain"><body>text</body></part></body></page>'),
+                u'<page><body><part content-type="text/plain"><body>text</body></part></body></page>'),
             (u'{{{#!text/x.moin.creole\ntext\n}}}',
-               u'<page><body><part content-type="text/x.moin.creole"><body>text</body></part></body></page>'),
+                u'<page><body><part content-type="text/x.moin.creole"><body>text</body></part></body></page>'),
         ]
         for i in data:
             yield (self.do, ) + i
@@ -284,6 +284,7 @@
         ]
         for i in data:
             yield (self.do, ) + i
+
     def test_interwiki(self):
         data = [
             (u'[[MoinMoin:RecentChanges]]',
@@ -308,7 +309,7 @@
                 '<page><body><p><a xlink:href="mailto:foo@bar.baz">mailto:foo@bar.baz</a></p></body></page>'),
             (u'[[mailto:foo@bar.baz|write me]]',
                 '<page><body><p><a xlink:href="mailto:foo@bar.baz">write me</a></p></body></page>'),
-            (u'[[mailto:foo.bar_baz@bar.baz]]', # . and _ are special characters commonly allowed by email systems
+            (u'[[mailto:foo.bar_baz@bar.baz]]',  # . and _ are special characters commonly allowed by email systems
                 '<page><body><p><a xlink:href="mailto:foo.bar_baz@bar.baz">mailto:foo.bar_baz@bar.baz</a></p></body></page>'),
         ]
         for i in data:
--- a/MoinMoin/converter/_tests/test_moinwiki_in_out.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test_moinwiki_in_out.py	Wed Mar 20 01:25:01 2013 +0100
@@ -128,7 +128,7 @@
             yield (self.do, ) + i
 
     def test_page(self):
-        pytest.skip("please help fixing moin wiki round trip tests") # XXX TODO
+        pytest.skip("please help fixing moin wiki round trip tests")  # XXX TODO
         data = [
             (u"""
 This page aims to introduce the most important elements of MoinMoin``'s syntax at a glance, showing first the markup verbatim and then how it is rendered by the wiki engine. Additionally, you'll find links to the relative help pages. Please note that some of the features depend on your configuration.
--- a/MoinMoin/converter/_tests/test_moinwiki_out.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test_moinwiki_out.py	Wed Mar 20 01:25:01 2013 +0100
@@ -7,7 +7,6 @@
 """
 
 
-import pytest
 import re
 
 from MoinMoin.converter.moinwiki_out import *
--- a/MoinMoin/converter/_tests/test_registry.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test_registry.py	Wed Mar 20 01:25:01 2013 +0100
@@ -6,8 +6,6 @@
 """
 
 
-import pytest
-
 from MoinMoin.util.mime import Type, type_moin_document, type_moin_wiki
 from MoinMoin.converter import default_registry
 from MoinMoin.converter.text_in import Converter as TextInConverter
@@ -45,7 +43,7 @@
                 (type_moin_document, Type('application/x-xhtml-moin-page'), HtmlOutConverterPage),
                 (type_moin_document, type_moin_wiki, MoinwikiOutConverter),
                 (type_moin_document, Type('x-moin/format;name=wiki'), MoinwikiOutConverter),
-            ]:
+        ]:
             conv = default_registry.get(type_input, type_output)
             assert isinstance(conv, ExpectedClass)
 
@@ -55,7 +53,7 @@
                 (dict(includes='expandall'), IncludeConverter),
                 (dict(links='extern'), LinkConverterExternOutput),
                 (dict(items='refs'), LinkConverterItemRefs),
-            ]:
+        ]:
             conv = default_registry.get(type_moin_document, type_moin_document, **kwargs)
             assert isinstance(conv, ExpectedClass)
 
--- a/MoinMoin/converter/_tests/test_rst_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test_rst_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -7,7 +7,6 @@
 """
 
 
-import pytest
 import re
 
 from MoinMoin.converter.rst_in import *
@@ -50,7 +49,7 @@
             (u'1. a\n2. b\n\nA. c\n\na. A\n\n   3. B\n\n   4. C\n\n', '<page><body><list item-label-generate="ordered"><list-item><list-item-body><p>a</p></list-item-body></list-item><list-item><list-item-body><p>b</p></list-item-body></list-item></list><list item-label-generate="ordered" list-style-type="upper-alpha"><list-item><list-item-body><p>c</p></list-item-body></list-item></list><list item-label-generate="ordered" list-style-type="lower-alpha"><list-item><list-item-body><p>A</p><list item-label-generate="ordered"><list-item><list-item-body><p>B</p></list-item-body></list-item><list-item><list-item-body><p>C</p></list-item-body></list-item></list></list-item-body></list-item></list></body></page>'),
             (u'* A\n\n   - B\n\n      + C\n\n   - D\n\n* E', '<page><body><list item-label-generate="unordered"><list-item><list-item-body><p>A</p><list><list-item><list-item-body><list item-label-generate="unordered"><list-item><list-item-body><p>B</p><list><list-item><list-item-body><list item-label-generate="unordered"><list-item><list-item-body><p>C</p></list-item-body></list-item></list></list-item-body></list-item></list></list-item-body></list-item><list-item><list-item-body><p>D</p></list-item-body></list-item></list></list-item-body></list-item></list></list-item-body></list-item><list-item><list-item-body><p>E</p></list-item-body></list-item></list></body></page>'),
             (u'what\n      def\n\nhow\n      to', '<page><body><list><list-item><list-item-label>what</list-item-label><list-item-body><p>def</p></list-item-body></list-item><list-item><list-item-label>how</list-item-label><list-item-body><p>to</p></list-item-body></list-item></list></body></page>')
-            ]
+        ]
         for i in data:
             yield (self.do, ) + i
 
@@ -63,7 +62,7 @@
    :scale: 50
    :alt: alternate text""", '<page><body><object alt="images/biohazard.png" height="100" scale="50" width="200" xlink:href="images/biohazard.png" /></body></page>'),
             (u'abc |a| cba\n\n.. |a| image:: test.png', '<page><body><p>abc <object alt="test.png" xlink:href="test.png" /> cba</p></body></page>'),
-            ]
+        ]
         for i in data:
             yield (self.do, ) + i
 
@@ -71,7 +70,7 @@
         data = [
             (u'Chapter 1 Title\n===============\n\nSection 1.1 Title\n-----------------\n\nSubsection 1.1.1 Title\n~~~~~~~~~~~~~~~~~~~~~~\n\nSection 1.2 Title\n-----------------\n\nChapter 2 Title\n===============\n', '<page><body><h outline-level="2">Chapter 1 Title</h><h outline-level="3">Section 1.1 Title</h><h outline-level="4">Subsection 1.1.1 Title</h><h outline-level="3">Section 1.2 Title</h><h outline-level="2">Chapter 2 Title</h></body></page>'),
             (u'================\n Document Title\n================\n\n----------\n Subtitle\n----------\n\nSection Title\n=============', '<page><body><h outline-level="1">Document Title</h><h outline-level="2">Subtitle</h><h outline-level="2">Section Title</h></body></page>')
-            ]
+        ]
         for i in data:
             yield (self.do, ) + i
 
@@ -79,7 +78,7 @@
         data = [
             (u'Abra [1]_\n\n.. [1] arba', '<page><body><p>Abra <note note-class="footnote"><note-body>arba</note-body></note></p></body></page>'),
             (u'Abra [#]_\n\n.. [#] arba', '<page><body><p>Abra <note note-class="footnote"><note-body>arba</note-body></note></p></body></page>'),
-            ]
+        ]
         for i in data:
             yield (self.do, ) + i
 
@@ -87,7 +86,7 @@
         data = [
             (u'Abra test_ arba\n\n.. _test: http://python.org', '<page><body><p>Abra <a xlink:href="http://python.org">test</a> arba</p></body></page>'),
             (u'Abra test__ arba\n\n.. __: http://python.org', '<page><body><p>Abra <a xlink:href="http://python.org">test</a> arba</p></body></page>')
-            ]
+        ]
         for i in data:
             yield (self.do, ) + i
 
@@ -100,7 +99,7 @@
             (u'.. contents::\n  :depth: 1\n', '<page><body><table-of-content outline-level="1" /></body></page>'),
             (u'.. parser:: python test=test\n  import test\n  test.s = 11', '<page><body><part content-type="x-moin/format;name=python"><arguments><argument name="test">test</argument></arguments>import test\ntest.s = 11</part></body></page>'),
             (u'.. include:: RecentChanges', '<page><body><part content-type="x-moin/macro;name=Include"><arguments><argument>RecentChanges</argument></arguments>&lt;&lt;Include(RecentChanges)&gt;&gt;</part></body></page>'),
-            ]
+        ]
         for i in data:
             yield (self.do, ) + i
 
@@ -154,4 +153,5 @@
         out = self.conv(input, 'text/x-rst;charset=utf-8', **args)
         assert self.serialize(out) == output
 
+
 coverage_modules = ['MoinMoin.converter.rst_in']
--- a/MoinMoin/converter/_tests/test_rst_out.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test_rst_out.py	Wed Mar 20 01:25:01 2013 +0100
@@ -6,7 +6,6 @@
 """
 
 
-import pytest
 import re
 
 from MoinMoin.converter.rst_out import *
@@ -68,7 +67,7 @@
         data = [
             (u"<page:table><page:table-body><page:table-row><page:table-cell>A</page:table-cell><page:table-cell>B</page:table-cell><page:table-cell page:number-rows-spanned=\"2\">D</page:table-cell></page:table-row><page:table-row><page:table-cell page:number-cols-spanned=\"2\">C</page:table-cell></page:table-row></page:table-body></page:table>", "+-+-+-+\n|A|B|D|\n+-+-+ +\n|C  | |\n+---+-+\n\n"),
             (u"<page:table><page:table-body><page:table-row><page:table-cell><page:strong>A</page:strong></page:table-cell><page:table-cell><page:strong>B</page:strong></page:table-cell><page:table-cell><page:strong>C</page:strong></page:table-cell></page:table-row><page:table-row><page:table-cell><page:p>1</page:p></page:table-cell><page:table-cell>2</page:table-cell><page:table-cell>3</page:table-cell></page:table-row></page:table-body></page:table>", u"+-----+-----+-----+\n|**A**|**B**|**C**|\n+-----+-----+-----+\n|1    |2    |3    |\n+-----+-----+-----+\n\n"),
-             (u'<page:page><page:body><page:table><page:table-header><page:table-row><page:table-cell><page:p>AAAAAAAAAAAAAAAAAA</page:p></page:table-cell><page:table-cell><page:p>BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB</page:p></page:table-cell></page:table-row></page:table-header><page:table-body><page:table-row><page:table-cell page:number-rows-spanned=\"2\"><page:p>cell spanning 2 rows</page:p></page:table-cell><page:table-cell><page:p>cell in the 2nd column</page:p></page:table-cell></page:table-row><page:table-row><page:table-cell><page:p>cell in the 2nd column of the 2nd row</page:p></page:table-cell></page:table-row><page:table-row><page:table-cell page:number-cols-spanned=\"2\"><page:p>test</page:p></page:table-cell></page:table-row><page:table-row><page:table-cell page:number-cols-spanned=\"2\"><page:p>test</page:p></page:table-cell></page:table-row></page:table-body></page:table></page:body></page:page>', """+--------------------+-------------------------------------+
+            (u'<page:page><page:body><page:table><page:table-header><page:table-row><page:table-cell><page:p>AAAAAAAAAAAAAAAAAA</page:p></page:table-cell><page:table-cell><page:p>BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB</page:p></page:table-cell></page:table-row></page:table-header><page:table-body><page:table-row><page:table-cell page:number-rows-spanned=\"2\"><page:p>cell spanning 2 rows</page:p></page:table-cell><page:table-cell><page:p>cell in the 2nd column</page:p></page:table-cell></page:table-row><page:table-row><page:table-cell><page:p>cell in the 2nd column of the 2nd row</page:p></page:table-cell></page:table-row><page:table-row><page:table-cell page:number-cols-spanned=\"2\"><page:p>test</page:p></page:table-cell></page:table-row><page:table-row><page:table-cell page:number-cols-spanned=\"2\"><page:p>test</page:p></page:table-cell></page:table-row></page:table-body></page:table></page:body></page:page>', """+--------------------+-------------------------------------+
 |AAAAAAAAAAAAAAAAAA  |BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB  |
 +====================+=====================================+
 |cell spanning 2 rows|cell in the 2nd column               |
@@ -180,4 +179,5 @@
         for i in data:
             yield (self.do, ) + i
 
+
 coverage_modules = ['MoinMoin.converter.rst_out']
--- a/MoinMoin/converter/_tests/test_smiley.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_tests/test_smiley.py	Wed Mar 20 01:25:01 2013 +0100
@@ -34,8 +34,8 @@
     '2 at once': (
         '<page><body><p>:-) :-(</p></body></page>',
         '/page/body/p'
-            '[span[1][@class="moin-text-icon moin-smile"]]'
-            '[span[2][@class="moin-text-icon moin-sad"]]'),
+        '[span[1][@class="moin-text-icon moin-smile"]]'
+        '[span[2][@class="moin-text-icon moin-sad"]]'),
     'strong': (
         '<page><body><p><strong>:-)</strong></p></body></page>',
         '/page/body/p/strong/span[@class="moin-text-icon moin-smile"]'),
--- a/MoinMoin/converter/_util.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_util.py	Wed Mar 20 01:25:01 2013 +0100
@@ -12,14 +12,16 @@
 from flask import g as flaskg
 from emeraldtree import ElementTree as ET
 
-from MoinMoin.config import uri_schemes
+from MoinMoin.constants.misc import URI_SCHEMES
 from MoinMoin.util.iri import Iri
 from MoinMoin.util.mime import Type
 from MoinMoin.util.tree import html, moin_page
 
+
 def allowed_uri_scheme(uri):
     parsed = Iri(uri)
-    return not parsed.scheme or parsed.scheme in uri_schemes
+    return not parsed.scheme or parsed.scheme in URI_SCHEMES
+
 
 def decode_data(data, contenttype=None):
     """
@@ -42,7 +44,8 @@
             coding = ct.parameters.get('charset', coding)
         data = data.decode(coding)
     if not isinstance(data, unicode):
-        raise TypeError("data must be rev or str (requires contenttype with charset) or unicode, but we got {0!r}".format(data))
+        raise TypeError("data must be rev or str (requires contenttype with charset) or unicode, "
+                        "but we got {0!r}".format(data))
     return data
 
 
@@ -119,7 +122,8 @@
         """
         if request.user_agent and flaskg.user.edit_on_doubleclick:
             # this is not py.test and user has option to edit on doubleclick
-            # TODO: move the 2 lines above and 2 related import statements outside of the converters (needed for standalone converter)
+            # TODO: move the 2 lines above and 2 related import statements outside of the converters
+            # (this is needed for a standalone converter)
             if self.last_lineno != self.iter_content.lineno:
                 # avoid adding same lineno to parent and multiple children or grand-children
                 elem.attrib[html.data_lineno] = self.iter_content.lineno
--- a/MoinMoin/converter/_wiki_macro.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/_wiki_macro.py	Wed Mar 20 01:25:01 2013 +0100
@@ -16,6 +16,7 @@
 from MoinMoin.util.mime import Type
 from MoinMoin.util.tree import moin_page, xinclude
 
+
 class ConverterMacro(object):
     def _BR_repl(self, args, text, context_block):
         if context_block:
@@ -42,8 +43,8 @@
             return text
 
         pagename = args[0]
-        heading = None # TODO
-        level = None # TODO
+        heading = None  # TODO
+        level = None  # TODO
         sort = 'sort' in args and args['sort']
         if sort and sort not in ('ascending', 'descending'):
             raise RuntimeError
--- a/MoinMoin/converter/archive_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/archive_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -27,6 +27,7 @@
     exception class used in case of trouble with opening/listing an archive
     """
 
+
 class ArchiveConverter(TableMixin):
     """
     Base class for archive converters, convert an archive to a DOM table
@@ -39,7 +40,8 @@
     def process_name(self, member_name):
         name = unicode(member_name, 'utf-8')
         attrib = {
-            xlink.href: Iri(scheme='wiki', authority='', path='/'+self.item_name, query=u'do=get&member={0}'.format(name)),
+            xlink.href: Iri(scheme='wiki', authority='', path='/' + self.item_name,
+                            query=u'do=get&member={0}'.format(name)),
         }
         return moin_page.a(attrib=attrib, children=[name, ])
 
@@ -56,7 +58,7 @@
             contents = [(self.process_size(size),
                          self.process_datetime(dt),
                          self.process_name(name),
-                        ) for size, dt, name in contents]
+            ) for size, dt, name in contents]
             table = self.build_dom_table(contents, head=[_("Size"), _("Timestamp"), _("Name")], cls='zebra')
             body = moin_page.body(children=(table, ))
             return moin_page.page(children=(body, ))
@@ -113,7 +115,7 @@
                     # display only normal files, not directories
                     rows.append((
                         zinfo.file_size,
-                        datetime(*zinfo.date_time), # y,m,d,h,m,s
+                        datetime(*zinfo.date_time),  # y,m,d,h,m,s
                         zinfo.filename,
                     ))
             return rows
--- a/MoinMoin/converter/audio_video_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/audio_video_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -31,7 +31,8 @@
         item_name = rev.item.name
         attrib = {
             moin_page.type_: unicode(self.input_type),
-            xlink.href: Iri(scheme='wiki', authority='', path='/'+item_name, query='do=get&rev={0}'.format(rev.revid)),
+            xlink.href: Iri(scheme='wiki', authority='', path='/' + item_name,
+                            query='do=get&rev={0}'.format(rev.revid)),
         }
         obj = moin_page.object_(attrib=attrib, children=[u'Your Browser does not support HTML5 audio/video element.', ])
         body = moin_page.body(children=(obj, ))
--- a/MoinMoin/converter/creole_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/creole_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -27,7 +27,7 @@
 
 import re
 
-from MoinMoin import config
+from MoinMoin.constants.misc import URI_SCHEMES
 from MoinMoin.util.iri import Iri
 from MoinMoin.util.tree import moin_page, xlink, xinclude
 
@@ -126,8 +126,7 @@
         $
     """
 
-    def block_macro_repl(self, _iter_content, stack, macro, macro_name,
-            macro_args=None, macro_text=None):
+    def block_macro_repl(self, _iter_content, stack, macro, macro_name, macro_args=None, macro_text=None):
         """Handles macros using the placeholder syntax."""
         stack.clear()
 
@@ -330,9 +329,9 @@
         """Handle all kinds of links."""
 
         if link_page is not None:
-            att = 'attachment:' # moin 1.9 needed this for an attached file
+            att = 'attachment:'  # moin 1.9 needed this for an attached file
             if link_page.startswith(att):
-                link_page = '/' + link_page[len(att):] # now we have a subitem
+                link_page = '/' + link_page[len(att):]  # now we have a subitem
             target = unicode(Iri(scheme='wiki.local', path=link_page))
             text = link_page
         else:
@@ -363,8 +362,7 @@
         )
     """
 
-    def inline_macro_repl(self, stack, macro, macro_name,
-            macro_args=None, macro_text=None):
+    def inline_macro_repl(self, stack, macro, macro_name, macro_args=None, macro_text=None):
         """Handles macros using the placeholder syntax."""
 
         if macro_args:
@@ -406,9 +404,9 @@
         """Handles objects included in the page."""
 
         if object_page is not None:
-            att = 'attachment:' # moin 1.9 needed this for an attached file
+            att = 'attachment:'  # moin 1.9 needed this for an attached file
             if object_page.startswith(att):
-                object_page = '/' + object_page[len(att):] # now we have a subitem
+                object_page = '/' + object_page[len(att):]  # now we have a subitem
             target = Iri(scheme='wiki.local', path=object_page)
             text = object_page
 
@@ -436,7 +434,7 @@
             )
             ($ | (?=\s | [,.:;!?()] (\s | $)))
         )
-    """ % dict(uri_schemes='|'.join(config.uri_schemes))
+    """ % dict(uri_schemes='|'.join(URI_SCHEMES))
 
     def inline_url_repl(self, stack, url, url_target, escaped_url=None):
         """Handle raw urls in text."""
--- a/MoinMoin/converter/docbook_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/docbook_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -32,6 +32,7 @@
 class NameSpaceError(Exception):
     pass
 
+
 class Converter(object):
     """
     Converter application/docbook+xml -> x.moin.document
@@ -43,7 +44,7 @@
 
     # DocBook elements which are completely ignored by our converter
     # We even do not process children of these elements
-    ignored_tags = set([# Info elements
+    ignored_tags = set([  # Info elements
                        'abstract', 'artpagenums', 'annotation',
                        'artpagenums', 'author', 'authorgroup',
                        'authorinitials', 'bibliocoverage', 'biblioid',
@@ -135,7 +136,7 @@
                       'simplesect', 'subtitle', 'synopsis',
                       'synopfragment', 'task', 'taskprerequisites',
                       'taskrelated', 'tasksummary', 'title',
-                     ])
+    ])
 
     # DocBook has admonition as individual element, but the DOM Tree
     # has only one element for it, so we will convert all the DocBook
@@ -144,18 +145,23 @@
 
     # DocBook can handle three kind of media: audio, image, video. Here
     # is an helper dictionary to process such of element.
-    media_tags = {'audioobject': (['wav', 'mp3', 'ogg'],
-                                 'audiodata',
-                                 'audio/',
-                                 ),
-                  'imageobject': (['gif', 'png', 'jpg', 'png'],
-                                 'imagedata',
-                                 'image/',
-                                 ),
-                  'videoobject': (['ogg', 'avi', 'mp4'],
-                                 'videodata',
-                                 'video/',
-                                 )}
+    media_tags = {
+        'audioobject': (
+            ['wav', 'mp3', 'ogg'],
+            'audiodata',
+            'audio/',
+        ),
+        'imageobject': (
+            ['gif', 'png', 'jpg', 'png'],
+            'imagedata',
+            'image/',
+        ),
+        'videoobject': (
+            ['ogg', 'avi', 'mp4'],
+            'videodata',
+            'video/',
+        )
+    }
 
     # DocBook tags which can be convert directly to a DOM Tree element
     simple_tags = {'code': moin_page.code,
@@ -248,7 +254,7 @@
         a given element.
         """
         new_children = []
-        depth = depth + 1
+        depth += 1
         for child in element:
             if isinstance(child, ET.Element):
                 r = self.visit(child, depth)
@@ -287,8 +293,7 @@
         """
         result = {}
         for key, value in element.attrib.iteritems():
-            if key.uri == xml \
-              and key.name in ['id', 'base', 'lang']:
+            if key.uri == xml and key.name in ['id', 'base', 'lang']:
                 result[key] = value
         if result:
             # We clear standard_attribute, if ancestror attribute
@@ -383,22 +388,20 @@
         for child in element:
             if isinstance(child, ET.Element):
                 if child.tag.name in self.media_tags:
-                    #XXX: Check the spec to be sure that object tag have only one child.
-                    #TODO: Better way to do it
+                    # XXX: Check the spec to be sure that object tag have only one child.
+                    # TODO: Better way to do it
                     prefered_format, data_tag, mimetype = self.media_tags[child.tag.name]
                     object_element = child
                     for grand_child in child:
                         if isinstance(grand_child, ET.Element):
                             object_data.append(grand_child)
                 if child.tag.name == 'caption':
-                    caption = self.do_children(child, depth+1)[0]
+                    caption = self.do_children(child, depth + 1)[0]
                 if child.tag.name == 'textobject':
                     text_object = child
-        return self.visit_data_element(object_element, depth, object_data,
-            text_object, caption)
+        return self.visit_data_element(object_element, depth, object_data, text_object, caption)
 
-    def visit_data_element(self, element, depth, object_data,
-                           text_object, caption):
+    def visit_data_element(self, element, depth, object_data, text_object, caption):
         """
         We will try to return an object element based on the
         object_data. If it is not possible, we return a paragraph
@@ -410,7 +413,7 @@
             if not text_object:
                 return
             else:
-                children = self.do_children(child, depth+1)[0]
+                children = self.do_children(child, depth + 1)[0]
                 return self.new(moin_page.p, attrib={},
                                 children=children)
         # We try to determine the best object to show
@@ -430,7 +433,7 @@
         # If we could not find any suitable object, we return
         # the text replacement.
         if not object_to_show:
-            children = self.do_children(child, depth+1)[0]
+            children = self.do_children(child, depth + 1)[0]
             return self.new(moin_page.p, attrib={},
                             children=children)
 
@@ -488,9 +491,9 @@
         for child in element:
             if isinstance(child, ET.Element):
                 if child.tag.name == "attribution":
-                    source = self.do_children(child, depth+1)
+                    source = self.do_children(child, depth + 1)
                 else:
-                    children.extend(self.do_children(child, depth+1))
+                    children.extend(self.do_children(child, depth + 1))
             else:
                 children.append(child)
         attrib = {}
@@ -555,7 +558,7 @@
             #XXX: Improve error
             raise SyntaxError("para child missing for formalpara element")
 
-        children = self.do_children(para_element, depth+1)[0]
+        children = self.do_children(para_element, depth + 1)[0]
         attrib = {}
         attrib[html('title')] = title_element[0]
         return self.new(moin_page.p, attrib=attrib, children=children)
@@ -743,8 +746,8 @@
         """
         self.is_section = True
         if depth > self.section_depth:
-            self.section_depth = self.section_depth + 1
-            self.heading_level = self.heading_level + 1
+            self.section_depth += 1
+            self.heading_level += 1
         elif depth < self.section_depth:
             self.heading_level = self.heading_level - (self.section_depth - depth)
             self.section_depth = depth
@@ -781,14 +784,14 @@
             if isinstance(child, ET.Element):
                 if child.tag.name == 'seg':
                     label_tag = ET.Element(moin_page('list-item-label'),
-                            attrib={}, children=labels[counter % len(labels)])
+                                           attrib={}, children=labels[counter % len(labels)])
                     body_tag = ET.Element(moin_page('list-item-body'),
-                            attrib={}, children=self.visit(child, depth))
+                                          attrib={}, children=self.visit(child, depth))
                     item_tag = ET.Element(moin_page('list-item'),
-                            attrib={}, children=[label_tag, body_tag])
+                                          attrib={}, children=[label_tag, body_tag])
                     item_tag = (item_tag, )
                     new.extend(item_tag)
-                    counter = counter + 1
+                    counter += 1
                 else:
                     r = self.visit(child)
                     if r is None:
@@ -824,8 +827,7 @@
                     labels.extend(r)
                 else:
                     if child.tag.name == 'seglistitem':
-                        r = self.visit_docbook_seglistitem(child,
-                            labels, depth)
+                        r = self.visit_docbook_seglistitem(child, labels, depth)
                     else:
                         r = self.visit(child)
                     if r is None:
@@ -924,8 +926,7 @@
         attrib = {}
         children = []
         if class_attribute:
-            attrib[html('class')] = ''.join(['db-tag-',
-                                        class_attribute])
+            attrib[html('class')] = ''.join(['db-tag-', class_attribute])
         else:
             attrib[html('class')] = 'db-tag'
         if namespace_attribute:
@@ -943,7 +944,7 @@
         trademark_entities = {'copyright': '&copy;',
                               'registred': '&reg;',
                               'trade': '&trade;',
-                             }
+        }
         trademark_class = element.get('class')
         children = self.do_children(element, depth)
         if trademark_class in trademark_entities:
@@ -980,7 +981,7 @@
         href = element.get(docbook.url)
         # Since it is an element of DocBook v.4,
         # The namespace does not always work, so we will try to retrive the attribute whatever
-        if not(href):
+        if not href:
             for key, value in element.attrib.iteritems():
                 if key.name == 'url' and allowed_uri_scheme(value):
                     href = value
@@ -1145,8 +1146,7 @@
         children.append(self.visit(element, depth))
         # We show the table of content only if it is not empty
         if self.is_section:
-            children.insert(0, self.new(moin_page('table-of-content'),
-                                    attrib={}, children={}))
+            children.insert(0, self.new(moin_page('table-of-content'), attrib={}, children={}))
         body = self.new(moin_page.body, attrib={}, children=children)
         return self.new(moin_page.page, attrib=attrib, children=[body])
 
--- a/MoinMoin/converter/docbook_out.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/docbook_out.py	Wed Mar 20 01:25:01 2013 +0100
@@ -261,7 +261,7 @@
             if self.parent_section != 0:
                 section_tag = 'sect{0}'.format(self.parent_section)
                 section = ET.Element(docbook(section_tag), attrib={},
-                          children=self.section_children[self.current_section])
+                                     children=self.section_children[self.current_section])
                 self.section_children[self.parent_section].append(section)
                 self.current_section = int(depth)
 
@@ -335,7 +335,7 @@
                     if child.tag.name == 'note-body':
                         body = self.do_children(child)
         # We process note only with note-body child
-        if not(body):
+        if not body:
             return
 
         body = self.new(docbook.simpara, attrib={}, children=body)
@@ -385,7 +385,7 @@
         if not title:
             #TODO: Translation
             title = "Table {0}".format(self.table_counter)
-        self.table_counter = self.table_counter + 1
+        self.table_counter += 1
         caption = ET.Element(docbook('caption'), attrib={}, children=[title])
         children = [caption]
         children.extend(self.do_children(element))
@@ -441,7 +441,7 @@
         for item in element:
             if item.tag.uri == moin_page and item.tag.name == 'body':
                 c = self.do_children(item)
-                if not(c):
+                if not c:
                     self.section_children = sorted(self.section_children.items(),
                                                    reverse=True)
                     section = None
@@ -515,5 +515,4 @@
 
 from . import default_registry
 from MoinMoin.util.mime import Type, type_moin_document
-default_registry.register(Converter._factory, type_moin_document,
-    Type('application/docbook+xml'))
+default_registry.register(Converter._factory, type_moin_document, Type('application/docbook+xml'))
--- a/MoinMoin/converter/everything.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/everything.py	Wed Mar 20 01:25:01 2013 +0100
@@ -25,7 +25,8 @@
     def __call__(self, rev, contenttype=None, arguments=None):
         item_name = rev.item.name
         attrib = {
-            xlink.href: Iri(scheme='wiki', authority='', path='/'+item_name, query='do=get&rev={0}'.format(rev.revid)),
+            xlink.href: Iri(scheme='wiki', authority='', path='/' + item_name,
+                            query='do=get&rev={0}'.format(rev.revid)),
         }
         a = moin_page.a(attrib=attrib, children=[u"Download {0}.".format(item_name)])
         body = moin_page.body(children=(a, ))
--- a/MoinMoin/converter/html_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/html_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -33,7 +33,7 @@
     # Namespace of our input data
     html_namespace = {
         html.namespace: 'xhtml',
-        }
+    }
 
     # HTML tags which can be converted directly to the moin_page namespace
     symmetric_tags = set(['div', 'p', 'strong', 'code', 'quote', 'blockquote'])
@@ -42,17 +42,17 @@
     list_tags = set(['ul', 'dir', 'ol'])
 
     # HTML tags which can be convert without attributes in a different DOM tag
-    simple_tags = {# Emphasis
-                   'em': moin_page.emphasis, 'i': moin_page.emphasis,
-                   # Strong
-                   'b': moin_page.strong, 'strong': moin_page.strong,
-                   # Code and Blockcode
-                   'pre': moin_page.blockcode, 'tt': moin_page.code,
-                   'samp': moin_page.code,
-                   # Lists
-                   'dt': moin_page.list_item_label, 'dd': moin_page.list_item_body,
-                   # TODO : Some tags related to tables can be also simplify
-                  }
+    simple_tags = {  # Emphasis
+        'em': moin_page.emphasis, 'i': moin_page.emphasis,
+        # Strong
+        'b': moin_page.strong, 'strong': moin_page.strong,
+        # Code and Blockcode
+        'pre': moin_page.blockcode, 'tt': moin_page.code,
+        'samp': moin_page.code,
+        # Lists
+        'dt': moin_page.list_item_label, 'dd': moin_page.list_item_body,
+        # TODO : Some tags related to tables can be also simplify
+    }
 
     # HTML Tag which does not have equivalence in the DOM Tree
     # But we keep the information using <span element>
@@ -65,7 +65,7 @@
                         'label', 'legend', 'link', 'map', 'menu', 'noframes', 'noscript',
                         'optgroup', 'option', 'param', 'script', 'select', 'style',
                         'textarea', 'title', 'var',
-                       ])
+    ])
 
     # standard_attributes are html attributes which are used
     # directly in the DOM tree, without any conversion
@@ -480,8 +480,8 @@
         # of <dt><dd>
         for child in element:
             # We need one dt tag, and one dd tag, a have a pair
-            if (child.tag.name == 'dt' or child.tag.name == 'dd'):
-                number_pair = number_pair + 1
+            if child.tag.name == 'dt' or child.tag.name == 'dd':
+                number_pair += 1
 
             # The following code is similar to do_children method
             if isinstance(child, ET.Element):
@@ -494,7 +494,7 @@
             else:
                 pair.append(r)
 
-            if (number_pair == 2):
+            if number_pair == 2:
                 # We have two elements of the pair
                 # So we can put it into a <list-item> element
                 list_item_element = ET.Element(moin_page.list_item,
--- a/MoinMoin/converter/html_out.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/html_out.py	Wed Mar 20 01:25:01 2013 +0100
@@ -34,6 +34,7 @@
         return re.sub(r'\+get/\+[0-9a-fA-F]+/', '', href)
     return href
 
+
 def mark_item_as_transclusion(elem, href):
     """
     Return elem after adding a "moin-transclusion" class and a "data-href" attribute with
@@ -86,7 +87,7 @@
     visit_style = Attribute('style')
     visit_title = Attribute('title')
     visit_id = Attribute('id')
-    visit_type = Attribute('type') # IE8 needs <object... type="image/svg+xml" ...> to display svg images
+    visit_type = Attribute('type')  # IE8 needs <object... type="image/svg+xml" ...> to display svg images
 
     def __init__(self, element):
         self.element = element
@@ -196,8 +197,7 @@
         # Unknown element are just copied
         return self.new_copy(elem.tag, elem)
 
-    def visit_moinpage_a(self, elem,
-            _tag_html_a=html.a, _tag_html_href=html.href, _tag_xlink_href=xlink.href):
+    def visit_moinpage_a(self, elem, _tag_html_a=html.a, _tag_html_href=html.href, _tag_xlink_href=xlink.href):
         attrib = {}
         href = elem.get(_tag_xlink_href)
         if href:
@@ -371,7 +371,7 @@
 
         if obj_type == "img":
             # Images have alt text
-            alt = ''.join(unicode(e) for e in elem) # XXX handle non-text e
+            alt = ''.join(unicode(e) for e in elem)  # XXX handle non-text e
             if alt:
                 attrib[html.alt] = alt
             new_elem = html.img(attrib=attrib)
@@ -401,7 +401,8 @@
 
                     if item[0].tag.name in ('object', 'a'):
                         # png, jpg, gif are objects here, will be changed to img when they are processed
-                        # transclusion is a single inline element "My pet {{bird.jpg}} flys." or "[[SomePage|{{Logo.png}}]]"
+                        # transclusion is a single inline element "My pet {{bird.jpg}} flys." or
+                        # "[[SomePage|{{Logo.png}}]]"
                         return self.new_copy(html.span, item, attribs)
 
                     elif item[0].tag.name == 'p':
@@ -615,12 +616,10 @@
                 headings = list(headings)
                 maxlevel = max(h[1] for h in headings)
                 headtogglelink = html.a(attrib={
-                                         html.class_: 'moin-showhide',
-                                         html.href_: '#',
-                                         html.onclick_:
-                                            "$('.moin-table-of-contents ol').toggle();return false;",
-                                     },
-                                     children=[('[+]'), ])
+                    html.class_: 'moin-showhide',
+                    html.href_: '#',
+                    html.onclick_: "$('.moin-table-of-contents ol').toggle();return false;",
+                }, children=['[+]', ])
                 elem_h = html.div(attrib={html.class_: 'moin-table-of-contents-heading'},
                                   children=[_('Contents'), headtogglelink])
                 elem.append(elem_h)
@@ -653,20 +652,16 @@
                         stack.pop()
                         stack_push(html.li({html.id_: 'li{0}'.format(id)}))
                     togglelink = html.a(attrib={
-                                         html.href_: "#",
-                                         html.onclick_:
-                                            "$('#li{0} ol').toggle();return false;".format(id),
-                                         html.class_: 'moin-showhide',
-                                     },
-                                     children=["[+]", ])
-                    elem_a = html.a(attrib={html.href: '#' + id},
-                                    children=[text, ])
+                        html.href_: "#",
+                        html.onclick_: "$('#li{0} ol').toggle();return false;".format(id),
+                        html.class_: 'moin-showhide',
+                    }, children=["[+]", ])
+                    elem_a = html.a(attrib={html.href: '#' + id}, children=[text, ])
                     stack_top_append(elem_a)
                     old_toggle = togglelink
         return ret
 
-    def visit(self, elem,
-            _tag_moin_page_page_href=moin_page.page_href):
+    def visit(self, elem, _tag_moin_page_page_href=moin_page.page_href):
         # TODO: Is this correct, or is <page> better?
         if elem.get(_tag_moin_page_page_href):
             self._special_stack.append(SpecialPage())
@@ -681,8 +676,7 @@
         else:
             return super(ConverterPage, self).visit(elem)
 
-    def visit_moinpage_h(self, elem,
-            _tag_html_id=html.id):
+    def visit_moinpage_h(self, elem, _tag_html_id=html.id):
         elem = super(ConverterPage, self).visit_moinpage_h(elem)
 
         id = elem.get(_tag_html_id)
@@ -725,11 +719,15 @@
         prefixed_id = '%s-%s' % (self._id.get_id('note-placement'), id)
 
         elem_ref = ET.XML("""
-<html:sup xmlns:html="{0}" html:id="note-{1}-ref" html:class="moin-footnote"><html:a html:href="#note-{2}">{3}</html:a></html:sup>
+<html:sup xmlns:html="{0}" html:id="note-{1}-ref" html:class="moin-footnote">
+<html:a html:href="#note-{2}">{3}</html:a>
+</html:sup>
 """.format(html, prefixed_id, prefixed_id, id))
 
         elem_note = ET.XML("""
-<html:p xmlns:html="{0}" html:id="note-{1}"><html:sup><html:a html:href="#note-{2}-ref">{3}</html:a></html:sup></html:p>
+<html:p xmlns:html="{0}" html:id="note-{1}">
+<html:sup><html:a html:href="#note-{2}-ref">{3}</html:a></html:sup>
+</html:p>
 """.format(html, prefixed_id, prefixed_id, id))
 
         elem_note.extend(body)
--- a/MoinMoin/converter/image_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/image_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -29,7 +29,8 @@
         item_name = rev.item.name
         attrib = {
             moin_page.type_: unicode(self.input_type),
-            xlink.href: Iri(scheme='wiki', authority='', path='/'+item_name, query='do=get&rev={0}'.format(rev.revid)),
+            xlink.href: Iri(scheme='wiki', authority='', path='/' + item_name,
+                            query='do=get&rev={0}'.format(rev.revid)),
         }
         obj = moin_page.object_(attrib=attrib, children=[item_name, ])
         body = moin_page.body(children=(obj, ))
--- a/MoinMoin/converter/include.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/include.py	Wed Mar 20 01:25:01 2013 +0100
@@ -85,7 +85,9 @@
 from __future__ import absolute_import, division
 
 from emeraldtree import ElementTree as ET
-import re, types, copy
+import re
+import types
+import copy
 
 from MoinMoin import log
 logging = log.getLogger(__name__)
@@ -95,7 +97,7 @@
 
 from whoosh.query import Term, And, Wildcard
 
-from MoinMoin.config import NAME, NAME_EXACT, WIKINAME
+from MoinMoin.constants.keys import NAME, NAME_EXACT, WIKINAME
 from MoinMoin.items import Item
 from MoinMoin.util.mime import type_moin_document
 from MoinMoin.util.iri import Iri, IriPath
@@ -105,16 +107,16 @@
 
 # elements generated by moin wiki markup that cannot have block children
 NO_BLOCK_CHILDREN = [
-        'p',
-        'span', # /*comment*/, ~+big+~, ~-small-~ via classes comment, moin-big, moin-small
-        'emphasis', # ''italic''
-        'strong', # '''bold'''
-        'del', # --(stroke)--
-        'ins', # __underline__
-        # 'sub', # ,,subscript,, # no markup allowed within subscripts
-        # 'sup', # ^superscript^ # no markup allowed within superscripts
-        'a', # [[SomeItem|{{logo.png}}]]
-        ]
+    'p',
+    'span',  # /*comment*/, ~+big+~, ~-small-~ via classes comment, moin-big, moin-small
+    'emphasis',  # ''italic''
+    'strong',  # '''bold'''
+    'del',  # --(stroke)--
+    'ins',  # __underline__
+    # 'sub',  # ,,subscript,, # no markup allowed within subscripts
+    # 'sup',  # ^superscript^ # no markup allowed within superscripts
+    'a',  # [[SomeItem|{{logo.png}}]]
+]
 
 
 class XPointer(list):
@@ -181,6 +183,7 @@
                 data = None
             self.append(self.Entry(''.join(name), None))
 
+
 class Converter(object):
     tag_a = moin_page.a
     tag_div = moin_page.div
@@ -198,7 +201,8 @@
             return cls()
 
     def recurse(self, elem, page_href):
-        # on first call, elem.tag.name=='page'. Descendants (body, div, p, include, page, etc.) are processed by recursing through DOM
+        # on first call, elem.tag.name=='page'.
+        # Descendants (body, div, p, include, page, etc.) are processed by recursing through DOM
 
         # stack is used to detect transclusion loops
         page_href_new = elem.get(self.tag_page_href)
@@ -215,7 +219,8 @@
         try:
             if elem.tag == self.tag_xi_include:
                 # we have already recursed several levels and found a transclusion: "{{SomePage}}" or similar
-                # process the transclusion and add it to the DOM.  Subsequent recursions will traverse through the transclusion's elements.
+                # process the transclusion and add it to the DOM.  Subsequent recursions will traverse through
+                # the transclusion's elements.
                 href = elem.get(self.tag_xi_href)
                 xpointer = elem.get(self.tag_xi_xpointer)
 
@@ -352,7 +357,8 @@
                 #  end of processing for transclusion; the "result" will get inserted into the DOM below
                 return result
 
-            # Traverse the DOM by calling self.recurse with each child of the current elem.  Starting elem.tag.name=='page'.
+            # Traverse the DOM by calling self.recurse with each child of the current elem.
+            # Starting elem.tag.name=='page'.
             container = []
             i = 0
             while i < len(elem):
@@ -370,7 +376,8 @@
                                 # the transcluded item is empty, insert an empty span into DOM
                                 attrib = Attributes(ret).convert()
                                 elem[i] = ET.Element(moin_page.span, attrib=attrib)
-                            elif isinstance(body[0], ET.Node) and (len(body) > 1 or body[0].tag.name not in ('p', 'object', 'a')):
+                            elif (isinstance(body[0], ET.Node) and
+                                  (len(body) > 1 or body[0].tag.name not in ('p', 'object', 'a'))):
                                 # Complex case: "some text {{BlockItem}} more text" or "\n{{BlockItem}}\n" where
                                 # the BlockItem body contains multiple p's, a table, preformatted text, etc.
                                 # These block elements cannot be made a child of the current elem, so we create
@@ -379,30 +386,34 @@
                                 before = copy.deepcopy(elem)
                                 after = copy.deepcopy(elem)
                                 before[:] = elem[0:i]
-                                after[:] = elem[i+1:]
+                                after[:] = elem[i + 1:]
                                 if len(before):
                                     # there are siblings before transclude, save them in container
                                     container.append(before)
                                 new_trans_ptr = len(container)
-                                # get attributes from page node; we expect {class: "moin-transclusion"; data-href: "http://some.org/somepage"}
+                                # get attributes from page node;
+                                # we expect {class: "moin-transclusion"; data-href: "http://some.org/somepage"}
                                 attrib = Attributes(ret).convert()
                                 # make new div node to hold transclusion, copy children, and save in container
                                 div = ET.Element(moin_page.div, attrib=attrib, children=body[:])
-                                container.append(div) # new_trans_ptr is index to this
+                                container.append(div)  # new_trans_ptr is index to this
                                 if len(after):
                                     container.append(after)
                                 if elem.tag.name == 'a':
-                                    # invalid input [[MyPage|{{BlockItem}}]], best option is to retain A-tag and fail html validation
+                                    # invalid input [[MyPage|{{BlockItem}}]],
+                                    # best option is to retain A-tag and fail html validation
                                     # TODO: error may not be obvious to user - add error message
                                     elem[i] = div
                                 else:
-                                    # move up 1 level in recursion where elem becomes the child and is usually replaced by container
+                                    # move up 1 level in recursion where elem becomes the child and
+                                    # is usually replaced by container
                                     return [container, new_trans_ptr]
                             else:
                                 # default action for odd things like circular transclusion error messages
                                 elem[i] = ret
                         elif isinstance(ret, types.ListType):
-                            # a container has been returned. Note: there are two places where a container may be returned
+                            # a container has been returned.
+                            # Note: there are two places where a container may be returned
                             ret_container, trans_ptr = ret
                             # trans_ptr points to the transclusion within ret_container.
                             # Here the transclusion will always contain a block level element
@@ -413,25 +424,29 @@
                                 before = copy.deepcopy(elem)
                                 after = copy.deepcopy(elem)
                                 before[:] = elem[0:i] + ret_container[0:trans_ptr]
-                                after[:] = ret_container[trans_ptr+1:] + elem[i+1:]
+                                after[:] = ret_container[trans_ptr + 1:] + elem[i + 1:]
                                 if len(before):
                                     container.append(before)
                                 new_trans_ptr = len(container)
                                 # child may have classes like "comment" that must be added to transcluded element
                                 classes = child.attrib.get(moin_page.class_, '').split()
-                                classes += ret_container[trans_ptr].attrib.get(html.class_, '').split() # this must be html, not moin_page
-                                ret_container[trans_ptr].attrib[html.class_] = ' '.join(classes) # this must be html, not moin_page
-                                container.append(ret_container[trans_ptr]) # the transclusion
+                                # this must be html, not moin_page:
+                                classes += ret_container[trans_ptr].attrib.get(html.class_, '').split()
+                                # this must be html, not moin_page:
+                                ret_container[trans_ptr].attrib[html.class_] = ' '.join(classes)
+                                container.append(ret_container[trans_ptr])  # the transclusion
                                 if len(after):
                                     container.append(after)
                                 return [container, new_trans_ptr]
                             else:
-                                # elem is a block element, replace child element with the container generated in lower recursion
-                                elem[i:i+1] = ret_container # elem[i] is the child
+                                # elem is a block element,
+                                # replace child element with the container generated in lower recursion
+                                elem[i:i + 1] = ret_container  # elem[i] is the child
                                 # avoid duplicate recursion over nodes already processed
-                                i += len(ret_container) -1
+                                i += len(ret_container) - 1
                         else:
-                            # default action for any ret not fitting special cases above, e.g. tranclusion is within a table cell
+                            # default action for any ret not fitting special cases above,
+                            # e.g. tranclusion is within a table cell
                             elem[i] = ret
                 # we are finished with this child, advance to next sibling
                 i += 1
--- a/MoinMoin/converter/link.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/link.py	Wed Mar 20 01:25:01 2013 +0100
@@ -14,7 +14,7 @@
 from flask import g as flaskg
 
 from MoinMoin.util.interwiki import is_known_wiki, url_for_item
-from MoinMoin.util.iri import Iri, IriPath
+from MoinMoin.util.iri import Iri
 from MoinMoin.util.mime import Type, type_moin_document
 from MoinMoin.util.tree import moin_page, xlink, xinclude
 from MoinMoin.wikiutil import AbsItemName
@@ -47,13 +47,12 @@
         # because it is also called in subclasses
         return self.traverse_tree(*args, **kw)
 
-    def traverse_tree(self, elem, page=None,
-            __tag_page_href=moin_page.page_href, __tag_link=_tag_xlink_href,
-            __tag_include=_tag_xinclude_href):
+    def traverse_tree(self, elem, page=None, __tag_page_href=moin_page.page_href,
+                      __tag_link=_tag_xlink_href, __tag_include=_tag_xinclude_href):
         """
         Traverses the tree and handles each element appropriately
         """
-        new_page_href=elem.get(__tag_page_href)
+        new_page_href = elem.get(__tag_page_href)
         if new_page_href:
             page = Iri(new_page_href)
 
@@ -129,10 +128,10 @@
                     k, v = kv, ''
                 if k == 'do':
                     do = v
-                    continue # we remove do=xxx from qs
+                    continue  # we remove do=xxx from qs
                 if k == 'rev':
                     rev = v
-                    continue # we remove rev=n from qs
+                    continue  # we remove rev=n from qs
                 result.append(u'{0}={1}'.format(k, v))
         if result:
             query = separator.join(result)
--- a/MoinMoin/converter/macro.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/macro.py	Wed Mar 20 01:25:01 2013 +0100
@@ -22,7 +22,7 @@
 from MoinMoin.converter._args import Arguments
 from MoinMoin.util import iri
 from MoinMoin.util.mime import type_moin_document, Type
-from MoinMoin.util.tree import html, moin_page
+from MoinMoin.util.tree import moin_page
 from MoinMoin.util.plugins import PluginMissingError
 
 
@@ -87,9 +87,7 @@
             # some standard text.
             logging.exception("Macro {0} raised an exception:".format(name))
             elem_error.append(_('<<%(macro_name)s: execution failed [%(error_msg)s] (see also the log)>>',
-                    macro_name=name,
-                    error_msg=unicode(e),
-                ))
+                              macro_name=name, error_msg=unicode(e), ))
 
         if len(elem_body):
             elem.append(elem_body)
--- a/MoinMoin/converter/markdown_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/markdown_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -25,6 +25,7 @@
 from markdown import Markdown
 import markdown.util as md_util
 
+
 def postproc_text(markdown, text):
     """
     Removes HTML or XML character references and entities from a text string.
@@ -58,10 +59,11 @@
                 text = unichr(htmlentitydefs.name2codepoint[text[1:-1]])
             except KeyError:
                 pass
-        return text # leave as is
+        return text  # leave as is
 
     return re.sub("&#?\w+;", fixup, text)
 
+
 class Converter(object):
     # {{{ html conversion
 
@@ -72,17 +74,17 @@
     list_tags = set(['ul', 'dir', 'ol'])
 
     # HTML tags which can be convert without attributes in a different DOM tag
-    simple_tags = {# Emphasis
-                   'em': moin_page.emphasis, 'i': moin_page.emphasis,
-                   # Strong
-                   'b': moin_page.strong, 'strong': moin_page.strong,
-                   # Code and Blockcode
-                   'pre': moin_page.blockcode, 'tt': moin_page.code,
-                   'samp': moin_page.code,
-                   # Lists
-                   'dt': moin_page.list_item_label, 'dd': moin_page.list_item_body,
-                   # TODO : Some tags related to tables can be also simplify
-                  }
+    simple_tags = {  # Emphasis
+        'em': moin_page.emphasis, 'i': moin_page.emphasis,
+        # Strong
+        'b': moin_page.strong, 'strong': moin_page.strong,
+        # Code and Blockcode
+        'pre': moin_page.blockcode, 'tt': moin_page.code,
+        'samp': moin_page.code,
+        # Lists
+        'dt': moin_page.list_item_label, 'dd': moin_page.list_item_body,
+        # TODO : Some tags related to tables can be also simplify
+    }
 
     # HTML Tag which does not have equivalence in the DOM Tree
     # But we keep the information using <span element>
@@ -95,7 +97,7 @@
                         'label', 'legend', 'link', 'map', 'menu', 'noframes', 'noscript',
                         'optgroup', 'option', 'param', 'script', 'select', 'style',
                         'textarea', 'title', 'var',
-                       ])
+    ])
 
     # standard_attributes are html attributes which are used
     # directly in the DOM tree, without any conversion
@@ -290,8 +292,7 @@
         elif element.tag == "ol":
             attrib[moin_page('item-label-generate')] = 'ordered'
 
-        return ET.Element(moin_page.list, attrib=attrib,
-                children=self.do_children(element))
+        return ET.Element(moin_page.list, attrib=attrib, children=self.do_children(element))
 
     def visit_a(self, element):
         key = xlink('href')
--- a/MoinMoin/converter/mediawiki_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/mediawiki_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -19,7 +19,8 @@
 from MoinMoin import log
 logging = log.getLogger(__name__)
 
-from MoinMoin import config
+from MoinMoin.constants.contenttypes import CHARSET
+from MoinMoin.constants.misc import URI_SCHEMES
 from MoinMoin.util.iri import Iri
 from MoinMoin.util.tree import html, moin_page, xlink
 
@@ -284,11 +285,10 @@
             yield match.group('text')
 
     def indent_repl(self, iter_content, stack, line,
-            indent, text, list_begin=None, list_definition=None,
-            list_definition_text=None, list_numbers=None,
-            list_bullet=None,
-            list_none=None):
-
+                    indent, text, list_begin=None, list_definition=None,
+                    list_definition_text=None, list_numbers=None,
+                    list_bullet=None,
+                    list_none=None):
         level = len(indent)
         list_type = 'unordered', 'none'
         if list_begin:
@@ -335,7 +335,7 @@
                 # TODO: definition list doesn't work,
                 #       if definition of the term on the next line
                 splited_text = text.split(':')
-                list_definition_text=splited_text.pop(0)
+                list_definition_text = splited_text.pop(0)
                 text = ':'.join(splited_text)
 
                 self.parse_inline(list_definition_text, new_stack, self.inline_re)
@@ -482,7 +482,8 @@
         )
     """
 
-    def inline_footnote_repl(self, stack, footnote, footnote_begin=None, footnote_text=None, footnote_end=None, footnote_start=None):
+    def inline_footnote_repl(self, stack, footnote,
+                             footnote_begin=None, footnote_text=None, footnote_end=None, footnote_start=None):
         #stack.top_check('emphasis'):
         if footnote_begin is not None:
             stack.push(moin_page.note(attrib={moin_page.note_class: 'footnote'}))
@@ -591,7 +592,7 @@
             \s*
             \]
         )
-    """ % dict(uri_schemes='|'.join(config.uri_schemes))
+    """ % dict(uri_schemes='|'.join(URI_SCHEMES))
 
     def parse_args(self, input):
         """
@@ -627,7 +628,7 @@
         return ret
 
     def inline_link_repl(self, stack, link, link_url=None, link_item=None,
-                            link_args=u'', external_link_url=None, alt_text=u''):
+                         link_args=u'', external_link_url=None, alt_text=u''):
         """Handle all kinds of links."""
         link_text = ''
         link_args_list = []
@@ -635,7 +636,7 @@
         parsed_args = self.parse_args(link_args[1:])
         query = None
         if parsed_args.keyword:
-            query = url_encode(parsed_args.keyword, charset=config.charset, encode_keys=True)
+            query = url_encode(parsed_args.keyword, charset=CHARSET, encode_keys=True)
         # Take the last of positional parameters as link_text(caption)
         if parsed_args.positional:
             link_text = parsed_args.positional.pop()
@@ -654,7 +655,7 @@
                     if 'do' not in args:
                         # by default, we want the item's get url for transclusion of raw data:
                         args['do'] = 'get'
-                    query = url_encode(args, charset=config.charset, encode_keys=True)
+                    query = url_encode(args, charset=CHARSET, encode_keys=True)
                     target = Iri(scheme='wiki.local', path=object_item, query=query, fragment=None)
                     text = object_item
                 else:
@@ -721,8 +722,8 @@
     """
 
     def inline_nowiki_repl(self, stack, nowiki, nowiki_text=None,
-            nowiki_text_pre=None, pre_args='',
-            nowiki_text_code=None, nowiki_text_tt=None):
+                           nowiki_text_pre=None, pre_args='',
+                           nowiki_text_code=None, nowiki_text_tt=None):
         text = None
 
         if nowiki_text is not None:
@@ -765,8 +766,8 @@
         block_comment,
         block_head,
         block_separator,
-       # block_macro,
-       # block_nowiki,
+        # block_macro,
+        # block_nowiki,
         block_text,
     )
     block_re = re.compile('|'.join(block), re.X | re.U | re.M)
@@ -777,13 +778,13 @@
         inline_link,
         inline_breakline,
         inline_blockquote,
-        #inline_macro,
+        # inline_macro,
         inline_nowiki,
-        #inline_object,
+        # inline_object,
         inline_emphstrong,
         inline_comment,
         inline_footnote,
-        #inline_size,
+        # inline_size,
         inline_strike,
         inline_subscript,
         inline_superscript,
@@ -831,18 +832,18 @@
             's',
             'sub',
             'sup',
-            ]
+        ]
 
         nowiki_tags = [
             'pre',
             'code',
             'tt',
             'nowiki',
-            ]
+        ]
 
         block_tags = [
             'blockquote',
-            ]
+        ]
 
         def __init__(self):
             self.opened_tags = []
@@ -877,7 +878,7 @@
 
         def __call__(self, line, tags=[]):
             tags = tags or self.opened_tags
-            match = re.match(r"(.*?)(\<.*\>.*)|(.*)", line)
+            match = re.match(r"(.*?)(<.*>.*)|(.*)", line)
             if match:
                 pre_text = match.group(1) or match.group(3)
                 # text may be None
@@ -923,7 +924,8 @@
                                     close_tag = self.Preprocessor_tag()
                                     while tag_name != close_tag.tag_name:
                                         close_tag = tags.pop()
-                                        tmp_line = '<{0}>{1}{2}</{3}>'.format(close_tag.tag, ''.join(close_tag.text), tmp_line, close_tag.tag_name)
+                                        tmp_line = '<{0}>{1}{2}</{3}>'.format(
+                                            close_tag.tag, ''.join(close_tag.text), tmp_line, close_tag.tag_name)
                                         if not len(tags):
                                             post_line.append(tmp_line)
                                         else:
--- a/MoinMoin/converter/moinwiki19_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/moinwiki19_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -16,10 +16,12 @@
 from MoinMoin import log
 logging = log.getLogger(__name__)
 
-from MoinMoin import config, wikiutil
+from MoinMoin import wikiutil
+from MoinMoin.constants.misc import URI_SCHEMES
+from MoinMoin.constants.chartypes import CHARS_LOWER, CHARS_UPPER
 from MoinMoin.util.interwiki import is_known_wiki
 from MoinMoin.util.iri import Iri
-from MoinMoin.util.tree import html, moin_page, xlink
+from MoinMoin.util.tree import moin_page, xlink
 
 from .moinwiki_in import Converter
 
@@ -42,7 +44,7 @@
           )
           \:
           (?P<freelink_interwiki_page>
-           (?=\S*[%(u)s%(l)s0..9]\S* )  # make sure there is something non-blank with at least one alphanum letter following
+           (?=\S*[%(u)s%(l)s0..9]\S* )  # make sure there is something non-blank with at >= 1 alphanum letter following
            [^\s"\'}\]|:,.\)?!]+  # we take all until we hit some blank or punctuation char ...
           )
           |
@@ -74,15 +76,15 @@
           $  # ... or end of line
          )
     """ % {
-        'u': config.chars_upper,
-        'l': config.chars_lower,
+        'u': CHARS_UPPER,
+        'l': CHARS_LOWER,
         'child': re.escape(wikiutil.CHILD_PREFIX),
         'parent': re.escape(wikiutil.PARENT_PREFIX),
     }
 
     def inline_freelink_repl(self, stack, freelink, freelink_bang=None,
-            freelink_interwiki_page=None, freelink_interwiki_ref=None,
-            freelink_page=None, freelink_email=None):
+                             freelink_interwiki_page=None, freelink_interwiki_ref=None,
+                             freelink_page=None, freelink_email=None):
         if freelink_bang:
             stack.top_append(freelink)
             return
@@ -108,8 +110,8 @@
                 return
 
             link = Iri(scheme='wiki',
-                    authority=freelink_interwiki_ref,
-                    path='/' + freelink_interwiki_page)
+                       authority=freelink_interwiki_ref,
+                       path='/' + freelink_interwiki_page)
             text = freelink_interwiki_page
 
         attrib[xlink.href] = link
@@ -143,7 +145,7 @@
                 )
             )
         )
-    """ % dict(uri_schemes='|'.join(config.uri_schemes))
+    """ % dict(uri_schemes='|'.join(URI_SCHEMES))
 
     def inline_url_repl(self, stack, url, url_target):
         url = Iri(url_target)
--- a/MoinMoin/converter/moinwiki_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/moinwiki_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -18,9 +18,10 @@
 from MoinMoin import log
 logging = log.getLogger(__name__)
 
-from MoinMoin import config
+from MoinMoin.constants.contenttypes import CHARSET
+from MoinMoin.constants.misc import URI_SCHEMES
 from MoinMoin.util.iri import Iri
-from MoinMoin.util.tree import html, moin_page, xlink, xinclude
+from MoinMoin.util.tree import moin_page, xlink, xinclude
 from MoinMoin.util.interwiki import is_known_wiki
 from MoinMoin.i18n import _
 
@@ -260,8 +261,8 @@
             yield line
 
     def block_nowiki_repl(self, iter_content, stack, nowiki, nowiki_marker,
-            nowiki_interpret=None, nowiki_name=None, nowiki_args=None,
-            nowiki_args_old=None):
+                          nowiki_interpret=None, nowiki_name=None, nowiki_args=None,
+                          nowiki_args_old=None):
         stack.clear()
 
         nowiki_marker_len = len(nowiki_marker)
@@ -405,11 +406,11 @@
             yield match.group('text')
 
     def indent_repl(self, iter_content, stack, line,
-            indent, text, list_begin=None, list_definition=None,
-            list_definition_text=None, list_numbers=None,
-            list_alpha=None, list_roman=None, list_bullet=None,
-            list_start_number=None, list_start_roman=None, list_start_alpha=None,
-            list_none=None):
+                    indent, text, list_begin=None, list_definition=None,
+                    list_definition_text=None, list_numbers=None,
+                    list_alpha=None, list_roman=None, list_bullet=None,
+                    list_start_number=None, list_start_roman=None, list_start_alpha=None,
+                    list_none=None):
 
         level = len(indent)
 
@@ -694,17 +695,17 @@
             )?
             \]\]
         )
-    """ % dict(uri_schemes='|'.join(config.uri_schemes))
+    """ % dict(uri_schemes='|'.join(URI_SCHEMES))
 
     def inline_link_repl(self, stack, link, link_url=None, link_item=None,
-            link_text=None, link_args=None,
-            link_interwiki_site=None, link_interwiki_item=None):
+                         link_text=None, link_args=None,
+                         link_interwiki_site=None, link_interwiki_item=None):
         """Handle all kinds of links."""
         if link_interwiki_site:
             if is_known_wiki(link_interwiki_site):
                 link = Iri(scheme='wiki',
-                        authority=link_interwiki_site,
-                        path='/' + link_interwiki_item)
+                           authority=link_interwiki_site,
+                           path='/' + link_interwiki_item)
                 element = moin_page.a(attrib={xlink.href: link})
                 stack.push(element)
                 if link_text:
@@ -717,14 +718,14 @@
                 # assume local language uses ":" inside of words, set link_item and continue
                 link_item = '{0}:{1}'.format(link_interwiki_site, link_interwiki_item)
         if link_args:
-            link_args = parse_arguments(link_args) # XXX needs different parsing
-            query = url_encode(link_args.keyword, charset=config.charset, encode_keys=True)
+            link_args = parse_arguments(link_args)  # XXX needs different parsing
+            query = url_encode(link_args.keyword, charset=CHARSET, encode_keys=True)
         else:
             query = None
         if link_item is not None:
-            att = 'attachment:' # moin 1.9 needed this for an attached file
+            att = 'attachment:'  # moin 1.9 needed this for an attached file
             if link_item.startswith(att):
-                link_item = '/' + link_item[len(att):] # now we have a subitem
+                link_item = '/' + link_item[len(att):]  # now we have a subitem
             if '#' in link_item:
                 path, fragment = link_item.rsplit('#', 1)
             else:
@@ -782,8 +783,7 @@
         )
     """
 
-    def inline_nowiki_repl(self, stack, nowiki, nowiki_text=None,
-            nowiki_text_backtick=None):
+    def inline_nowiki_repl(self, stack, nowiki, nowiki_text=None, nowiki_text_backtick=None):
         text = None
         if nowiki_text is not None:
             text = nowiki_text
@@ -829,14 +829,14 @@
                            object_text=None, object_args=None):
         """Handles objects included in the page."""
         if object_args:
-            args = parse_arguments(object_args).keyword # XXX needs different parsing
+            args = parse_arguments(object_args).keyword  # XXX needs different parsing
         else:
             args = {}
         if object_item is not None:
-            query = url_encode(args, charset=config.charset, encode_keys=True)
-            att = 'attachment:' # moin 1.9 needed this for an attached file
+            query = url_encode(args, charset=CHARSET, encode_keys=True)
+            att = 'attachment:'  # moin 1.9 needed this for an attached file
             if object_item.startswith(att):
-                object_item = '/' + object_item[len(att):] # now we have a subitem
+                object_item = '/' + object_item[len(att):]  # now we have a subitem
             target = Iri(scheme='wiki.local', path=object_item, query=query, fragment=None)
             text = object_item
 
@@ -887,7 +887,7 @@
         def add_attr_to_style(attrib, attr):
             attr = attr.strip().decode('unicode-escape')
             if not attr.endswith(';'):
-                attr = attr + ';'
+                attr += ';'
             if attrib.get(moin_page('style'), ""):
                 attrib[moin_page('style')] = attrib.get(moin_page('style'), "") + " " + attr
             else:
@@ -949,7 +949,8 @@
                     cell_markup = cell_markup.split('<')[1]
                     msg1 = _('Error:')
                     msg2 = _('is invalid within')
-                    cell_text = '[ {0} "{1}" {2} <{3}>&nbsp;]<<BR>>{4}'.format(msg1, error, msg2, cell_markup, cell_text)
+                    cell_text = '[ {0} "{1}" {2} <{3}>&nbsp;]<<BR>>{4}'.format(
+                        msg1, error, msg2, cell_markup, cell_text)
                     if no_errors:
                         add_attr_to_style(element.attrib, 'background-color: pink; color: black;')
                     no_errors = False
--- a/MoinMoin/converter/moinwiki_out.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/moinwiki_out.py	Wed Mar 20 01:25:01 2013 +0100
@@ -29,8 +29,8 @@
     a_open = u'[['
     a_separator = u'|'
     a_close = u']]'
-    verbatim_open = u'{' # * 3
-    verbatim_close = u'}'# * 3
+    verbatim_open = u'{'  # * 3
+    verbatim_close = u'}'  # * 3
     monospace = u'`'
     strong = u"'''"
     emphasis = u"''"
@@ -58,7 +58,7 @@
         (u'ordered', u'upper-roman'): u'I.',
         (u'unordered', None): u'*',
         (None, None): u'::',
-        }
+    }
 
     def __init__(self):
         pass
@@ -73,29 +73,31 @@
 
     supported_tag = {
         'moinpage': (
-                'a',
-                'blockcode',
-                'break_line',
-                'code',
-                'div',
-                'emphasis',
-                'h',
-                'list',
-                'list_item',
-                'list_item_label',
-                'list_item_body',
-                'p',
-                'page',
-                'separator',
-                'span',
-                'strong',
-                'object',
-                'table',
-                'table_header',
-                'teble_footer',
-                'table_body',
-                'table_row',
-                'table_cell')}
+            'a',
+            'blockcode',
+            'break_line',
+            'code',
+            'div',
+            'emphasis',
+            'h',
+            'list',
+            'list_item',
+            'list_item_label',
+            'list_item_body',
+            'p',
+            'page',
+            'separator',
+            'span',
+            'strong',
+            'object',
+            'table',
+            'table_header',
+            'teble_footer',
+            'table_body',
+            'table_row',
+            'table_cell',
+        )
+    }
 
     @classmethod
     def factory(cls, input, output, **kw):
@@ -182,7 +184,7 @@
         args = u''
         if len(href) > 1:
             # With normal
-            args = u','.join([u'&'+s for s in findall(r'(?:^|;|,|&|)(\w+=\w+)(?:,|&|$|)', href[1])])
+            args = u','.join([u'&' + s for s in findall(r'(?:^|;|,|&|)(\w+=\w+)(?:,|&|$|)', href[1])])
         href = href[0].split(u'wiki.local:')[-1]
         args = u','.join(s for s in [args, params] if s)
 
@@ -204,7 +206,8 @@
         for s in findall(r'}+', text):
             if max_subpage_lvl <= len(s):
                 max_subpage_lvl = len(s) + 1
-        ret = u'{0}\n{1}\n{2}\n'.format(Moinwiki.verbatim_open * max_subpage_lvl, text, Moinwiki.verbatim_close * max_subpage_lvl)
+        ret = u'{0}\n{1}\n{2}\n'.format(
+            Moinwiki.verbatim_open * max_subpage_lvl, text, Moinwiki.verbatim_close * max_subpage_lvl)
         return ret
 
     def open_moinpage_code(self, elem):
@@ -239,8 +242,7 @@
         return Moinwiki.linebreak
 
     def open_moinpage_list(self, elem):
-        label_type = (elem.get(moin_page.item_label_generate, None),
-                        elem.get(moin_page.list_style_type, None))
+        label_type = elem.get(moin_page.item_label_generate, None), elem.get(moin_page.list_style_type, None)
         self.list_item_labels.append(
             Moinwiki.list_type.get(label_type, u''))
         self.list_level += 1
@@ -268,7 +270,8 @@
         if self.list_item_labels[-1] == u'' or self.list_item_labels[-1] == Moinwiki.definition_list_marker:
             self.list_item_labels[-1] = Moinwiki.definition_list_marker
             self.list_item_label = self.list_item_labels[-1] + u' '
-            ret = u' ' * (len(u''.join(self.list_item_labels[:-1])) + len(self.list_item_labels[:-1]))# self.list_level
+            ret = u' ' * (len(u''.join(self.list_item_labels[:-1])) +
+                          len(self.list_item_labels[:-1]))  # self.list_level
             if self.last_closed:
                 ret = u'\n{0}'.format(ret)
         childrens_output = self.open_children(elem)
@@ -278,7 +281,8 @@
         ret = u''
         if self.last_closed:
             ret = u'\n'
-        ret += u' ' * (len(u''.join(self.list_item_labels[:-1])) + len(self.list_item_labels[:-1])) + self.list_item_label
+        ret += u' ' * (len(u''.join(self.list_item_labels[:-1])) +
+                       len(self.list_item_labels[:-1])) + self.list_item_label
         return ret + self.open_children(elem)
 
     def open_moinpage_note(self, elem):
@@ -300,7 +304,7 @@
         href = href.split(u'?')
         args = u''
         if len(href) > 1:
-            args =u' '.join([s for s in findall(r'(?:^|;|,|&|)(\w+=\w+)(?:,|&|$)', href[1]) if s[:3] != u'do='])
+            args = u' '.join([s for s in findall(r'(?:^|;|,|&|)(\w+=\w+)(?:,|&|$)', href[1]) if s[:3] != u'do='])
         href = href[0].split(u'wiki.local:')[-1]
         # TODO: add '|' to Moinwiki class and rewrite this using % formatting
         ret = Moinwiki.object_open
@@ -324,16 +328,14 @@
             else:
                 ret = self.open_children(elem) + Moinwiki.p
         elif self.status[-2] == 'table':
-            if self.last_closed and self.last_closed != 'table_cell'\
-                                and self.last_closed != 'table_row':
+            if self.last_closed and self.last_closed != 'table_cell' and self.last_closed != 'table_row':
                 ret = Moinwiki.linebreak + self.open_children(elem)
             else:
                 ret = self.open_children(elem)
         elif self.status[-2] == 'list':
-            if self.last_closed and self.last_closed != 'list_item'\
-                                and self.last_closed != 'list_item_header'\
-                                and self.last_closed != 'list_item_footer'\
-                                and self.last_closed != 'list_item_label':
+            if self.last_closed and (
+                self.last_closed != 'list_item' and self.last_closed != 'list_item_header' and
+                self.last_closed != 'list_item_footer' and self.last_closed != 'list_item_label'):
                 ret = Moinwiki.linebreak + self.open_children(elem)
             else:
                 ret = self.open_children(elem)
@@ -354,7 +356,10 @@
             for s in findall(r'}+', childrens_output):
                 if max_subpage_lvl <= len(s):
                     max_subpage_lvl = len(s) + 1
-            return u'{0}{1}{2}{3}\n'.format(Moinwiki.verbatim_open * max_subpage_lvl, ret, childrens_output, Moinwiki.verbatim_close * max_subpage_lvl)
+            return u'{0}{1}{2}{3}\n'.format(
+                Moinwiki.verbatim_open * max_subpage_lvl,
+                ret, childrens_output,
+                Moinwiki.verbatim_close * max_subpage_lvl)
 
         self.status.append('text')
         childrens_output = self.open_children(elem)
@@ -377,7 +382,9 @@
         if len(type) == 2:
             if type[0] == "x-moin/macro":
                 if len(elem) and iter(elem).next().tag.name == "arguments":
-                    return u"<<{0}({1})>>\n".format(type[1].split(u'=')[1], u','.join([u''.join(c.itertext()) for c in iter(elem).next() if c.tag.name == u"argument"]))
+                    return u"<<{0}({1})>>\n".format(
+                        type[1].split(u'=')[1],
+                        u','.join([u''.join(c.itertext()) for c in iter(elem).next() if c.tag.name == u"argument"]))
                 else:
                     return u"<<{0}()>>\n".format(type[1].split(u'=')[1])
             elif type[0] == "x-moin/format":
@@ -406,7 +413,7 @@
         if hr_class:
             try:
                 height = int(hr_class.split(hr_class_prefix)[1]) - 1
-                if (0 <= height <= 5):
+                if 0 <= height <= 5:
                     hr_ending = (u'-' * height) + hr_ending
             except:
                 raise ElementException('page:separator has invalid class {0}'.format(hr_class))
@@ -422,11 +429,10 @@
         if text_decoration == u'underline':
             return Moinwiki.underline + self.open_children(elem) + Moinwiki.underline
         if font_size:
-            return u"{0}{1}{2}".format(Moinwiki.larger_open if font_size == u"120%"
-                                           else Moinwiki.smaller_open,
-                                       self.open_children(elem),
-                                       Moinwiki.larger_close if font_size == u"120%"
-                                           else Moinwiki.smaller_close)
+            return u"{0}{1}{2}".format(
+                Moinwiki.larger_open if font_size == u"120%" else Moinwiki.smaller_open,
+                self.open_children(elem),
+                Moinwiki.larger_close if font_size == u"120%" else Moinwiki.smaller_close)
         if baseline_shift == u'super':
             return u'^{0}^'.format(u''.join(elem.itertext()))
         if baseline_shift == u'sub':
@@ -502,7 +508,7 @@
         if table_cellstyle:
             attrib.append(u'style="{0}"'.format(table_cellstyle))
         if number_rows_spanned:
-            attrib.append(u'|'+unicode(number_rows_spanned))
+            attrib.append(u'|' + unicode(number_rows_spanned))
 
         attrib = u' '.join(attrib)
 
--- a/MoinMoin/converter/nonexistent_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/nonexistent_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -27,7 +27,7 @@
     def __call__(self, rev, contenttype=None, arguments=None):
         item_name = rev.item.name
         attrib = {
-            xlink.href: Iri(scheme='wiki', authority='', path='/'+item_name, query='do=modify'),
+            xlink.href: Iri(scheme='wiki', authority='', path='/' + item_name, query='do=modify'),
         }
         a = moin_page.a(attrib=attrib, children=[_("%(item_name)s does not exist. Create it?", item_name=item_name)])
         body = moin_page.body(children=(a, ))
--- a/MoinMoin/converter/pdf_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/pdf_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -20,7 +20,8 @@
 
 
 LAPARAMS = LAParams(
-    # value is specified not as an actual length, but as a proportion of the length to the size of each character in question.
+    # value is specified not as an actual length, but as a proportion of the length to the
+    # size of each character in question.
     # two text chunks whose distance is closer than the char_margin is considered
     # continuous and get grouped into one.
     char_margin=0.3,
--- a/MoinMoin/converter/pygments_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/pygments_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -97,7 +97,8 @@
             """
             if lexer is None and contenttype is not None:
                 ct = Type(contenttype)
-                mimetype = '{0}/{1}'.format(ct.type, ct.subtype) # pygments can't process parameters (like e.g. ...;charset=utf-8)
+                # pygments can't process parameters (like e.g. ...;charset=utf-8):
+                mimetype = '{0}/{1}'.format(ct.type, ct.subtype)
                 try:
                     lexer = pygments.lexers.get_lexer_for_mimetype(mimetype)
                 except pygments.util.ClassNotFound:
@@ -121,7 +122,7 @@
 else:
     # we have no Pygments, minimal Converter replacement, so highlight view does not crash
     class Converter(object):
-        def __init__(self, lexer=None, mimetype=None):
+        def __init__(self, lexer=None, contenttype=None):
             pass
 
         def __call__(self, content, arguments=None):
--- a/MoinMoin/converter/rst_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/rst_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -147,7 +147,7 @@
 
     def visit_bullet_list(self, node):
         self.open_moin_page_node(moin_page.list(
-                        attrib={moin_page.item_label_generate: u'unordered'}))
+            attrib={moin_page.item_label_generate: u'unordered'}))
 
     def depart_bullet_list(self, node):
         self.close_moin_page_node()
@@ -233,23 +233,25 @@
         new_element = moin_page.table_cell()
         if 'morerows' in node.attributes:
             new_element.set(moin_page.number_rows_spanned,
-                            repr(int(node['morerows'])+1))
+                            repr(int(node['morerows']) + 1))
         if 'morecols' in node.attributes:
             new_element.set(moin_page.number_cols_spanned,
-                            repr(int(node['morecols'])+1))
+                            repr(int(node['morecols']) + 1))
         self.open_moin_page_node(new_element)
 
     def depart_entry(self, node):
         self.close_moin_page_node()
 
     def visit_enumerated_list(self, node):
-        enum_style = {'arabic': None,
-                'loweralpha': u'lower-alpha',
-                'upperalpha': u'upper-alpha',
-                'lowerroman': u'lower-roman',
-                'upperroman': u'upper-roman'}
+        enum_style = {
+            'arabic': None,
+            'loweralpha': u'lower-alpha',
+            'upperalpha': u'upper-alpha',
+            'lowerroman': u'lower-roman',
+            'upperroman': u'upper-roman',
+        }
         new_node = moin_page.list(
-                attrib={moin_page.item_label_generate: u'ordered'})
+            attrib={moin_page.item_label_generate: u'ordered'})
         type = enum_style.get(node['enumtype'], None)
         if type:
             new_node.set(moin_page.list_style_type, type)
@@ -307,7 +309,7 @@
 
     def visit_footnote_reference(self, node):
         self.open_moin_page_node(moin_page.note(
-                            attrib={moin_page.note_class: u'footnote'}))
+            attrib={moin_page.note_class: u'footnote'}))
         new_footnote = moin_page.note_body()
         self.open_moin_page_node(new_footnote)
         self.footnotes[node.children[-1]] = new_footnote
@@ -398,7 +400,9 @@
             for name, value in named_args:
                 args.append(moin_page.argument(attrib={moin_page.name: name}, children=[value]))
             arguments = moin_page.arguments(children=args)
-            self.open_moin_page_node(moin_page.part(children=[arguments], attrib={moin_page.content_type: "x-moin/format;name={0}".format(parser.split(' ')[0])}))
+            self.open_moin_page_node(moin_page.part(
+                children=[arguments],
+                attrib={moin_page.content_type: "x-moin/format;name={0}".format(parser.split(' ')[0])}))
         else:
             self.open_moin_page_node(moin_page.blockcode())
 
@@ -428,7 +432,7 @@
 
     def visit_reference(self, node):
         refuri = node.get('refuri', u'')
-        if refuri.startswith(u'<<') and refuri.endswith(u'>>'): # moin macro
+        if refuri.startswith(u'<<') and refuri.endswith(u'>>'):  # moin macro
             macro_name = refuri[2:-2].split(u'(')[0]
             if macro_name == u"TableOfContents":
                 arguments = refuri[2:-2].split(u'(')[1][:-1].split(u',')
@@ -440,9 +444,7 @@
             arguments = refuri[2:-2].split(u'(')[1][:-1].split(u',')
             self.open_moin_page_node(
                 moin_page.part(
-                    attrib={
-                        moin_page.content_type:
-                            "x-moin/macro;name={0}".format(macro_name)}))
+                    attrib={moin_page.content_type: "x-moin/macro;name={0}".format(macro_name)}))
             if arguments:
                 self.open_moin_page_node(moin_page.arguments())
                 for i in arguments:
@@ -615,15 +617,15 @@
 
 class Writer(writers.Writer):
 
-    supported = ('moin-x-document')
+    supported = ('moin-x-document', )
     config_section = 'MoinMoin writer'
     config_section_dependencies = ('writers', )
     output = None
     visitor_attributes = []
 
     def translate(self):
-        self.visitor = visitor = NodeVisitor(self.document)
-        self.document.walkabout(visitor)
+        self.visitor = visitor = NodeVisitor()
+        walkabout(self.document, visitor)
         self.output = visitor.tree()
 
 
@@ -695,8 +697,7 @@
     # reference hack (`<<SomeMacro>>`_). This however simply adds a node to the
     # document tree which is a reference, but through a much better user
     # interface.
-    def macro(self, name, arguments, options, content, lineno,
-                content_offset, block_text, state, state_machine):
+    def macro(self, name, arguments, options, content, lineno, content_offset, block_text, state, state_machine):
         # content contains macro to be called
         if len(content):
             # Allow either with or without brackets
@@ -714,8 +715,7 @@
     macro.required_arguments = 1
     macro.optional_arguments = 0
 
-    def table_of_content(self, name, arguments, options, content, lineno,
-                            content_offset, block_text, state, state_machine):
+    def table_of_content(self, name, arguments, options, content, lineno, content_offset, block_text, state, state_machine):
         text = ''
         for i in content:
             m = re.search(r':(\w+): (\w+)', i)
@@ -732,8 +732,7 @@
     table_of_content.required_arguments = 1
     table_of_content.optional_arguments = 0
 
-    def parser(self, name, arguments, options, content, lineo,
-                content_offset, block_text, state, state_machine):
+    def parser(self, name, arguments, options, content, lineo, content_offset, block_text, state, state_machine):
         block = literal_block()
         block['parser'] = content[0]
         block.children = [nodes.Text(u"\n".join(content[1:]))]
@@ -759,12 +758,21 @@
             try:
                 docutils_tree = core.publish_doctree(source=input)
             except utils.SystemMessage as inst:
-                string_numb = re.match(re.compile(r'<string>\:([0-9]*)\:\s*\(.*?\)\s*(.*)', re.X | re.U | re.M | re.S), str(inst))
+                string_numb = re.match(re.compile(r'<string>:([0-9]*):\s*\(.*?\)\s*(.*)',
+                                                  re.X | re.U | re.M | re.S), str(inst))
                 if string_numb:
                     str_num = string_numb.group(1)
                     input = input.split('\n')
                     if str_num:
-                        input = ['.. error::\n ::\n\n  Parse error on line number {0}:\n\n  {1}\n\n  Go back and try fix that.\n\n'.format(str_num, string_numb.group(2).replace('\n', '\n  '))]
+                        input = [('.. error::\n'
+                                  ' ::\n'
+                                  '\n'
+                                  '  Parse error on line number {0}:\n'
+                                  '\n'
+                                  '  {1}\n'
+                                  '\n'
+                                  '  Go back and try fix that.\n'
+                                  '\n').format(str_num, string_numb.group(2).replace('\n', '\n  '))]
                         continue
                 else:
                     input = ['.. error::\n ::\n\n  {0}\n\n'.format(str(inst).replace('\n', '\n  '))]
--- a/MoinMoin/converter/rst_out.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/rst_out.py	Wed Mar 20 01:25:01 2013 +0100
@@ -65,9 +65,8 @@
         self.j = 0
         self.table.append(row)
         if self.i > 0:
-            if len(self.table[-2]) > (self.j):
-                self.add_cell(self.table[-2][self.j][0],
-                                self.table[-2][self.j][1] - 1, Cell(''))
+            if len(self.table[-2]) > self.j:
+                self.add_cell(self.table[-2][self.j][0], self.table[-2][self.j][1] - 1, Cell(''))
         return row
 
     def end_row(self):
@@ -92,13 +91,12 @@
         if cs < 1 or rs < 1:
             return
         self.table[-1].append((cs, rs, cell))
-        for i in range(cs-1):
-            self.table[-1].append((cs-i-1, rs, Cell('')))
+        for i in range(cs - 1):
+            self.table[-1].append((cs - i - 1, rs, Cell('')))
         self.j += cs
         if self.i > 0:
             if len(self.table[-2]) > self.j:
-                self.add_cell(self.table[-2][self.j][0],
-                                self.table[-2][self.j][1] - 1, Cell(''))
+                self.add_cell(self.table[-2][self.j][0], self.table[-2][self.j][1] - 1, Cell(''))
         return
 
     def height(self):
@@ -166,7 +164,7 @@
             line = [u'+']
             row = self.table[0]
             for col in range(len(cols)):
-                line.append(u'-'*cols[col])
+                line.append(u'-' * cols[col])
                 if self.table[0][col][0] > 1:
                     line.append(u'-')
                 else:
@@ -192,11 +190,11 @@
                 line = [u'+']
                 for col in range(len(cols)):
                     if self.table[row][col][1] > 1:
-                        line.append(u' '*cols[col])
+                        line.append(u' ' * cols[col])
                     elif row == self.header_count - 1:
-                        line.append(u'='*cols[col])
+                        line.append(u'=' * cols[col])
                     else:
-                        line.append(u'-'*cols[col])
+                        line.append(u'-' * cols[col])
                     if self.table[row][col][0] > 1:
                         if row + 1 < len(rows)\
                                 and self.table[row + 1][col][0] > 1\
@@ -233,7 +231,7 @@
         (u'ordered', u'upper-roman'): u'I.',
         (u'unordered', None): u'*',
         (None, None): u' ',
-        }
+    }
 
 
 class Converter(object):
@@ -245,29 +243,31 @@
 
     supported_tag = {
         'moinpage': (
-                'a',
-                'blockcode',
-                'break_line',
-                'code',
-                'div',
-                'emphasis',
-                'h',
-                'list',
-                'list_item',
-                'list_item_label',
-                'list_item_body',
-                'p',
-                'page',
-                'separator',
-                'span',
-                'strong',
-                'object',
-                'table',
-                'table_header',
-                'teble_footer',
-                'table_body',
-                'table_row',
-                'table_cell')}
+            'a',
+            'blockcode',
+            'break_line',
+            'code',
+            'div',
+            'emphasis',
+            'h',
+            'list',
+            'list_item',
+            'list_item_label',
+            'list_item_body',
+            'p',
+            'page',
+            'separator',
+            'span',
+            'strong',
+            'object',
+            'table',
+            'table_header',
+            'teble_footer',
+            'table_body',
+            'table_row',
+            'table_cell',
+        )
+    }
 
     @classmethod
     def factory(cls, input, output, **kw):
@@ -334,19 +334,21 @@
                         childrens_output.append(u'\n\n')
                 elif self.status[-1] == "list":
                     child =\
-                        re.sub(r"\n(.)", lambda m: u"\n{0}{1}".format(u' '*(len(u''.join(self.list_item_labels)) + len(self.list_item_labels)), m.group(1)), child)
+                        re.sub(r"\n(.)", lambda m: u"\n{0}{1}".format(
+                            u' ' * (len(u''.join(self.list_item_labels)) + len(self.list_item_labels)), m.group(1)), child)
                     if self.last_closed == "p":
-                        childrens_output.append(u'\n'
-                                + u' '
-                                * (len(''.join(self.list_item_labels))
-                                   + len(self.list_item_labels)))
+                        childrens_output.append(
+                            u'\n' + u' '
+                            * (len(''.join(self.list_item_labels)) +
+                               len(self.list_item_labels)))
                 elif self.status[-1] == "text":
                     if self.last_closed == "p":
                         childrens_output.append(self.define_references())
                         childrens_output.append(u'\n')
                 elif self.status[-2] == "list":
                     child =\
-                        re.sub(r"\n(.)", lambda m: u"\n{0}{1}".format(u' '*(len(u''.join(self.list_item_labels)) + len(self.list_item_labels)), m.group(1)), child)
+                        re.sub(r"\n(.)", lambda m: u"\n{0}{1}".format(u' ' *
+                               (len(u''.join(self.list_item_labels)) + len(self.list_item_labels)), m.group(1)), child)
                 childrens_output.append(child)
                 self.last_closed = 'text'
         self.delete_newlines = delete_newlines
@@ -384,7 +386,7 @@
                 return u"`{0}`__".format(text)
             else:
                 while text in [t for (t, h) in self.all_used_references]:
-                    text = text + u"~"
+                    text += u"~"
         self.used_references.append((text, href))
         self.all_used_references.append((text, href))
         #self.objects.append("\n\n.. _%s: %s\n\n" % (text, href))
@@ -394,8 +396,7 @@
         text = u''.join(elem.itertext())
         max_subpage_lvl = 3
         text = text.replace(u'\n', u'\n  '
-                                  + u' ' * (len(u''.join(self.list_item_labels))
-                                         + len(self.list_item_labels)))
+                            + u' ' * (len(u''.join(self.list_item_labels)) + len(self.list_item_labels)))
 
         if self.list_level >= 0:
             self.delete_newlines = True
@@ -408,7 +409,8 @@
                 if i:
                     self.output[-1] = self.output[-1][:i]
             """
-        return u"::\n\n  {0}{1}\n\n".format(u' ' * (len(u''.join(self.list_item_labels)) + len(self.list_item_labels)), text)
+        return u"::\n\n  {0}{1}\n\n".format(
+            u' ' * (len(u''.join(self.list_item_labels)) + len(self.list_item_labels)), text)
 
     def open_moinpage_code(self, elem):
         ret = u"{0}{1}{2}".format(ReST.monospace, u''.join(elem.itertext()), ReST.monospace)
@@ -443,8 +445,7 @@
         return ReST.linebreak
 
     def open_moinpage_list(self, elem):
-        label_type = (elem.get(moin_page.item_label_generate, None),
-                        elem.get(moin_page.list_style_type, None))
+        label_type = elem.get(moin_page.item_label_generate, None), elem.get(moin_page.list_style_type, None)
         self.list_item_labels.append(
             ReST.list_type.get(label_type, u' '))
         self.list_level += 1
@@ -485,7 +486,7 @@
         if self.last_closed:
             ret = u'\n'
         ret += (u' ' * (len(u''.join(self.list_item_labels[:-1]))
-                       + len(self.list_item_labels[:-1]))
+                        + len(self.list_item_labels[:-1]))
                 + self.list_item_label)
         if self.list_item_labels[-1] in [u'1.', u'i.', u'I.', u'a.', u'A.']:
             self.list_item_labels[-1] = u'#.'
@@ -510,8 +511,7 @@
         href = href.split(u'?')
         args = u''
         if len(href) > 1:
-            args =[s for s in re.findall(r'(?:^|;|,|&|)(\w+=\w+)(?:,|&|$)',
-                                            href[1]) if s[:3] != u'do=']
+            args = [s for s in re.findall(r'(?:^|;|,|&|)(\w+=\w+)(?:,|&|$)', href[1]) if s[:3] != u'do=']
         href = href[0]
         alt = elem.get(moin_page.alt, u'')
         if not alt:
@@ -520,7 +520,8 @@
             ret = u'|{0}|'.format(alt)
         args_text = u''
         if args:
-            args_text = u"\n  {0}".format(u'\n  '.join(u':{0}: {1}'.format(arg.split(u'=')[0], arg.split(u'=')[1]) for arg in args))
+            args_text = u"\n  {0}".format(u'\n  '.join(u':{0}: {1}'.format(
+                arg.split(u'=')[0], arg.split(u'=')[1]) for arg in args))
         self.objects.append(u".. {0} image:: {1}{2}".format(ret, href, args_text))
         return ret
 
@@ -537,13 +538,13 @@
                 ret = self.open_children(elem) + ReST.p + set
         elif self.status[-1] == 'table':
             self.status.append('p')
-            if self.last_closed and self.last_closed != 'table_cell'\
-                                and self.last_closed != 'table_row'\
-                                and self.last_closed != 'table_header'\
-                                and self.last_closed != 'table_footer'\
-                                and self.last_closed != 'table_body'\
-                                and self.last_closed != 'line_break':
-          #                      and self.last_closed != 'p':
+            if self.last_closed and self.last_closed != 'table_cell' \
+                and self.last_closed != 'table_row' \
+                and self.last_closed != 'table_header' \
+                and self.last_closed != 'table_footer' \
+                and self.last_closed != 'table_body' \
+                and self.last_closed != 'line_break':
+                # and self.last_closed != 'p':
                 ret = ReST.linebreak + self.open_children(elem)
             elif self.last_closed == 'p' or self.last_closed == 'line_break':
                 ret = self.open_children(elem)
@@ -553,17 +554,17 @@
             self.status.append('p')
             if self.last_closed and self.last_closed == 'list_item_label':
                 ret = self.open_children(elem)
-            elif self.last_closed and self.last_closed != 'list_item'\
-                                and self.last_closed != 'list_item_header'\
-                                and self.last_closed != 'list_item_footer'\
-                                and self.last_closed != 'p':
+            elif self.last_closed and self.last_closed != 'list_item' \
+                and self.last_closed != 'list_item_header' \
+                and self.last_closed != 'list_item_footer' \
+                and self.last_closed != 'p':
                 ret = (ReST.linebreak + u' '
                                         * (len(u''.join(self.list_item_labels))
                                            + len(self.list_item_labels)) + self.open_children(elem))
             elif self.last_closed and self.last_closed == 'p':
                 #return ReST.p +\
                 ret = (u"\n" + u' ' * (len(u''.join(self.list_item_labels))
-                                    + len(self.list_item_labels)) + self.open_children(elem))
+                                       + len(self.list_item_labels)) + self.open_children(elem))
             else:
                 ret = self.open_children(elem)
             if not self.delete_newlines:
@@ -586,7 +587,8 @@
         if len(type) == 2:
             if type[0] == u"x-moin/macro":
                 if len(elem) and iter(elem).next().tag.name == "arguments":
-                    alt = u"<<{0}({1})>>".format(type[1].split(u'=')[1], u','.join([u''.join(c.itertext()) for c in iter(elem).next() if c.tag.name == "argument"]))
+                    alt = u"<<{0}({1})>>".format(type[1].split(u'=')[1], u','.join(
+                        [u''.join(c.itertext()) for c in iter(elem).next() if c.tag.name == "argument"]))
                 else:
                     alt = u"<<{0}()>>".format(type[1].split(u'=')[1])
 
@@ -656,7 +658,8 @@
         table = repr(self.tablec)
         if self.status[-1] == "list":
             table =\
-                re.sub(r"\n(.)", lambda m: u"\n{0}{1}".format(u' '*(len(u''.join(self.list_item_labels)) + len(self.list_item_labels)), m.group(1)), u"\n" + table)
+                re.sub(r"\n(.)", lambda m: u"\n{0}{1}".format(
+                    u' ' * (len(u''.join(self.list_item_labels)) + len(self.list_item_labels)), m.group(1)), u"\n" + table)
             return table + ReST.p
         return table + ReST.linebreak
 
@@ -684,11 +687,9 @@
 
     def open_moinpage_table_row(self, elem):
         self.table_rowclass = elem.attrib.get('class', u'')
-        self.table_rowclass = u' '.join([s for s in [self.table_rowsclass,
-                                                    self.table_rowclass] if s])
+        self.table_rowclass = u' '.join([s for s in [self.table_rowsclass, self.table_rowclass] if s])
         self.table_rowstyle = elem.attrib.get('style', u'')
-        self.table_rowstyle = u' '.join([s for s in [self.table_rowsstyle,
-                                                    self.table_rowstyle] if s])
+        self.table_rowstyle = u' '.join([s for s in [self.table_rowsstyle, self.table_rowstyle] if s])
         self.table.append([])
         self.tablec.add_row()
         ret = self.open_children(elem)
@@ -700,10 +701,8 @@
     def open_moinpage_table_cell(self, elem):
         table_cellclass = elem.attrib.get('class', u'')
         table_cellstyle = elem.attrib.get('style', u'')
-        number_cols_spanned\
-                = int(elem.get(moin_page.number_cols_spanned, 1))
-        number_rows_spanned\
-                = int(elem.get(moin_page.number_rows_spanned, 1))
+        number_cols_spanned = int(elem.get(moin_page.number_cols_spanned, 1))
+        number_rows_spanned = int(elem.get(moin_page.number_rows_spanned, 1))
 
         attrib = []
 
@@ -730,9 +729,7 @@
 
         attrib = ' '.join(attrib)
         """
-        self.table[-1].append((number_cols_spanned,
-                                number_rows_spanned,
-                                [self.open_children(elem)]))
+        self.table[-1].append((number_cols_spanned, number_rows_spanned, [self.open_children(elem)]))
         cell = self.table[-1][-1]
         self.tablec.add_cell(cell[0], cell[1], Cell(u''.join(cell[2])))
         return u''
@@ -750,12 +747,10 @@
         """
         ret = u''
         self.all_used_references.extend(self.used_references)
-        definitions = [u" " * (len(u''.join(self.list_item_labels))
-                                    + len(self.list_item_labels))
-                                  + u".. _{0}: {1}".format(t, h) for t, h in self.used_references]
-        definitions.extend(u" " * (len(u''.join(self.list_item_labels))
-                                     + len(self.list_item_labels))
-                                  + link for link in self.objects)
+        definitions = [u" " * (len(u''.join(self.list_item_labels)) + len(self.list_item_labels))
+                       + u".. _{0}: {1}".format(t, h) for t, h in self.used_references]
+        definitions.extend(u" " * (len(u''.join(self.list_item_labels)) + len(self.list_item_labels))
+                           + link for link in self.objects)
         definition_block = u"\n\n".join(definitions)
 
         if definitions:
--- a/MoinMoin/converter/smiley.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/smiley.py	Wed Mar 20 01:25:01 2013 +0100
@@ -64,7 +64,7 @@
     ($|(?=\s))  # we require either ending of line or some space after a smiley
 """ % {'smiley': u'|'.join([re.escape(s) for s in smileys])}
 
-    smiley_re = re.compile(smiley_rule, re.UNICODE|re.VERBOSE)
+    smiley_re = re.compile(smiley_rule, re.UNICODE | re.VERBOSE)
 
     # We do not process any smiley conversion within these elements.
     tags_to_ignore = set(['code', 'blockcode', ])
--- a/MoinMoin/converter/xml_in.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/converter/xml_in.py	Wed Mar 20 01:25:01 2013 +0100
@@ -14,7 +14,8 @@
 
 from ._util import decode_data
 
-RX_STRIPXML = re.compile(u"<[^>]*?>", re.U|re.DOTALL|re.MULTILINE)
+RX_STRIPXML = re.compile(u"<[^>]*?>", re.U | re.DOTALL | re.MULTILINE)
+
 
 def strip_xml(text):
     text = RX_STRIPXML.sub(u" ", text)
--- a/MoinMoin/datastruct/backends/__init__.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/datastruct/backends/__init__.py	Wed Mar 20 01:25:01 2013 +0100
@@ -209,7 +209,8 @@
         else:
             groups = flaskg.groups
             for group_name in self.member_groups:
-                if group_name not in processed_groups and group_name in groups and groups[group_name].__contains__(member, processed_groups):
+                if (group_name not in processed_groups and group_name in groups and
+                        groups[group_name].__contains__(member, processed_groups)):
                     return True
 
         return False
@@ -250,7 +251,8 @@
                     yield group_name
 
     def __repr__(self):
-        return "<{0!r} name={1!r} members={2!r} member_groups={3!r}>".format(self.__class__, self.name, self.members, self.member_groups)
+        return "<{0!r} name={1!r} members={2!r} member_groups={3!r}>".format(
+            self.__class__, self.name, self.members, self.member_groups)
 
 
 class BaseDict(object, DictMixin):
--- a/MoinMoin/datastruct/backends/_tests/test_composite_groups.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/datastruct/backends/_tests/test_composite_groups.py	Wed Mar 20 01:25:01 2013 +0100
@@ -13,7 +13,6 @@
 from MoinMoin.datastruct.backends._tests import GroupsBackendTest
 from MoinMoin.datastruct import ConfigGroups, CompositeGroups, GroupDoesNotExistError
 from MoinMoin._tests import wikiconfig
-from MoinMoin import security
 
 
 class TestCompositeGroupsBackend(GroupsBackendTest):
--- a/MoinMoin/datastruct/backends/_tests/test_config_dicts.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/datastruct/backends/_tests/test_config_dicts.py	Wed Mar 20 01:25:01 2013 +0100
@@ -26,4 +26,5 @@
         for result in test_keyiterator:
             assert result in expected
 
+
 coverage_modules = ['MoinMoin.datastruct.backends.config_dicts']
--- a/MoinMoin/datastruct/backends/_tests/test_lazy_config_groups.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/datastruct/backends/_tests/test_lazy_config_groups.py	Wed Mar 20 01:25:01 2013 +0100
@@ -8,7 +8,7 @@
 
 from MoinMoin.datastruct.backends._tests import GroupsBackendTest
 from MoinMoin.datastruct.backends.config_lazy_groups import ConfigLazyGroups
-from MoinMoin.datastruct import ConfigGroups, CompositeGroups, GroupDoesNotExistError
+from MoinMoin.datastruct import ConfigGroups, CompositeGroups
 from MoinMoin._tests import wikiconfig
 
 
--- a/MoinMoin/datastruct/backends/_tests/test_wiki_dicts.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/datastruct/backends/_tests/test_wiki_dicts.py	Wed Mar 20 01:25:01 2013 +0100
@@ -11,8 +11,9 @@
 
 from MoinMoin.datastruct.backends._tests import DictsBackendTest
 from MoinMoin.datastruct.backends import wiki_dicts
-from MoinMoin.config import SOMEDICT
+from MoinMoin.constants.keys import SOMEDICT
 from MoinMoin._tests import become_trusted, update_item
+
 DATA = "This is a dict item."
 
 
@@ -40,4 +41,5 @@
         expected = {u'Two': u'2', u'One': u'1'}
         assert result == expected
 
+
 coverage_modules = ['MoinMoin.datastruct.backends.wiki_dicts']
--- a/MoinMoin/datastruct/backends/_tests/test_wiki_groups.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/datastruct/backends/_tests/test_wiki_groups.py	Wed Mar 20 01:25:01 2013 +0100
@@ -17,7 +17,7 @@
 
 from MoinMoin.datastruct.backends._tests import GroupsBackendTest
 from MoinMoin.datastruct import GroupDoesNotExistError
-from MoinMoin.config import NAME, USERGROUP
+from MoinMoin.constants.keys import NAME, USERGROUP
 from MoinMoin.security import AccessControlList
 from MoinMoin.user import User
 from MoinMoin._tests import become_trusted, create_random_string_list, update_item
@@ -106,4 +106,5 @@
         assert not has_rights_before, 'AnotherUser has no read rights because in the beginning he is not a member of a group item NewGroup'
         assert has_rights_after, 'AnotherUser must have read rights because after appenditem he is member of NewGroup'
 
+
 coverage_modules = ['MoinMoin.datastruct.backends.wiki_groups']
--- a/MoinMoin/datastruct/backends/wiki_dicts.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/datastruct/backends/wiki_dicts.py	Wed Mar 20 01:25:01 2013 +0100
@@ -11,7 +11,7 @@
 
 from flask import g as flaskg
 
-from MoinMoin.config import CURRENT, SOMEDICT
+from MoinMoin.constants.keys import CURRENT, SOMEDICT
 from MoinMoin.datastruct.backends import BaseDict, BaseDictsBackend, DictDoesNotExistError
 
 
--- a/MoinMoin/datastruct/backends/wiki_groups.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/datastruct/backends/wiki_groups.py	Wed Mar 20 01:25:01 2013 +0100
@@ -16,7 +16,7 @@
 
 from flask import g as flaskg
 
-from MoinMoin.config import CURRENT, USERGROUP
+from MoinMoin.constants.keys import CURRENT, USERGROUP
 from MoinMoin.datastruct.backends import GreedyGroup, BaseGroupsBackend, GroupDoesNotExistError
 
 
--- a/MoinMoin/error.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/error.py	Wed Mar 20 01:25:01 2013 +0100
@@ -10,7 +10,8 @@
 
 import sys
 
-from MoinMoin import config
+from MoinMoin.constants.contenttypes import CHARSET
+
 
 class Error(Exception):
     """ Base class for moin moin errors
@@ -20,11 +21,11 @@
 
     Standard errors work safely only with strings using ascii or
     unicode. This class can be used safely with both strings using
-    config.charset and unicode.
+    CHARSET and unicode.
 
     You can init this class with either unicode or string using
-    config.charset encoding. On output, the class will convert the string
-    to unicode or the unicode to string, using config.charset.
+    CHARSET encoding. On output, the class will convert the string
+    to unicode or the unicode to string, using CHARSET.
 
     When you want to render an error, use unicode() or str() as needed.
     """
@@ -33,21 +34,21 @@
         """ Initialize an error, decode if needed
 
         :param message: unicode, str or object that support __unicode__
-            and __str__. __str__ should use config.charset.
+            and __str__. __str__ should use CHARSET.
         """
         self.message = message
 
     def __unicode__(self):
         """ Return unicode error message """
         if isinstance(self.message, str):
-            return unicode(self.message, config.charset)
+            return unicode(self.message, CHARSET)
         else:
             return unicode(self.message)
 
     def __str__(self):
         """ Return encoded message """
         if isinstance(self.message, unicode):
-            return self.message.encode(config.charset)
+            return self.message.encode(CHARSET)
         else:
             return str(self.message)
 
@@ -94,14 +95,17 @@
                 break
         return all
 
+
 class FatalError(CompositeError):
     """ Base class for fatal error we can't handle
 
     Do not use this class but its more specific sub classes.
     """
 
+
 class ConfigurationError(FatalError):
     """ Raise when fatal misconfiguration is found """
 
+
 class InternalError(FatalError):
     """ Raise when internal fatal error is found """
--- a/MoinMoin/forms.py	Tue Mar 19 20:32:47 2013 +0100
+++ b/MoinMoin/forms.py	Wed Mar 20 01:25:01 2013 +0100
@@ -9,10 +9,13 @@
 """
 
 
-import re, datetime
+import re
+import datetime
 import json
+from operator import itemgetter
 
-from flatland import Element, Form, String, Integer, Boolean, Enum, Dict, JoinedString, List, Array, DateTime as _DateTime
+from flatland import (Element, Form, String, Integer, Boolean, Enum as BaseEnum, Dict, JoinedString, List, Array,
+                      DateTime as _DateTime)
 from flatland.util import class_cloner, Unspecified
 from flatland.validation import Validator, Present, IsEmail, ValueBetween, URLValidator, Converted, ValueAtLeast
 from flatland.exc import AdaptationError
@@ -22,10 +25,35 @@
 from MoinMoin.constants.forms import *
 from MoinMoin.constants.keys import ITEMID, NAME
 from MoinMoin.i18n import _, L_, N_
-from MoinMoin.security.textcha import TextCha, TextChaizedForm, TextChaValid
 from MoinMoin.util.forms import FileStorage
 
 
+class Enum(BaseEnum):
+    """
+    An Enum with a convenience class method out_of.
+    """
+    @classmethod
+    def out_of(cls, choice_specs, sort_by=None):
+        """
+        A convenience class method to build Enum with extra data attached to
+        each valid value.
+
+        :param choice_specs: An iterable of tuples. The elements are collected
+                             into the choice_specs property; the tuples' first
+                             elements become the valid values of the Enum. e.g.
+                             for choice_specs = [(v1, ...), (v2, ...), ... ],
+                             the valid values are v1, v2, ...
+
+        :param sort_by: If not None, sort choice_specs by the sort_by'th
+                        element.
+        """
+        if sort_by is not None:
+            choice_specs = sorted(choice_specs, key=itemgetter(sort_by))
+        else:
+            choice_specs = list(choice_specs)
+        return cls.valued(*[e[0] for e in choice_specs]).with_properties(choice_specs=choice_specs)
+
+
 Text = String.with_properties(widget=WIDGET_TEXT)
 
 MultilineText = String.with_properties(widget=WIDGET_MULTILINE_TEXT)
@@ -47,7 +75,7 @@
     def validate(self, element, state):
         try:
             json.loads(element.value)
-        except: # catch ANY exception that happens due to unserializing
+        except:  # catch ANY exception that happens due to unserializing
             return self.note_error(element, state, 'invalid_json_msg')
         return True
 
@@ -59,7 +87,8 @@
 
 YourOpenID = OpenID.with_properties(placeholder=L_("Your OpenID address"))
 
-Email = String.using(label=L_('E-Mail')).with_properties(widget=WIDGET_EMAIL, placeholder=L_("E-Mail address")).validated_by(IsEmail())
+Email = String.using(label=L_('E-Mail')).with_properties(widget=WIDGET_EMAIL,
+                                                         placeholder=L_("E-Mail address")).validated_by(IsEmail())
 
 YourEmail = Email.with_properties(placeholder=L_("Your E-Mail address"))
 
@@ -73,6 +102,15 @@
 
 Select = Enum.with_properties(widget=WIDGET_SELECT)
 
+# SelectSubmit is like Select in that it is rendered as a group of controls
+# with different (predefined) `value`s for the same `name`. But the controls are
+# submit buttons instead of radio buttons.
+#
+# This is used to present the user several "OK" buttons with slightly different
+# semantics, like "Update" and "Update and Close" on a ticket page, or
+# "Save as Draft" and "Publish" when editing a blog entry.
+SelectSubmit = Enum.with_properties(widget=WIDGET_SELECT_SUBMIT)
+
 
 # Need a better name to capture the behavior
 class MyJoinedString(JoinedString):
@@ -88,9 +126,11 @@
     def u(self):
         return self.separator.join(child.u for child in self)
 
-Tags = MyJoinedString.of(String).with_properties(widget=WIDGET_TEXT).using(label=L_('Tags'), optional=True, separator=', ', separator_regex=re.compile(r'\s*,\s*'))
+Tags = MyJoinedString.of(String).with_properties(widget=WIDGET_TEXT).using(
+    label=L_('Tags'), optional=True, separator=', ', separator_regex=re.compile(r'\s*,\s*'))
 
-Names = MyJoinedString.of(String).with_properties(widget=WIDGET_TEXT).using(label=L_('Names'), optional=True, separator=', ', separator_regex=re.compile(r'\s*,\s*'))
+Names = MyJoinedString.of(String).with_properties(widget=WIDGET_TEXT).using(
+    label=L_('Names'), optional=True, separator=', ', separator_regex=re.compile(r'\s*,\s*'))
 
 Search = Text.using(default=u'', optional=True).with_properties(widget=WIDGET_SEARCH, placeholder=L_("Search Query"))
 
@@ -138,13 +178,12 @@
             dt = utctimestamp(dt)
         return dt
 
-DateTime = (DateTimeUNIX.with_properties(widget=WIDGET_DATETIME, placeholder=_("YYYY-MM-DD HH:MM:SS (example: 2013-12-31 23:59:59)"))
+DateTime = (DateTimeUNIX.with_properties(widget=WIDGET_DATETIME,
+                                         placeholder=_("YYYY-MM-DD HH:MM:SS (example: 2013-12-31 23:59:59)"))
             .validated_by(Converted(incorrect=L_("Please use the following format: YYYY-MM-DD HH:MM:SS"))))
 
 File = FileStorage.with_properties(widget=WIDGET_FILE)
 
-Submit = String.usi