changeset 4516:f4e745c7f8e8

merged moin/1.8
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Thu, 29 Jan 2009 09:44:57 +0100
parents b1f78aafc581 (diff) 04f3cfbf446a (current diff)
children 47eee6dfcdec
files MoinMoin/__init__.py MoinMoin/action/fullsearch.py MoinMoin/config/multiconfig.py MoinMoin/i18n/__init__.py MoinMoin/search/builtin.py MoinMoin/security/antispam.py MoinMoin/version.py MoinMoin/wikiutil.py docs/CHANGES docs/INSTALL.html wiki/config/wikiconfig.py
diffstat 377 files changed, 42828 insertions(+), 8473 deletions(-) [+]
line wrap: on
line diff
--- a/MANIFEST.in	Wed Jan 28 17:06:22 2009 +0100
+++ b/MANIFEST.in	Thu Jan 29 09:44:57 2009 +0100
@@ -13,6 +13,9 @@
 # include stuff for translators
 recursive-include   MoinMoin/i18n *
 
+# include non-py stuff from werkzeug
+recursive-include   MoinMoin/support/werkzeug/debug *
+
 # contrib stuff
 recursive-include   contrib *
 
--- a/Makefile	Wed Jan 28 17:06:22 2009 +0100
+++ b/Makefile	Thu Jan 29 09:44:57 2009 +0100
@@ -13,33 +13,27 @@
 
 install-docs:
 	-mkdir build
-	wget -U MoinMoin/Makefile -O build/INSTALL.html "http://master18.moinmo.in/MoinMoin/InstallDocs?action=print"
+	wget -U MoinMoin/Makefile -O build/INSTALL.html "http://master19.moinmo.in/InstallDocs?action=print"
 	sed \
-		-e 's#href="/#href="http://master18.moinmo.in/#g' \
-		-e 's#http://[a-z\.]*/wiki/classic/#/wiki/classic/#g' \
-		-e 's#http://[a-z\.]*/wiki/modern/#/wiki/modern/#g' \
-		-e 's#http://[a-z\.]*/wiki/rightsidebar/#/wiki/rightsidebar/#g' \
-		-e 's#/wiki/classic/#wiki/htdocs/classic/#g' \
-		-e 's#/wiki/modern/#wiki/htdocs/modern/#g' \
-		-e 's#/wiki/rightsidebar/#wiki/htdocs/rightsidebar/#g' \
+		-e 's#href="/#href="http://master19.moinmo.in/#g' \
+		-e 's#http://[a-z0-9\.]*/wiki/modernized/#../wiki/htdocs/modernized/#g' \
+		-e 's#/wiki/common/#../wiki/htdocs/common/#g' \
+		-e 's#/wiki/modernized/#../wiki/htdocs/modernized/#g' \
         build/INSTALL.html >docs/INSTALL.html
 	-rm build/INSTALL.html
 
-	wget -U MoinMoin/Makefile -O build/UPDATE.html "http://master18.moinmo.in/HelpOnUpdating?action=print"
+	wget -U MoinMoin/Makefile -O build/UPDATE.html "http://master19.moinmo.in/HelpOnUpdating?action=print"
 	sed \
-		-e 's#href="/#href="http://master18.moinmo.in/#g' \
-		-e 's#http://[a-z\.]*/wiki/classic/#/wiki/classic/#g' \
-		-e 's#http://[a-z\.]*/wiki/modern/#/wiki/modern/#g' \
-		-e 's#http://[a-z\.]*/wiki/rightsidebar/#/wiki/rightsidebar/#g' \
-		-e 's#/wiki/classic/#wiki/htdocs/classic/#g' \
-		-e 's#/wiki/modern/#wiki/htdocs/modern/#g' \
-		-e 's#/wiki/rightsidebar/#wiki/htdocs/rightsidebar/#g' \
+		-e 's#href="/#href="http://master19.moinmo.in/#g' \
+		-e 's#http://[a-z0-9\.]*/wiki/modernized/#../wiki/htdocs/modernized/#g' \
+		-e 's#/wiki/common/#../wiki/htdocs/common/#g' \
+		-e 's#/wiki/modernized/#../wiki/htdocs/modernized/#g' \
         build/UPDATE.html >docs/UPDATE.html
 	-rm build/UPDATE.html
 	-rmdir build
 
 interwiki:
-	wget -U MoinMoin/Makefile -O $(share)/data/intermap.txt "http://master18.moinmo.in/InterWikiMap?action=raw"
+	wget -U MoinMoin/Makefile -O $(share)/data/intermap.txt "http://master19.moinmo.in/InterWikiMap?action=raw"
 	chmod 664 $(share)/data/intermap.txt
 
 check-tabs:
@@ -53,8 +47,8 @@
 # Should be used only on TW machine
 underlay:
 	rm -rf $(share)/underlay
-	MoinMoin/script/moin.py --config-dir=/srv/moin/cfg/1.8 --wiki-url=master18.moinmo.in/ maint globaledit
-	MoinMoin/script/moin.py --config-dir=/srv/moin/cfg/1.8 --wiki-url=master18.moinmo.in/ maint reducewiki --target-dir=$(share)/underlay
+	MoinMoin/script/moin.py --config-dir=/srv/moin/cfg/1.8 --wiki-url=master19.moinmo.in/ maint globaledit
+	MoinMoin/script/moin.py --config-dir=/srv/moin/cfg/1.8 --wiki-url=master19.moinmo.in/ maint reducewiki --target-dir=$(share)/underlay
 	rm -rf $(share)/underlay/pages/InterWikiMap
 	rm -rf $(share)/underlay/pages/MoinPagesEditorGroup
 	cd $(share); rm -f underlay.tar; tar cf underlay.tar underlay
--- a/MoinMoin/Page.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/Page.py	Thu Jan 29 09:44:57 2009 +0100
@@ -109,7 +109,8 @@
             (for 'meta') or the complete cache ('pagelists').
             @param request: the request object
         """
-        elog = request.editlog
+        from MoinMoin.logfile import editlog
+        elog = editlog.EditLog(request)
         old_pos = self.log_pos
         new_pos, items = elog.news(old_pos)
         if items:
@@ -753,12 +754,13 @@
                 url = "%s/%s/%s" % (request.cfg.url_prefix_action, action, url)
             url = '%s?%s' % (url, querystr)
 
+        if not relative:
+            url = '%s/%s' % (request.script_root, url)
+
         # Add anchor
         if anchor:
             url = "%s#%s" % (url, wikiutil.url_quote_plus(anchor))
 
-        if not relative:
-            url = '%s/%s' % (request.getScriptname(), url)
         return url
 
     def link_to_raw(self, request, text, querystr=None, anchor=None, **kw):
@@ -963,26 +965,25 @@
             offer a dialogue to save it to disk (used by Save action).
         """
         request = self.request
-        request.setHttpHeader("Content-type: text/plain; charset=%s" % config.charset)
+        request.mimetype = 'text/plain'
         if self.exists():
             # use the correct last-modified value from the on-disk file
             # to ensure cacheability where supported. Because we are sending
             # RAW (file) content, the file mtime is correct as Last-Modified header.
-            request.setHttpHeader("Status: 200 OK")
-            request.setHttpHeader("Last-Modified: %s" % util.timefuncs.formathttpdate(os.path.getmtime(self._text_filename())))
+            request.status_code = 200
+            request.last_modified = os.path.getmtime(self._text_filename())
             text = self.encodeTextMimeType(self.body)
             #request.setHttpHeader("Content-Length: %d" % len(text))  # XXX WRONG! text is unicode obj, but we send utf-8!
             if content_disposition:
                 # TODO: fix the encoding here, plain 8 bit is not allowed according to the RFCs
                 # There is no solution that is compatible to IE except stripping non-ascii chars
                 filename_enc = "%s.txt" % self.page_name.encode(config.charset)
-                request.setHttpHeader('Content-Disposition: %s; filename="%s"' % (
-                                      content_disposition, filename_enc))
+                dispo_string = '%s; filename="%s"' % (content_disposition, filename_enc)
+                request.headers.add('Content-Disposition', dispo_string)
         else:
-            request.setHttpHeader('Status: 404 NOTFOUND')
+            request.status_code = 404
             text = u"Page %s not found." % self.page_name
 
-        request.emit_http_headers()
         request.write(text)
 
     def send_page(self, **keywords):
@@ -1007,11 +1008,11 @@
         send_special = keywords.get('send_special', False)
         print_mode = keywords.get('print_mode', 0)
         if print_mode:
-            media = 'media' in request.form and request.form['media'][0] or 'print'
+            media = request.values.get('media', 'print')
         else:
             media = 'screen'
         self.hilite_re = (keywords.get('hilite_re') or
-                          request.form.get('highlight', [None])[0])
+                          request.values.get('highlight'))
 
         # count hit?
         if keywords.get('count_hit', 0):
@@ -1022,7 +1023,7 @@
         pi = self.pi
 
         if 'redirect' in pi and not (
-            'action' in request.form or 'redirect' in request.form or content_only):
+            'action' in request.values or 'redirect' in request.values or content_only):
             # redirect to another page
             # note that by including "action=show", we prevent endless looping
             # (see code in "request") or any cascaded redirection
@@ -1051,8 +1052,8 @@
             try:
                 self.formatter.set_highlight_re(self.hilite_re)
             except re.error, err:
-                if 'highlight' in request.form:
-                    del request.form['highlight']
+                if 'highlight' in request.values:
+                    del request.values['highlight']
                 request.theme.add_msg(_('Invalid highlighting regular expression "%(regex)s": %(error)s') % {
                                           'regex': self.hilite_re,
                                           'error': str(err),
@@ -1077,12 +1078,12 @@
         page_exists = self.exists()
         if not content_only:
             if emit_headers:
-                request.setHttpHeader("Content-Type: %s; charset=%s" % (self.output_mimetype, self.output_charset))
+                request.content_type = "%s; charset=%s" % (self.output_mimetype, self.output_charset)
                 if page_exists:
                     if not request.user.may.read(self.page_name):
-                        request.setHttpHeader('Status: 403 Permission Denied')
+                        request.status_code = 403
                     else:
-                        request.setHttpHeader('Status: 200 OK')
+                        request.status_code = 200
                     if not request.cacheable:
                         # use "nocache" headers if we're using a method that is not simply "display"
                         request.disableHttpCaching(level=2)
@@ -1097,8 +1098,7 @@
                         #request.setHttpHeader("Last-Modified: %s" % util.timefuncs.formathttpdate(lastmod))
                         pass
                 else:
-                    request.setHttpHeader('Status: 404 NOTFOUND')
-                request.emit_http_headers()
+                    request.status_code = 404
 
             if not page_exists and self.request.isSpiderAgent:
                 # don't send any 404 content to bots
@@ -1117,8 +1117,8 @@
 
                 # This redirect message is very annoying.
                 # Less annoying now without the warning sign.
-                if 'redirect' in request.form:
-                    redir = request.form['redirect'][0]
+                if 'redirect' in request.values:
+                    redir = request.values['redirect']
                     request.theme.add_msg('<strong>%s</strong><br>' % (
                         _('Redirected from page "%(page)s"') % {'page':
                             wikiutil.link_tag(request, wikiutil.quoteWikinameURL(redir) + "?action=show", self.formatter.text(redir))}), "info")
--- a/MoinMoin/PageEditor.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/PageEditor.py	Thu Jan 29 09:44:57 2009 +0100
@@ -197,12 +197,11 @@
 
         # Emit http_headers after checks (send_page)
         request.disableHttpCaching(level=2)
-        request.emit_http_headers()
 
         # check if we want to load a draft
         use_draft = None
         if 'button_load_draft' in form:
-            wanted_draft_timestamp = int(form.get('draft_ts', ['0'])[0])
+            wanted_draft_timestamp = int(form.get('draft_ts', '0'))
             if wanted_draft_timestamp:
                 draft = self._load_draft()
                 if draft is not None:
@@ -214,7 +213,7 @@
         if use_draft is not None:
             title = _('Draft of "%(pagename)s"')
             # Propagate original revision
-            rev = int(form['draft_rev'][0])
+            rev = int(form['draft_rev'])
             self.set_raw_body(use_draft, modified=1)
             preview = use_draft
         elif preview is None:
@@ -234,7 +233,7 @@
 
         # get request parameters
         try:
-            text_rows = int(form['rows'][0])
+            text_rows = int(form['rows'])
         except StandardError:
             text_rows = self.cfg.edit_rows
             if request.user.valid:
@@ -276,9 +275,9 @@
             # If the page exists, we get the text from the page.
             # TODO: maybe warn if template argument was ignored because the page exists?
             raw_body = self.get_raw_body()
-        elif 'template' in form:
+        elif 'template' in request.values:
             # If the page does not exist, we try to get the content from the template parameter.
-            template_page = wikiutil.unquoteWikiname(form['template'][0])
+            template_page = wikiutil.unquoteWikiname(request.values['template'])
             if request.user.may.read(template_page):
                 raw_body = Page(request, template_page).get_raw_body()
                 if raw_body:
@@ -332,10 +331,9 @@
             raw_body = _('Describe %s here.') % (self.page_name, )
 
         # send form
-        request.write('<form id="editor" method="post" action="%s/%s#preview" onSubmit="flgChange = false;">' % (
-            request.getScriptname(),
-            wikiutil.quoteWikinameURL(self.page_name),
-            ))
+        request.write('<form id="editor" method="post" action="%s#preview" onSubmit="flgChange = false;">' % (
+                request.href(self.page_name)
+        ))
 
         # yet another weird workaround for broken IE6 (it expands the text
         # editor area to the right after you begin to type...). IE sucks...
@@ -351,7 +349,7 @@
         request.write('<input type="hidden" name="ticket" value="%s">' % wikiutil.createTicket(request))
 
         # Save backto in a hidden input
-        backto = form.get('backto', [None])[0]
+        backto = request.values.get('backto')
         if backto:
             request.write(unicode(html.INPUT(type="hidden", name="backto", value=backto)))
 
@@ -410,7 +408,7 @@
     document.write('<label for="chktrivialtop">%(label)s</label>');
     //-->
 </script> ''' % {
-                'checked': ('', 'checked')[form.get('trivial', ['0'])[0] == '1'],
+                'checked': ('', 'checked')[form.get('trivial', '0') == '1'],
                 'label': _("Trivial change"),
             })
 
@@ -460,7 +458,7 @@
 <label for="chktrivial">%(label)s</label>
 
 ''' % {
-                'checked': ('', 'checked')[form.get('trivial', ['0'])[0] == '1'],
+                'checked': ('', 'checked')[form.get('trivial', '0') == '1'],
                 'label': _("Trivial change"),
                 })
 
@@ -469,7 +467,7 @@
 <input type="checkbox" name="rstrip" id="chkrstrip" value="1" %(checked)s>
 <label for="chkrstrip">%(label)s</label>
 ''' % {
-            'checked': ('', 'checked')[form.get('rstrip', ['0'])[0] == '1'],
+            'checked': ('', 'checked')[form.get('rstrip', '0') == '1'],
             'label': _('Remove trailing whitespace from each line')
             })
         request.write("</p>")
@@ -514,7 +512,7 @@
         self._save_draft(newtext, rev) # shall we really save a draft on CANCEL?
         self.lock.release()
 
-        backto = request.form.get('backto', [None])[0]
+        backto = request.values.get('backto')
         if backto:
             pg = Page(request, backto)
             request.http_redirect(pg.url(request, relative=False))
@@ -672,7 +670,7 @@
 
             # Remove cache entry (if exists)
             pg = Page(self.request, self.page_name)
-            key = self.request.form.get('key', ['text_html'])[0]
+            key = self.request.form.get('key', 'text_html') # XXX see cleanup code in deletePage
             caching.CacheEntry(self.request, pg, key, scope='item').remove()
             caching.CacheEntry(self.request, pg, "pagelinks", scope='item').remove()
 
--- a/MoinMoin/PageGraphicalEditor.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/PageGraphicalEditor.py	Thu Jan 29 09:44:57 2009 +0100
@@ -87,12 +87,11 @@
 
         # Emit http_headers after checks (send_page)
         request.disableHttpCaching(level=2)
-        request.emit_http_headers()
 
         # check if we want to load a draft
         use_draft = None
         if 'button_load_draft' in form:
-            wanted_draft_timestamp = int(form.get('draft_ts', ['0'])[0])
+            wanted_draft_timestamp = int(form.get('draft_ts', '0'))
             if wanted_draft_timestamp:
                 draft = self._load_draft()
                 if draft is not None:
@@ -104,7 +103,7 @@
         if use_draft is not None:
             title = _('Draft of "%(pagename)s"')
             # Propagate original revision
-            rev = int(form['draft_rev'][0])
+            rev = int(form['draft_rev'])
             self.set_raw_body(use_draft, modified=1)
             preview = use_draft
         elif preview is None:
@@ -124,7 +123,7 @@
 
         # get request parameters
         try:
-            text_rows = int(form['rows'][0])
+            text_rows = int(form['rows'])
         except StandardError:
             text_rows = self.cfg.edit_rows
             if request.user.valid:
@@ -168,9 +167,9 @@
             # If the page exists, we get the text from the page.
             # TODO: maybe warn if template argument was ignored because the page exists?
             raw_body = self.get_raw_body()
-        elif 'template' in form:
+        elif 'template' in request.values:
             # If the page does not exist, we try to get the content from the template parameter.
-            template_page = wikiutil.unquoteWikiname(form['template'][0])
+            template_page = wikiutil.unquoteWikiname(request.values['template'])
             if request.user.may.read(template_page):
                 raw_body = Page(request, template_page).get_raw_body()
                 if raw_body:
@@ -224,9 +223,8 @@
             raw_body = _('Describe %s here.') % (self.page_name, )
 
         # send form
-        request.write('<form id="editor" method="post" action="%s/%s#preview">' % (
-            request.getScriptname(),
-            wikiutil.quoteWikinameURL(self.page_name),
+        request.write('<form id="editor" method="post" action="%s#preview">' % (
+                request.href(self.page_name)
             ))
 
         # yet another weird workaround for broken IE6 (it expands the text
@@ -247,7 +245,7 @@
         request.write('<input type="hidden" name="ticket" value="%s">' % wikiutil.createTicket(request))
 
         # Save backto in a hidden input
-        backto = form.get('backto', [None])[0]
+        backto = request.values.get('backto')
         if backto:
             request.write(unicode(html.INPUT(type="hidden", name="backto", value=backto)))
 
@@ -298,7 +296,7 @@
 <input type="checkbox" name="trivial" id="chktrivialtop" value="1" %(checked)s onclick="toggle_trivial(this)">
 <label for="chktrivialtop">%(label)s</label>
 ''' % {
-          'checked': ('', 'checked')[form.get('trivial', ['0'])[0] == '1'],
+          'checked': ('', 'checked')[form.get('trivial', '0') == '1'],
           'label': _("Trivial change"),
        })
 
@@ -315,7 +313,7 @@
         url_prefix_local = request.cfg.url_prefix_local
         wikipage = wikiutil.quoteWikinameURL(self.page_name)
         fckbasepath = url_prefix_local + '/applets/FCKeditor'
-        wikiurl = request.getScriptname()
+        wikiurl = request.script_root
         if not wikiurl or wikiurl[-1] != '/':
             wikiurl += '/'
         themepath = '%s/%s' % (url_prefix_static, request.theme.name)
@@ -377,7 +375,7 @@
 &nbsp;
 <input type="checkbox" name="trivial" id="chktrivial" value="1" %(checked)s onclick="toggle_trivial(this)">
 <label for="chktrivial">%(label)s</label> ''' % {
-                'checked': ('', 'checked')[form.get('trivial', ['0'])[0] == '1'],
+                'checked': ('', 'checked')[form.get('trivial', '0') == '1'],
                 'label': _("Trivial change"),
                 })
 
@@ -386,7 +384,7 @@
 <input type="checkbox" name="rstrip" id="chkrstrip" value="1" %(checked)s>
 <label for="chkrstrip">%(label)s</label>
 </p> ''' % {
-            'checked': ('', 'checked')[form.get('rstrip', ['0'])[0] == '1'],
+            'checked': ('', 'checked')[form.get('rstrip', '0') == '1'],
             'label': _('Remove trailing whitespace from each line')
             })
 
--- a/MoinMoin/_tests/ldap_testbase.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/_tests/ldap_testbase.py	Thu Jan 29 09:44:57 2009 +0100
@@ -41,7 +41,7 @@
 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
+import os, shutil, tempfile, time, base64, md5
 from StringIO import StringIO
 import signal
 
@@ -187,6 +187,8 @@
         f.write(db_config)
         f.close()
 
+        rootpw = '{MD5}' + base64.b64encode(md5.new(self.rootpw).digest())
+
         # create slapd.conf from content template in slapd_config
         slapd_config = slapd_config % {
             'ldap_dir': self.ldap_dir,
@@ -194,7 +196,7 @@
             'schema_dir': self.schema_dir,
             'basedn': self.basedn,
             'rootdn': self.rootdn,
-            'rootpw': self.rootpw,
+            'rootpw': rootpw,
         }
         if isinstance(slapd_config, unicode):
             slapd_config = slapd_config.encode(self.coding)
--- a/MoinMoin/_tests/ldap_testdata.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/_tests/ldap_testdata.py	Thu Jan 29 09:44:57 2009 +0100
@@ -78,14 +78,16 @@
 objectClass: account
 objectClass: simpleSecurityObject
 uid: usera
-userPassword: usera
+# this is md5 encoded 'usera' for password
+userPassword: {MD5}aXqgOSc5gSW7YoLi9BSmvg==
 
 dn: uid=userb,ou=Unit B,ou=Users,ou=testing,dc=example,dc=org
 cn: Vorname Nachname
 objectClass: inetOrgPerson
 sn: Nachname
 uid: userb
-userPassword: userb
+# this is md5 encoded 'userb' for password
+userPassword: {MD5}ThvfQsM7OQFjqSUQOX2XsA==
 
 dn: cn=Group A,ou=Groups,ou=testing,dc=example,dc=org
 cn: Group A
--- a/MoinMoin/_tests/test_sourcecode.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/_tests/test_sourcecode.py	Thu Jan 29 09:44:57 2009 +0100
@@ -19,6 +19,7 @@
 EXCLUDE = [
     '/contrib/DesktopEdition/setup_py2exe.py', # has crlf
     '/contrib/TWikiDrawPlugin', # 3rd party java stuff
+    '/contrib/flup-server', # 3rd party WSGI adapters
     '/MoinMoin/support', # 3rd party libs or non-broken stdlib stuff
     '/wiki/htdocs/applets/FCKeditor', # 3rd party GUI editor
     '/tests/wiki', # this is our test wiki
--- a/MoinMoin/_tests/test_user.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/_tests/test_user.py	Thu Jan 29 09:44:57 2009 +0100
@@ -38,11 +38,11 @@
 
     def setup_method(self, method):
         # Save original user and cookie
-        self.saved_cookie = self.request.saved_cookie
+        self.saved_cookie = self.request.cookies
         self.saved_user = self.request.user
 
         # Create anon user for the tests
-        self.request.saved_cookie = ''
+        self.request.cookies = {}
         self.request.user = user.User(self.request)
 
         # Prevent user list caching - we create and delete users too fast for that.
@@ -64,7 +64,7 @@
             del self.user
 
         # Restore original user
-        self.request.saved_cookie = self.saved_cookie
+        self.request.cookies = self.saved_cookie
         self.request.user = self.saved_user
 
         # Remove user name to id cache, or next test will fail
--- a/MoinMoin/_tests/test_wikiutil.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/_tests/test_wikiutil.py	Thu Jan 29 09:44:57 2009 +0100
@@ -9,7 +9,7 @@
 
 import py
 
-from MoinMoin import wikiutil
+from MoinMoin import config, wikiutil
 
 
 class TestQueryStringSupport:
@@ -969,4 +969,80 @@
         assert relative_page == wikiutil.RelPageName(current_page, absolute_page)
 
 
+class TestNormalizePagename(object):
+
+    def testPageInvalidChars(self):
+        """ request: normalize pagename: remove invalid unicode chars
+
+        Assume the default setting
+        """
+        test = u'\u0000\u202a\u202b\u202c\u202d\u202e'
+        expected = u''
+        result = wikiutil.normalize_pagename(test, self.request.cfg)
+        assert result == expected
+
+    def testNormalizeSlashes(self):
+        """ request: normalize pagename: normalize slashes """
+        cases = (
+            (u'/////', u''),
+            (u'/a', u'a'),
+            (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, self.request.cfg)
+            assert result == expected
+
+    def testNormalizeWhitespace(self):
+        """ request: normalize pagename: normalize whitespace """
+        cases = (
+            (u'         ', u''),
+            (u'    a', u'a'),
+            (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'),
+            # All 30 unicode spaces
+            (config.chars_spaces, u''),
+            )
+        for test, expected in cases:
+            result = wikiutil.normalize_pagename(test, self.request.cfg)
+            assert result == expected
+
+    def testUnderscoreTestCase(self):
+        """ request: normalize pagename: underscore convert to spaces and normalized
+
+        Underscores should convert to spaces, then spaces should be
+        normalized, order is important!
+        """
+        cases = (
+            (u'         ', u''),
+            (u'  a', u'a'),
+            (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, self.request.cfg)
+            assert result == expected
+
+class TestGroupPages(object):
+
+    def testNormalizeGroupName(self):
+        """ request: normalize pagename: restrict groups to alpha numeric Unicode
+
+        Spaces should normalize after invalid chars removed!
+        """
+        cases = (
+            # current acl chars
+            (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.isGroupPage(test, self.request.cfg):
+                result = wikiutil.normalize_pagename(test, self.request.cfg)
+                assert result == expected
+
 coverage_modules = ['MoinMoin.wikiutil']
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/_tests/test_wsgiapp.py	Thu Jan 29 09:44:57 2009 +0100
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+"""
+    MoinMoin - MoinMoin.wsgiapp Tests
+
+    @copyright: 2008 MoinMoin:FlorianKrupicka
+    @license: GNU GPL, see COPYING for details.
+"""
+from StringIO import StringIO
+
+from MoinMoin import wsgiapp
+
+DOC_TYPE = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">'
+
+class TestApplication:
+    # self.client is made by conftest
+
+    # These should exist
+    PAGES = ('FrontPage', 'RecentChanges', 'HelpContents', 'FindPage')
+    # ... and these should not
+    NO_PAGES = ('FooBar', 'TheNone/ExistantPage/', '%33Strange%74Codes')
+
+    def testWSGIAppExisting(self):
+        for page in self.PAGES:
+            def _test_(page=page):
+                appiter, status, headers = self.client.get('/%s' % page)
+                output = ''.join(appiter)
+                print output
+                assert status[:3] == '200'
+                assert ('Content-Type', 'text/html; charset=utf-8') in headers
+                for needle in (DOC_TYPE, page):
+                    assert needle in output
+            yield _test_
+
+    def testWSGIAppAbsent(self):
+        for page in self.NO_PAGES:
+            def _test_(page=page):
+                appiter, status, headers = self.client.get('/%s' % page)
+                assert status[:3] == '404'
+                output = ''.join(appiter)
+                for needle in ('new empty page', 'page template'):
+                    assert needle in output
+            yield _test_
--- a/MoinMoin/action/AttachFile.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/AttachFile.py	Thu Jan 29 09:44:57 2009 +0100
@@ -27,7 +27,8 @@
     @license: GNU GPL, see COPYING for details.
 """
 
-import os, time, zipfile, mimetypes, errno
+import os, time, zipfile, mimetypes, errno, datetime
+from StringIO import StringIO
 
 from MoinMoin import log
 logging = log.getLogger(__name__)
@@ -37,6 +38,7 @@
 from MoinMoin.util import filesys, timefuncs
 from MoinMoin.security.textcha import TextCha
 from MoinMoin.events import FileAttachedEvent, send_event
+from MoinMoin.support import tarfile
 
 action_name = __name__.split('.')[-1]
 
@@ -76,34 +78,20 @@
     else:
         return u"/".join(pieces[:-1]), pieces[-1]
 
-
-def attachUrl(request, pagename, filename=None, **kw):
-    # filename is not used yet, but should be used later to make a sub-item url
-    if kw:
-        qs = '?%s' % wikiutil.makeQueryString(kw, want_unicode=False)
-    else:
-        qs = ''
-    return "%s/%s%s" % (request.getScriptname(), wikiutil.quoteWikinameURL(pagename), qs)
-
-
 def getAttachUrl(pagename, filename, request, addts=0, escaped=0, do='get', drawing='', upload=False):
     """ Get URL that points to attachment `filename` of page `pagename`. """
     if upload:
         if not drawing:
-            url = attachUrl(request, pagename, filename,
-                            rename=wikiutil.taintfilename(filename), action=action_name)
+            url = request.href(pagename, rename=wikiutil.taintfilename(filename),
+                               action=action_name)
         else:
-            url = attachUrl(request, pagename, filename,
-                            rename=wikiutil.taintfilename(filename), drawing=drawing, action=action_name)
+            url = request.href(pagename, rename=wikiutil.taintfilename(filename),
+                               drawing=drawing, action=action_name)
     else:
         if not drawing:
-            url = attachUrl(request, pagename, filename,
-                            target=filename, action=action_name, do=do)
+            url = request.href(pagename, target=filename, action=action_name, do=do)
         else:
-            url = attachUrl(request, pagename, filename,
-                            drawing=drawing, action=action_name)
-    if escaped:
-        url = wikiutil.escape(url)
+            url = request.href(pagename, drawing=drawing, action=action_name)
     return url
 
 
@@ -123,7 +111,7 @@
     fmt = request.formatter
     attach_count = _('[%d attachments]') % len(files)
     attach_icon = request.theme.make_icon('attach', vars={'attach_count': attach_count})
-    attach_link = (fmt.url(1, attachUrl(request, pagename, action=action_name), rel='nofollow') +
+    attach_link = (fmt.url(1, request.href(pagename, action=action_name), rel='nofollow') +
                    attach_icon +
                    fmt.url(0))
     return attach_link
@@ -251,10 +239,10 @@
     _ = request.getText
 
     error = None
-    if not request.form.get('target', [''])[0]:
+    if not request.values.get('target'):
         error = _("Filename of attachment not specified!")
     else:
-        filename = wikiutil.taintfilename(request.form['target'][0])
+        filename = wikiutil.taintfilename(request.values['target'])
         fpath = getFilename(request, pagename, filename)
 
         if os.path.isfile(fpath):
@@ -322,7 +310,7 @@
                          fmt.text(label_get) +
                          fmt.url(0))
 
-            if ext == '.draw':
+            if ext == '.tdraw':
                 links.append(fmt.url(1, getAttachUrl(pagename, file, request, drawing=base)) +
                              fmt.text(label_edit) +
                              fmt.url(0))
@@ -408,14 +396,15 @@
 
     now = time.time()
     pubpath = request.cfg.url_prefix_static + "/applets/TWikiDrawPlugin"
-    basename = request.form['drawing'][0]
-    drawpath = getAttachUrl(pagename, basename + '.draw', request, escaped=1)
-    pngpath = getAttachUrl(pagename, basename + '.png', request, escaped=1)
-    pagelink = attachUrl(request, pagename, '', action=action_name, ts=now)
+    basename = request.values['drawing']
+    ci = ContainerItem(request, pagename, basename + '.tdraw')
+    drawpath = ci.member_url(basename + '.draw')
+    pngpath = ci.member_url(basename + '.png')
+    pagelink = request.href(pagename, action=action_name, ts=now)
     helplink = Page(request, "HelpOnActions/AttachFile").url(request)
-    savelink = attachUrl(request, pagename, '', action=action_name, do='savedrawing')
+    savelink = request.href(pagename, action=action_name, do='savedrawing')
     #savelink = Page(request, pagename).url(request) # XXX include target filename param here for twisted
-                                           # request, {'savename': request.form['drawing'][0]+'.draw'}
+                                           # request, {'savename': request.values['drawing']+'.draw'}
     #savelink = '/cgi-bin/dumpform.bat'
 
     timestamp = '&amp;ts=%s' % now
@@ -460,7 +449,7 @@
     if writeable:
         request.write('<h2>' + _("New Attachment") + '</h2>')
         request.write("""
-<form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data">
+<form action="%(url)s" method="POST" enctype="multipart/form-data">
 <dl>
 <dt>%(upload_label_file)s</dt>
 <dd><input type="file" name="file" size="50"></dd>
@@ -477,14 +466,13 @@
 </p>
 </form>
 """ % {
-    'baseurl': request.getScriptname(),
-    'pagename': wikiutil.quoteWikinameURL(pagename),
+    'url': request.href(pagename),
     'action_name': action_name,
     'upload_label_file': _('File to upload'),
     'upload_label_rename': _('Rename to'),
-    'rename': wikiutil.escape(request.form.get('rename', [''])[0], 1),
+    'rename': wikiutil.escape(request.form.get('rename', ''), 1),
     'upload_label_overwrite': _('Overwrite existing attachment of same name'),
-    'overwrite_checked': ('', 'checked')[request.form.get('overwrite', ['0'])[0] == '1'],
+    'overwrite_checked': ('', 'checked')[request.form.get('overwrite', '0') == '1'],
     'upload_button': _('Upload'),
     'textcha': TextCha(request).render(),
 })
@@ -495,7 +483,7 @@
     if not writeable:
         request.write('<p>%s</p>' % _('You are not allowed to attach a file to this page.'))
 
-    if writeable and request.form.get('drawing', [None])[0]:
+    if writeable and request.values.get('drawing'):
         send_hotdraw(pagename, request)
 
 
@@ -507,12 +495,12 @@
     """ Main dispatcher for the 'AttachFile' action. """
     _ = request.getText
 
-    do = request.form.get('do', ['upload_form'])
-    handler = globals().get('_do_%s' % do[0])
+    do = request.values.get('do', 'upload_form')
+    handler = globals().get('_do_%s' % do)
     if handler:
         msg = handler(pagename, request)
     else:
-        msg = _('Unsupported AttachFile sub-action: %s') % (wikiutil.escape(do[0]), )
+        msg = _('Unsupported AttachFile sub-action: %s') % wikiutil.escape(do)
     if msg:
         error_msg(pagename, request, msg)
 
@@ -524,7 +512,6 @@
 def upload_form(pagename, request, msg=''):
     _ = request.getText
 
-    request.emit_http_headers()
     # Use user interface language for this generated page
     request.setContentLanguage(request.lang)
     request.theme.add_msg(msg, "dialog")
@@ -555,9 +542,15 @@
         return _('TextCha: Wrong answer! Go back and try again...')
 
     form = request.form
-    overwrite = form.get('overwrite', [u'0'])[0]
+
+    file_upload = request.files.get('file')
+    if not file_upload:
+        # This might happen when trying to upload file names
+        # with non-ascii characters on Safari.
+        return _("No file content. Delete non ASCII characters from the file name and try again.")
+
     try:
-        overwrite = int(overwrite)
+        overwrite = int(form.get('overwrite', '0'))
     except:
         overwrite = 0
 
@@ -567,84 +560,122 @@
     if overwrite and not request.user.may.delete(pagename):
         return _('You are not allowed to overwrite a file attachment of this page.')
 
-    filename = form.get('file__filename__')
-    rename = form.get('rename', [u''])[0].strip()
+    rename = form.get('rename', u'').strip()
     if rename:
         target = rename
     else:
-        target = filename
+        target = file_upload.filename
 
-    target = preprocess_filename(target)
     target = wikiutil.clean_input(target)
 
     if not target:
         return _("Filename of attachment not specified!")
 
-    # get file content
-    filecontent = request.form.get('file', [None])[0]
-    if filecontent is None:
-        # This might happen when trying to upload file names
-        # with non-ascii characters on Safari.
-        return _("No file content. Delete non ASCII characters from the file name and try again.")
-
     # add the attachment
     try:
-        target, bytes = add_attachment(request, pagename, target, filecontent, overwrite=overwrite)
+        target, bytes = add_attachment(request, pagename, target, file_upload.stream, overwrite=overwrite)
         msg = _("Attachment '%(target)s' (remote name '%(filename)s')"
                 " with %(bytes)d bytes saved.") % {
-                'target': target, 'filename': filename, 'bytes': bytes}
+                'target': target, 'filename': file_upload.filename, 'bytes': bytes}
     except AttachmentAlreadyExists:
         msg = _("Attachment '%(target)s' (remote name '%(filename)s') already exists.") % {
-            'target': target, 'filename': filename}
+            'target': target, 'filename': file_upload.filename}
 
     # return attachment list
     upload_form(pagename, request, msg)
 
 
+class ContainerItem:
+    """ A storage container (multiple objects in 1 tarfile) """
+
+    def __init__(self, request, pagename, containername):
+        self.request = request
+        self.pagename = pagename
+        self.containername = containername
+        self.container_filename = getFilename(request, pagename, containername)
+
+    def member_url(self, member):
+        """ return URL for accessing container member
+            (we use same URL for get (GET) and put (POST))
+        """
+        url = Page(self.request, self.pagename).url(self.request, {
+            'action': 'AttachFile',
+            'do': 'box',  # shorter to type than 'container'
+            'target': self.containername,
+            #'member': member,
+        })
+        return url + '&member=%s' % member
+        # member needs to be last in qs because twikidraw looks for "file extension" at the end
+
+    def get(self, member):
+        """ return a file-like object with the member file data
+        """
+        tf = tarfile.TarFile(self.container_filename)
+        return tf.extractfile(member)
+
+    def put(self, member, content, content_length=None):
+        """ save data into a container's member """
+        tf = tarfile.TarFile(self.container_filename, mode='a')
+        if isinstance(member, unicode):
+            member = member.encode('utf-8')
+        ti = tarfile.TarInfo(member)
+        if isinstance(content, str):
+            if content_length is None:
+                content_length = len(content)
+            content = StringIO(content) # we need a file obj
+        elif not hasattr(content, 'read'):
+            logging.error("unsupported content object: %r" % content)
+            raise
+        assert content_length >= 0  # we don't want -1 interpreted as 4G-1
+        ti.size = content_length
+        tf.addfile(ti, content)
+        tf.close()
+
+    def truncate(self):
+        f = open(self.container_filename, 'w')
+        f.close()
+
+    def exists(self):
+        return os.path.exists(self.container_filename)
+
 def _do_savedrawing(pagename, request):
     _ = request.getText
 
     if not request.user.may.write(pagename):
         return _('You are not allowed to save a drawing on this page.')
 
-    filename = request.form['filename'][0]
-    filecontent = request.form['filepath'][0]
+    file_upload = request.files.get('filepath')
+    if not file_upload:
+        # This might happen when trying to upload file names
+        # with non-ascii characters on Safari.
+        return _("No file content. Delete non ASCII characters from the file name and try again.")
 
+    filename = request.form['filename']
     basepath, basename = os.path.split(filename)
     basename, ext = os.path.splitext(basename)
 
-    # get directory, and possibly create it
-    attach_dir = getAttachDir(request, pagename, create=1)
-    savepath = os.path.join(attach_dir, basename + ext)
-
-    if ext == '.draw':
-        _addLogEntry(request, 'ATTDRW', pagename, basename + ext)
+    ci = ContainerItem(request, pagename, basename + '.tdraw')
+    filecontent = file_upload.stream
+    content_length = None
+    if ext == '.draw': # TWikiDraw POSTs this first
+        _addLogEntry(request, 'ATTDRW', pagename, basename + '.tdraw')
+        ci.truncate()
         filecontent = filecontent.read() # read file completely into memory
         filecontent = filecontent.replace("\r", "")
     elif ext == '.map':
+        # touch attachment directory to invalidate cache if new map is saved
+        attach_dir = getAttachDir(request, pagename)
+        os.utime(attach_dir, None)
         filecontent = filecontent.read() # read file completely into memory
         filecontent = filecontent.strip()
-
-    if filecontent:
-        # filecontent is either a file or a non-empty string
-        stream = open(savepath, 'wb')
-        try:
-            _write_stream(filecontent, stream)
-        finally:
-            stream.close()
     else:
-        # filecontent is empty string (e.g. empty map file), delete the target file
-        try:
-            os.unlink(savepath)
-        except OSError, err:
-            if err.errno != errno.ENOENT: # no such file
-                raise
+        #content_length = file_upload.content_length
+        # XXX gives -1 for wsgiref :( If this is fixed, we could use the file obj,
+        # without reading it into memory completely:
+        filecontent = filecontent.read()
 
-    # touch attachment directory to invalidate cache if new map is saved
-    if ext == '.map':
-        os.utime(attach_dir, None)
+    ci.put(basename + ext, filecontent, content_length)
 
-    request.emit_http_headers()
     request.write("OK")
 
 
@@ -710,17 +741,17 @@
 
     if 'cancel' in request.form:
         return _('Move aborted!')
-    if not wikiutil.checkTicket(request, request.form['ticket'][0]):
+    if not wikiutil.checkTicket(request, request.form['ticket']):
         return _('Please use the interactive user interface to move attachments!')
     if not request.user.may.delete(pagename):
         return _('You are not allowed to move attachments from this page.')
 
     if 'newpagename' in request.form:
-        new_pagename = request.form.get('newpagename')[0]
+        new_pagename = request.form.get('newpagename')
     else:
         upload_form(pagename, request, msg=_("Move aborted because new page name is empty."))
     if 'newattachmentname' in request.form:
-        new_attachment = request.form.get('newattachmentname')[0]
+        new_attachment = request.form.get('newattachmentname')
         if new_attachment != wikiutil.taintfilename(new_attachment):
             upload_form(pagename, request, msg=_("Please use a valid filename for attachment '%(filename)s'.") % {
                                   'filename': new_attachment})
@@ -728,7 +759,7 @@
     else:
         upload_form(pagename, request, msg=_("Move aborted because new attachment name is empty."))
 
-    attachment = request.form.get('oldattachmentname')[0]
+    attachment = request.form.get('oldattachmentname')
     move_file(request, pagename, new_pagename, attachment, new_attachment)
 
 
@@ -743,11 +774,10 @@
 
     # move file
     d = {'action': action_name,
-         'baseurl': request.getScriptname(),
+         'url': request.href(pagename),
          'do': 'attachment_move',
          'ticket': wikiutil.createTicket(request),
          'pagename': pagename,
-         'pagename_quoted': wikiutil.quoteWikinameURL(pagename),
          'attachment_name': filename,
          'move': _('Move'),
          'cancel': _('Cancel'),
@@ -755,7 +785,7 @@
          'attachment_label': _("New attachment name"),
         }
     formhtml = '''
-<form action="%(baseurl)s/%(pagename_quoted)s" method="POST">
+<form action="%(url)s" method="POST">
 <input type="hidden" name="action" value="%(action)s">
 <input type="hidden" name="do" value="%(do)s">
 <input type="hidden" name="ticket" value="%(ticket)s">
@@ -787,6 +817,46 @@
     return thispage.send_page()
 
 
+def _do_box(pagename, request):
+    _ = request.getText
+
+    pagename, filename, fpath = _access_file(pagename, request)
+    if not request.user.may.read(pagename):
+        return _('You are not allowed to get attachments from this page.')
+    if not filename:
+        return # error msg already sent in _access_file
+
+    timestamp = datetime.datetime.fromtimestamp(os.path.getmtime(fpath))
+    if_modified = request.if_modified_since
+    if if_modified and if_modified >= timestamp:
+        request.status_code = 304
+    else:
+        ci = ContainerItem(request, pagename, filename)
+        filename = wikiutil.taintfilename(request.values['member'])
+        mt = wikiutil.MimeType(filename=filename)
+        content_type = mt.content_type()
+        mime_type = mt.mime_type()
+
+        # TODO: fix the encoding here, plain 8 bit is not allowed according to the RFCs
+        # There is no solution that is compatible to IE except stripping non-ascii chars
+        filename_enc = filename.encode(config.charset)
+
+        # for dangerous files (like .html), when we are in danger of cross-site-scripting attacks,
+        # we just let the user store them to disk ('attachment').
+        # For safe files, we directly show them inline (this also works better for IE).
+        dangerous = mime_type in request.cfg.mimetypes_xss_protect
+        content_dispo = dangerous and 'attachment' or 'inline'
+
+        request.content_type = content_type
+        request.last_modified = timestamp
+        #request.content_length = os.path.getsize(fpath)
+        content_dispo_string = '%s; filename="%s"' % (content_dispo, filename_enc)
+        request.headers.add('Content-Disposition', content_dispo_string)
+
+        # send data
+        request.send_file(ci.get(filename))
+
+
 def _do_get(pagename, request):
     _ = request.getText
 
@@ -796,9 +866,10 @@
     if not filename:
         return # error msg already sent in _access_file
 
-    timestamp = timefuncs.formathttpdate(int(os.path.getmtime(fpath)))
-    if request.if_modified_since == timestamp:
-        request.emit_http_headers(["Status: 304 Not modified"])
+    timestamp = datetime.datetime.fromtimestamp(os.path.getmtime(fpath))
+    if_modified = request.if_modified_since
+    if if_modified and if_modified >= timestamp:
+        request.status_code = 304
     else:
         mt = wikiutil.MimeType(filename=filename)
         content_type = mt.content_type()
@@ -814,12 +885,11 @@
         dangerous = mime_type in request.cfg.mimetypes_xss_protect
         content_dispo = dangerous and 'attachment' or 'inline'
 
-        request.emit_http_headers([
-            'Content-Type: %s' % content_type,
-            'Last-Modified: %s' % timestamp,
-            'Content-Length: %d' % os.path.getsize(fpath),
-            'Content-Disposition: %s; filename="%s"' % (content_dispo, filename_enc),
-        ])
+        request.content_type = content_type
+        request.last_modified = timestamp
+        request.content_length = os.path.getsize(fpath)
+        content_dispo_string = '%s; filename="%s"' % (content_dispo, filename_enc)
+        request.headers.add('Content-Disposition', content_dispo_string)
 
         # send data
         request.send_file(open(fpath, 'rb'))
@@ -1053,7 +1123,6 @@
         return
 
     # send header & title
-    request.emit_http_headers()
     # Use user interface language for this generated page
     request.setContentLanguage(request.lang)
     title = _('attachment:%(filename)s of %(pagename)s') % {
--- a/MoinMoin/action/CopyPage.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/CopyPage.py	Thu Jan 29 09:44:57 2009 +0100
@@ -46,20 +46,19 @@
         """ copy this page to "pagename" """
         _ = self._
         form = self.form
-        newpagename = form.get('newpagename', [u''])[0]
-        newpagename = self.request.normalizePagename(newpagename)
-        comment = form.get('comment', [u''])[0]
+        newpagename = form.get('newpagename', u'')
+        newpagename = wikiutil.normalize_pagename(newpagename, self.cfg)
+        comment = form.get('comment', u'')
         comment = wikiutil.clean_input(comment)
 
         self.page = PageEditor(self.request, self.pagename)
         success, msgs = self.page.copyPage(newpagename, comment)
 
         copy_subpages = 0
-        if form.has_key('copy_subpages'):
-            try:
-                copy_subpages = int(form['copy_subpages'][0])
-            except:
-                pass
+        try:
+            copy_subpages = int(form['copy_subpages'])
+        except:
+            pass
 
         if copy_subpages and self.subpages or (not self.users_subpages and self.subpages):
             for name in self.subpages:
@@ -85,7 +84,7 @@
 
             d = {
                 'subpage': subpages,
-                'subpages_checked': ('', 'checked')[self.request.form.get('subpages_checked', ['0'])[0] == '1'],
+                'subpages_checked': ('', 'checked')[self.request.form.get('subpages_checked', '0') == '1'],
                 'subpage_label': _('Copy all /subpages too?'),
                 'pagename': wikiutil.escape(self.pagename, True),
                 'newname_label': _("New name"),
--- a/MoinMoin/action/DeletePage.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/DeletePage.py	Thu Jan 29 09:44:57 2009 +0100
@@ -44,7 +44,7 @@
     def do_action(self):
         """ Delete pagename """
         form = self.form
-        comment = form.get('comment', [u''])[0]
+        comment = form.get('comment', u'')
         comment = wikiutil.clean_input(comment)
 
         # Create a page editor that does not do editor backups, because
@@ -53,11 +53,10 @@
         success, msgs = self.page.deletePage(comment)
 
         delete_subpages = 0
-        if 'delete_subpages' in form:
-            try:
-                delete_subpages = int(form['delete_subpages'][0])
-            except:
-                pass
+        try:
+            delete_subpages = int(form['delete_subpages'])
+        except:
+            pass
 
         if delete_subpages and self.subpages:
             for name in self.subpages:
@@ -75,7 +74,7 @@
 
             d = {
                 'subpage': subpages,
-                'subpages_checked': ('', 'checked')[self.request.form.get('subpages_checked', ['0'])[0] == '1'],
+                'subpages_checked': ('', 'checked')[self.request.form.get('subpages_checked', '0') == '1'],
                 'subpage_label': _('Delete all /subpages too?'),
                 'comment_label': _("Optional reason for the deletion"),
                 'buttons_html': buttons_html,
--- a/MoinMoin/action/Despam.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/Despam.py	Thu Jan 29 09:44:57 2009 +0100
@@ -104,14 +104,13 @@
     request.write('''
 </table>
 <p>
-<form method="post" action="%s/%s">
+<form method="post" action="%s">
 <input type="hidden" name="action" value="Despam">
 <input type="hidden" name="editor" value="%s">
 <input type="submit" name="ok" value="%s">
 </form>
 </p>
-''' % (request.getScriptname(), wikiutil.quoteWikinameURL(pagename),
-       wikiutil.url_quote(editor), _("Revert all!")))
+''' % (request.href(pagename), wikiutil.url_quote(editor), _("Revert all!")))
 
 def revert_page(request, pagename, editor):
     if not request.user.may.revert(pagename):
@@ -183,11 +182,10 @@
         request.theme.add_msg(_('You are not allowed to use this action.'), "error")
         return Page.Page(request, pagename).send_page()
 
-    editor = request.form.get('editor', [None])[0]
+    editor = request.form.get('editor')
     timestamp = time.time() - DAYS * 24 * 3600
-    ok = request.form.get('ok', [0])[0]
+    ok = request.form.get('ok', 0)
 
-    request.emit_http_headers()
     request.theme.send_title("Despam", pagename=pagename)
     # Start content (important for RTL support)
     request.write(request.formatter.startContent("content"))
--- a/MoinMoin/action/LikePages.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/LikePages.py	Thu Jan 29 09:44:57 2009 +0100
@@ -41,8 +41,6 @@
         return
 
     # more than one match, list 'em
-    request.emit_http_headers()
-
     # This action generate data using the user language
     request.setContentLanguage(request.lang)
 
--- a/MoinMoin/action/Load.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/Load.py	Thu Jan 29 09:44:57 2009 +0100
@@ -36,11 +36,17 @@
         form = self.form
         request = self.request
 
-        comment = form.get('comment', [u''])[0]
+        comment = form.get('comment', u'')
         comment = wikiutil.clean_input(comment)
 
-        filename = form.get('file__filename__')
-        rename = form.get('rename', [''])[0].strip()
+        file_upload = request.files.get('file')
+        if not file_upload:
+            # This might happen when trying to upload file names
+            # with non-ascii characters on Safari.
+            return False, _("No file content. Delete non ASCII characters from the file name and try again.")
+
+        filename = file_upload.filename
+        rename = form.get('rename', '').strip()
         if rename:
             target = rename
         else:
@@ -50,9 +56,7 @@
         target = wikiutil.clean_input(target)
 
         if target:
-            filecontent = form['file'][0]
-            if hasattr(filecontent, 'read'): # a file-like object
-                filecontent = filecontent.read() # XXX reads complete file into memory!
+            filecontent = file_upload.stream.read() # XXX reads complete file into memory!
             filecontent = wikiutil.decodeUnknownInput(filecontent)
 
             self.pagename = target
--- a/MoinMoin/action/LocalSiteMap.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/LocalSiteMap.py	Thu Jan 29 09:44:57 2009 +0100
@@ -31,7 +31,6 @@
 
 def execute(pagename, request):
     _ = request.getText
-    request.emit_http_headers()
 
     # This action generate data using the user language
     request.setContentLanguage(request.lang)
--- a/MoinMoin/action/MyPages.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/MyPages.py	Thu Jan 29 09:44:57 2009 +0100
@@ -58,7 +58,6 @@
     pagecontent = pagecontent.replace('\n', '\r\n')
 
     from MoinMoin.parser.text_moin_wiki import Parser as WikiParser
-    request.emit_http_headers()
 
     # This action generate data using the user language
     request.setContentLanguage(request.lang)
--- a/MoinMoin/action/PackagePages.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/PackagePages.py	Thu Jan 29 09:44:57 2009 +0100
@@ -44,9 +44,8 @@
         redirects to new page.
         """
         _ = self.request.getText
-        form = self.request.form
 
-        if 'cancel' in form:
+        if 'cancel' in self.request.values:
             # User canceled
             return self.page.send_page()
 
@@ -65,14 +64,13 @@
     def package(self):
         """ Calls collectpackage() with the arguments specified. """
         _ = self.request.getText
-        form = self.request.form
 
         # Get new name from form and normalize.
-        pagelist = form.get('pagelist', [u''])[0]
-        packagename = form.get('packagename', [u''])[0]
-        include_attachments = form.get('include_attachments', [False])[0]
+        pagelist = self.request.values.get('pagelist', u'')
+        packagename = self.request.values.get('packagename', u'')
+        include_attachments = self.request.values.get('include_attachments', False)
 
-        if not form.get('submit', [None])[0]:
+        if not self.request.values.get('submit'):
             self.request.theme.add_msg(self.makeform(), "dialog")
             raise ActionError
 
@@ -115,11 +113,10 @@
             error = u'<p class="error">%s</p>\n' % error
 
         d = {
-            'baseurl': self.request.getScriptname(),
+            'url': self.request.href(self.pagename),
             'error': error,
             'action': self.__class__.__name__,
             'pagename': wikiutil.escape(self.pagename, True),
-            'pagename_quoted': wikiutil.quoteWikinameURL(self.pagename),
             'include_attachments_label': _('Include all attachments?'),
             'package': _('Package pages'),
             'cancel': _('Cancel'),
@@ -128,7 +125,7 @@
         }
         form = '''
 %(error)s
-<form method="post" action="%(baseurl)s/%(pagename_quoted)s">
+<form method="post" action="%(url)s">
 <input type="hidden" name="action" value="%(action)s">
 <table>
     <tr>
@@ -196,7 +193,7 @@
 
         pages = []
         for pagename in pagelist:
-            pagename = self.request.normalizePagename(pagename)
+            pagename = wikiutil.normalize_pagename(pagename, self.request.cfg)
             if pagename:
                 page = Page(self.request, pagename)
                 if page.exists() and self.request.user.may.read(pagename):
--- a/MoinMoin/action/RenamePage.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/RenamePage.py	Thu Jan 29 09:44:57 2009 +0100
@@ -45,20 +45,19 @@
         """ Rename this page to "pagename" """
         _ = self._
         form = self.form
-        newpagename = form.get('newpagename', [u''])[0]
-        newpagename = self.request.normalizePagename(newpagename)
-        comment = form.get('comment', [u''])[0]
+        newpagename = form.get('newpagename', u'')
+        newpagename = wikiutil.normalize_pagename(newpagename, self.cfg)
+        comment = form.get('comment', u'')
         comment = wikiutil.clean_input(comment)
 
         self.page = PageEditor(self.request, self.pagename)
         success, msgs = self.page.renamePage(newpagename, comment)
 
         rename_subpages = 0
-        if 'rename_subpages' in form:
-            try:
-                rename_subpages = int(form['rename_subpages'][0])
-            except:
-                pass
+        try:
+            rename_subpages = int(form['rename_subpages'])
+        except:
+            pass
 
         if rename_subpages and self.subpages:
             for name in self.subpages:
@@ -84,7 +83,7 @@
 
             d = {
                 'subpage': subpages,
-                'subpages_checked': ('', 'checked')[self.request.form.get('subpages_checked', ['0'])[0] == '1'],
+                'subpages_checked': ('', 'checked')[self.request.form.get('subpages_checked', '0') == '1'],
                 'subpage_label': _('Rename all /subpages too?'),
                 'pagename': wikiutil.escape(self.pagename, True),
                 'newname_label': _("New name"),
--- a/MoinMoin/action/RenderAsDocbook.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/RenderAsDocbook.py	Thu Jan 29 09:44:57 2009 +0100
@@ -9,5 +9,5 @@
 
 def execute(pagename, request):
     url = Page(request, pagename).url(request, {'action': 'show', 'mimetype': 'text/docbook'})
-    request.http_redirect(url)
+    return request.http_redirect(url)
 
--- a/MoinMoin/action/SpellCheck.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/SpellCheck.py	Thu Jan 29 09:44:57 2009 +0100
@@ -102,7 +102,7 @@
     from MoinMoin.PageEditor import PageEditor
     # get the new words as a string (if any are marked at all)
     try:
-        newwords = request.form['newwords']
+        newwords = request.form.getlist('newwords')
     except KeyError:
         # no new words checked
         return
@@ -187,8 +187,8 @@
 
         # add a form containing the bad words
         if own_form:
-            msg = msg + ('<form method="post" action="%s/%s">\n'
-                         '<input type="hidden" name="action" value="%s">\n') % (request.getScriptname(), wikiutil.quoteWikinameURL(page.page_name), action_name)
+            msg = msg + ('<form method="post" action="%s">\n'
+                         '<input type="hidden" name="action" value="%s">\n') % (request.href(page.page_name), action_name)
 
         checkbox = '<input type="checkbox" name="newwords" value="%(word)s">%(word)s&nbsp;&nbsp;'
         msg = msg + (
--- a/MoinMoin/action/SubscribeUser.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/SubscribeUser.py	Thu Jan 29 09:44:57 2009 +0100
@@ -16,30 +16,28 @@
 
 def show_form(pagename, request):
     _ = request.getText
-    request.emit_http_headers()
     request.theme.send_title(_("Subscribe users to the page %s") % pagename, pagename=pagename)
 
     request.write("""
-<form action="%s/%s" method="POST" enctype="multipart/form-data">
+<form action="%s" method="POST" enctype="multipart/form-data">
 <input type="hidden" name="action" value="SubscribeUser">
 %s <input type="text" name="users" size="50">
 <input type="submit" value="Subscribe">
 </form>
-""" % (request.getScriptname(), wikiutil.quoteWikinameURL(pagename),
+""" % (request.href(pagename),
       _("Enter user names (comma separated):")))
     request.theme.send_footer(pagename)
     request.theme.send_closing_html()
 
 def show_result(pagename, request):
     _ = request.getText
-    request.emit_http_headers()
 
     request.theme.send_title(_("Subscribed for %s:") % pagename, pagename=pagename)
 
     from MoinMoin.formatter.text_html import Formatter
     formatter = Formatter(request)
 
-    result = subscribe_users(request, request.form['users'][0].split(","), pagename, formatter)
+    result = subscribe_users(request, request.form['users'].split(","), pagename, formatter)
     request.write(result)
 
     request.theme.send_footer(pagename)
@@ -119,9 +117,8 @@
         request_url = "localhost/"
 
     # Setup MoinMoin environment
-    from MoinMoin.request import request_cli
-    request = request_cli.Request(url=request_url)
-    request.form = request.args = request.setup_args()
+    from MoinMoin.web.contexts import ScriptContext
+    request = ScriptContext(url=request_url)
 
     from MoinMoin.formatter.text_plain import Formatter
     formatter = Formatter(request)
--- a/MoinMoin/action/SyncPages.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/SyncPages.py	Thu Jan 29 09:44:57 2009 +0100
@@ -122,8 +122,8 @@
     def fix_params(self, params):
         """ Does some fixup on the parameters. """
         # Load the password
-        if "password" in self.request.form:
-            params["password"] = self.request.form["password"][0]
+        if "password" in self.request.values:
+            params["password"] = self.request.values["password"]
 
         # merge the pageList case into the pageMatch case
         if params["pageList"] is not None:
@@ -178,7 +178,7 @@
         params = self.fix_params(self.parse_page())
 
         try:
-            if "cancel" in self.request.form:
+            if "cancel" in self.request.values:
                 raise ActionStatus(_("Operation was canceled."), "error")
 
             if params["direction"] == UP:
--- a/MoinMoin/action/__init__.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/__init__.py	Thu Jan 29 09:44:57 2009 +0100
@@ -18,16 +18,19 @@
     Additionally to the usual stuff, we provide an ActionBase class here with
     some of the usual base functionality for an action, like checking
     actions_excluded, making and checking tickets, rendering some form,
-    displaying errors and doing stuff after an action.
+    displaying errors and doing stuff after an action. Also utility functions
+    regarding actions are located here.
 
     @copyright: 2000-2004 Juergen Hermann <jh@web.de>,
                 2006 MoinMoin:ThomasWaldmann
+                2008 MoinMoin:FlorianKrupicka
     @license: GNU GPL, see COPYING for details.
 """
 
 from MoinMoin.util import pysupport
 from MoinMoin import config, wikiutil
 from MoinMoin.Page import Page
+from MoinMoin.support.python_compatibility import set
 
 # create a list of extension actions from the package directory
 modules = pysupport.getPackageModules(__file__)
@@ -88,7 +91,7 @@
             return True
         # Require a valid ticket. Make outside attacks harder by
         # requiring two full HTTP transactions
-        ticket = self.form.get('ticket', [''])[0]
+        ticket = self.form.get('ticket', '')
         return wikiutil.checkTicket(self.request, ticket)
 
     # UI ---------------------------------------------------------------------
@@ -134,19 +137,17 @@
 
         d = {
             'method': self.method,
-            'baseurl': self.request.getScriptname(),
+            'url': self.request.href(self.pagename),
             'enctype': self.enctype,
             'error_html': error_html,
             'actionname': self.actionname,
-            'pagename': self.pagename,
-            'pagename_quoted': wikiutil.quoteWikinameURL(self.pagename),
             'ticket_html': ticket_html,
             'user_html': self.get_form_html(buttons_html),
         }
 
         form_html = '''
 %(error_html)s
-<form action="%(baseurl)s/%(pagename_quoted)s" method="%(method)s" enctype="%(enctype)s">
+<form action="%(url)s" method="%(method)s" enctype="%(enctype)s">
 <div>
 <input type="hidden" name="action" value="%(actionname)s">
 %(ticket_html)s
@@ -236,14 +237,14 @@
         Page(request, pagename, rev=rev).send_raw()
 
 def do_show(pagename, request, content_only=0, count_hit=1, cacheable=1, print_mode=0):
-    """ show a page, either current revision or the revision given by rev form value.
+    """ show a page, either current revision or the revision given by "rev=" value.
         if count_hit is non-zero, we count the request for statistics.
     """
     # We must check if the current page has different ACLs.
     if not request.user.may.read(pagename):
         Page(request, pagename).send_page()
     else:
-        mimetype = request.form.get('mimetype', [u"text/html"])[0]
+        mimetype = request.values.get('mimetype', u"text/html")
         rev = request.rev or 0
         if rev == 0:
             request.cacheable = cacheable
@@ -254,22 +255,21 @@
         )
 
 def do_format(pagename, request):
-    """ send a page using a specific formatter given by mimetype form key.
+    """ send a page using a specific formatter given by "mimetype=" value.
         Since 5.5.2006 this functionality is also done by do_show, but do_format
         has a default of text/plain when no format is given.
         It also does not count in statistics and also does not set the cacheable flag.
         DEPRECATED: remove this action when we don't need it any more for compatibility.
     """
-    if 'mimetype' not in request.form:
-        request.form['mimetype'] = [u"text/plain"]
+    if 'mimetype' not in request.values:
+        request.values['mimetype'] = u"text/plain"
     do_show(pagename, request, count_hit=0, cacheable=0)
 
 def do_content(pagename, request):
     """ same as do_show, but we only show the content """
     # XXX temporary fix to make it work until Page.send_page gets refactored
-    request.setHttpHeader("Content-Type: text/html; charset=%s" % config.charset)
-    request.setHttpHeader('Status: 200 OK')
-    request.emit_http_headers()
+    request.mimetype = 'text/html'
+    request.status_code = 200
     do_show(pagename, request, count_hit=0, content_only=1)
 
 def do_print(pagename, request):
@@ -283,10 +283,10 @@
 def do_refresh(pagename, request):
     """ Handle refresh action """
     # Without arguments, refresh action will refresh the page text_html cache.
-    arena = request.form.get('arena', ['Page.py'])[0]
+    arena = request.values.get('arena', 'Page.py')
     if arena == 'Page.py':
         arena = Page(request, pagename)
-    key = request.form.get('key', ['text_html'])[0]
+    key = request.values.get('key', 'text_html')
 
     # Remove cache entry (if exists), and send the page
     from MoinMoin import caching
@@ -296,27 +296,71 @@
 
 def do_goto(pagename, request):
     """ redirect to another page """
-    target = request.form.get('target', [''])[0]
+    target = request.values.get('target', '')
     request.http_redirect(Page(request, target).url(request))
 
 # Dispatching ----------------------------------------------------------------
-def getNames(cfg):
-    if not hasattr(cfg.cache, 'action_names'):
-        lnames = names[:]
-        lnames.extend(wikiutil.getPlugins('action', cfg))
-        cfg.cache.action_names = lnames # remember it
-    return cfg.cache.action_names
+def get_names(config):
+    """ Get a list of known actions.
 
-def getHandler(request, action, identifier="execute"):
-    """ return a handler function for a given action or None """
+    @param config: a config object
+    @rtype: set
+    @return: set of known actions
+    """
+    if not hasattr(config.cache, 'action_names'):
+        actions = names[:]
+        actions.extend(wikiutil.getPlugins('action', config))
+        actions = set([action for action in actions
+                      if not action in config.actions_excluded])
+        config.cache.action_names = actions # remember it
+    return config.cache.action_names
+
+def getHandler(cfg, action, identifier="execute"):
+    """ return a handler function for a given action or None.
+
+    TODO: remove request dependency
+    """
     # check for excluded actions
-    if action in request.cfg.actions_excluded:
+    if action in cfg.actions_excluded:
         return None
 
     try:
-        handler = wikiutil.importPlugin(request.cfg, "action", action, identifier)
+        handler = wikiutil.importPlugin(cfg, "action", action, identifier)
     except wikiutil.PluginMissingError:
         handler = globals().get('do_' + action)
 
     return handler
 
+def get_available_actions(config, page, user):
+        """ Get a list of actions available on a particular page
+        for a particular user.
+
+        The set does not contain actions that starts with lower case.
+        Themes use this set to display the actions to the user.
+
+        @param config: a config object (for the per-wiki actions)
+        @param page: the page to which the actions should apply
+        @param user: the user which wants to apply an action
+        @rtype: set
+        @return: set of avaiable actions
+        """
+        if not user.may.read(page.page_name):
+            return []
+
+
+        actions = get_names(config)
+
+        # Filter non ui actions (starts with lower case letter)
+        actions = [action for action in actions if not action[0].islower()]
+
+        # Filter actions by page type, acl and user state
+        excluded = []
+        if (page.isUnderlayPage() and not page.isStandardPage()) or \
+                not user.may.write(page.page_name) or \
+                not user.may.delete(page.page_name):
+                # Prevent modification of underlay only pages, or pages
+                # the user can't write and can't delete
+                excluded = [u'RenamePage', u'DeletePage', ] # AttachFile must NOT be here!
+        return set([action for action in actions if not action in excluded])
+
+
--- a/MoinMoin/action/_tests/test_attachfile.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/_tests/test_attachfile.py	Thu Jan 29 09:44:57 2009 +0100
@@ -68,7 +68,7 @@
         Tests if AttachFile.getAttachUrl taints a filename
         """
         filename = "<test2.txt>"
-        expect = "rename=_test2.txt_&"
+        expect = "rename=_test2.txt_"
         result = AttachFile.getAttachUrl(self.pagename, filename, self.request, upload=True)
 
         assert expect in result
--- a/MoinMoin/action/backup.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/backup.py	Thu Jan 29 09:44:57 2009 +0100
@@ -54,7 +54,7 @@
     request.emit_http_headers()
     request.setContentLanguage(request.lang)
     title = _('Wiki Backup')
-    request.theme.send_title(title, form=request.form, pagename=pagename)
+    request.theme.send_title(title, pagename=pagename)
     request.write(request.formatter.startContent("content"))
 
     request.write(_("""= Downloading a backup =
@@ -103,7 +103,7 @@
         return sendMsg(request, pagename,
                        msg=_('You are not allowed to do remote backup.'), msgtype="error")
 
-    dowhat = request.form.get('do', [None])[0]
+    dowhat = request.form.get('do')
     if dowhat == 'backup':
         sendBackup(request)
     elif dowhat is None:
--- a/MoinMoin/action/bookmark.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/bookmark.py	Thu Jan 29 09:44:57 2009 +0100
@@ -19,7 +19,7 @@
         request.theme.add_msg(_("You must login to use this action: %(action)s.") % {"action": actname}, "error")
         return Page(request, pagename).send_page()
 
-    timestamp = request.form.get('time', [None])[0]
+    timestamp = request.values.get('time')
     if timestamp is not None:
         if timestamp == 'del':
             tm = None
--- a/MoinMoin/action/cache.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/cache.py	Thu Jan 29 09:44:57 2009 +0100
@@ -41,7 +41,7 @@
 
 action_name = __name__.split('.')[-1]
 
-# Do NOT get this directly from request.form or user would be able to read any cache!
+# Do NOT get this directly from request.values or user would be able to read any cache!
 cache_arena = 'sendcache'  # just using action_name is maybe rather confusing
 
 # We maybe could use page local caching (not 'wiki' global) to have less directory entries.
@@ -196,10 +196,7 @@
 
 def url(request, key, do='get'):
     """ return URL for the object cached for key """
-    return "%s/?%s" % (
-        request.getScriptname(),
-        wikiutil.makeQueryString(dict(action=action_name, do=do, key=key), want_unicode=False))
-
+    return request.href(action=action_name, do=do, key=key)
 
 def _get_headers(request, key):
     """ get last_modified and headers cached for key """
@@ -242,7 +239,7 @@
         _do_remove(request, key)
 
 def execute(pagename, request):
-    do = request.form.get('do', [None])[0]
-    key = request.form.get('key', [None])[0]
+    do = request.values.get('do')
+    key = request.values.get('key')
     _do(request, do, key)
 
--- a/MoinMoin/action/chart.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/chart.py	Thu Jan 29 09:44:57 2009 +0100
@@ -19,7 +19,7 @@
         request.theme.add_msg(_("Charts are not available!"), "error")
         return request.page.send_page()
 
-    chart_type = request.form.get('type', [''])[0].strip()
+    chart_type = request.values.get('type', '').strip()
     if not chart_type:
         request.theme.add_msg(_('You need to provide a chart type!'), "error")
         return request.page.send_page()
--- a/MoinMoin/action/diff.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/diff.py	Thu Jan 29 09:44:57 2009 +0100
@@ -21,7 +21,7 @@
         return
 
     try:
-        date = request.form['date'][0]
+        date = request.values['date']
         try:
             date = long(date) # must be long for py 2.2.x
         except StandardError:
@@ -30,11 +30,11 @@
         date = 0
 
     try:
-        rev1 = int(request.form.get('rev1', [-1])[0])
+        rev1 = int(request.values.get('rev1', -1))
     except StandardError:
         rev1 = 0
     try:
-        rev2 = int(request.form.get('rev2', [0])[0])
+        rev2 = int(request.values.get('rev2', 0))
     except StandardError:
         rev2 = 0
 
@@ -44,7 +44,7 @@
             rev1 = -1
 
     # spacing flag?
-    ignorews = int(request.form.get('ignorews', [0])[0])
+    ignorews = int(request.values.get('ignorews', 0))
 
     _ = request.getText
 
@@ -71,7 +71,6 @@
     # This action generates content in the user language
     request.setContentLanguage(request.lang)
 
-    request.emit_http_headers()
     request.theme.send_title(_('Diff for "%s"') % (pagename, ), pagename=pagename, allow_doubleclick=1)
 
     if rev1 > 0 and rev2 > 0 and rev1 > rev2 or rev1 == 0 and rev2 > 0:
--- a/MoinMoin/action/dumpform.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/dumpform.py	Thu Jan 29 09:44:57 2009 +0100
@@ -12,6 +12,5 @@
     """ dump the form data we received in this request for debugging """
     data = util.dumpFormData(request.form)
 
-    request.emit_http_headers()
     request.write("<html><body>%s</body></html>" % data)
 
--- a/MoinMoin/action/edit.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/edit.py	Thu Jan 29 09:44:57 2009 +0100
@@ -33,7 +33,7 @@
     if editor not in valideditors:
         editor = request.cfg.editor_default
 
-    editorparam = request.form.get('editor', [editor])[0]
+    editorparam = request.values.get('editor', editor)
     if editorparam == "guipossible":
         lasteditor = editor
     elif editorparam == "textonly":
@@ -49,11 +49,11 @@
         editor = 'text'
 
     rev = request.rev or 0
-    savetext = request.form.get('savetext', [None])[0]
-    comment = request.form.get('comment', [u''])[0]
-    category = request.form.get('category', [None])[0]
-    rstrip = int(request.form.get('rstrip', ['0'])[0])
-    trivial = int(request.form.get('trivial', ['0'])[0])
+    savetext = request.form.get('savetext')
+    comment = request.form.get('comment', u'')
+    category = request.form.get('category')
+    rstrip = int(request.form.get('rstrip', '0'))
+    trivial = int(request.form.get('trivial', '0'))
 
     if 'button_switch' in request.form:
         if editor == 'text':
@@ -78,7 +78,7 @@
     cancelled = 'button_cancel' in request.form
 
     if request.cfg.edit_ticketing:
-        ticket = request.form.get('ticket', [''])[0]
+        ticket = request.form.get('ticket', '')
         if not wikiutil.checkTicket(request, ticket):
             request.theme.add_msg(_('Please use the interactive user interface to use action %(actionname)s!') % {'actionname': 'edit' }, "error")
             pg.send_page()
@@ -88,7 +88,7 @@
     try:
         if lasteditor == 'gui':
             # convert input from Graphical editor
-            format = request.form.get('format', ['wiki'])[0]
+            format = request.form.get('format', 'wiki')
             if format == 'wiki':
                 converter_name = 'text_html_text_moin_wiki'
             else:
--- a/MoinMoin/action/fckdialog.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/fckdialog.py	Thu Jan 29 09:44:57 2009 +0100
@@ -15,7 +15,6 @@
 
 def macro_dialog(request):
     help = get_macro_help(request)
-    request.emit_http_headers()
     request.write(
         '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html>
@@ -164,13 +163,12 @@
 
 def page_list(request):
     from MoinMoin import search
-    name = request.form.get("pagename", [""])[0]
+    name = request.values.get("pagename", "")
     if name:
         searchresult = search.searchPages(request, 't:"%s"' % name)
         pages = [p.page_name for p in searchresult.hits]
     else:
         pages = [name]
-    request.emit_http_headers()
     request.write(
         '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html>
@@ -201,9 +199,8 @@
 ''' % "".join(["<option>%s</option>\n" % p for p in pages]))
 
 def link_dialog(request):
-    request.emit_http_headers()
     # list of wiki pages
-    name = request.form.get("pagename", [""])[0]
+    name = request.values.get("pagename", "")
     if name:
         from MoinMoin import search
         # XXX error handling!
@@ -242,7 +239,7 @@
 
     # wiki url
     url_prefix_static = request.cfg.url_prefix_static
-    scriptname = request.getScriptname()
+    scriptname = request.script_root
     if not scriptname or scriptname[-1] != "/":
         scriptname += "/"
     action = scriptname
@@ -367,9 +364,8 @@
 ##############################################################################
 
 def attachment_dialog(request):
-    request.emit_http_headers()
     # list of wiki pages
-    name = request.form.get("pagename", [""])[0]
+    name = request.values.get("pagename", "")
     if name:
         from MoinMoin import search
         # XXX error handling!
@@ -393,7 +389,7 @@
 
     # wiki url
     url_prefix_static = request.cfg.url_prefix_static
-    scriptname = request.getScriptname()
+    scriptname = request.script_root
     if not scriptname or scriptname[-1] != "/":
         scriptname += "/"
     action = scriptname
@@ -461,7 +457,6 @@
 ##############################################################################
 
 def image_dialog(request):
-    request.emit_http_headers()
     url_prefix_static = request.cfg.url_prefix_static
     request.write('''
 <!--
@@ -524,7 +519,7 @@
 #############################################################################
 
 def execute(pagename, request):
-    dialog = request.form.get("dialog", [""])[0]
+    dialog = request.values.get("dialog", "")
 
     if dialog == "macro":
         macro_dialog(request)
--- a/MoinMoin/action/fullsearch.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/fullsearch.py	Thu Jan 29 09:44:57 2009 +0100
@@ -22,12 +22,12 @@
     'fullsearch' with localized string. If both missing, default to
     True (might happen with Safari) if this isn't an advanced search.
 """
-    form = request.form
+    form = request.values
     if 'titlesearch' in form and 'fullsearch' in form:
         ret = -1 # spammer / bot
     else:
         try:
-            ret = int(form['titlesearch'][0])
+            ret = int(form['titlesearch'])
         except ValueError:
             ret = 1
         except KeyError:
@@ -37,7 +37,7 @@
 def isAdvancedSearch(request):
     """ Return True if advanced search is requested """
     try:
-        return int(request.form['advancedsearch'][0])
+        return int(request.values['advancedsearch'])
     except KeyError:
         return False
 
@@ -66,38 +66,40 @@
 
     advancedsearch = isAdvancedSearch(request)
 
+    form = request.values
+
     # context is relevant only for full search
     if titlesearch:
         context = 0
     elif advancedsearch:
         context = 180 # XXX: hardcoded context count for advancedsearch
     else:
-        context = int(request.form.get('context', [0])[0])
+        context = int(form.get('context', 0))
 
     # Get other form parameters
-    needle = request.form.get(fieldname, [''])[0]
-    case = int(request.form.get('case', [0])[0])
-    regex = int(request.form.get('regex', [0])[0]) # no interface currently
-    hitsFrom = int(request.form.get('from', [0])[0])
+    needle = form.get(fieldname, '')
+    case = int(form.get('case', 0))
+    regex = int(form.get('regex', 0)) # no interface currently
+    hitsFrom = int(form.get('from', 0))
     mtime = None
     msg = ''
     historysearch = 0
 
     # if advanced search is enabled we construct our own search query
     if advancedsearch:
-        and_terms = request.form.get('and_terms', [''])[0].strip()
-        or_terms = request.form.get('or_terms', [''])[0].strip()
-        not_terms = request.form.get('not_terms', [''])[0].strip()
-        #xor_terms = request.form.get('xor_terms', [''])[0].strip()
-        categories = request.form.get('categories', [''])
-        timeframe = request.form.get('time', [''])[0].strip()
-        language = request.form.get('language', [''])
-        mimetype = request.form.get('mimetype', [0])
-        excludeunderlay = request.form.get('excludeunderlay', [0])[0]
-        nosystemitems = request.form.get('nosystemitems', [0])[0]
-        historysearch = request.form.get('historysearch', [0])[0]
+        and_terms = form.get('and_terms', '').strip()
+        or_terms = form.get('or_terms', '').strip()
+        not_terms = form.get('not_terms', '').strip()
+        #xor_terms = form.get('xor_terms', '').strip()
+        categories = form.getlist('categories') or ['']
+        timeframe = form.get('time', '').strip()
+        language = form.getlist('language') or ['']
+        mimetype = form.getlist('mimetype') or [0]
+        excludeunderlay = form.get('excludeunderlay', 0)
+        nosystemitems = form.get('nosystemitems', 0)
+        historysearch = form.get('historysearch', 0)
 
-        mtime = request.form.get('mtime', [''])[0]
+        mtime = form.get('mtime', '')
         if mtime:
             mtime_parsed = None
 
@@ -224,12 +226,10 @@
         Page(request, pagename).send_page()
         return
 
-    request.emit_http_headers()
-
     # This action generates data using the user language
     request.setContentLanguage(request.lang)
 
-    request.theme.send_title(title % needle, form=request.form, pagename=pagename)
+    request.theme.send_title(title % needle, pagename=pagename)
 
     # Start content (important for RTL support)
     request.write(request.formatter.startContent("content"))
--- a/MoinMoin/action/info.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/info.py	Thu Jan 29 09:44:57 2009 +0100
@@ -76,7 +76,7 @@
         _ = request.getText
         default_count, limit_max_count = request.cfg.history_count
         try:
-            max_count = int(request.form.get('max_count', [default_count])[0])
+            max_count = int(request.values.get('max_count', default_count))
         except:
             max_count = default_count
         max_count = min(max_count, limit_max_count)
@@ -143,7 +143,7 @@
                     if line.action == 'ATTNEW':
                         actions.append(render_action(_('view'), {'action': 'AttachFile', 'do': 'view', 'target': '%s' % filename}))
                     elif line.action == 'ATTDRW':
-                        actions.append(render_action(_('edit'), {'action': 'AttachFile', 'drawing': '%s' % filename.replace(".draw", "")}))
+                        actions.append(render_action(_('edit'), {'action': 'AttachFile', 'drawing': '%s' % filename.replace(".tdraw", "")}))
 
                     actions.append(render_action(_('get'), {'action': 'AttachFile', 'do': 'get', 'target': '%s' % filename}))
                     if request.user.may.delete(pagename):
@@ -187,8 +187,6 @@
     page = Page(request, pagename)
     title = page.split_title()
 
-    request.emit_http_headers()
-
     request.setContentLanguage(request.lang)
     f = request.formatter
 
@@ -207,14 +205,8 @@
         request.write("[%s] " % page.link_to(request, text=text, querystr=querystr, rel='nofollow'))
     request.write(f.paragraph(0))
 
-    try:
-        show_hitcounts = int(request.form.get('hitcounts', [0])[0]) != 0
-    except ValueError:
-        show_hitcounts = False
-    try:
-        show_general = int(request.form.get('general', [0])[0]) != 0
-    except ValueError:
-        show_general = False
+    show_hitcounts = int(request.values.get('hitcounts', 0)) != 0
+    show_general = int(request.values.get('general', 0)) != 0
 
     if show_hitcounts:
         from MoinMoin.stats import hitcounts
--- a/MoinMoin/action/links.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/links.py	Thu Jan 29 09:44:57 2009 +0100
@@ -11,15 +11,9 @@
 
 def execute(pagename, request):
     _ = request.getText
-    form = request.form
-
     # get the MIME type
-    if 'mimetype' in form:
-        mimetype = form['mimetype'][0]
-    else:
-        mimetype = "text/html"
-
-    request.emit_http_headers(["Content-Type: %s; charset=%s" % (mimetype, config.charset)])
+    mimetype = request.values.get('mimetype', 'text/html')
+    request.mimetype = mimetype
 
     if mimetype == "text/html":
         request.theme.send_title(_('Full Link List for "%s"') % request.cfg.sitename)
--- a/MoinMoin/action/login.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/login.py	Thu Jan 29 09:44:57 2009 +0100
@@ -38,7 +38,6 @@
         form.append(html.INPUT(type='hidden', name='stage',
                                value=request._login_multistage_name))
 
-        request.emit_http_headers()
         request.theme.send_title(_("Login"), pagename=self.pagename)
         # Start content (important for RTL support)
         request.write(request.formatter.startContent("content"))
@@ -59,7 +58,7 @@
 
         error = None
 
-        islogin = form.get('login', [''])[0]
+        islogin = form.get('login', '')
 
         if islogin: # user pressed login button
             if request._login_multistage:
@@ -74,7 +73,6 @@
             return self.page.send_page()
 
         else: # show login form
-            request.emit_http_headers()
             request.theme.send_title(_("Login"), pagename=self.pagename)
             # Start content (important for RTL support)
             request.write(request.formatter.startContent("content"))
--- a/MoinMoin/action/newaccount.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/newaccount.py	Thu Jan 29 09:44:57 2009 +0100
@@ -19,7 +19,7 @@
     _ = request.getText
     form = request.form
 
-    if request.request_method != 'POST':
+    if request.method != 'POST':
         return
 
     if not TextCha(request).check_answer_from_form():
@@ -30,7 +30,7 @@
 
     # Require non-empty name
     try:
-        theuser.name = form['name'][0]
+        theuser.name = form['name']
     except KeyError:
         return _("Empty user name. Please enter a user name.")
 
@@ -45,8 +45,8 @@
         return _("This user name already belongs to somebody else.")
 
     # try to get the password and pw repeat
-    password = form.get('password1', [''])[0]
-    password2 = form.get('password2', [''])[0]
+    password = form.get('password1', '')
+    password2 = form.get('password2', '')
 
     # Check if password is given and matches with password repeat
     if password != password2:
@@ -69,7 +69,7 @@
             return "Can't encode password: %s" % str(err)
 
     # try to get the email, for new users it is required
-    email = wikiutil.clean_input(form.get('email', [''])[0])
+    email = wikiutil.clean_input(form.get('email', ''))
     theuser.email = email.strip()
     if not theuser.email and 'email' not in request.cfg.user_form_remove:
         return _("Please provide your email address. If you lose your"
@@ -172,7 +172,6 @@
         request.theme.add_msg(_create_user(request), "dialog")
         return page.send_page()
     else: # show create form
-        request.emit_http_headers()
         request.theme.send_title(_("Create Account"), pagename=pagename)
 
         request.write(request.formatter.startContent("content"))
--- a/MoinMoin/action/newpage.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/newpage.py	Thu Jan 29 09:44:57 2009 +0100
@@ -19,8 +19,8 @@
     def __init__(self, request, referrer):
         self.request = request
         self.referrer = referrer # The page the user came from
-        self.pagename = self.request.form.get('pagename', [None])[0]
-        self.nametemplate = self.request.form.get('nametemplate', ['%s'])[0]
+        self.pagename = self.request.values.get('pagename')
+        self.nametemplate = self.request.values.get('nametemplate', '%s')
         self.nametemplate = self.nametemplate.replace('\x00', '')
 
     def checkAndCombineArguments(self):
@@ -82,11 +82,11 @@
             pagename = self.pagename
             query = {'action': 'edit', 'backto': self.referrer}
 
-            template = self.request.form.get('template', [''])[0]
+            template = self.request.values.get('template', '')
             if template:
                 query['template'] = template
 
-            parent = self.request.form.get('parent', [''])[0]
+            parent = self.request.values.get('parent', '')
             if parent:
                 pagename = "%s/%s" % (parent, pagename)
 
@@ -97,7 +97,7 @@
 
 def execute(pagename, request):
     """ Temporary glue code for current moin action system """
-    if request.request_method != 'POST':
+    if request.method != 'POST':
         return False, u''
 
     return NewPage(request, pagename).render()
--- a/MoinMoin/action/pollsistersites.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/pollsistersites.py	Thu Jan 29 09:44:57 2009 +0100
@@ -54,5 +54,5 @@
         except TypeError: # catch bug in python 2.5: "EnvironmentError expected at most 3 arguments, got 4"
             status.append(u"Site: %s Status: Not updated." % sistername)
 
-    request.emit_http_headers(["Content-Type: text/plain; charset=UTF-8"])
+    request.mimetype = 'text/plain'
     request.write("\r\n".join(status).encode("utf-8"))
--- a/MoinMoin/action/recoverpass.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/recoverpass.py	Thu Jan 29 09:44:57 2009 +0100
@@ -30,7 +30,7 @@
 Contact the owner of the wiki, who can enable email.""")
 
     try:
-        email = wikiutil.clean_input(form['email'][0].lower())
+        email = wikiutil.clean_input(form['email'].lower())
         if not email:
             # continue if email not given
             raise KeyError
@@ -42,7 +42,7 @@
         pass
 
     try:
-        username = wikiutil.clean_input(form['name'][0])
+        username = wikiutil.clean_input(form['name'])
         if not username:
             # continue if name not given
             raise KeyError
@@ -152,7 +152,7 @@
 
     page = Page(request, pagename)
     _ = request.getText
-    form = request.form
+    form = request.values # link in mail -> GET request
 
     if not request.cfg.mail_enabled:
         request.theme.add_msg(_("""This wiki is not enabled for mail processing.
@@ -160,13 +160,13 @@
         page.send_page()
         return
 
-    submitted = form.get('account_sendmail', [''])[0]
-    token = form.get('token', [''])[0]
-    newpass = form.get('password', [''])[0]
-    name = form.get('name', [''])[0]
+    submitted = form.get('account_sendmail', '')
+    token = form.get('token', '')
+    newpass = form.get('password', '')
+    name = form.get('name', '')
 
     if token and name and newpass:
-        newpass2 = form.get('password_repeat', [''])[0]
+        newpass2 = form.get('password_repeat', '')
         msg = _("Passwords don't match!")
         msg_type = 'error'
         if newpass == newpass2:
@@ -190,7 +190,6 @@
             return
 
     if token and name:
-        request.emit_http_headers()
         request.theme.send_title(_("Password reset"), pagename=pagename)
 
         request.write(request.formatter.startContent("content"))
@@ -205,13 +204,12 @@
         request.theme.send_footer(pagename)
         request.theme.send_closing_html()
     elif submitted: # user pressed create button
-        if request.request_method != 'POST':
+        if request.method != 'POST':
             return
         msg = _do_recover(request)
         request.theme.add_msg(msg, "dialog")
         page.send_page()
     else: # show create form
-        request.emit_http_headers()
         request.theme.send_title(_("Lost password"), pagename=pagename)
 
         request.write(request.formatter.startContent("content"))
--- a/MoinMoin/action/refresh.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/refresh.py	Thu Jan 29 09:44:57 2009 +0100
@@ -11,10 +11,10 @@
 def execute(pagename, request):
     """ Handle refresh action """
     # Without arguments, refresh action will refresh the page text_html cache.
-    arena = request.form.get('arena', ['Page.py'])[0]
+    arena = request.values.get('arena', 'Page.py')
     if arena == 'Page.py':
         arena = Page(request, pagename)
-    key = request.form.get('key', ['text_html'])[0]
+    key = request.values.get('key', 'text_html')
 
     # Remove cache entry (if exists), and send the page
     from MoinMoin import caching
--- a/MoinMoin/action/revert.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/revert.py	Thu Jan 29 09:44:57 2009 +0100
@@ -48,10 +48,10 @@
     def do_action(self):
         """ revert pagename """
         form = self.form
-        comment = form.get('comment', [u''])[0]
+        comment = form.get('comment', u'')
         comment = wikiutil.clean_input(comment)
 
-        if self.request.request_method != 'POST':
+        if self.request.method != 'POST':
             return False, u''
 
         rev = self.request.rev
--- a/MoinMoin/action/rss_rc.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/rss_rc.py	Thu Jan 29 09:44:57 2009 +0100
@@ -24,8 +24,7 @@
     """ Send recent changes as an RSS document
     """
     if not wikixml.ok:
-        httpheaders = ["Content-Type: text/plain; charset=%s" % config.charset]
-        request.emit_http_headers(httpheaders)
+        request.mimetype = 'text/plain'
         request.write("rss_rc action is not supported because of missing pyxml module.")
         return
 
@@ -34,22 +33,22 @@
     # get params
     items_limit = 100
     try:
-        max_items = int(request.form['items'][0])
+        max_items = int(request.values['items'])
         max_items = min(max_items, items_limit) # not more than `items_limit`
     except (KeyError, ValueError):
         # not more than 15 items in a RSS file by default
         max_items = 15
     try:
-        unique = int(request.form.get('unique', [0])[0])
+        unique = int(request.values.get('unique', 0))
     except ValueError:
         unique = 0
     try:
-        diffs = int(request.form.get('diffs', [0])[0])
+        diffs = int(request.values.get('diffs', 0))
     except ValueError:
         diffs = 0
     ## ddiffs inserted by Ralf Zosel <ralf@zosel.com>, 04.12.2003
     try:
-        ddiffs = int(request.form.get('ddiffs', [0])[0])
+        ddiffs = int(request.values.get('ddiffs', 0))
     except ValueError:
         ddiffs = 0
 
@@ -86,31 +85,27 @@
     if request.if_modified_since == timestamp:
         if request.if_none_match:
             if request.if_none_match == etag:
-                request.emit_http_headers(["Status: 304 Not modified"])
+                request.status_code = 304
         else:
-            request.emit_http_headers(["Status: 304 Not modified"])
+            request.status_code = 304
     elif request.if_none_match == etag:
         if request.if_modified_since:
             if request.if_modified_since == timestamp:
-                request.emit_http_headers(["Status: 304 Not modified"])
+                request.status_code = 304
         else:
-            request.emit_http_headers(["Status: 304 Not modified"])
+            request.status_code = 304
     else:
         # generate an Expires header, using whatever setting the admin
         # defined for suggested cache lifetime of the RecentChanges RSS doc
-        expires = timefuncs.formathttpdate(time.time() + cfg.rss_cache)
+        expires = time.time() + cfg.rss_cache
 
-        httpheaders = ["Content-Type: text/xml; charset=%s" % config.charset,
-                       "Expires: %s" % expires,
-                       "Last-Modified: %s" % timestamp,
-                       "Etag: %s" % etag, ]
+        request.mime_type = 'text/xml'
+        request.expires = expires
+        request.last_modified = lastmod
+        request.headers.add('Etag', etag)
 
         # send the generated XML document
-        request.emit_http_headers(httpheaders)
-
-        baseurl = request.getBaseURL()
-        if not baseurl.endswith('/'):
-            baseurl += '/'
+        baseurl = request.url_root
 
         logo = re.search(r'src="([^"]*)"', cfg.logo_string)
         if logo:
@@ -139,7 +134,7 @@
 
         # emit channel description
         handler.startNode('channel', {
-            (handler.xmlns['rdf'], 'about'): request.getBaseURL(),
+            (handler.xmlns['rdf'], 'about'): request.url_root,
             })
         handler.simpleNode('title', cfg.sitename)
         page = Page(request, pagename)
--- a/MoinMoin/action/serveopenid.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/serveopenid.py	Thu Jan 29 09:44:57 2009 +0100
@@ -18,7 +18,7 @@
 from openid.server import server
 from openid.message import IDENTIFIER_SELECT
 from MoinMoin.widget import html
-from MoinMoin.request import MoinMoinFinish
+from MoinMoin.web.request import MoinMoinFinish
 
 def execute(pagename, request):
     return MoinOpenIDServer(pagename, request).handle()
@@ -31,9 +31,8 @@
 
     def serveYadisEP(self, endpoint_url):
         request = self.request
-        hdrs = ['Content-type: application/xrds+xml']
+        request.content_type = 'application/xrds+xml'
 
-        request.emit_http_headers(hdrs)
         user_url = request.getQualifiedURL(request.page.url(request))
         self.request.write("""\
 <?xml version="1.0" encoding="UTF-8"?>
@@ -79,9 +78,8 @@
 
     def serveYadisIDP(self, endpoint_url):
         request = self.request
-        hdrs = ['Content-type: application/xrds+xml']
+        request.content_type = 'application/xrds+xml'
 
-        request.emit_http_headers(hdrs)
         user_url = request.getQualifiedURL(request.page.url(request))
         self.request.write("""\
 <?xml version="1.0" encoding="UTF-8"?>
@@ -190,7 +188,7 @@
         server_url = request.getQualifiedURL(
                          request.page.url(request, querystr={'action': 'serveopenid'}))
 
-        yadis_type = form.get('yadis', [None])[0]
+        yadis_type = form.get('yadis')
         if yadis_type == 'ep':
             return self.serveYadisEP(server_url)
         elif yadis_type == 'idp':
@@ -198,7 +196,7 @@
 
         # if the identity is set it must match the server URL
         # sort of arbitrary, but we have to have some restriction
-        identity = form.get('openid.identity', [None])[0]
+        identity = form.get('openid.identity')
         if identity == IDENTIFIER_SELECT:
             identity, server_url = self._make_identity()
             if not identity:
@@ -217,7 +215,7 @@
         openidsrv = server.Server(store, op_endpoint=server_url)
 
         answer = None
-        if form.has_key('dontapprove'):
+        if 'dontapprove' in form:
             answer = self.handle_response(False, username, identity)
             if answer is None:
                 return
@@ -227,8 +225,8 @@
                 return
         else:
             query = {}
-            for key in form.keys():
-                query[key] = form[key][0]
+            for key in form:
+                query[key] = form[key]
             try:
                 openidreq = openidsrv.decodeRequest(query)
             except Exception, e:
@@ -249,10 +247,9 @@
             else:
                 answer = openidsrv.handleRequest(openidreq)
         webanswer = openidsrv.encodeResponse(answer)
-        headers = ['Status: %d OpenID status' % webanswer.code]
+        request.status = '%d OpenID status' % webanswer.code
         for hdr in webanswer.headers:
-            headers += [hdr+': '+webanswer.headers[hdr]]
-        request.emit_http_headers(headers)
+            request.headers.add(hdr, webanswer.headers[hdr])
         request.write(webanswer.body)
         raise MoinMoinFinish
 
@@ -266,7 +263,7 @@
         if session_nonce is not None:
             del self.request.session['openidserver.nonce']
         # use empty string if nothing was sent
-        form_nonce = form.get('nonce', [''])[0]
+        form_nonce = form.get('nonce', '')
         if session_nonce != form_nonce:
             self.request.makeForbidden403()
             self.request.write('invalid nonce')
@@ -285,7 +282,7 @@
             return openidreq.answer(False)
 
 
-        if form.get('remember', ['no'])[0] == 'yes':
+        if form.get('remember', 'no') == 'yes':
             if not hasattr(request.user, 'openid_trusted_roots'):
                 request.user.openid_trusted_roots = []
             request.user.openid_trusted_roots.append(strbase64(openidreq.trust_root))
@@ -324,7 +321,6 @@
 Once you have logged in, simply reload this page.'''))
             return
 
-        request.emit_http_headers()
         request.theme.send_title(_("OpenID Trust verification"), pagename=request.page.page_name)
         # Start content (important for RTL support)
         request.write(request.formatter.startContent("content"))
@@ -397,7 +393,6 @@
         request = self.request
         _ = self._
 
-        request.emit_http_headers()
         request.theme.send_title(_("OpenID not served"), pagename=request.page.page_name)
         # Start content (important for RTL support)
         request.write(request.formatter.startContent("content"))
--- a/MoinMoin/action/showtags.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/showtags.py	Thu Jan 29 09:44:57 2009 +0100
@@ -13,9 +13,7 @@
 from MoinMoin.wikisync import TagStore
 
 def execute(pagename, request):
-    mimetype = "text/plain"
-
-    request.emit_http_headers(["Content-Type: %s; charset=%s" % (mimetype, config.charset)])
+    request.mimetype = "text/plain"
 
     page = Page(request, pagename)
     tags = TagStore(page)
--- a/MoinMoin/action/sisterpages.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/sisterpages.py	Thu Jan 29 09:44:57 2009 +0100
@@ -32,30 +32,26 @@
     if request.if_modified_since == timestamp:
         if request.if_none_match:
             if request.if_none_match == etag:
-                request.emit_http_headers(["Status: 304 Not modified"])
+                request.status_code = 304
         else:
-            request.emit_http_headers(["Status: 304 Not modified"])
+            request.status_code = 304
     elif request.if_none_match == etag:
         if request.if_modified_since:
             if request.if_modified_since == timestamp:
-                request.emit_http_headers(["Status: 304 Not modified"])
+                request.status_code = 304
         else:
-            request.emit_http_headers(["Status: 304 Not modified"])
+            request.status_code = 304
     else:
         # generate an Expires header, using 1d cache lifetime of sisterpages list
-        expires = timefuncs.formathttpdate(time.time() + 24*3600)
+        expires = time.time() + 24*3600
 
-        httpheaders = ["Content-Type: text/plain; charset=UTF-8",
-                       "Expires: %s" % expires,
-                       "Last-Modified: %s" % timestamp,
-                       "Etag: %s" % etag, ]
+        request.mime_type = 'text/plain'
+        request.expires = expires
+        request.last_modified = timestamp
+        request.headers.add("Etag", etag)
 
         # send the generated XML document
-        request.emit_http_headers(httpheaders)
-
-        baseurl = request.getBaseURL()
-        if not baseurl.endswith('/'):
-            baseurl += '/'
+        baseurl = request.url_root
 
         # Get list of user readable pages
         pages = request.rootpage.getPageList()
--- a/MoinMoin/action/sitemap.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/sitemap.py	Thu Jan 29 09:44:57 2009 +0100
@@ -62,10 +62,9 @@
 
 def execute(pagename, request):
     _ = request.getText
-    form = request.form
     request.user.datetime_fmt = datetime_fmt
 
-    request.emit_http_headers(["Content-Type: text/xml; charset=UTF-8"])
+    request.mimetype ='text/xml'
 
     # we emit a piece of data so other side doesn't get bored:
     request.write("""<?xml version="1.0" encoding="UTF-8"?>\r\n""")
@@ -86,7 +85,7 @@
 
     # Get page dict readable by current user
     try:
-        underlay = int(form.get('underlay', [1])[0])
+        underlay = int(request.values.get('underlay', 1))
     except ValueError:
         underlay = 1
     pages = request.rootpage.getPageDict(include_underlay=underlay)
--- a/MoinMoin/action/thread_monitor.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/thread_monitor.py	Thu Jan 29 09:44:57 2009 +0100
@@ -33,7 +33,6 @@
     else:
         dump_fname = "nowhere"
 
-    request.emit_http_headers()
     request.write('<html><body>A dump has been saved to %s.</body></html>' % dump_fname)
 
 def execute_wiki(pagename, request):
@@ -44,8 +43,6 @@
         request.theme.add_msg(_('You are not allowed to use this action.'), "error")
         return Page.Page(request, pagename).send_page()
 
-    request.emit_http_headers()
-
     request.theme.send_title("Thread monitor")
     request.write('<pre>')
 
--- a/MoinMoin/action/titleindex.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/titleindex.py	Thu Jan 29 09:44:57 2009 +0100
@@ -14,15 +14,9 @@
 
 
 def execute(pagename, request):
-    form = request.form
-
     # get the MIME type
-    if 'mimetype' in form:
-        mimetype = form['mimetype'][0]
-    else:
-        mimetype = "text/plain"
-
-    request.emit_http_headers(["Content-Type: %s; charset=%s" % (mimetype, config.charset)])
+    mimetype = request.values.get('mimetype', "text/plain")
+    request.mimetype = mimetype
 
     # Get list of user readable pages
     pages = request.rootpage.getPageList()
--- a/MoinMoin/action/userprefs.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/userprefs.py	Thu Jan 29 09:44:57 2009 +0100
@@ -16,7 +16,7 @@
     Return error msg_class, msg tuple or None, None.
     """
     _ = request.getText
-    sub = request.form.get('handler', [None])[0]
+    sub = request.values.get('handler')
 
     if sub in request.cfg.userprefs_disabled:
         return None, None
@@ -63,12 +63,12 @@
     # returns text, title, msg_class, msg
     pagename = request.page.page_name
 
-    if 'handler' in request.form:
+    if 'handler' in request.values:
         msg_class, msg = _handle_submission(request)
     else:
         msg_class, msg = None, None
 
-    sub = request.form.get('sub', [''])[0]
+    sub = request.args.get('sub', '')
     cls = None
     if sub and sub not in request.cfg.userprefs_disabled:
         try:
@@ -101,7 +101,6 @@
         title = _("Settings") + ":" + title
     else:
         title = _("Settings")
-    request.emit_http_headers()
     request.theme.add_msg(msg, msg_class)
     request.theme.send_title(title, page=request.page, pagename=pagename)
     # Start content (important for RTL support)
--- a/MoinMoin/action/userprofile.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/action/userprofile.py	Thu Jan 29 09:44:57 2009 +0100
@@ -17,9 +17,9 @@
     if not request.user.isSuperUser():
         request.theme.add_msg(_("Only superuser is allowed to use this action."), "error")
     else:
-        user_name = form.get('name', [''])[0]
-        key = form.get('key', [''])[0]
-        val = form.get('val', [''])[0]
+        user_name = form.get('name', '')
+        key = form.get('key', '')
+        val = form.get('val', '')
         if key in cfg.user_checkbox_fields:
             val = int(val)
         uid = user.getUserId(request, user_name)
--- a/MoinMoin/auth/__init__.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/auth/__init__.py	Thu Jan 29 09:44:57 2009 +0100
@@ -160,9 +160,7 @@
     if request.page:
         return request.page.url(request, querystr=fields)
     else:
-        qstr = wikiutil.makeQueryString(fields)
-        return ''.join([request.getBaseURL(), '?', qstr])
-
+        return request.abs_href(**fields)
 
 class LoginReturn(object):
     """ LoginReturn - base class for auth method login() return value"""
@@ -257,3 +255,94 @@
                'userprefslink': userprefslink,
                'sendmypasswordlink': sendmypasswordlink}
 
+def handle_login(request, userobj=None, username=None, password=None,
+                 attended=True, openid_identifier=None, stage=None):
+    """
+    Process a 'login' request by going through the configured authentication
+    methods in turn. The passable keyword arguments are explained in more
+    detail at the top of this file.
+    """
+    params = {
+        'username': username,
+        'password': password,
+        'attended': attended,
+        'openid_identifier': openid_identifier,
+        'multistage': (stage and True) or None
+    }
+    for authmethod in request.cfg.auth:
+        if stage and authmethod.name != stage:
+            continue
+        ret = authmethod.login(request, userobj, **params)
+
+        userobj = ret.user_obj
+        cont = ret.continue_flag
+        if stage:
+            stage = None
+            del params['multistage']
+
+        if ret.multistage:
+            request._login_multistage = ret.multistage
+            request._login_multistage_name = authmethod.name
+            return userobj
+
+        if ret.redirect_to:
+            nextstage = auth.get_multistage_continuation_url(request, authmethod.name)
+            url = ret.redirect_to
+            url = url.replace('%return_form', quote_plus(nextstage))
+            url = url.replace('%return', quote(nextstage))
+            abort(redirect(url))
+        msg = ret.message
+        if msg and not msg in request._login_messages:
+            request._login_messages.append(msg)
+
+        if not cont:
+            break
+
+    return userobj
+
+def handle_logout(request, userobj):
+    """ Logout the passed user from every configured authentication method. """
+    for authmethod in request.cfg.auth:
+        userobj, cont = authmethod.logout(request, userobj, cookie=request.cookies)
+        if not cont:
+            break
+    return userobj
+
+def handle_request(request, userobj):
+    """ Handle the per-request callbacks of the configured authentication methods. """
+    for authmethod in request.cfg.auth:
+        userobj, cont = authmethod.request(request, userobj, cookie=request.cookies)
+        if not cont:
+            break
+    return userobj
+
+def setup_setuid(request, userobj):
+    """ Check for setuid conditions in the session and setup an user
+    object accordingly. Returns a tuple of the new user objects.
+
+    @param request: a moin request object
+    @param userobj: a moin user object
+    @rtype: boolean
+    @return: (new_user, user) or (user, None)
+    """
+    old_user = None
+    if 'setuid' in request.session and userobj.isSuperUser():
+        old_user = userobj
+        uid = request.session['setuid']
+        userobj = user.User(request, uid, auth_method='setuid')
+        userobj.valid = True
+    return (userobj, old_user)
+
+def setup_from_session(request, session):
+    userobj = None
+    if 'user.id' in session:
+        auth_userid = session['user.id']
+        auth_method = session['user.auth_method']
+        auth_attrs = session['user.auth_attribs']
+        if auth_method and auth_method in \
+                [auth.name for auth in request.cfg.auth]:
+            userobj = user.User(request, id=auth_userid,
+                                auth_method=auth_method,
+                                auth_attribs=auth_attrs)
+    logging.debug("session started for user %r", userobj)
+    return userobj
--- a/MoinMoin/auth/_tests/test_auth.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/auth/_tests/test_auth.py	Thu Jan 29 09:44:57 2009 +0100
@@ -5,14 +5,11 @@
     @copyright: 2008 MoinMoin:ThomasWaldmann
     @license: GNU GPL, see COPYING for details.
 """
-
 import py.test
 py.test.skip("broken due to test Config refactoring, fix later")
 
-import StringIO, urllib
-
-from MoinMoin.server.server_wsgi import WsgiConfig
-from MoinMoin.request import request_wsgi
+from MoinMoin.web.request import TestRequest, evaluate_request
+from MoinMoin import wsgiapp
 from MoinMoin._tests import wikiconfig
 
 
@@ -25,55 +22,32 @@
 
         Some test needs specific config values, or they will fail.
         """
-        config = WsgiConfig() # you MUST create an instance
 
     def teardown_class(cls):
         """ Stuff that should run to clean up the state of this test class
 
         """
-        pass
 
-    def setup_env(self, **kw):
-        default_environ = {
-            'SERVER_NAME': 'localhost',
-            'SERVER_PORT': '80',
-            'SCRIPT_NAME': '',
-            'PATH_INFO': '/',
-            'QUERY_STRING': '',
-            'REQUEST_METHOD': 'GET',
-            'REMOTE_ADDR': '10.10.10.10',
-            'HTTP_HOST': 'localhost',
-            #'HTTP_COOKIE': '',
-            #'HTTP_ACCEPT_LANGUAGE': '',
-        }
-        env = {}
-        env.update(default_environ)
-        env.update(kw)
-        if 'wsgi.input' not in env:
-            env['wsgi.input'] = StringIO.StringIO()
-        return env
-
-    def process_request(self, environ):
-        request = request_wsgi.Request(environ)
-        save_user = request.user # keep a reference, request.finish does "del request.user"
-        request.run()
-        request.user = save_user
-        return request # request.status, request.headers, request.output()
+    def run_request(self, **params):
+        request = TestRequest(**params)
+        context = wsgiapp.init(request)
+        wsgiapp.run(context)
+        return context
 
 
 class TestNoAuth(AuthTest):
     def testNoAuth(self):
         """ run a simple request, no auth, just check if it succeeds """
-        environ = self.setup_env()
-        request = self.process_request(environ)
+        request = self.run_request()
 
         # anon user?
         assert not request.user.valid
 
+        appiter, status, headers = evaluate_request(request.request)
         # check if the request resulted in normal status, result headers and content
-        assert request.status == '200 OK'
+        assert status[:3] == '200'
         has_ct = has_v = has_cc = False
-        for k, v in request.headers:
+        for k, v in headers:
             if k == 'Content-Type':
                 assert v.startswith('text/html')
                 has_ct = True
@@ -90,8 +64,7 @@
         assert has_v
         # XXX BROKEN?:
         #assert has_cc # cache anon user's content
-        output = request.output()
-        assert '</html>' in output
+        assert '</html>' in ''.join(appiter)
 
 class TestAnonSession(AuthTest):
     class Config(wikiconfig.Config):
@@ -103,20 +76,21 @@
         trail_expected = []
         first = True
         for pagename in self.PAGES:
-            environ = self.setup_env(PATH_INFO='/%s' % pagename,
-                                     HTTP_COOKIE=cookie)
-            request = self.process_request(environ)
+            environ_overrides = {'HTTP_COOKIE': cookie}
+            request = self.run_request(path='/%s' % pagename,
+                                       environ_overrides=environ_overrides)
 
             # anon user?
             assert not request.user.valid
 
             # Do we have a session?
-            assert request.session
+            assert request.session is not None
 
+            appiter, status, headers = evaluate_request(request.request)
             # check if the request resulted in normal status, result headers and content
-            assert request.status == '200 OK'
+            assert status[:3] == '200'
             has_ct = has_v = has_cc = False
-            for k, v in request.headers:
+            for k, v in headers:
                 if k == 'Content-Type':
                     assert v.startswith('text/html')
                     has_ct = True
@@ -134,8 +108,7 @@
             assert has_v
             # XX BROKEN
             #assert not has_cc # do not cache anon user's (with session!) content
-            output = request.output()
-            assert '</html>' in output
+            assert '</html>' in ''.join(appiter)
 
             # The trail is only ever saved on the second page display
             # because otherwise anonymous sessions would be created
@@ -163,24 +136,27 @@
     def testHttpAuthSession(self):
         """ run some requests with http auth, check whether session works """
         username = u'HttpAuthTestUser'
+        auth_info = u'%s:%s' % (username, u'testpass')
+        auth_header = 'Basic %s' % auth_info.encode('base64')
         cookie = ''
         trail_expected = []
         first = True
         for pagename in self.PAGES:
-            environ = self.setup_env(AUTH_TYPE='Basic', REMOTE_USER=str(username),
-                                     PATH_INFO='/%s' % pagename,
-                                     HTTP_COOKIE=cookie)
-            request = self.process_request(environ)
+            environ_overrides = {'HTTP_COOKIE': cookie,
+                                 'HTTP_AUTHORIZATION': auth_header}
+            request = self.run_request(path='/%s' % pagename,
+                                       environ_overrides=environ_overrides)
 
             # Login worked?
             assert request.user.valid
             assert request.user.name == username
 
             # Do we have a session?
-            assert request.session
+            assert request.session is not None
 
+            appiter, status, headers = evaluate_request(request.request)
             # check if the request resulted in normal status, result headers and content
-            assert request.status == '200 OK'
+            assert status[:3] == '200'
             has_ct = has_v = has_cc = False
             for k, v in request.headers:
                 if k == 'Content-Type':
@@ -199,8 +175,7 @@
             assert has_ct
             assert has_v
             assert has_cc # do not cache logged-in user's content
-            output = request.output()
-            assert '</html>' in output
+            assert '</html>' in ''.join(appiter)
 
             # The trail is only ever saved on the second page display
             # because otherwise anonymous sessions would be created
@@ -233,30 +208,29 @@
         first = True
         for pagename in self.PAGES:
             if first:
-                formdata = urllib.urlencode({
-                    'name': username.encode('utf-8'),
-                    'password': password.encode('utf-8'),
+                formdata = {
+                    'name': username,
+                    'password': password,
                     'login': 'login',
-                })
-                environ = self.setup_env(PATH_INFO='/%s' % pagename,
-                                         HTTP_CONTENT_TYPE='application/x-www-form-urlencoded',
-                                         HTTP_CONTENT_LENGTH='%d' % len(formdata),
-                                         QUERY_STRING='action=login', REQUEST_METHOD='POST',
-                                         **{'wsgi.input': StringIO.StringIO(formdata)})
+                }
+                request = self.run_request(path='/%s' % pagename,
+                                           query_string='login=login',
+                                           method='POST', form_data=formdata)
             else: # not first page, use session cookie
-                environ = self.setup_env(PATH_INFO='/%s' % pagename,
-                                         HTTP_COOKIE=cookie)
-            request = self.process_request(environ)
+                environ_overrides = {'HTTP_COOKIE': cookie}
+                request = self.run_request(path='/%s' % pagename,
+                                           environ_overrides=environ_overrides)
 
             # Login worked?
             assert request.user.valid
             assert request.user.name == username
 
             # Do we have a session?
-            assert request.session
+            assert request.session is not None
 
+            appiter, status, headers = evaluate_request(request.request)
             # check if the request resulted in normal status, result headers and content
-            assert request.status == '200 OK'
+            assert status[:3] == '200'
             has_ct = has_v = has_cc = False
             for k, v in request.headers:
                 if k == 'Content-Type':
@@ -275,8 +249,7 @@
             assert has_ct
             assert has_v
             assert has_cc # do not cache logged-in user's content
-            output = request.output()
-            assert '</html>' in output
+            assert '</html>' in ''.join(appiter)
 
             # The trail is only ever saved on the second page display
             # because otherwise anonymous sessions would be created
--- a/MoinMoin/auth/_tests/test_ldap_login.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/auth/_tests/test_ldap_login.py	Thu Jan 29 09:44:57 2009 +0100
@@ -12,6 +12,7 @@
 from MoinMoin._tests.ldap_testbase import LDAPTstBase, LdapEnvironment, check_environ, SLAPD_EXECUTABLE
 from MoinMoin._tests.ldap_testdata import *
 from MoinMoin._tests import nuke_user, wikiconfig
+from MoinMoin.auth import handle_login
 
 # first check if we have python 2.4, python-ldap and slapd:
 msg = check_environ()
@@ -60,21 +61,21 @@
         handle_auth = self.request.handle_auth
 
         # tests that must not authenticate:
-        u = handle_auth(None, username='', password='', login=True)
+        u = handle_login(self.request, None, username='', password='')
         assert u is None
-        u = handle_auth(None, username='usera', password='', login=True)
+        u = handle_login(self.request, None, username='usera', password='')
         assert u is None
-        u = handle_auth(None, username='usera', password='userawrong', login=True)
+        u = handle_login(self.request, None, username='usera', password='userawrong')
         assert u is None
-        u = handle_auth(None, username='userawrong', password='usera', login=True)
+        u = handle_login(self.request, None, username='userawrong', password='usera')
         assert u is None
 
         # tests that must authenticate:
-        u1 = handle_auth(None, username='usera', password='usera', login=True)
+        u1 = handle_login(self.request, None, username='usera', password='usera')
         assert u1 is not None
         assert u1.valid
 
-        u2 = handle_auth(None, username='userb', password='userb', login=True)
+        u2 = handle_login(self.request, None, username='userb', password='userb')
         assert u2 is not None
         assert u2.valid
 
@@ -111,27 +112,25 @@
 
         nuke_user(self.request, u'usera')
 
-        handle_auth = self.request.handle_auth
-
         # do a LDAPAuth login (as a side effect, this autocreates the user profile):
-        u1 = handle_auth(None, username='usera', password='usera', login=True)
+        u1 = handle_login(self.request, None, username='usera', password='usera')
         assert u1 is not None
         assert u1.valid
 
         # now we kill the LDAP server:
-        self.ldap_env.slapd.stop()
+        #self.ldap_env.slapd.stop()
 
         # now try a MoinAuth login:
         # try the default password that worked in 1.7 up to rc1:
-        u2 = handle_auth(None, username='usera', password='{SHA}NotStored', login=True)
+        u2 = handle_login(self.request, None, username='usera', password='{SHA}NotStored')
         assert u2 is None
 
         # try using no password:
-        u2 = handle_auth(None, username='usera', password='', login=True)
+        u2 = handle_login(self.request, None, username='usera', password='')
         assert u2 is None
 
         # try using wrong password:
-        u2 = handle_auth(None, username='usera', password='wrong', login=True)
+        u2 = handle_login(self.request, None, username='usera', password='wrong')
         assert u2 is None
 
 
@@ -221,7 +220,7 @@
         handle_auth = self.request.handle_auth
 
         # authenticate user (with primary slapd):
-        u1 = handle_auth(None, username='usera', password='usera', login=True)
+        u1 = handle_login(self.request, None, username='usera', password='usera')
         assert u1 is not None
         assert u1.valid
 
@@ -229,7 +228,7 @@
         self.ldap_envs[0].slapd.stop()
 
         # try if we can still authenticate (with the second slapd):
-        u2 = handle_auth(None, username='usera', password='usera', login=True)
+        u2 = handle_login(self.request, None, username='usera', password='usera')
         assert u2 is not None
         assert u2.valid
 
--- a/MoinMoin/auth/http.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/auth/http.py	Thu Jan 29 09:44:57 2009 +0100
@@ -14,7 +14,6 @@
 """
 
 from MoinMoin import config, user
-from MoinMoin.request import request_twisted, request_cli, request_standalone
 from MoinMoin.auth import BaseAuth
 from base64 import decodestring
 
@@ -36,45 +35,10 @@
         if user_obj:
             return user_obj, True
 
-        # for standalone, request authorization and verify it,
-        # deny access if it isn't verified
-        if isinstance(request, request_standalone.Request):
-            request.setHttpHeader('WWW-Authenticate: Basic realm="MoinMoin"')
-            auth = request.headers.get('Authorization')
-            if auth:
-                auth = auth.split()[-1]
-                info = decodestring(auth).split(':', 1)
-                if len(info) == 2:
-                    u = user.User(request, auth_username=info[0], password=info[1],
-                                  auth_method=self.name, auth_attribs=[])
-            if not u:
-                request.makeForbidden(401, _('You need to log in.'))
-        # for Twisted, just check
-        elif isinstance(request, request_twisted.Request):
-            username = request.twistd.getUser().decode(config.charset)
-            password = request.twistd.getPassword().decode(config.charset)
-            # when using Twisted http auth, we use username and password from
-            # the moin user profile, so both can be changed by user.
-            u = user.User(request, auth_username=username, password=password,
-                          auth_method=self.name, auth_attribs=())
-        elif not isinstance(request, request_cli.Request):
-            env = request.env
-            auth_type = env.get('AUTH_TYPE', '')
-            if auth_type in ['Basic', 'Digest', 'NTLM', 'Negotiate', ]:
-                username = env.get('REMOTE_USER', '').decode(config.charset)
-                if auth_type in ('NTLM', 'Negotiate', ):
-                    # converting to standard case so the user can even enter wrong case
-                    # (added since windows does not distinguish between e.g.
-                    #  "Mike" and "mike")
-                    username = username.split('\\')[-1] # split off domain e.g.
-                                                        # from DOMAIN\user
-                    # this "normalizes" the login name from {meier, Meier, MEIER} to Meier
-                    # put a comment sign in front of next line if you don't want that:
-                    username = username.title()
-                # when using http auth, we have external user name and password,
-                # we don't use the moin user profile for those attributes.
-                u = user.User(request, auth_username=username,
-                              auth_method=self.name, auth_attribs=('name', 'password'))
+        authobj = request.authorization
+        if authobj:
+            u = user.User(request, auth_username=authobj.username,
+                          auth_method=self.name, auth_attribs=('name', 'password'))
 
         if u and self.autocreate:
             u.create_or_update()
--- a/MoinMoin/auth/openidrp.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/auth/openidrp.py	Thu Jan 29 09:44:57 2009 +0100
@@ -136,7 +136,7 @@
                                         MoinOpenIDStore(request))
         query = {}
         for key in request.form:
-            query[key] = request.form[key][0]
+            query[key] = request.form[key]
         current_url = get_multistage_continuation_url(request, self.name,
                                                       {'oidstage': '1'})
         info = oidconsumer.complete(query, current_url)
@@ -173,7 +173,7 @@
             return CancelLogin(None)
 
         _ = request.getText
-        newname = request.form.get('username', [''])[0]
+        newname = request.form.get('username', '')
         if not newname:
             return MultistageFormLogin(self._get_account_name)
         if not user.isValidName(request, newname):
@@ -198,8 +198,8 @@
             return CancelLogin()
 
         _ = request.getText
-        username = request.form.get('username', [''])[0]
-        password = request.form.get('password', [''])[0]
+        username = request.form.get('username', '')
+        password = request.form.get('password', '')
         if not password:
             return self._handle_name_continuation(request)
         u = user.User(request, name=username, password=password,
@@ -214,7 +214,7 @@
             return MultistageFormLogin(assoc)
 
     def _handle_continuation(self, request):
-        oidstage = request.form.get('oidstage', [0])[0]
+        oidstage = request.form.get('oidstage', '0')
         if oidstage == '1':
             return self._handle_verify_continuation(request)
         elif oidstage == '2':
@@ -282,7 +282,7 @@
 
             return_to = get_multistage_continuation_url(request, self.name,
                                                         {'oidstage': '1'})
-            trust_root = request.getBaseURL()
+            trust_root = request.url_root
             if oidreq.shouldSendRedirect():
                 redirect_url = oidreq.redirectURL(trust_root, return_to)
                 return MultistageRedirectLogin(redirect_url)
--- a/MoinMoin/auth/sslclientcert.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/auth/sslclientcert.py	Thu Jan 29 09:44:57 2009 +0100
@@ -11,7 +11,6 @@
 """
 
 from MoinMoin import config, user
-from MoinMoin.request import request_twisted
 from MoinMoin.auth import BaseAuth
 
 class SSLClientCertAuth(BaseAuth):
@@ -35,60 +34,53 @@
     def request(self, request, user_obj, **kw):
         u = None
         changed = False
-        # check if we are running Twisted
-        if isinstance(request, request_twisted.Request):
-            return user_obj, True # not supported if we run twisted
-            # Addendum: this seems to need quite some twisted insight and coding.
-            # A pointer i got on #twisted: divmod's vertex.sslverify
-            # If you really need this, feel free to implement and test it and
-            # submit a patch if it works.
-        else:
-            env = request.env
-            if env.get('SSL_CLIENT_VERIFY', 'FAILURE') == 'SUCCESS':
-
-                # check authority list if given
-                if self.authorities and env.get('SSL_CLIENT_I_DN_OU') in self.authorities:
-                    return user_obj, True
 
-                email_lower = None
-                if self.email_key:
-                    email = env.get('SSL_CLIENT_S_DN_Email', '').decode(config.charset)
-                    email_lower = email.lower()
-                commonname_lower = None
-                if self.name_key:
-                    commonname = env.get('SSL_CLIENT_S_DN_CN', '').decode(config.charset)
-                    commonname_lower = commonname.lower()
-                if email_lower or commonname_lower:
-                    for uid in user.getUserList(request):
-                        u = user.User(request, uid,
-                                      auth_method=self.name, auth_attribs=())
-                        if self.email_key and email_lower and u.email.lower() == email_lower:
-                            u.auth_attribs = ('email', 'password')
-                            if self.use_name and commonname_lower != u.name.lower():
-                                u.name = commonname
-                                changed = True
-                                u.auth_attribs = ('email', 'name', 'password')
-                            break
-                        if self.name_key and commonname_lower and u.name.lower() == commonname_lower:
-                            u.auth_attribs = ('name', 'password')
-                            if self.use_email and email_lower != u.email.lower():
-                                u.email = email
-                                changed = True
-                                u.auth_attribs = ('name', 'email', 'password')
-                            break
-                    else:
-                        u = None
-                    if u is None:
-                        # user wasn't found, so let's create a new user object
-                        u = user.User(request, name=commonname_lower, auth_username=commonname_lower,
-                                      auth_method=self.name)
+        env = request.environ
+        if env.get('SSL_CLIENT_VERIFY', 'FAILURE') == 'SUCCESS':
+
+            # check authority list if given
+            if self.authorities and env.get('SSL_CLIENT_I_DN_OU') in self.authorities:
+                return user_obj, True
+
+            email_lower = None
+            if self.email_key:
+                email = env.get('SSL_CLIENT_S_DN_Email', '').decode(config.charset)
+                email_lower = email.lower()
+            commonname_lower = None
+            if self.name_key:
+                commonname = env.get('SSL_CLIENT_S_DN_CN', '').decode(config.charset)
+                commonname_lower = commonname.lower()
+            if email_lower or commonname_lower:
+                for uid in user.getUserList(request):
+                    u = user.User(request, uid,
+                                  auth_method=self.name, auth_attribs=())
+                    if self.email_key and email_lower and u.email.lower() == email_lower:
+                        u.auth_attribs = ('email', 'password')
+                        if self.use_name and commonname_lower != u.name.lower():
+                            u.name = commonname
+                            changed = True
+                            u.auth_attribs = ('email', 'name', 'password')
+                        break
+                    if self.name_key and commonname_lower and u.name.lower() == commonname_lower:
                         u.auth_attribs = ('name', 'password')
-                        if self.use_email:
+                        if self.use_email and email_lower != u.email.lower():
                             u.email = email
+                            changed = True
                             u.auth_attribs = ('name', 'email', 'password')
-            elif user_obj and user_obj.auth_method == self.name:
-                user_obj.valid = False
-                return user_obj, False
+                        break
+                else:
+                    u = None
+                if u is None:
+                    # user wasn't found, so let's create a new user object
+                    u = user.User(request, name=commonname_lower, auth_username=commonname_lower,
+                                  auth_method=self.name)
+                    u.auth_attribs = ('name', 'password')
+                    if self.use_email:
+                        u.email = email
+                        u.auth_attribs = ('name', 'email', 'password')
+        elif user_obj and user_obj.auth_method == self.name:
+            user_obj.valid = False
+            return user_obj, False
         if u and self.autocreate:
             u.create_or_update(changed)
         if u and u.valid:
--- a/MoinMoin/config/multiconfig.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/config/multiconfig.py	Thu Jan 29 09:44:57 2009 +0100
@@ -16,13 +16,15 @@
 from MoinMoin import log
 logging = log.getLogger(__name__)
 
-from MoinMoin import config, error, util, wikiutil
+from MoinMoin import config, error, util, wikiutil, web
 from MoinMoin.auth import MoinAuth
+import MoinMoin.auth as authmodule
 import MoinMoin.events as events
 from MoinMoin.events import PageChangedEvent, PageRenamedEvent
 from MoinMoin.events import PageDeletedEvent, PageCopiedEvent
 from MoinMoin.events import PageRevertedEvent, FileAttachedEvent
 from MoinMoin import session
+import MoinMoin.web.session
 from MoinMoin.packages import packLine
 from MoinMoin.security import AccessControlList
 from MoinMoin.support.python_compatibility import set
@@ -693,6 +695,8 @@
      "See HelpOnSessions."),
     ('session_id_handler', DefaultExpression('session.MoinCookieSessionIDHandler()'),
      "Only used by the DefaultSessionHandler, see HelpOnSessions."),
+    ('session_service', DefaultExpression('web.session.FileSessionService()'),
+     "New session service (used by the new WSGI layer)"),
     ('cookie_secure', None,
      'Use secure cookie. (None = auto-enable secure cookie for https, True = ever use secure cookie, False = never use secure cookie).'),
     ('cookie_domain', None,
--- a/MoinMoin/conftest.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/conftest.py	Thu Jan 29 09:44:57 2009 +0100
@@ -30,6 +30,8 @@
 sys.path.insert(0, str(moindir))
 
 from MoinMoin.support.python_compatibility import set
+from MoinMoin.web.request import TestRequest, Client
+from MoinMoin.wsgiapp import Application, init
 from MoinMoin._tests import maketestwiki, wikiconfig
 
 coverage_modules = set()
@@ -55,7 +57,6 @@
         coverage.erase()
         coverage.start()
 
-
     py.test.config.addoptions('MoinMoin options', py.test.config.Option('-C',
         '--coverage', action='callback', callback=callback,
         help='Output information about code coverage (slow!)'))
@@ -65,17 +66,12 @@
 
 
 def init_test_request(given_config=None, static_state=[False]):
-    from MoinMoin.request import request_cli
-    from MoinMoin.user import User
-    from MoinMoin.formatter.text_html import Formatter as HtmlFormatter
     if not static_state[0]:
         maketestwiki.run(True)
         static_state[0] = True
-    request = request_cli.Request(given_config=given_config)
-    request.form = request.args = request.setup_args()
-    request.user = User(request)
-    request.html_formatter = HtmlFormatter(request)
-    request.formatter = request.html_formatter
+    request = TestRequest()
+    request.given_config = given_config
+    request = init(request)
     return request
 
 
@@ -98,8 +94,12 @@
         cls = self.obj
         if hasattr(cls, 'Config'):
             cls.request = init_test_request(given_config=cls.Config)
+            cls.client = Client(Application(cls.Config))
         else:
             cls.request = self.parent.request
+            #XXX: this is the extremely messy way to configure the wsgi app
+            #     with the correct testing config
+            cls.client = Client(Application(self.parent.request.cfg.__class__))
         super(MoinClassCollector, self).setup()
 
 
--- a/MoinMoin/converter/_tests/test_text_html_text_moin_wiki.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/converter/_tests/test_text_html_text_moin_wiki.py	Thu Jan 29 09:44:57 2009 +0100
@@ -14,7 +14,7 @@
 from MoinMoin.converter import text_html_text_moin_wiki as converter
 from MoinMoin.parser.text_moin_wiki import Parser
 from MoinMoin.formatter.text_gedit import Formatter
-from MoinMoin.request import Clock
+from MoinMoin.util.clock import Clock
 from MoinMoin.error import ConvertError
 
 convert = converter.convert
--- a/MoinMoin/converter/text_html_text_moin_wiki.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/converter/text_html_text_moin_wiki.py	Thu Jan 29 09:44:57 2009 +0100
@@ -1205,7 +1205,7 @@
         href = attrs.pop('href', None)
         css_class = attrs.get('class')
 
-        scriptname = self.request.getScriptname()
+        scriptname = self.request.script_root
         if scriptname == "":
             scriptname = "/"
 
--- a/MoinMoin/events/emailnotify.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/events/emailnotify.py	Thu Jan 29 09:44:57 2009 +0100
@@ -136,7 +136,7 @@
     for lang in subscribers:
         recipients.extend(subscribers[lang])
 
-    attachlink = request.getBaseURL() + getAttachUrl(event.pagename, event.filename, request)
+    attachlink = request.url_root + getAttachUrl(event.pagename, event.filename, request)
     pagelink = request.getQualifiedURL(page.url(request, {}))
 
     for lang in subscribers:
--- a/MoinMoin/events/jabbernotify.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/events/jabbernotify.py	Thu Jan 29 09:44:57 2009 +0100
@@ -75,7 +75,7 @@
     for lang in subscribers:
         recipients.extend(subscribers[lang])
 
-    attachlink = request.getBaseURL() + getAttachUrl(event.pagename, event.filename, request)
+    attachlink = request.url_root + getAttachUrl(event.pagename, event.filename, request)
     pagelink = request.getQualifiedURL(page.url(request, {}))
 
     for lang in subscribers.keys():
--- a/MoinMoin/events/notification.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/events/notification.py	Thu Jan 29 09:44:57 2009 +0100
@@ -78,7 +78,7 @@
         'The "%(pagename)s" page has been changed by %(editor)s:\n') % {
             'pagename': page.page_name,
             'editor': page.uid_override or user.getUserIdentification(request),
-            'sitename': page.cfg.sitename or request.getBaseURL(),
+            'sitename': page.cfg.sitename or request.url_root,
         }
 
         # append a diff (or append full page text if there is no diff)
@@ -98,7 +98,7 @@
             'The page "%(pagename)s" has been deleted by %(editor)s:\n\n') % {
                 'pagename': page.page_name,
                 'editor': page.uid_override or user.getUserIdentification(request),
-                'sitename': page.cfg.sitename or request.getBaseURL(),
+                'sitename': page.cfg.sitename or request.url_root,
         }
 
     elif msgtype == "page_renamed":
@@ -107,7 +107,7 @@
             'The page "%(pagename)s" has been renamed from "%(oldname)s" by %(editor)s:\n') % {
                 'editor': page.uid_override or user.getUserIdentification(request),
                 'pagename': page.page_name,
-                'sitename': page.cfg.sitename or request.getBaseURL(),
+                'sitename': page.cfg.sitename or request.url_root,
                 'oldname': kwargs['old_name']
         }
 
@@ -150,7 +150,7 @@
 
     data['subject'] = _("New attachment added to page %(pagename)s on %(sitename)s") % {
                 'pagename': page_name,
-                'sitename': request.cfg.sitename or request.getBaseURL(),
+                'sitename': request.cfg.sitename or request.url_root,
                 }
 
     data['text'] = _("Dear Wiki user,\n\n"
--- a/MoinMoin/failure.py	Wed Jan 28 17:06:22 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,208 +0,0 @@
-# -*- coding: iso-8859-1 -*-
-""" MoinMoin failure
-
-    Handle fatal errors by showing a message and debugging information.
-
-    @copyright: 2004-2005 Nir Soffer <nirs@freeshell.org>
-    @license: GNU GPL, see COPYING for details.
-"""
-import sys, os
-import traceback
-
-from MoinMoin import log
-logging = log.getLogger(__name__)
-
-from MoinMoin.support import cgitb
-from MoinMoin.error import ConfigurationError
-
-
-class View(cgitb.View):
-    """ Display an error message and debugging information
-
-    Additions to cgitb.View:
-     - Multiple tracebacks support
-     - Debugging information is shown only in debug mode
-     - Moin application information
-     - General help text and links
-     - Handle multiple paragraphs in exception message
-
-    cgitb is heavily modified cgitb, but fully backward compatible with
-    the standard cgitb. It should not contain any moin specific code.
-
-    cgitb was refactored to be easy to customize by applications
-    developers. This moin specific subclass is an example.
-    """
-    debugInfoID = 'debug-info'
-
-    def formatContent(self):
-        content = (
-            self.script(),
-            self.formatStylesheet(),
-            self.formatTitle(),
-            self.formatMessage(),
-            self.formatButtons(),
-            self.formatDebugInfo(),
-            self.formatTextTraceback()
-            )
-        return ''.join(content)
-
-    def script(self):
-        return '''
-<script type="text/javascript">
-function toggleDebugInfo() {
-    var tb = document.getElementById('%s');
-    if (tb == null) return;
-    tb.style.display = tb.style.display ? '' : 'none';
-}
-</script>
-''' % self.debugInfoID
-
-    def stylesheet(self):
-        return cgitb.View.stylesheet(self) + """
-.cgitb .buttons {margin: 0.5em 0; padding: 5px 10px;}
-.cgitb .buttons li {display: inline; margin: 0; padding: 0 0.25em;}
-"""
-
-    def formatMessage(self):
-        """ handle multiple paragraphs messages and add general help """
-        f = self.formatter
-        text = [self.formatExceptionMessage(self.info)]
-
-        if self.info[0] == ConfigurationError:
-            tbt = traceback.extract_tb(self.info[1].exceptions()[-1][2])[-1]
-            text.append(
-                f.paragraph('Error in your configuration file "%s"'
-                            ' around line %d.' % tbt[:2]))
-        else:
-            text.append(
-                f.paragraph("If you want to report a bug, please save "
-                            "this page and  attach it to your bug report."))
-        return ''.join(text)
-
-    def formatButtons(self):
-        """ Add 'buttons' to the error dialog """
-        f = self.formatter
-        buttons = [f.link('javascript:toggleDebugInfo()',
-                          'Show debugging information')]
-        if self.info[0] != ConfigurationError:
-            buttons.append(
-                   f.link('http://moinmo.in/MoinMoinBugs',
-                          'Report bug'))
-            buttons.append(
-                   f.link('http://moinmo.in/FrontPage',
-                          'Visit MoinMoin wiki'))
-        return f.list(buttons, {'class': 'buttons'})
-
-    def formatDebugInfo(self):
-        """ Put debugging information in a hidden div """
-        attributes = {'id': self.debugInfoID}
-        info = [self.debugInfoHideScript(),
-                self.formatTraceback(),
-                self.formatSystemDetails(), ]
-        return self.formatter.section(''.join(info), attributes)
-
-    def debugInfoHideScript(self):
-        """ Hide debug info for javascript enabled browsers """
-        if self.debug:
-            return ''
-        return '''
-<script type="text/javascript">toggleDebugInfo()</script>
-'''
-
-    def formatTraceback(self):
-        return self.formatAllTracebacks(self.formatOneTraceback)
-
-    def formatTextTraceback(self):
-        template = self.textTracebackTemplate()
-        return template % self.formatAllTracebacks(self.formatOneTextTraceback)
-
-    def formatAllTracebacks(self, formatFuction):
-        """ Format multiple tracebacks using formatFunction """
-        tracebacks = []
-        for ttype, tvalue, tb in self.exceptions():
-            if ttype is None:
-                break
-            tracebacks.append(formatFuction((ttype, tvalue, tb)))
-            del tb
-        return ''.join(tracebacks)
-
-    def exceptions(self):
-        """ Return a list of exceptions info, starting at self.info """
-        try:
-            return [self.info] + self.info[1].exceptions()
-        except AttributeError:
-            return [self.info]
-
-    def applicationDetails(self):
-        """ Add MoinMoin details to system details """
-        from MoinMoin import version
-        return ['MoinMoin: Release %s (%s)' % (version.release,
-                                              version.revision)]
-
-    def formatExceptionMessage(self, info):
-        """ Handle multiple paragraphs in exception message """
-        text = cgitb.View.exceptionMessage(self, info)
-        text = text.split('\n\n')
-        text = ''.join([self.formatter.paragraph(item) for item in text])
-        return text
-
-
-def handle(request, err):
-    """ Handle failures
-
-    Display fancy error view, or fallback to simple text traceback
-    """
-    if 'MOIN_DEBUG' in os.environ:
-        raise err
-
-    savedError = sys.exc_info()
-    logging.exception('An exception occurred, URI was "%s".' % request.request_uri)
-
-    try:
-        display = request.cfg.traceback_show # might fail if we have no cfg yet
-    except:
-        # default to True here to allow an admin setting up the wiki
-        # to see the errors made in the configuration file
-        display = True
-
-    try:
-        debug = 'debug' in request.form
-    except:
-        debug = False
-
-    try:
-        # try to output a nice html error page
-        handler = cgitb.Hook(file=request, display=display, viewClass=View, debug=debug)
-        handler.handle(savedError)
-    except:
-        # if that fails, log the cgitb problem ...
-        logging.exception('cgitb raised this exception')
-        # ... and try again with a simpler output method:
-        request.write('<pre>\n')
-        printTextException(request, savedError, display)
-        request.write('\nAdditionally cgitb raised this exception:\n')
-        printTextException(request, display=display)
-        request.write('</pre>\n')
-
-
-
-def printTextException(request, info=None, display=True):
-    """ Simple text exception that should never fail
-
-    Print all exceptions in a composite error.
-    """
-    if not display:
-        request.write("(Traceback display forbidden by configuration)\n")
-        return
-    from MoinMoin import wikiutil
-    if info is None:
-        info = sys.exc_info()
-    try:
-        exceptions = [info] + info[1].exceptions()
-    except AttributeError:
-        exceptions = [info]
-    for info in exceptions:
-        text = ''.join(traceback.format_exception(*info))
-        text = wikiutil.escape(text)
-        request.write(text)
-
--- a/MoinMoin/formatter/__init__.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/formatter/__init__.py	Thu Jan 29 09:44:57 2009 +0100
@@ -74,12 +74,12 @@
 
     def startContent(self, content_id="content", **kw):
         if self.page:
-            self.request.begin_include(self.page.page_name)
+            self.request.uid_generator.begin(self.page.page_name)
         return ""
 
     def endContent(self):
         if self.page:
-            self.request.end_include()
+            self.request.uid_generator.end()
         return ""
 
     # Links ##############################################################
@@ -93,7 +93,7 @@
             return ''
         if not pagename and page:
             pagename = page.page_name
-        pagename = self.request.normalizePagename(pagename)
+        pagename = wikiutil.normalize_pagename(pagename, self.request.cfg)
         if pagename and pagename not in self.pagelinks:
             self.pagelinks.append(pagename)
 
@@ -407,11 +407,11 @@
         '''
         Take an ID and make it unique in the current namespace.
         '''
-        ns = self.request.include_id
+        ns = self.request.uid_generator.include_id
         if not ns is None:
             ns = self.sanitize_to_id(ns)
         id = self.sanitize_to_id(id)
-        id = self.request.make_unique_id(id, ns)
+        id = self.request.uid_generator(id, ns)
         return id
 
     def qualify_id(self, id):
@@ -421,7 +421,7 @@
         is suitable if the dot ('.') is valid in IDs for your
         formatter.
         '''
-        ns = self.request.include_id
+        ns = self.request.uid_generator.include_id
         if not ns is None:
             ns = self.sanitize_to_id(ns)
             return '%s.%s' % (ns, id)
--- a/MoinMoin/formatter/_tests/test_formatter.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/formatter/_tests/test_formatter.py	Thu Jan 29 09:44:57 2009 +0100
@@ -21,7 +21,7 @@
             pass
         else:
             print "Formatting using %r" % formatter
-            self.formatPage("SyntaxReference", formatter)
+            self.formatPage("HelpOnMoinWikiSyntax", formatter)
             print "Done."
 
     def testSyntaxReferenceDocBook(self):
@@ -57,7 +57,7 @@
                 pass
             else:
                 print "Formatting using %r" % formatter
-                self.formatPage("SyntaxReference", formatter)
+                self.formatPage("HelpOnMoinWikiSyntax", formatter)
                 print "Done."
 
     def formatPage(self, pagename, formatter):
--- a/MoinMoin/formatter/text_docbook.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/formatter/text_docbook.py	Thu Jan 29 09:44:57 2009 +0100
@@ -364,7 +364,7 @@
     def url(self, on, url=None, css=None, **kw):
         if url and url.startswith("/"):
             # convert to absolute path:
-            url = "%s%s"%(self.request.getBaseURL(), url)
+            url = "%s%s"%(self.request.base_url, url)
 
         if not on:
             self._cleanupUlinkNode()
@@ -457,7 +457,7 @@
             src = kw['src']
             if src.startswith("/"):
                 # convert to absolute path:
-                src = self.request.getBaseURL()+src
+                src = self.request.url_root + src
             image.setAttribute('fileref', src)
         if kw.has_key('width'):
             image.setAttribute('width', str(kw['width']))
--- a/MoinMoin/formatter/text_html.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/formatter/text_html.py	Thu Jan 29 09:44:57 2009 +0100
@@ -410,7 +410,7 @@
         """
 
         if hasattr(self, 'page'):
-            self.request.begin_include(self.page.page_name)
+            self.request.uid_generator.begin(self.page.page_name)
 
         result = []
         # Use the content language
@@ -434,7 +434,7 @@
         result.append(self.anchordef('bottom'))
         result.append(self._close('div', newline=newline))
         if hasattr(self, 'page'):
-            self.request.end_include()
+            self.request.uid_generator.end()
         return ''.join(result)
 
     def lang(self, on, lang_name):
@@ -655,35 +655,25 @@
     def attachment_drawing(self, url, text, **kw):
         # XXX text arg is unused!
         _ = self.request.getText
-        pagename, filename = AttachFile.absoluteName(url, self.page.page_name)
-        fname = wikiutil.taintfilename(filename)
-        drawing = fname
-        fname = fname + u".png"
-        filename = filename + u".png"
-        # fallback for old gif drawings (1.1 -> 1.2)
-        exists = AttachFile.exists(self.request, pagename, fname)
-        if not exists:
-            gfname = fname[:-4] + u".gif"
-            gfilename = filename[:-4] + u".gif"
-            exists = AttachFile.exists(self.request, pagename, gfname)
-            if exists:
-                fname, filename = gfname, gfilename
+        pagename, drawing = AttachFile.absoluteName(url, self.page.page_name)
+        containername = wikiutil.taintfilename(drawing) + ".tdraw"
 
-        # check whether attachment exists, possibly point to upload form
-        drawing_url = AttachFile.getAttachUrl(pagename, fname, self.request, drawing=drawing, upload=True)
-        if not exists:
-            title = _('Create new drawing "%(filename)s (opens in new window)"') % {'filename': fname}
+        drawing_url = AttachFile.getAttachUrl(pagename, containername, self.request, drawing=drawing, upload=True)
+        ci = AttachFile.ContainerItem(self.request, pagename, containername)
+        if not ci.exists():
+            title = _('Create new drawing "%(filename)s (opens in new window)"') % {'filename': drawing}
             img = self.icon('attachimg')  # TODO: we need a new "drawimg" in similar grey style and size
             css = 'nonexistent'
             return self.url(1, drawing_url, css=css, title=title) + img + self.url(0)
 
-        title = _('Edit drawing %(filename)s (opens in new window)') % {'filename': self.text(fname)}
-        kw['src'] = AttachFile.getAttachUrl(pagename, filename, self.request, addts=1)
+        title = _('Edit drawing %(filename)s (opens in new window)') % {'filename': self.text(drawing)}
+        kw['src'] = src = ci.member_url(drawing + u'.png')
         kw['css'] = 'drawing'
 
-        mappath = AttachFile.getFilename(self.request, pagename, drawing + u'.map')
+        mapfile = ci.get(drawing + u'.map')
         try:
-            map = file(mappath, 'r').read()
+            map = mapfile.read()
+            mapfile.close()
         except (IOError, OSError):
             map = ''
         if map:
@@ -691,11 +681,11 @@
             mapid = 'ImageMapOf' + drawing
             map = map.replace('%MAPNAME%', mapid)
             # add alt and title tags to areas
-            map = re.sub('href\s*=\s*"((?!%TWIKIDRAW%).+?)"', r'href="\1" alt="\1" title="\1"', map)
+            map = re.sub(r'href\s*=\s*"((?!%TWIKIDRAW%).+?)"', r'href="\1" alt="\1" title="\1"', map)
             map = map.replace('%TWIKIDRAW%"', '%s" alt="%s" title="%s"' % (drawing_url, title, title))
             # unxml, because 4.01 concrete will not validate />
             map = map.replace('/>', '>')
-            title = _('Clickable drawing: %(filename)s') % {'filename': self.text(fname)}
+            title = _('Clickable drawing: %(filename)s') % {'filename': self.text(drawing)}
             if 'title' not in kw:
                 kw['title'] = title
             if 'alt' not in kw:
--- a/MoinMoin/i18n/MoinMoin.pot	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/MoinMoin.pot	Thu Jan 29 09:44:57 2009 +0100
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -2045,19 +2045,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr ""
 
-msgid "Password is too short."
-msgstr ""
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr ""
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr ""
 
--- a/MoinMoin/i18n/__init__.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/__init__.py	Thu Jan 29 09:44:57 2009 +0100
@@ -362,15 +362,12 @@
     the request, normalizing to lower case.
     """
     fallback = []
-    accepted = request.http_accept_language
+    accepted = request.accept_languages
     if accepted:
-        # Extract the languages names from the string
-        accepted = accepted.split(',')
-        accepted = [lang.split(';')[0] for lang in accepted]
         # Add base language for each sub language. If the user specified
         # a sub language like "en-us", we will try to to provide it or
         # a least the base language "en" in this case.
-        for lang in accepted:
+        for lang, quality in accepted:
             lang = lang.lower()
             fallback.append(lang)
             if '-' in lang:
--- a/MoinMoin/i18n/ar.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/ar.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: moin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2008-04-12 20:07+0200\n"
 "Last-Translator: Mohamed Yahya <yahya.mohamed@gmail.com>\n"
 "Language-Team: \n"
@@ -2144,21 +2144,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "لا يسمح لك بتحرير هذه الصفحة"
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "اعادة كلمة السر"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "لا يوجد كلمة سر. الرجاء إدخال إسم مستخدم و كلمة سر"
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr ""
 
--- a/MoinMoin/i18n/bg.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/bg.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2006-02-11 12:20-0800\n"
 "Last-Translator: Hristo Iliev <hristo@phys.uni-sofia.bg>\n"
 "Language-Team: Bulgarian <moin-devel@lists.sourceforge.net>\n"
@@ -2350,21 +2350,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Бяхте абонирани за тази страница."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Повторение на паролата"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Липсва парола. Моля, въведете потребителско име и парола."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Разлики"
 
--- a/MoinMoin/i18n/ca.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/ca.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: moin 1.7\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2008-07-30 17:24+0200\n"
 "Last-Translator: Jordi Mallach <jordi@sindominio.net>\n"
 "Language-Team: Catalan <ca@dodds.net>\n"
@@ -2244,21 +2244,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Vos heu subscrit a aquesta pàgina."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Contrasenya (comprovació)"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Manca la contrasenya. Introduïu el nom d'usuari i contrasenya."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Diferències"
 
--- a/MoinMoin/i18n/cs.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/cs.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2007-11-05 22:11+0100\n"
 "Last-Translator: Václav Haisman <v.haisman@sh.cvut.cz>\n"
 "Language-Team: Czech <moin@lists.sourceforge.net>\n"
@@ -2308,21 +2308,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Přihlásili jste se k odběru této stránky."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Opakovat heslo"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Prázdné heslo. Prosím vložte jméno a heslo."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Rozdíly"
 
--- a/MoinMoin/i18n/da.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/da.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2007-04-22 18:50+0100\n"
 "Last-Translator: Jonas Smedegaard <dr@jones.dk>\n"
 "Language-Team: Danish <moin-devel@lists.sourceforge.net>\n"
@@ -2339,21 +2339,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Du abonnerer nu på denne side."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Adgangskode gentaget"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Manglende adgangskode. Angiv venligst brugernavn og adgangskode."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "forskelle"
 
--- a/MoinMoin/i18n/de.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/de.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.8\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2008-08-30 19:48+0200\n"
 "Last-Translator: Thomas Waldmann <tw-public@gmx.de>\n"
 "Language-Team: German <moin-user@lists.sourceforge.net>\n"
@@ -814,8 +814,7 @@
 "    User name: %(username)s\n"
 "    Email address: %(useremail)s"
 msgstr ""
-"Lieber Superuser, ein neuer Benutzer wurde gerade auf %(sitename)s erzeugt. "
-"Details folgen:\n"
+"Lieber Superuser, ein neuer Benutzer wurde gerade auf %(sitename)s erzeugt. Details folgen:\n"
 "\n"
 "    Benutzer-Name:  %(username)s\n"
 "    E-Mail-Adresse: %(useremail)s"
@@ -2404,21 +2403,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Sie müssen die Seite abonniert haben, um das Abonnement zu entfernen."
 
-msgid "Password is too short."
-msgstr "Passwort ist zu kurz."
-
-msgid "Password has not enough different characters."
-msgstr "Passwort hat nicht genug unterschiedliche Buchstaben."
-
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr ""
-"Passwort ist zu einfach (das Passwort enthält den Namen oder der Name "
-"enthält das Passwort)."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr "Passwort ist zu einfach (Tastatur-Sequenz)."
-
 msgid "Diffs"
 msgstr "DifferenzAnzeige"
 
@@ -2542,7 +2526,7 @@
 msgstr "Abmelden"
 
 msgid "Clear message"
-msgstr "Meldung ausblenden"
+msgstr "Nachricht löschen"
 
 #, python-format
 msgid "last edited %(time)s by %(editor)s"
--- a/MoinMoin/i18n/el.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/el.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2007-12-22 17:56+0200\n"
 "Last-Translator: YiannisValassakis <tungolcild@gmail.com>\n"
 "Language-Team: Greek <moin-devel@lists.sourceforge.net>\n"
@@ -2155,20 +2155,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr ""
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Κωδικός"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr ""
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr ""
 
--- a/MoinMoin/i18n/en.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/en.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -11,7 +11,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.5\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2005-01-8 00:00+0100\n"
 "Last-Translator: Thomas Waldmann <tw-public@gmx.de>\n"
 "Language-Team: German <moin-devel@lists.sourceforge.net>\n"
@@ -2052,19 +2052,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr ""
 
-msgid "Password is too short."
-msgstr ""
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr ""
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr ""
 
--- a/MoinMoin/i18n/es.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/es.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2008-08-15 10:04-0500\n"
 "Last-Translator: Igor Támara <igor@tamaraptino.org>\n"
 "Language-Team: Spanish <moin-devel@lists.sourceforge.net>\n"
@@ -2353,23 +2353,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Necesitas estar suscrito para cancelar la suscripción."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Restaurar clave"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr ""
-"Faltó ingresar la contraseña. Por favor, ingresa el nombre de usuario y "
-"contraseña"
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Diferencias"
 
--- a/MoinMoin/i18n/fa.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/fa.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: 1.7.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2005-07-22 17:11+0330\n"
 "Last-Translator: Mehdi Hassanpour <h.mehdi@gmail.com>\n"
 "Language-Team: Persian <h.mehdi@gmail.com>\n"
@@ -336,8 +336,8 @@
 "Other users will be ''warned'' until %(bumptime)s that you are editing this "
 "page."
 msgstr ""
-"سایر کاربران تا %(bumptime)s پیغامی مبنی بر اینکه شما در حال ویرایش این صفحه "
-"هستید، دریافت خواهند نمود."
+"سایر کاربران تا %(bumptime)s پیغامی مبنی بر اینکه شما در حال ویرایش این "
+"صفحه هستید، دریافت خواهند نمود."
 
 msgid "Use the Preview button to extend the locking period."
 msgstr "جهت تمدید مدت زمان قفل ویرایش دکمه پیش‌نمایش را فشار دهید."
@@ -805,8 +805,7 @@
 "    User name: %(username)s\n"
 "    Email address: %(useremail)s"
 msgstr ""
-"مدیر گرامی، یک حساب کاربری جدید هم اکنون در %(sitename)s ایجاد شده است. "
-"جزئیات به شرح زیر است:\n"
+"مدیر گرامی، یک حساب کاربری جدید هم اکنون در %(sitename)s ایجاد شده است. جزئیات به شرح زیر است:\n"
 "\n"
 "    نام کاربری: %(username)s\n"
 "    آدرس ایمیل: %(useremail)s"
@@ -2346,20 +2345,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "پیش لغو عضویت می‌بایست عضو باشید."
 
-msgid "Password is too short."
-msgstr "طول کلمه عبور بسیار کوتاه است"
-
-msgid "Password has not enough different characters."
-msgstr "کلمه عبور دارای حروف متفاوت کافی نیست."
-
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr ""
-"کلمه عبور آسان است (کلمه عبور شامل نام است و یا نام شامل کلمه عبور است)."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr "کلمه عبور بسیار آسان است (حروف صفحه‌کلید پشت سر هم)."
-
 msgid "Diffs"
 msgstr "تغییرات"
 
--- a/MoinMoin/i18n/fi.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/fi.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -11,9 +11,9 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: MoinMoin 1.8\n"
+"Project-Id-Version: MoinMoin 1.7\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2008-06-13 18:25+0300\n"
 "Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>\n"
 "Language-Team: Finnish <moin-devel@lists.sourceforge.net>\n"
@@ -242,7 +242,7 @@
 msgstr ""
 "'''Sivu nimeltä {{{'%s'}}} on jo olemassa.'''\n"
 "\n"
-"Anna sivulle eri nimi."
+"Koeta eri nimeä."
 
 #, python-format
 msgid "Could not copy page because of file system error: %s."
@@ -451,6 +451,7 @@
 msgid "The file %s was not found in the package."
 msgstr "Tiedostoa %s ei löytynyt paketista."
 
+# Is ”asettamiseksi uudelleen” ok in Finnish?
 #, python-format
 msgid ""
 "Login Name: %s\n"
@@ -480,7 +481,7 @@
 
 #, python-format
 msgid "[%(sitename)s] Your wiki account data"
-msgstr "[%(sitename)s] Wiki-tunnuksesi tiedot"
+msgstr "[%(sitename)s] Wikitunnuksesi tiedot"
 
 msgid "Line"
 msgstr "Rivi"
@@ -792,7 +793,7 @@
 msgid "New user account created on %(sitename)s"
 msgstr "Wikiin %(sitename)s on luotu uusi käyttäjätunnus"
 
-#, python-format
+#, fuzzy, python-format
 msgid ""
 "Dear Superuser, a new user has just been created on %(sitename)s\". Details "
 "follow:\n"
@@ -800,8 +801,8 @@
 "    User name: %(username)s\n"
 "    Email address: %(useremail)s"
 msgstr ""
-"Tiedoksi pääkäyttäjälle, uusi käyttäjä on luotu äskettäin sivustolle %"
-"(sitename)s\". Lisätietoja käyttäjästä:\n"
+"Tiedoksi pääkäyttäjälle, uusi käyttäjä on luotu äskettäin.\n"
+"Lisätietoja:\n"
 "\n"
 "    Käyttäjätunnus: %(username)s\n"
 "    Sähköpostiosoite: %(useremail)s"
@@ -1245,7 +1246,7 @@
 msgid "Please first create a homepage before creating additional pages."
 msgstr "Luo kotisivu, ennen kuin luot muita sivuja."
 
-#, python-format
+#, fuzzy, python-format
 msgid ""
 "You can add some additional sub pages to your already existing homepage "
 "here.\n"
@@ -1273,9 +1274,9 @@
 "\n"
 msgstr ""
 "Voit lisätä omalle kotisivullesi alasivuja\n"
-"tästä.\n"
-"Voit valita, millaiset oikeudet muilla käyttäjillä on\n"
-"sivuillesi. Oikeudet riippuvat tietyn käyttäjän kuulumisesta vastaavalle "
+"tästä. \n"
+"Voit valita kuinka avoimia sivuja haluat muiden lukijoiden ja\n"
+"kirjoittajien suhteen. Oikeudet riippuvat kuulumisesta vastaavalle "
 "ryhmäsivulle.\n"
 "\n"
 "Kirjoita vain alasivun nimi ja napsauta painiketta luodaksesi sivu.\n"
@@ -1283,10 +1284,9 @@
 "Ennen kuin teet pääsyltään rajoitettuja sivuja, varmista että vastaava\n"
 "ryhmäsivu on olemassa ja että kyseisellä sivulla on haluttujen käyttäjien "
 "tunnukset. Käytä ryhmäsivun\n"
-"luomiseksi sivupohjaa KotiSivuRyhmätPohja.\n"
+"luomiseksi sivupohjaa HomepageGroupsTemplate.\n"
 "\n"
-"||'''Lisää uusi henkilökohtainen sivu:'''||'''Vastaava pääsyrajoituksen "
-"ryhmä:'''||\n"
+"||'''Lisää uusi oma sivu:'''||'''Vastaava pääsyrajoituksen ryhmä:'''||\n"
 "||<<NewPage(HomepageReadWritePageTemplate,luettavissa ja kirjoitettavissa,%"
 "(username)s)>>||[\"%(username)s/ReadWriteGroup\"]||\n"
 "||<<NewPage(HomepageReadPageTemplate,vain luettavissa,%(username)s)>>||[\"%"
@@ -1400,7 +1400,7 @@
 "Enter a new password below."
 msgstr ""
 "\n"
-"== Salasanan uusiminen ==\n"
+"== Salasanan asettaminen uudelleen ==\n"
 "Syötä uusi salasana alle."
 
 msgid "Lost password"
@@ -1451,18 +1451,6 @@
 "\n"
 "To get a backup, just click here:"
 msgstr ""
-"= Varmuuskopion lataus =\n"
-"\n"
-"Ota seuraavat asiat huomioon:\n"
-" * Säilytä varmuuskopiot turvallisessa paikassa - ne sisältävät "
-"arkaluonteista tietoa.\n"
-" * Varmista, että wikin backup_*-määritykset ovat kelvolliset ja kattavat "
-"kaikki asetukset.\n"
-" * Varmista, että varmuuskopiotiedosto sisältää kaiken oleellisen, jotta "
-"palautus onnistuisi mahdollisissa ongelmatilanteissa.\n"
-" * Varmista, että varmuuskopiotiedoston lataus onnistuu.\n"
-"\n"
-"Lataa varmuuskopiotiedosto oheisesta linkistä:"
 
 msgid "Backup"
 msgstr "Varmuuskopio"
@@ -2360,20 +2348,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Et voi perua tilausta, sillä et ole tilaaja."
 
-msgid "Password is too short."
-msgstr "Salasana on liian lyhyt."
-
-msgid "Password has not enough different characters."
-msgstr "Salasanassa ei ole riittävästi eri merkkejä."
-
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr ""
-"Salasana on liian helppo arvata (salasana sisältää nimen tai nimi salasanan)."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr "Salasana on liian helppo arvata."
-
 msgid "Diffs"
 msgstr "Erot"
 
@@ -2610,10 +2584,11 @@
 msgstr "Käyttäjä"
 
 msgid "[ATTACH]"
-msgstr "[LIITÄ]"
-
+msgstr ""
+
+#, fuzzy
 msgid "Variable name"
-msgstr "Muuttujan nimi"
+msgstr "Tiedostonimi"
 
 msgid "Description"
 msgstr "Kuvaus"
@@ -2673,10 +2648,6 @@
 "''italic'', those may be due to third-party extensions needing configuration "
 "or settings that were removed from Moin."
 msgstr ""
-"Taulukossa näkyvät asetukset, joilla ei ole oletusarvoja tässä wikissä. "
-"Asetukset, joita järjestelmä ei tunnista, näytetään ''kursivoituna''. Ne "
-"saattavat olla kolmansien osapuolien laajennuksiin liittyviä asetuksia tai "
-"vaihtoehtoisesti asetuksia, jotka on poistettu MoinMoinista."
 
 msgid "Setting"
 msgstr "Asetus"
@@ -3283,7 +3254,8 @@
 
 #~ msgid ""
 #~ "Unknown user name: {{{\"%s\"}}}. Please enter user name and password."
-#~ msgstr "Tuntematon käyttäjä: {{{\"%s\"}}}. Anna käyttäjänimi ja salasana."
+#~ msgstr ""
+#~ "Tuntematon käyttäjänimi: {{{\"%s\"}}}. Anna käyttäjänimi ja salasana."
 
 #~ msgid "raw"
 #~ msgstr "muotoilematon"
@@ -3339,5 +3311,6 @@
 #~ msgstr ""
 #~ "Valitettavasti joku muu tallensi sivun sillä aikaa kun muokkasit sitä.\n"
 #~ "\n"
-#~ "Toimi seuraavasti: Käytä selaimen Takaisin-painiketta ja kopioi\n"
+#~ "Ystävällisesti toimi seuraavasti: Käytä selaimesi Takaisin-nappia ja "
+#~ "kopioi\n"
 #~ "muutoksesi leikepöydälle. Eteenpäin-napilla pääset takaisin t"
--- a/MoinMoin/i18n/fr.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/fr.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,10 +13,10 @@
 msgstr ""
 "Project-Id-Version: moin\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
-"PO-Revision-Date: 2008-09-29 01:03+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
+"PO-Revision-Date: 2008-06-12 00:32+0200\n"
 "Last-Translator: Jean-Philippe Guérard <fevrier@tigreraye.org>\n"
-"Language-Team: français <traduc@traduc.org>\n"
+"Language-Team: Français\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -25,7 +25,6 @@
 "X-Language-in-English: French\n"
 "X-HasWikiMarkup: True\n"
 "Plural-Forms:  nplurals=2; plural=(n > 1);\n"
-"X-Generator: KBabel 1.11.4\n"
 
 #, python-format
 msgid "Argument \"%s\" must be a boolean value, not \"%s\""
@@ -217,14 +216,14 @@
 msgstr "Modification mineure"
 
 msgid "Comment:"
-msgstr "Commentaire :"
+msgstr "Commentaire :"
 
 msgid "<No addition>"
 msgstr "<Pas d'ajout>"
 
 #, python-format
 msgid "Add to: %(category)s"
-msgstr "Ajouter à : %(category)s"
+msgstr "Ajouter à : %(category)s"
 
 msgid "Remove trailing whitespace from each line"
 msgstr "Supprimer les espaces en fin de ligne"
@@ -251,7 +250,7 @@
 #, python-format
 msgid "Could not copy page because of file system error: %s."
 msgstr ""
-"Impossible de renommer la page du fait d'une erreur du système de fichiers : "
+"Impossible de renommer la page du fait d'une erreur du système de fichiers : "
 "%s."
 
 msgid "You are not allowed to rename this page!"
@@ -263,7 +262,7 @@
 #, python-format
 msgid "Could not rename page because of file system error: %s."
 msgstr ""
-"Impossible de renommer la page à cause d'une erreur du système de fichier : %"
+"Impossible de renommer la page à cause d'une erreur du système de fichier : %"
 "s."
 
 msgid "You are not allowed to delete this page!"
@@ -330,7 +329,7 @@
 "page, car vous n'en avez pas les droits d'administration !"
 
 msgid "Notifications sent to:"
-msgstr "Notifications envoyées à :"
+msgstr "Notifications envoyées à :"
 
 #, python-format
 msgid ""
@@ -388,7 +387,7 @@
 #, python-format
 msgid "Invalid highlighting regular expression \"%(regex)s\": %(error)s"
 msgstr ""
-"L'expression rationnelle de surlignage : « %(regex)s » est incorrecte : %"
+"L'expression rationnelle de surlignage : « %(regex)s » est incorrecte : %"
 "(error)s"
 
 msgid ""
@@ -480,11 +479,11 @@
 "\n"
 "Password reset URL: %s/?action=recoverpass&name=%s&token=%s\n"
 msgstr ""
-"Nom d'utilisateur : %s\n"
+"Nom d'utilisateur : %s\n"
 "\n"
-"Code de récupération du mot de passe : %s\n"
+"Code de récupération du mot de passe : %s\n"
 "\n"
-"URL de remise à zéro du mot de passe : %s/?action=recoverpass&name=%s&token=%"
+"URL de remise à zéro du mot de passe : %s/?action=recoverpass&name=%s&token=%"
 "s\n"
 
 msgid ""
@@ -550,7 +549,7 @@
 
 #, python-format
 msgid "last modified: %s"
-msgstr "dernière modification : %s"
+msgstr "dernière modification : %s"
 
 msgid "match"
 msgstr "correspondance"
@@ -682,7 +681,7 @@
 
 #, python-format
 msgid "OpenID error: %s."
-msgstr "Erreur OpenID : %s."
+msgstr "Erreur OpenID: %s."
 
 msgid "Verification canceled."
 msgstr "La vérification a été annulée."
@@ -697,7 +696,7 @@
 msgstr "Le mot de passe entré est incorrect."
 
 msgid "OpenID verification requires that you click this button:"
-msgstr "Veuillez cliquer sur ce bouton pour l'identification OpenID :"
+msgstr "Veuillez cliquer sur ce bouton pour l'identification OpenID:"
 
 msgid "Anonymous sessions need to be enabled for OpenID login."
 msgstr ""
@@ -759,8 +758,8 @@
 "Attachment link: %(attach)s\n"
 "Page link: %(page)s\n"
 msgstr ""
-"Lien vers la pièce jointe : %(attach)s\n"
-"Lien vers une page : %(page)s\n"
+"Lien vers la pièce jointe: %(attach)s\n"
+"Lien vers une page: %(page)s\n"
 
 #, python-format
 msgid ""
@@ -776,10 +775,10 @@
 "vous vous êtes abonné aux notifications des modifications d'une page ou "
 "d'une catégorie du wiki « %(sitename)s ».\n"
 "\n"
-"La page « %(pagename)s » a été modifiée par %(editor)s :\n"
+"La page « %(pagename)s » a été modifiée par %(editor)s :\n"
 
 msgid "New page:\n"
-msgstr "Nouvelle page :\n"
+msgstr "Nouvelle page :\n"
 
 msgid "No differences found!\n"
 msgstr "Aucune différence n'a été trouvée !\n"
@@ -799,7 +798,7 @@
 "vous vous êtes abonné aux notifications des modifications d'une page ou "
 "d'une catégorie du wiki « %(sitename)s ».\n"
 "\n"
-"La page « %(pagename)s » a été supprimée par %(editor)s :\n"
+"La page « %(pagename)s » a été supprimée par %(editor)s :\n"
 "\n"
 
 #, python-format
@@ -817,13 +816,13 @@
 "vous vous êtes abonné aux notifications des modifications d'une page\n"
 "du wiki « %(sitename)s ».\n"
 "\n"
-"La page « %(oldname)s » a été renommée « %(pagename)s » par %(editor)s :\n"
+"La page « %(oldname)s » a été renommée « %(pagename)s » par %(editor)s :\n"
 
 #, python-format
 msgid "New user account created on %(sitename)s"
 msgstr "Nouveau compte utilisateur créé sur %(sitename)s"
 
-#, python-format
+#, fuzzy, python-format
 msgid ""
 "Dear Superuser, a new user has just been created on %(sitename)s\". Details "
 "follow:\n"
@@ -831,11 +830,11 @@
 "    User name: %(username)s\n"
 "    Email address: %(useremail)s"
 msgstr ""
-"Cher super-utilisateur, un nouveau compte vient d'être créé sur le site « %"
-"(sitename)s ». En voici les détails :\n"
+"Cher super-utilisateur, un nouveau compte vient d'être créé, dont voici les "
+"détails:\n"
 "\n"
-"    Nom d'utilisateur : %(username)s\n"
-"    Adresse de courrier électronique : %(useremail)s"
+"    Nom d'utilisateur: %(username)s\n"
+"    Adresse de courrier électronique: %(useremail)s"
 
 #, python-format
 msgid "New attachment added to page %(pagename)s on %(sitename)s"
@@ -858,10 +857,10 @@
 "\n"
 "vous vous êtes abonné aux notifications de changements pour la page \"%"
 "(page_name)s\".Une pièce jointe vient d'y être ajouté par %(editor)s. "
-"Quelques détails sur la pièce jointe :\n"
+"Quelques détails sur la pièce jointe:\n"
 "\n"
-"Nom : %(attach_name)s\n"
-"Taille : %(attach_size)s\n"
+"Nom: %(attach_name)s\n"
+"Taille: %(attach_size)s\n"
 
 msgid "Attachment link"
 msgstr "Lien vers une pièce jointe"
@@ -899,7 +898,7 @@
 "<<Verbatim(----)>> filet horizontal.\n"
 " Titres:: = Titre 1 = ; == Titre 2 == ; === Titre 3 === ; ==== Titre 4 "
 "==== ; ===== Titre 5 =====.\n"
-" Listes:: une espace suivi de : * puces ; 1., a., A., i., I. énumérations ; "
+" Listes:: une espace suivi de : * puces ; 1., a., A., i., I. énumérations ; "
 "1.#n énumération commençant à n ; une espace seule ajoute une indentation.\n"
 " Liens:: <<Verbatim(MotsAccolésDébutantParDesMajuscules)>> ; <<Verbatim"
 "([[cible|intitulé]])>>.\n"
@@ -936,7 +935,7 @@
 
 #, python-format
 msgid "%(errortype)s processing error"
-msgstr "Erreur d'exécution : %(errortype)s"
+msgstr "Erreur d'exécution : %(errortype)s"
 
 msgid ""
 "Rendering of reStructured text is not possible, please install Docutils."
@@ -964,19 +963,19 @@
 "reStructuredText Quick Reference]].\n"
 msgstr ""
 "{{{\n"
-"Mise en relief : *italique* **gras** ``à chasse fixe``\n"
+"Mise en relief : *italique* **gras** ``à chasse fixe``\n"
 "\n"
-"Titres : Titre 1  Titre 2  Titre 3\n"
+"Titres : Titre 1  Titre 2  Titre 3\n"
 "         =======  -------  ~~~~~~~\n"
 "\n"
-"Filet horizontal : ---- \n"
+"Filet horizontal : ---- \n"
 "\n"
-"Liens : SoulignéFinal_ `plusieurs mots encadrés d'accents graves`_ "
+"Liens : SoulignéFinal_ `plusieurs mots encadrés d'accents graves`_ "
 "externe_ \n"
 "\n"
-".. _externe : http://exemple.fr.invalid/blabla/\n"
+".. _externe : http://exemple.fr.invalid/blabla/\n"
 "\n"
-"Listes : * puces ; 1., a. énumérations.\n"
+"Listes : * puces ; 1., a. énumérations.\n"
 "}}}\n"
 "(!) Pour en savoir plus, consultez le \n"
 "[[http://docutils.sourceforge.net/docs/user/rst/quickref.html|Guide de "
@@ -987,12 +986,12 @@
 
 #, python-format
 msgid "**You are not allowed to read the page: %s**"
-msgstr "** Vous n'êtes pas autorisé à lire la page : %s ! **"
+msgstr "** Vous n'êtes pas autorisé à lire la page : %s ! **"
 
 #, python-format
 msgid "**Could not find the referenced page: %s**"
 msgstr ""
-"**Impossible de trouver la page à laquelle il est fait référence : %s**"
+"**Impossible de trouver la page à laquelle il est fait référence : %s**"
 
 msgid ""
 " Emphasis:: <<Verbatim(//)>>''italics''<<Verbatim(//)>>; <<Verbatim(**)"
@@ -1147,7 +1146,7 @@
 
 #, python-format
 msgid "Password not acceptable: %s"
-msgstr "Mot de passe non acceptable : %s"
+msgstr "Mot de passe non acceptable : %s"
 
 msgid "Your password has been changed."
 msgstr "Votre mot de passe a été changé."
@@ -1175,7 +1174,7 @@
 msgstr "'''Type d'évènement'''"
 
 msgid "Select the events you want to be notified about."
-msgstr "Sélectionnez les évènement dont vous souhaitez être averti :"
+msgstr "Sélectionnez les évènement dont vous souhaitez être averti :"
 
 msgid ""
 "Before you can be notified, you need to provide a way to contact you in the "
@@ -1242,7 +1241,7 @@
 "Aucune page indiquée via --pages ou --search, on prend le paquet complet."
 
 msgid "All attachments included into the package."
-msgstr "Toutes les pièces-jointes sont incluses dans le paquet."
+msgstr ""
 
 msgid "Output file already exists! Cowardly refusing to continue!"
 msgstr "Le fichier de sortie existe déjà ! Abandon lâche de l'opération."
@@ -1333,8 +1332,8 @@
 "Utilisez le ModèleDeGroupeDePagePersonnelle lors de la création des pages\n"
 "correspondant aux groupes.\n"
 "\n"
-"||'''Ajout d'une nouvelle page personnelle :'''||'''Groupes utilisés pour "
-"les listes de contrôle d'accès :'''||\n"
+"||'''Ajout d'une nouvelle page personnelle :'''||'''Groupes utilisés pour "
+"les listes de contrôle d'accès :'''||\n"
 "||<<NewPage(HomepageReadWritePageTemplate,page ouverte en écriture,%"
 "(username)s)>>||[%(username)s/GroupeDesRédacteurs]||\n"
 "||<<NewPage(HomepageReadPageTemplate,page en lecture seule,%(username)s)>>||"
@@ -1352,7 +1351,7 @@
 "Utilisez l'interface interactive pour exécuter l'action %(actionname)s !"
 
 msgid "TextCha: Wrong answer! Go back and try again..."
-msgstr "TextCha : mauvaise réponse ! Revenez en arrière et réessayez..."
+msgstr "TextCha : mauvaise réponse ! Revenez en arrière et réessayez..."
 
 #, python-format
 msgid "You must login to use this action: %(action)s."
@@ -1486,8 +1485,9 @@
 "de récupération, entrez votre nom d'utilisateur, le mot-clef et\n"
 "un nouveau mot de passe (deux fois) ci-dessous"
 
+#, fuzzy
 msgid "Wiki Backup"
-msgstr "Sauvegarde du wiki"
+msgstr "Balisage Wiki"
 
 msgid ""
 "= Downloading a backup =\n"
@@ -1503,18 +1503,6 @@
 "\n"
 "To get a backup, just click here:"
 msgstr ""
-"= Envoi d'une sauvegarde =\n"
-"\n"
-"Quelques conseils :\n"
-" * Conservez vos sauvegardes dans un endroit sûr et protégé — elles "
-"contiennent des informations sensibles.\n"
-" * Assurez-vous que les valeurs backup_* du paramétrage de votre wiki soient "
-"correctes et complètes.\n"
-" * Assurez-vous que les sauvegardes que vous récupérez contiennent tout ce "
-"dont vous aurez besoin en cas de problème.\n"
-" * Assurez-vous d'avoir bien reçu le fichier de sauvegarde.\n"
-"\n"
-"Pour récupérer la sauvegarde, cliquez ici :"
 
 msgid "Backup"
 msgstr "Sauvegarde"
@@ -1524,7 +1512,7 @@
 
 #, python-format
 msgid "Unknown backup subaction: %s."
-msgstr "Sous-action de sauvegarde inconnue : %s."
+msgstr "Sous-action de sauvegarde inconnue : %s."
 
 msgid "You must login to add a quicklink."
 msgstr "Vous devez être identifié pour ajouter un lien rapide."
@@ -1669,7 +1657,7 @@
 
 #, python-format
 msgid "Unsupported AttachFile sub-action: %s"
-msgstr "Sous-action d'ajout non disponible : %s"
+msgstr "Sous-action d'ajout non disponible : %s"
 
 #, python-format
 msgid "Attachments for \"%(pagename)s\""
@@ -1749,7 +1737,7 @@
 "s »."
 
 msgid "Move aborted because new attachment name is empty."
-msgstr "Déplacement annulé : le nom de la nouvelle pièce jointe est vide."
+msgstr "Déplacement annulé : le nom de la nouvelle pièce jointe est vide."
 
 msgid "Move"
 msgstr "Déplacer"
@@ -1819,7 +1807,7 @@
 msgstr "Pièce jointe « %(filename)s » décompressée."
 
 msgid "A severe error occurred:"
-msgstr "Une erreur sévère s'est produite :"
+msgstr "Une erreur sévère s'est produite :"
 
 #, python-format
 msgid "Attachment '%(filename)s'"
@@ -1829,7 +1817,7 @@
 msgstr "Téléchargement"
 
 msgid "Package script:"
-msgstr "Script d'installation :"
+msgstr "Script d'installation :"
 
 msgid "File Name"
 msgstr "Nom du fichier"
@@ -1860,14 +1848,14 @@
 msgstr "Abonner les utilisateurs à la page %s"
 
 msgid "Enter user names (comma separated):"
-msgstr "Entrez les noms d'utilisateurs (séparés par des virgules) :"
+msgstr "Entrez les noms d'utilisateurs (séparés par des virgules) :"
 
 #, python-format
 msgid "Subscribed for %s:"
 msgstr "Abonné à %s"
 
 msgid "Not a user:"
-msgstr "N'est pas un utilisateur :"
+msgstr "N'est pas un utilisateur :"
 
 msgid "You are not allowed to perform this action."
 msgstr "Vous n'êtes pas autorisé à réaliser cette action."
@@ -1911,14 +1899,15 @@
 
 #, python-format
 msgid "Invalid filename \"%s\"!"
-msgstr "Nom de fichier incorrect : « %s » !"
+msgstr "Nom de fichier incorrect : « %s » !"
 
 #, python-format
 msgid "Created the package %s containing the pages %s."
 msgstr "Page %s créée contenant les pages %s."
 
+#, fuzzy
 msgid "Include all attachments?"
-msgstr "Inclure toutes les pièces-jointes ?"
+msgstr "[%d pièces jointes]"
 
 msgid "Package pages"
 msgstr "Pages du paquet"
@@ -1951,7 +1940,7 @@
 msgid "Exception while calling rollback function:"
 msgstr ""
 "Une exception est survenue lors de l'appel à la fonction d'annulation des "
-"modifications :"
+"modifications :"
 
 msgid ""
 "Please enter your password of your account at the remote wiki below. "
@@ -2005,7 +1994,7 @@
 
 #, python-format
 msgid "After filtering: %s pages"
-msgstr "Après filtrage : %s pages"
+msgstr "Après filtrage : %s pages"
 
 #, python-format
 msgid "Skipped page %s because of no write access to local page."
@@ -2019,7 +2008,7 @@
 
 #, python-format
 msgid "Error while deleting page %s locally:"
-msgstr "Erreur lors de la suppression de la page locale %s :"
+msgstr "Erreur lors de la suppression de la page locale %s :"
 
 #, python-format
 msgid "Deleted page %s remotely."
@@ -2027,7 +2016,7 @@
 
 #, python-format
 msgid "Error while deleting page %s remotely:"
-msgstr "Erreur lors de la suppression de la page distante %s :"
+msgstr "Erreur lors de la suppression de la page distante %s :"
 
 #, python-format
 msgid ""
@@ -2167,7 +2156,7 @@
 "(totalwords)d words%(localwords)s and are highlighted below:"
 msgstr ""
 "Les %(badwords)d mots suivants n'ont pu être trouvé dans le dictionnaire sur "
-"un total de %(totalwords)d mots%(localwords)s et sont surlignés ci-dessous :"
+"un total de %(totalwords)d mots%(localwords)s et sont surlignés ci-dessous :"
 
 msgid "Add checked words to dictionary"
 msgstr "Ajouter les mots cochés au dictionnaire"
@@ -2290,7 +2279,7 @@
 "ou cliquez sur le bouton ci-dessous pour annuler cette vérification."
 
 msgid "Please choose:"
-msgstr "Choisissez :"
+msgstr "Choisissez :"
 
 msgid "Settings"
 msgstr "Paramètres"
@@ -2300,16 +2289,16 @@
 
 #, python-format
 msgid "Page size: %d"
-msgstr "Taille de la page : %d"
+msgstr "Taille de la page : %d"
 
 msgid "SHA digest of this page's content is:"
-msgstr "L'empreinte SHA du contenu de cette page est :"
+msgstr "L'empreinte SHA du contenu de cette page est :"
 
 msgid "The following users subscribed to this page:"
-msgstr "Les utilisateurs suivants sont abonnés à cette page :"
+msgstr "Les utilisateurs suivants sont abonnés à cette page :"
 
 msgid "This page links to the following pages:"
-msgstr "Cette page est reliée aux pages suivantes :"
+msgstr "Cette page est reliée aux pages suivantes :"
 
 msgid "Diff"
 msgstr "Comparer"
@@ -2340,7 +2329,7 @@
 
 #, python-format
 msgid "Show \"%(title)s\""
-msgstr "Voir : %(title)s"
+msgstr "Voir : %(title)s"
 
 msgid "General Page Infos"
 msgstr "Informations générales"
@@ -2367,7 +2356,7 @@
 
 #, python-format
 msgid "Advanced Search: \"%s\""
-msgstr "Recherche avancée : « %s »"
+msgstr "Recherche avancée : « %s »"
 
 #, python-format
 msgid "Full Text Search: \"%s\""
@@ -2438,21 +2427,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Il est nécessaire d'être abonné pour se désabonner."
 
-msgid "Password is too short."
-msgstr "Mot de passe trop court."
-
-msgid "Password has not enough different characters."
-msgstr "Le mot de passe ne contient pas assez de caractères différents."
-
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr ""
-"Mot de passe trop simple (le mot de passe contient le nom, ou bien le nom "
-"est contenu dans le mot de passe)."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr "Mot de passe trop simple (séquence de touches du clavier)."
-
 msgid "Diffs"
 msgstr "Différences"
 
@@ -2603,7 +2577,7 @@
 msgstr "Rechercher"
 
 msgid "More Actions:"
-msgstr "Autres actions :"
+msgstr "Autres actions :"
 
 msgid "------------------------"
 msgstr "------------------------"
@@ -2683,7 +2657,7 @@
 msgstr "(mémorisé dans le cache le %s)"
 
 msgid "Or try one of these actions:"
-msgstr "Ou essayez l'une de ces actions :"
+msgstr "Ou essayez l'une de ces actions :"
 
 msgid "Wiki"
 msgstr "Wiki"
@@ -2695,13 +2669,14 @@
 msgstr "Utilisateur"
 
 msgid "[ATTACH]"
-msgstr "[JOINDRE]"
-
+msgstr ""
+
+#, fuzzy
 msgid "Variable name"
-msgstr "Nom de variable"
+msgstr "Nom du paquet"
 
 msgid "Description"
-msgstr "Description"
+msgstr ""
 
 #, python-format
 msgid "Upload new attachment \"%(filename)s\""
@@ -2712,7 +2687,7 @@
 "%(extension_name)s %(extension_type)s: Required argument %(argument_name)s "
 "missing."
 msgstr ""
-"%(extension_name)s %(extension_type)s : l'argument %(argument_name)s requis "
+"%(extension_name)s %(extension_type)s : l'argument %(argument_name)s requis "
 "est absent."
 
 #, python-format
@@ -2720,7 +2695,7 @@
 "%(extension_name)s %(extension_type)s: Invalid %(argument_name)s=%"
 "(argument_value)s!"
 msgstr ""
-"%(extension_name)s %(extension_type)s : %(argument_name)s=%(argument_value)s "
+"%(extension_name)s %(extension_type)s : %(argument_name)s=%(argument_value)s "
 "est incorrect !"
 
 #, python-format
@@ -2729,7 +2704,7 @@
 "of its mimetype %(mimetype)s."
 msgstr ""
 "Le paramétrage actuel ne permet pas d'intégrer à la page le fichier %(file)s "
-"du fait de son type MIME : %(mimetype)s."
+"du fait de son type MIME : %(mimetype)s."
 
 msgid "Embedded"
 msgstr "intégré"
@@ -2750,7 +2725,7 @@
 msgstr "Affichage"
 
 msgid "Wiki configuration"
-msgstr "Paramétrage du wiki"
+msgstr ""
 
 msgid ""
 "This table shows all settings in this wiki that do not have default values. "
@@ -2758,11 +2733,8 @@
 "''italic'', those may be due to third-party extensions needing configuration "
 "or settings that were removed from Moin."
 msgstr ""
-"Cette table contient tous les paramètres de ce wiki qui n'ont pas de valeur "
-"par défaut. Les paramètres inconnus du système de paramétrage sont affichés "
-"en italique. Il peut s'agir de paramètres provenant d'extensions tierces qui "
-"ont besoin d'être paramétrées ou de paramètres supprimés de MoinMoin."
-
+
+#, fuzzy
 msgid "Setting"
 msgstr "Paramètres"
 
@@ -2954,7 +2926,7 @@
 
 #, python-format
 msgid "(currently set to %s)"
-msgstr "(ayant actuellement la valeur : %s)"
+msgstr "(ayant actuellement la valeur : %s)"
 
 msgid "Delete bookmark"
 msgstr "Supprimer le signet"
@@ -2967,7 +2939,7 @@
 
 #, python-format
 msgid "Invalid include arguments \"%s\"!"
-msgstr "Les arguments du include sont incorrects : « %s » !"
+msgstr "Les arguments du include sont incorrects : « %s » !"
 
 #, python-format
 msgid "Nothing found for \"%s\"!"
@@ -2988,7 +2960,7 @@
 #, python-format
 msgid "Connection to mailserver '%(server)s' failed: %(reason)s"
 msgstr ""
-"La connexion au serveur de messagerie « %(server)s » a échouée : %(reason)s"
+"La connexion au serveur de messagerie « %(server)s » a échouée : %(reason)s"
 
 msgid "Mail not sent"
 msgstr "Courrier non envoyé"
@@ -3097,7 +3069,7 @@
 
 #, python-format
 msgid "Inlined image: %(url)s"
-msgstr "Image incluse : %(url)s"
+msgstr "Image incluse : %(url)s"
 
 #, python-format
 msgid "Create new drawing \"%(filename)s (opens in new window)\""
@@ -3113,3 +3085,56 @@
 
 msgid "Toggle line numbers"
 msgstr "Afficher/masquer les numéros de lignes"
+
+#~ msgid ""
+#~ "Restored Backup: %(filename)s to target dir: %(targetdir)s.\n"
+#~ "Files: %(filecount)d, Directories: %(dircount)d"
+#~ msgstr ""
+#~ "Sauvegarde restaurée : %(filename)s dans le répertoire : %(targetdir)s.\n"
+#~ "Fichiers : %(filecount)d ; répertoires : %(dircount)d"
+
+#~ msgid "Restoring backup: %(filename)s to target dir: %(targetdir)s failed."
+#~ msgstr ""
+#~ "Restauration de sauvegarde : échec de la restauration de %(filename)s "
+#~ "vers %(targetdir)s."
+
+#~ msgid "Wiki Backup / Restore"
+#~ msgstr "Sauvegarde et restauration du wiki"
+
+#~ msgid ""
+#~ "Some hints:\n"
+#~ " * To restore a backup:\n"
+#~ "  * Restoring a backup will overwrite existing data, so be careful.\n"
+#~ "  * Rename it to <siteid>.tar.<compression> (remove the --date--time--UTC "
+#~ "stuff).\n"
+#~ "  * Put the backup file into the backup_storage_dir (use scp, ftp, ...).\n"
+#~ "  * Hit the <<GetText(Restore)>> button below.\n"
+#~ "\n"
+#~ " * To make a backup, just hit the <<GetText(Backup)>> button and save the "
+#~ "file\n"
+#~ "   you get to a secure place.\n"
+#~ "\n"
+#~ "Please make sure your wiki configuration backup_* values are correct and "
+#~ "complete.\n"
+#~ "\n"
+#~ msgstr ""
+#~ "Quelques astuces :\n"
+#~ " * Pour restaurer une sauvegarde :\n"
+#~ "  * Restaurer une sauvegarde effacera les données existantes. Soyez "
+#~ "prudents.\n"
+#~ "  * Renommez-la en <identifiant_site>.tar.<compression> (enlevez les --"
+#~ "date--heure--UTC).\n"
+#~ "  * Placez le fichier de sauvegarde dans le répertoire backup_storage_dir "
+#~ "(via scp, ftp, ...).\n"
+#~ "  * Cliquez sur le bouton <<GetText(Restore)>> ci-dessous.\n"
+#~ "\n"
+#~ " * Pour réaliser une sauvegarde, cliquez simplement sur le bouton "
+#~ "<<GetText(Backup)>>\n"
+#~ "et sauvegardez le fichier obtenu dans un endroit sûr.\n"
+#~ "\n"
+#~ "Assurez-vous que les paramètres backup_* du wiki sont définis et "
+#~ "corrects.\n"
+#~ "\n"
+
+#~ msgid "Restore"
+#~ msgstr "Restauration"
--- a/MoinMoin/i18n/gl.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/gl.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2007-02-22 17:39-0300\n"
 "Last-Translator: Iván Méndez <imendez@udc.es>\n"
 "Language-Team: Galician <moin-devel@lists.sourceforge.net>\n"
@@ -2353,23 +2353,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Subscribiuse a esta páxina."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Repetir o contrasinal para validalo"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr ""
-"Faltou introducir o contrasinal. Por favor, introduza o nome de usuario e o "
-"contrasinal"
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Diferenzas"
 
--- a/MoinMoin/i18n/he.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/he.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.7\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2008-08-22 02:05+0300\n"
 "Last-Translator: Dror Livne <livne.dror@gmail.com>\n"
 "Language-Team: Hebrew <moin-user@lists.sourceforge.net>\n"
@@ -2255,21 +2255,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "חובה לבצע מינוי לדף בכדי להסיר את המינוי."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "איפוס ססמה"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "סיסמה חסרה. אנא הכנס שם משתמש וסיסמה."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "הבדלים"
 
--- a/MoinMoin/i18n/hi.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/hi.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: \n"
 "Last-Translator: Rakesh Pandit <rakesh.pandit@gmail.com>\n"
 "Language-Team: Hindi\n"
@@ -2112,20 +2112,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "आप इस पृष्ट पर अिभदािनत कर दिए गए है।"
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "संकेत शब्द"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr ""
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr ""
 
--- a/MoinMoin/i18n/hr.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/hr.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.7\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2006-08-17 20:50+0100\n"
 "Last-Translator: Translation sponsored by Tenalt Ltd. (info@tenalt.com)\n"
 "Language-Team: \n"
@@ -2320,21 +2320,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Ne možete odjaviti pretplatu sa stranica na koje niste pretplaćeni."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Lozinka (ponovno)"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Lozinka nije unešena. Upišite korisničko ime i lozinku"
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Razlike"
 
--- a/MoinMoin/i18n/hu.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/hu.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2006-06-15 15:55+0200\n"
 "Last-Translator: jmarton@omikk.bme.hu, arostas@omikk.bme.hu\n"
 "Language-Team: Hungarian <HU@li.org>\n"
@@ -2293,21 +2293,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Ön előfizetett erre a lapra."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Jelszó mégegyszer"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Hiányzik a jelszó. Kérjük adja meg a felhasználónevet és a jelszót."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Különbségek"
 
--- a/MoinMoin/i18n/id.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/id.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2006-10-07 23:19+0700\n"
 "Last-Translator: Fajrin Azis <fajrin.azis@gmail.com>\n"
 "Language-Team: Indonesian <id@ll.com>\n"
@@ -2349,21 +2349,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Anda butuh menjadi berlangganan ke tidak berlangganan."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Ulangi kata sandi"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Kurang kata sandi. Silakan masukkan nama pengguna dan kata sandi."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Perbedaan"
 
--- a/MoinMoin/i18n/it.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/it.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,8 +13,8 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.8\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
-"PO-Revision-Date: 2008-10-30 22:02+0100\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
+"PO-Revision-Date: 2008-09-20 16:31+0200\n"
 "Last-Translator: Milo Casagrande <milo@ubuntu.com>\n"
 "Language-Team: Italian\n"
 "MIME-Version: 1.0\n"
@@ -88,7 +88,7 @@
 msgstr "Manca il valore per la chiave \"%(token)s\""
 
 msgid "Your changes are not saved!"
-msgstr "Le modifiche non sono state salvate."
+msgstr "Le tue modifiche non sono state salvate."
 
 msgid "You are not allowed to edit this page."
 msgstr "Non è consentito modificare questa pagina."
@@ -225,7 +225,7 @@
 msgstr "Aggiungi a: %(category)s"
 
 msgid "Remove trailing whitespace from each line"
-msgstr "Rimuovere gli spazi in fondo a ogni riga"
+msgstr "Rimuovere gli spazi in fondo a ogni riga di testo"
 
 msgid "Edit was cancelled."
 msgstr "Le modifiche sono state annullate."
@@ -264,9 +264,7 @@
 msgstr "Non si è autorizzati a eliminare questa pagina."
 
 msgid "Thank you for your changes. Your attention to detail is appreciated."
-msgstr ""
-"Grazie per il proprio contributo. La vostra attenzione ai dettagli è molto "
-"apprezzata."
+msgstr "Grazie per il proprio contributo. La vostra attenzione ai dettagli è molto apprezzata."
 
 #, python-format
 msgid "Page \"%s\" was successfully deleted!"
@@ -320,7 +318,7 @@
 "momento che non si dispone dei permessi di amministrazione su di essa."
 
 msgid "Notifications sent to:"
-msgstr "Notifiche inviate a:"
+msgstr "Notifica inviata a:"
 
 #, python-format
 msgid ""
@@ -415,8 +413,8 @@
 "The remote wiki uses a different InterWiki name (%(remotename)s) internally "
 "than you specified (%(localname)s)."
 msgstr ""
-"Il wiki remoto usa internamente un altro nome InterWiki (%(remotename)s) "
-"rispetto a quello specifato (%(localname)s)."
+"Il wiki remoto usa all'interno un altro nome InterWiki (%(remotename)s) "
+"rispetto a quello che specificato (%(localname)s)."
 
 msgid "Text mode"
 msgstr "Modo testuale"
@@ -645,7 +643,7 @@
 msgstr "Scegli questo nome"
 
 msgid "This is not a valid username, choose a different one."
-msgstr "Questo nome utente non è valido, sceglierne uno diverso."
+msgstr "Non è un nome utente valido, sceglierne uno diverso."
 
 msgid ""
 "The username you have chosen is already\n"
@@ -817,8 +815,7 @@
 "    User name: %(username)s\n"
 "    Email address: %(useremail)s"
 msgstr ""
-"Gentile Super-utente, è stato appena creato un nuovo utente su \"%(sitename)s"
-"\". Seguono i dettagli:\n"
+"Gentile Super-utente, è stato appena creato un nuovo utente su \"%(sitename)s\". Seguono i dettagli:\n"
 "\n"
 "    Nome utente: %(username)s\n"
 "    Indirizzo email: %(useremail)s"
@@ -1069,7 +1066,7 @@
 msgstr "Fuso orario"
 
 msgid "Your time is"
-msgstr "La propria ora locale è"
+msgstr "La tua ora locale è"
 
 msgid "Server time is"
 msgstr "L'ora del server è"
@@ -1131,11 +1128,10 @@
 msgstr "Per modificare la password inserirne una nuova due volte."
 
 msgid "Password repeat"
-msgstr "Ripetere la password"
-
-# (ndt) messo al plurale, più corretto
+msgstr "Ripeti la password"
+
 msgid "Notification"
-msgstr "Notifiche"
+msgstr "Notifica"
 
 msgid "Notification settings saved!"
 msgstr "Impostazioni di notifica salvate."
@@ -1160,7 +1156,7 @@
 "generali un mezzo per poter essere contattati."
 
 msgid "Subscribed events"
-msgstr "Abbonato/a agli eventi"
+msgstr "Abbonato agli eventi"
 
 msgid "Subscribed wiki pages<<BR>>(one regex per line)"
 msgstr "Abbonato/a alle pagine<<BR>>(un'espressione regolare per riga)"
@@ -1476,10 +1472,8 @@
 "\n"
 "Prestare attenzione:\n"
 " * Salvare i backup in un luogo sicuro, contengono informazioni sensibili.\n"
-" * Assicurarsi che i valori \"backup_*\" della configurazione del wiki siano "
-"corretti.\n"
-" * Assicurarsi che il file di backup ottenuto contenga tutto quello che "
-"serve in caso di problemi.\n"
+" * Assicurarsi che i valori \"backup_*\" della configurazione del wiki siano corretti.\n"
+" * Assicurarsi che il file di backup ottenuto contenga tutto quello che serve in caso di problemi.\n"
 " * Assicurarsi che venga scaricato senza alcun problema.\n"
 "\n"
 "Per ottenere un backup, fare clic qui:"
@@ -1636,7 +1630,7 @@
 msgstr "Allegati"
 
 msgid "You are not allowed to attach a file to this page."
-msgstr "Non è consentito inserire allegati su questa pagina."
+msgstr "Non si è autorizzati a inserire allegati in questa pagina."
 
 #, python-format
 msgid "Unsupported AttachFile sub-action: %s"
@@ -1652,9 +1646,7 @@
 msgid ""
 "No file content. Delete non ASCII characters from the file name and try "
 "again."
-msgstr ""
-"Nessun contenuto. Eliminare i caratteri non ASCII dal nome del file e "
-"riprovare."
+msgstr "Nessun contenuto. Eliminare i caratteri non ASCII dal nome del file e riprovare."
 
 #, python-format
 msgid ""
@@ -1924,10 +1916,7 @@
 "Please enter your password of your account at the remote wiki below. "
 "<<BR>> /!\\ You should trust both wikis because the password could be read "
 "by the particular administrators."
-msgstr ""
-"Inserire qui sotto la propria password per il wiki remoto. <<BR>> /!\\ È "
-"necessario fidarsi di entrambi i wiki, poiché agli amministratori è "
-"possibile leggere la password."
+msgstr "Inserire qui sotto la propria password per il wiki remoto. <<BR>> /!\\ È necessario fidarsi di entrambi i wiki, poiché agli amministratori è possibile leggere la password."
 
 msgid "Operation was canceled."
 msgstr "L'operazione è stata annullata."
@@ -1995,18 +1984,13 @@
 msgid ""
 "The item %s cannot be merged automatically but was changed in both wikis. "
 "Please delete it in one of both wikis and try again."
-msgstr ""
-"Non è stato possibile unire automaticamente l'elemento %s, ma è stato "
-"modificato in entrambi i wiki. Eliminarlo in uno dei due wiki e riprovare."
+msgstr "Non è stato possibile unire automaticamente l'elemento %s, ma è stato modificato in entrambi i wiki. Eliminarlo in uno dei due wiki e riprovare."
 
 #, python-format
 msgid ""
 "The item %s has different mime types in both wikis and cannot be merged. "
 "Please delete it in one of both wikis or unify the mime type, and try again."
-msgstr ""
-"Non è stato possibile unire l'elemento %s perché ha dei tipi MIME differenti "
-"nei due wiki. Eliminarlo in uno dei due wiki oppure sistemare i tipi MIME e "
-"riprovare."
+msgstr "Non è stato possibile unire l'elemento %s perché ha dei tipi MIME differenti nei due wiki. Eliminarlo in uno dei due wiki oppure sistemare i tipi MIME e riprovare."
 
 #, python-format
 msgid ""
@@ -2029,10 +2013,7 @@
 msgid ""
 "The page %s could not be synced. The remote page was renamed. This is not "
 "supported yet. You may want to delete one of the pages to get it synced."
-msgstr ""
-"Non è stato possibile sincronizzare la pagina %s. La pagina remota è stata "
-"rinominata. Questa operazione non è ancora supportata. È possibile "
-"eliminarla in uno dei due wiki per sincronizzarla."
+msgstr "Non è stato possibile sincronizzare la pagina %s. La pagina remota è stata rinominata. Questa operazione non è ancora supportata. È possibile eliminarla in uno dei due wiki per sincronizzarla."
 
 #, python-format
 msgid "Skipped page %s because of a locally or remotely unresolved conflict."
@@ -2392,21 +2373,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "È necessario essere abbonati per poter annullare l'abbonamento."
 
-msgid "Password is too short."
-msgstr "La password è troppo corta."
-
-msgid "Password has not enough different characters."
-msgstr "La password non è composta da abbastanza caratteri diversi."
-
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr ""
-"La password è troppo facile (contiene il nome o il nome contiene la "
-"password)."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr "La password è troppo facile (sequenza di tasti)."
-
 msgid "Diffs"
 msgstr "Differenze"
 
@@ -2448,7 +2414,7 @@
 msgstr "Ad accesso eseguito, andare all'ultima pagina visitata"
 
 msgid "Show comment sections"
-msgstr "Mostrare le sezioni di commento"
+msgstr "Mostrare le sezioni con commenti"
 
 msgid "Show question mark for non-existing pagelinks"
 msgstr "Mostrare un punto di domanda per i collegamenti a pagine non esistenti"
@@ -2469,7 +2435,7 @@
 msgstr "Aggiungere uno spazio tra le singole parole dei nomi wiki"
 
 msgid "Remember login information"
-msgstr "Ricordare le informazioni di accesso"
+msgstr "Ricordare le mie informazioni di accesso"
 
 msgid "Disable this account forever"
 msgstr "Disabilitare questo account per sempre"
@@ -2707,12 +2673,7 @@
 "Settings that the configuration system doesn't know about are shown in "
 "''italic'', those may be due to third-party extensions needing configuration "
 "or settings that were removed from Moin."
-msgstr ""
-"Questa tabella mostra tutte le impostazioni di questo wiki che non hanno "
-"valori predefiniti. Le impostazioni di cui il sistema di configurazione non "
-"è a conoscenza sono mostrate in ''corsivo''; potrebbero essere estensioni di "
-"terze parti che necessitano di impostazioni o di una configurazione tolta da "
-"Moin."
+msgstr "Questa tabella mostra tutte le impostazioni di questo wiki che non hanno valori predefiniti. Le impostazioni di cui il sistema di configurazione non è a conoscenza sono mostrate in ''corsivo''; potrebbero essere estensioni di terze parti che necessitano di impostazioni o di una configurazione tolta da Moin."
 
 msgid "Setting"
 msgstr "Impostazioni"
--- a/MoinMoin/i18n/ja.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/ja.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -11,9 +11,9 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: MoinMoin 1.8\n"
+"Project-Id-Version: MoinMoin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2008-06-18 07:54+0900\n"
 "Last-Translator: MasatakeIwasaki\n"
 "Language-Team: Japanese <moin-devel@lists.sourceforge.net>\n"
@@ -869,8 +869,10 @@
 "ク'''''<<Verbatim(''''')>>、<<Verbatim('')>>''混合 ''<<Verbatim(''')"
 ">>'''''ボールド'''<<Verbatim(''')>>とイタリック''<<Verbatim('')>>、<<Verbatim"
 "(----)>> 水平線。\n"
-" 見出し:: = タイトル1 =、== タイトル2 ==、=== タイトル3 ===、==== タイトル4 "
-"====、===== タイトル5 =====。\n"
+" 見出し:: <<Verbatim(=)>> タイトル1 <<Verbatim(=)>>、<<Verbatim(==)>> タイト"
+"ル2 <<Verbatim(==)>>、<<Verbatim(===)>> タイトル3 <<Verbatim(===)>>、"
+"<<Verbatim(====)>> タイトル4 <<Verbatim(====)>>、<<Verbatim(=====)>> タイトル"
+"5 <<Verbatim(=====)>>。\n"
 " リスト:: 半角スペースに続けて: * 小丸、1., a., A., i., I. 番号付アイテム、1."
 "#n nから番号開始、半角スペースのみでインデント。\n"
 " リンク:: <<Verbatim(JoinCapitalizedWords)>>、<<Verbatim([[ターゲット|リンク"
@@ -1154,11 +1156,13 @@
 msgid "Subscribed wiki pages<<BR>>(one regex per line)"
 msgstr "購読中のwikiページ<<BR>>(1行あたりひとつの正規表現)"
 
+#, fuzzy
 msgid "OpenID server"
-msgstr ""
-
+msgstr "OpenIDのサービスが提供されていません"
+
+#, fuzzy
 msgid "The selected websites have been removed."
-msgstr ""
+msgstr "選択されたOpenIDは削除されています。"
 
 msgid "Trusted websites"
 msgstr ""
@@ -1439,8 +1443,9 @@
 "ユーザ名、パスワード回復トークン、新しいパスワード(2回)を以下に入力してくださ"
 "い。"
 
+#, fuzzy
 msgid "Wiki Backup"
-msgstr ""
+msgstr "Wikiマークアップ"
 
 msgid ""
 "= Downloading a backup =\n"
@@ -1848,8 +1853,9 @@
 msgid "Created the package %s containing the pages %s."
 msgstr "パッケージ %s を作成しました。(ページ %s を含む)"
 
+#, fuzzy
 msgid "Include all attachments?"
-msgstr ""
+msgstr "[添付ファイル数: %d]"
 
 msgid "Package pages"
 msgstr "ページをパッケージ化"
@@ -2348,19 +2354,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "購読していないページの購読を止めることはできません。"
 
-msgid "Password is too short."
-msgstr ""
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr ""
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "差分"
 
@@ -2599,8 +2592,9 @@
 msgid "[ATTACH]"
 msgstr ""
 
+#, fuzzy
 msgid "Variable name"
-msgstr ""
+msgstr "ファイル名"
 
 msgid "Description"
 msgstr ""
--- a/MoinMoin/i18n/ko.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/ko.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2008-03-12 15:01+0900\n"
 "Last-Translator: Seungik Lee <seungiklee@gmail.com>\n"
 "Language-Team: Korean <moin-devel@lists.sourceforge.net>\n"
@@ -2253,21 +2253,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "구독하고 있지 않으므로 구독 취소할 수 없습니다."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "암호 (확인)"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "비밀번호가 없습니다. 사용자 이름과 비밀번호를 다시 입력하세요."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "차이점 비교"
 
--- a/MoinMoin/i18n/ku.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/ku.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2006-12-08 18:50+0000\n"
 "Last-Translator: Erdal Ronahi <erdal.ronahi@gmail.com>\n"
 "Language-Team: Kurdish <ku@li.org>\n"
@@ -2142,20 +2142,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Tu bû endamê vî rûpelî."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Şîfre"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr ""
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Cudahî"
 
--- a/MoinMoin/i18n/lt.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/lt.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.7\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2008-06-29 13:35+0200\n"
 "Last-Translator: Aurelijus Sudzius <ruledbyfate@gmail.com>\n"
 "Language-Team: Lithuanian <ruledbyfate@gmail.com>\n"
@@ -2351,21 +2351,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Juma pirma reikia užsiprenumeruoti, kad galėtumėte atsisakyti."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Slaptažodžio atkūrimas"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Trūksta slaptažodžio. Prašome įvesti naudotojo vardą ir slaptažodį."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Pakeitimai"
 
--- a/MoinMoin/i18n/lv.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/lv.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.7\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2008-05-10 22:31+0200\n"
 "Last-Translator: Radomirs Cirskis <nad2000 AT AT AT AT gmail SPAM NO NO DOT "
 "NO SPAM com>\n"
@@ -2013,11 +2013,13 @@
 msgid "Revert to this revision"
 msgstr "Atgriezties pie šīs versijas"
 
+#, fuzzy
 msgid "Previous change"
-msgstr "Iepriekšējais labojums"
-
+msgstr "iepriekšējā"
+
+#, fuzzy
 msgid "Next change"
-msgstr "Nākamais labojums"
+msgstr "Bez izmaiņām"
 
 #, python-format
 msgid "The page was saved %(count)d times, though!"
@@ -2065,8 +2067,9 @@
 msgid "Really copy this page?"
 msgstr "Jūs tiešām vēlaties kopēt šo lapu?"
 
+#, fuzzy
 msgid "Revert"
-msgstr "Atgriezt"
+msgstr "Atgriezt visu!"
 
 msgid "You are not allowed to revert this page!"
 msgstr "Jūs nedrīkstat atjaunot no arhīva šo lapu!"
@@ -2080,11 +2083,13 @@
 "Jūs vēlaties atgriezt iepriekšēju lapas versiju, sākumā atveriet aplūkošanai "
 "lapas iepriekšējo versiju."
 
+#, fuzzy
 msgid "Optional reason for reverting this page"
-msgstr "Šīs lapas atgriešanas iemesls (neobligāts)"
-
+msgstr "Kopēšanas iemesls (neobligāts)"
+
+#, fuzzy
 msgid "Really revert this page?"
-msgstr "Jūs tiešām vēlaties atgriezt šo lapu?"
+msgstr "Jūs tiešām vēlaties pārdēvēt šo lapu?"
 
 msgid ""
 "You need to manually go to your OpenID provider wiki\n"
@@ -2114,19 +2119,20 @@
 msgstr ""
 
 msgid "Identity URL"
-msgstr "Identitātes URL"
-
+msgstr ""
+
+#, fuzzy
 msgid "Remember decision"
-msgstr ""
+msgstr "PyStemmer versija"
 
 msgid "Remember this trust decision and don't ask again"
 msgstr ""
 
 msgid "Approve"
-msgstr "Apstiprināt"
+msgstr ""
 
 msgid "Don't approve"
-msgstr "Neapstiprināt"
+msgstr ""
 
 msgid "OpenID not served"
 msgstr ""
@@ -2140,10 +2146,10 @@
 msgstr ""
 
 msgid "Please choose:"
-msgstr "Lūdzu izvēlieties:"
+msgstr ""
 
 msgid "Settings"
-msgstr "Iestatījumi"
+msgstr ""
 
 msgid "General Information"
 msgstr "Vispārēja informācija"
@@ -2164,8 +2170,9 @@
 msgid "Diff"
 msgstr "Atšķirība"
 
+#, fuzzy
 msgid "to previous"
-msgstr "uz iepriekšējo"
+msgstr "iepriekšējā"
 
 #, python-format
 msgid "Revert to revision %(rev)d."
@@ -2277,25 +2284,13 @@
 msgid "Can't remove regular expression subscription!"
 msgstr "Regulāras izteiksmes pierakstu izdzēst nevar!"
 
+#, fuzzy
 msgid "Edit the subscription regular expressions in your settings."
-msgstr "Labojiet parasktīšanās regulāras izteiksmes savos iestatījumos."
+msgstr "Labojiet parasktīšanās regulāras izteiksmes savā LietotājaIstatījumi."
 
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Lai atrakstītos, jums nepieciešams būt parakstījušam(-šai) uz šo lapu."
 
-msgid "Password is too short."
-msgstr "Parole ir pārāk īsa."
-
-msgid "Password has not enough different characters."
-msgstr "Parolē ir parmaz atšķirīgu zīmju."
-
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Parole ir pārak vienkārša (parole satur vārdu vai vārds satur paroli)."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr "Parole ir pārāk vienkārša (secīgi spiesti taustiņi)."
-
 msgid "Diffs"
 msgstr "Atšķirības"
 
@@ -2535,8 +2530,9 @@
 msgid "[ATTACH]"
 msgstr ""
 
+#, fuzzy
 msgid "Variable name"
-msgstr "Mainīgā nosaukums"
+msgstr "Faila nosaukums"
 
 msgid "Description"
 msgstr ""
@@ -2592,7 +2588,7 @@
 msgstr ""
 
 msgid "Setting"
-msgstr "Iestatījums"
+msgstr ""
 
 msgid "Search for items"
 msgstr "Meklēt vienības"
@@ -2642,11 +2638,12 @@
 msgid "Go get it!"
 msgstr "Satver!"
 
+#, fuzzy
 msgid "File attachment browser"
-msgstr "Datnes piesaistes pārlūks"
+msgstr "Jauna piesaistes nosaukums"
 
 msgid "User account browser"
-msgstr "Lietotāju kontu pārlūks"
+msgstr ""
 
 msgid "No wanted pages in this wiki."
 msgstr "Šajā viki pieprasīto lapu nav."
@@ -3078,7 +3075,7 @@
 #~ msgid "Use UserPreferences to change settings of the selected user account"
 #~ msgstr ""
 #~ "Lai mainītu lietotāja iestatījumus vai izveidotu lietotāja kontu, "
-#~ "izmantojiet LietotājaIestatījumi"
+#~ "izmantojiet LietotājaIstatījumi"
 
 #~ msgid ""
 #~ "This list does not work, unless you have entered a valid email address!"
--- a/MoinMoin/i18n/mk.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/mk.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: moin\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2008-06-27 22:39+0200\n"
 "Last-Translator: Novica Nakov\n"
 "Language-Team: Macedonian <ossm-members@hedona.on.net.mk>\n"
@@ -2357,21 +2357,6 @@
 msgstr ""
 "Не можете да откажете претплата од страница на која не сте претплатени."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Ресетирање на лозинка"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Лозинката не е внесена. Внесете корисничко име и лозинка."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Разлики"
 
--- a/MoinMoin/i18n/mn.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/mn.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2006-12-05 12:04+0800\n"
 "Last-Translator: Amgalanbaatar Delegdorj <d.amgalanbaatar@gmail.com>\n"
 "Language-Team: Mongolia <d.amgalanbaatar@gmail.com>\n"
@@ -2355,21 +2355,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Энэ хуудас нь бүртгэгдсэн хуудсуудын жагсаалтад нэмэгдлээ."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Нууц үгээ давт"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Нууц үг алга байна. Хэрэглэгчийн нэр болон нууц үг оруулна уу."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "ЯлгааХаруулах"
 
--- a/MoinMoin/i18n/nb.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/nb.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -11,9 +11,11 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: MoinMoin 1.8\n"
-"PO-Revision-Date: 2008-12-02 15:24+0100\n"
-"Last-Translator: Martin Thorsen Ranang <mtr@ranang.org>\n"
+"Project-Id-Version: MoinMoin 1.6\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
+"PO-Revision-Date: 2004-12-01 21:30+0200\n"
+"Last-Translator: Joerg Cassens <jmt@cassens.org>\n"
 "Language-Team: Norwegian <moinmoin-nb@cassens.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
@@ -70,11 +72,11 @@
 
 #, python-format
 msgid "Argument \"%s\" is required"
-msgstr "Argumentet \\\"%s\\\" er påkrevd"
-
-#, python-format
+msgstr ""
+
+#, fuzzy, python-format
 msgid "No argument named \"%s\""
-msgstr "Ingen argumenter heter \"%s\""
+msgstr "Ingen sider matcher \"%s\"!"
 
 #, python-format
 msgid "Expected \"=\" to follow \"%(token)s\""
@@ -84,8 +86,9 @@
 msgid "Expected a value for key \"%(token)s\""
 msgstr "Forventet en verdi for variablen \"%(token)s\""
 
+#, fuzzy
 msgid "Your changes are not saved!"
-msgstr "Dine endringer er ikke lagret!"
+msgstr "Du har ikke endret på sidens innhold, så den ble ikke lagret!"
 
 msgid "You are not allowed to edit this page."
 msgstr "Du har ikke tillatelse til å redigere denne siden."
@@ -98,10 +101,10 @@
 
 #, fuzzy
 msgid "The lock you held timed out. Be prepared for editing conflicts!"
-msgstr "Din låsing av siden er utgått på tid, så vær forberedt på redigeringskonflikter!"
+msgstr "Din låsing av siden er utgått på tid, så vær forberedt på konflikter!"
 
 msgid "Page name is too long, try shorter name."
-msgstr "Sidenavnet er for langt, forsøk med et kortere navn."
+msgstr ""
 
 #, fuzzy, python-format
 msgid "Draft of \"%(pagename)s\""
@@ -117,15 +120,15 @@
 
 #, python-format
 msgid "Your edit lock on %(lock_page)s has expired!"
-msgstr "Din redigeringslås på %(lock_page)s har gått ut!"
+msgstr "Din lås på %(lock_page)s har gått ut!"
 
 #, python-format
 msgid "Your edit lock on %(lock_page)s will expire in # minutes."
-msgstr "Din redigeringslås på %(lock_page)s går ut om # minutter."
+msgstr "Din lås på %(lock_page)s går ut om # minutter."
 
 #, python-format
 msgid "Your edit lock on %(lock_page)s will expire in # seconds."
-msgstr "Din redigeringslås på %(lock_page)s går ut om # sekunder."
+msgstr "Din lås på %(lock_page)s går ut om # sekunder."
 
 msgid "Someone else deleted this page while you were editing!"
 msgstr "En annen har slettet denne siden mens du redigerte den!"
@@ -196,7 +199,7 @@
 msgstr "Forhåndsvisning"
 
 msgid "GUI Mode"
-msgstr "GUI-modus"
+msgstr ""
 
 msgid "Load Draft"
 msgstr ""
@@ -204,18 +207,19 @@
 msgid "Trivial change"
 msgstr "Mindre oppdatering"
 
+#, fuzzy
 msgid "Comment:"
-msgstr "Kommentar:"
+msgstr "Kommentar"
 
 msgid "<No addition>"
-msgstr "<Ingen tilføyelse>"
+msgstr "<Ingen tilføyelser>"
 
 #, python-format
 msgid "Add to: %(category)s"
-msgstr "Legg til i: %(category)s"
+msgstr ""
 
 msgid "Remove trailing whitespace from each line"
-msgstr "Fjern ekstra mellomrom på slutten av hver linje"
+msgstr "Fjern ekstra mellomrom på slutten av linjer"
 
 msgid "Edit was cancelled."
 msgstr "Redigeringen ble avbrutt."
@@ -254,8 +258,9 @@
 msgid "Could not rename page because of file system error: %s."
 msgstr "Navn ikke endret på grunn av filsystemfeil: %s."
 
+#, fuzzy
 msgid "You are not allowed to delete this page!"
-msgstr "Du har ikke tillatelse til å slette denne siden!"
+msgstr "Du har ikke tillatelse til å tilbakestille denne siden!"
 
 msgid "Thank you for your changes. Your attention to detail is appreciated."
 msgstr "Takk for dine endringer. Ditt bidrag er verdsatt."
@@ -392,10 +397,10 @@
 msgstr "Du har ikke tillatelse til å se denne siden."
 
 msgid "The wiki is currently not reachable."
-msgstr "Wikien er for øyeblikket ikke tilgjengelig."
+msgstr ""
 
 msgid "Invalid username or password."
-msgstr "Ugyldig brukernavn eller passord."
+msgstr ""
 
 #, python-format
 msgid ""
@@ -404,21 +409,21 @@
 msgstr ""
 
 msgid "Text mode"
-msgstr "Tekstmodus"
+msgstr ""
 
 #, python-format
 msgid "The package needs a newer version of MoinMoin (at least %s)."
-msgstr "Pakken trenger en nyere versjon av MoinMoin (minst %s)."
+msgstr ""
 
 msgid "The theme name is not set."
-msgstr "Temanavnet er ikke satt."
+msgstr ""
 
 msgid "Installing theme files is only supported for standalone type servers."
 msgstr ""
 
-#, python-format
+#, fuzzy, python-format
 msgid "Installation of '%(filename)s' failed."
-msgstr "Installasjonen av '%(filename)s' mislyktes."
+msgstr "Tegningen '%(filename)s' er lagret."
 
 #, python-format
 msgid "The file %s is not a MoinMoin package file."
@@ -488,24 +493,28 @@
 "%(be)s results out of about %(pages)d pages."
 msgstr ""
 
+#, fuzzy
 msgid "seconds"
-msgstr "sekunder"
-
+msgstr "%.2f sekunder"
+
+#, fuzzy
 msgid "Previous"
-msgstr "Forrige"
-
+msgstr "Forhåndsvisning"
+
+#, fuzzy
 msgid "Next"
-msgstr "Neste"
-
+msgstr "Tekst"
+
+#, fuzzy
 msgid "rev"
-msgstr "rev"
+msgstr "tilbakestill"
 
 msgid "current"
-msgstr "nåværende"
-
-#, python-format
+msgstr ""
+
+#, fuzzy, python-format
 msgid "last modified: %s"
-msgstr "sist endret: %s"
+msgstr "sist endret %(time)s"
 
 msgid "match"
 msgstr "resultat"
@@ -517,7 +526,7 @@
 msgstr ""
 
 msgid "Language"
-msgstr "Språk"
+msgstr ""
 
 msgid "<Browser setting>"
 msgstr "<Nettleseroppsett>"
@@ -528,14 +537,16 @@
 msgid "Date"
 msgstr "Dato"
 
+#, fuzzy
 msgid "Views/day"
-msgstr "Visninger/dag"
-
+msgstr "Vis"
+
+#, fuzzy
 msgid "Edits/day"
-msgstr "Endringer/dag"
+msgstr "Rediger"
 
 msgid "Page hits and edits"
-msgstr "Sidebesøk og -endringer"
+msgstr "Sidebesøk og -redigeringer"
 
 #, python-format
 msgid "%(chart_title)s for %(filterpage)s"
@@ -576,10 +587,10 @@
 msgstr ""
 
 msgid "Failed to connect to database."
-msgstr "Mislyktes med databasetilkobling."
+msgstr ""
 
 msgid "Missing password. Please enter user name and password."
-msgstr "Passordet mangler. Vær vennlig å oppgi brukernavn og passord."
+msgstr "Passordet mangler. Oppgi et passord."
 
 #, python-format
 msgid ""
@@ -605,10 +616,10 @@
 msgstr "Navn"
 
 msgid "Choose this name"
-msgstr "Velg dette navnet"
+msgstr ""
 
 msgid "This is not a valid username, choose a different one."
-msgstr "Dette er ikke et gyldig brukernavn, velg et annet."
+msgstr ""
 
 msgid ""
 "The username you have chosen is already\n"
@@ -629,7 +640,7 @@
 
 #, fuzzy
 msgid "Verification canceled."
-msgstr "Verifiseringen ble avbrutt."
+msgstr "Redigeringen ble avbrutt."
 
 msgid "OpenID failure."
 msgstr ""
@@ -638,7 +649,7 @@
 msgstr ""
 
 msgid "The password you entered is not valid."
-msgstr "Passordet du oppga er ikke gyldig."
+msgstr ""
 
 msgid "OpenID verification requires that you click this button:"
 msgstr ""
@@ -661,35 +672,40 @@
 msgstr ""
 
 msgid "Page has been modified"
-msgstr "Siden har blitt endret"
+msgstr ""
 
 msgid "Page has been modified in a trivial fashion"
-msgstr "Siden har gjennomgått mindre endringer"
-
+msgstr ""
+
+#, fuzzy
 msgid "Page has been renamed"
-msgstr "Siden har fått nytt navn"
-
+msgstr "Sidebesøk og -redigeringer"
+
+#, fuzzy
 msgid "Page has been deleted"
-msgstr "Siden har blitt slettet"
-
+msgstr "Siden \"%s\" ble slettet."
+
+#, fuzzy
 msgid "Page has been copied"
-msgstr "Siden har blitt kopiert"
-
+msgstr "Sidebesøk og -redigeringer"
+
+#, fuzzy
 msgid "A new attachment has been added"
-msgstr "En nytt vedlegg har blitt lagt til"
+msgstr "Nytt vedlegg"
 
 msgid "A page has been reverted to a previous state"
-msgstr "En side har gått tilbake til sin forrige tilstand"
-
+msgstr ""
+
+#, fuzzy
 msgid "A user has subscribed to a page"
-msgstr "En bruker har abonnert på en side"
+msgstr "Du abonnerer nå på denne siden."
 
 msgid "A new account has been created"
-msgstr "En ny konto har blitt opprettet"
-
-#, python-format
+msgstr ""
+
+#, fuzzy, python-format
 msgid "[%(sitename)s] %(trivial)sUpdate of \"%(pagename)s\" by %(username)s"
-msgstr "[%(sitename)s] %(trivial)soppdatering av \"%(pagename)s\" av %(username)s"
+msgstr "[%(sitename)s] %(trivial)soppdatering av \"%(pagename)s\""
 
 msgid "Trivial "
 msgstr "Mindre "
@@ -709,11 +725,13 @@
 "\n"
 "The \"%(pagename)s\" page has been changed by %(editor)s:\n"
 msgstr ""
-"Kjære, wiki-bruker.\n"
+"Hei, wiki-bruker!\n"
 "\n"
-"Du har abonnert på endringer av wiki-siden \"%(sitename)s\".\n"
+"Du abonnerer på oppdateringer på en wiki-side eller wiki-kategori på \"%"
+"(sitename)s\".\n"
 "\n"
-"Siden \"%(pagename)s\" har blitt endret av %(editor)s:\n"
+"Følgende sider er redigert av %(editor)s:\n"
+"%(pagelink)s\n"
 "\n"
 
 msgid "New page:\n"
@@ -722,7 +740,7 @@
 msgid "No differences found!\n"
 msgstr "Fant ingen endringer!\n"
 
-#, python-format
+#, fuzzy, python-format
 msgid ""
 "Dear wiki user,\n"
 "\n"
@@ -732,14 +750,16 @@
 "The page \"%(pagename)s\" has been deleted by %(editor)s:\n"
 "\n"
 msgstr ""
-"Kjære, wiki-bruker.\n"
-"\n"
-"Du har abonnert på endringer av wiki-siden \"%(sitename)s\".\n"
+"Hei, wiki-bruker!\n"
 "\n"
-"Siden \"%(pagename)s\" har blitt slettet av %(editor)s:\n"
+"Du abonnerer på oppdateringer på en wiki-side eller wiki-kategori på \"%"
+"(sitename)s\".\n"
 "\n"
-
-#, python-format
+"Følgende sider er redigert av %(editor)s:\n"
+"%(pagelink)s\n"
+"\n"
+
+#, fuzzy, python-format
 msgid ""
 "Dear wiki user,\n"
 "\n"
@@ -749,11 +769,13 @@
 "The page \"%(pagename)s\" has been renamed from \"%(oldname)s\" by %(editor)"
 "s:\n"
 msgstr ""
-"Kjære, wiki-bruker.\n"
+"Hei, wiki-bruker!\n"
 "\n"
-"Du har abonnert på endringer av wiki-siden \"%(sitename)s\".\n"
+"Du abonnerer på oppdateringer på en wiki-side eller wiki-kategori på \"%"
+"(sitename)s\".\n"
 "\n"
-"Siden \"%(pagename)s\" fikk endret navn fra \"%(oldname)s\" av %(editor)s:\n"
+"Følgende sider er redigert av %(editor)s:\n"
+"%(pagelink)s\n"
 "\n"
 
 #, python-format
@@ -785,18 +807,20 @@
 "Attachment size: %(attach_size)s\n"
 msgstr ""
 
+#, fuzzy
 msgid "Attachment link"
-msgstr "Vedleggslenke"
-
+msgstr "Nytt vedlegg"
+
+#, fuzzy
 msgid "Page link"
-msgstr "Sidelenke"
+msgstr "Sider som \"%s\"!"
 
 msgid "Changed page"
-msgstr "Endret side"
+msgstr ""
 
 #, fuzzy
 msgid "Page changed"
-msgstr "Siden ble endret"
+msgstr "Lagre endringene"
 
 #, fuzzy
 msgid ""
@@ -932,7 +956,7 @@
 "(!) For more help, see HelpOnEditing or SyntaxReference.\n"
 
 msgid "Preferences"
-msgstr "Preferanser"
+msgstr ""
 
 #, python-format
 msgid ""
@@ -949,7 +973,7 @@
 msgstr "Dette brukernavnet er allerede i bruk."
 
 msgid "Empty user name. Please enter a user name."
-msgstr "Tomt brukernavn. Vær vennlig å oppgi et gyldig brukernavn."
+msgstr "Tomt brukernavn. Oppgi gyldig brukernavn."
 
 #, fuzzy
 msgid ""
@@ -962,12 +986,13 @@
 msgid "This email already belongs to somebody else."
 msgstr "Denne e-postadressen tilhører en annen bruker."
 
+#, fuzzy
 msgid "This jabber id already belongs to somebody else."
-msgstr "Denne jabber-id'en tilhører allerede en annen bruker."
+msgstr "Denne e-postadressen tilhører en annen bruker."
 
 #, python-format
 msgid "The theme '%(theme_name)s' could not be loaded!"
-msgstr "Utseendet '%(theme_name)s' kunne ikke lastes!"
+msgstr "Utseendet '%(theme_name)s' finnes ikke!"
 
 msgid "User preferences saved!"
 msgstr "Brukerprofil lagret!"
@@ -976,10 +1001,10 @@
 msgstr "Standard"
 
 msgid "the one preferred"
-msgstr "den foretrukne"
+msgstr ""
 
 msgid "free choice"
-msgstr "fritt valg"
+msgstr ""
 
 msgid "Save"
 msgstr "Lagre"
@@ -1015,10 +1040,10 @@
 msgstr "Hurtiglenker"
 
 msgid "Switch user"
-msgstr "Bytt bruker"
+msgstr ""
 
 msgid "No user selected"
-msgstr "Ingen bruker er valgt"
+msgstr ""
 
 msgid ""
 "You can now change the settings of the selected user account; log out to get "
@@ -1026,30 +1051,31 @@
 msgstr ""
 
 msgid "You are the only user."
-msgstr "Du er den eneste brukeren."
+msgstr ""
 
 msgid ""
 "As a superuser, you can temporarily assume the identity of another user."
 msgstr ""
 
 msgid "Select User"
-msgstr "Velg bruker"
-
+msgstr ""
+
+#, fuzzy
 msgid "Change password"
-msgstr "Endre passord"
+msgstr "Passord"
 
 msgid "Passwords don't match!"
 msgstr "Passordene er ikke like!"
 
 msgid "Please specify a password!"
-msgstr "Vær vennlig å oppgi et passord!"
+msgstr "Oppgi et passord!"
 
 #, python-format
 msgid "Password not acceptable: %s"
-msgstr "Passordet er ikke godkjent: %s"
+msgstr ""
 
 msgid "Your password has been changed."
-msgstr "Passordet ditt er blitt endret."
+msgstr ""
 
 msgid "To change your password, enter a new password twice."
 msgstr ""
@@ -1083,7 +1109,7 @@
 
 #, fuzzy
 msgid "Subscribed events"
-msgstr "Abonnerte hendelser"
+msgstr "Abonner"
 
 #, fuzzy
 msgid "Subscribed wiki pages<<BR>>(one regex per line)"
@@ -1144,12 +1170,13 @@
 msgid "Output file already exists! Cowardly refusing to continue!"
 msgstr ""
 
+#, fuzzy
 msgid "Username"
-msgstr "Brukernavn"
+msgstr "Bruker"
 
 #, fuzzy
 msgid "Member of Groups"
-msgstr "Medlem av grupper"
+msgstr "Antall sider"
 
 msgid "Email"
 msgstr "E-postadresse"
@@ -1184,7 +1211,7 @@
 msgstr "Lokal oversikt for \"%s\""
 
 msgid "Please log in first."
-msgstr "Vær vennlig å logge inn først."
+msgstr ""
 
 msgid "Please first create a homepage before creating additional pages."
 msgstr ""
@@ -1229,10 +1256,10 @@
 
 #, fuzzy, python-format
 msgid "You must login to use this action: %(action)s."
-msgstr "Du må logge inn for å utføre denne operasjonen: %(action)s."
+msgstr "Du har ikke tillatelse til å redigere denne siden."
 
 msgid "You are not allowed to subscribe to a page you can't read."
-msgstr "Du får ikke lov til å abonnere på en side du ikke kan lese."
+msgstr "Du har ikke tillatelse til å abonnere på en side du ikke kan lese!"
 
 #, fuzzy
 msgid "This wiki is not enabled for mail/Jabber processing."
@@ -1319,21 +1346,20 @@
 msgid "Your token is invalid!"
 msgstr ""
 
+#, fuzzy
 msgid "Password reset"
-msgstr "Nullstill passord"
-
+msgstr "Gjenta passord"
+
+#, fuzzy
 msgid ""
 "\n"
 "== Password reset ==\n"
 "Enter a new password below."
-msgstr ""
-"\n"
-"== Nullstilling av passord ==\n"
-"Oppgi et nytt passord nedenfor."
+msgstr "Passordet mangler. Oppgi et passord."
 
 #, fuzzy
 msgid "Lost password"
-msgstr "Tapt passord"
+msgstr "Passord"
 
 msgid ""
 "\n"
@@ -1352,8 +1378,9 @@
 "username, the recovery token and a new password (twice) below."
 msgstr ""
 
+#, fuzzy
 msgid "Wiki Backup"
-msgstr "Wiki-sikkerhetskopi"
+msgstr "Wiki-markering"
 
 msgid ""
 "= Downloading a backup =\n"
@@ -1370,16 +1397,17 @@
 "To get a backup, just click here:"
 msgstr ""
 
+#, fuzzy
 msgid "Backup"
-msgstr "Sikkerhetskopi"
+msgstr "Oppmerking"
 
 #, fuzzy
 msgid "You are not allowed to do remote backup."
-msgstr "Du har ikke tillatelse til å utføre en sikkerhetskopi til et annet sted."
+msgstr "Du har ikke tillatelse til å redigere denne siden."
 
 #, fuzzy, python-format
 msgid "Unknown backup subaction: %s."
-msgstr ""
+msgstr "Opplastningsoperasjonen er ikke støttet: %s"
 
 msgid "You must login to add a quicklink."
 msgstr ""
@@ -1424,8 +1452,9 @@
 msgid "Comment"
 msgstr "Kommentar"
 
+#, fuzzy
 msgid "Page Name"
-msgstr "Sidenavn"
+msgstr "Nytt navn"
 
 #, fuzzy
 msgid "You are not allowed to create the supplementation page."
@@ -1478,7 +1507,7 @@
 msgstr "slett"
 
 msgid "move"
-msgstr "flytt"
+msgstr ""
 
 msgid "get"
 msgstr "hent"
@@ -1493,7 +1522,7 @@
 msgstr ""
 
 msgid "install"
-msgstr "installer"
+msgstr ""
 
 #, python-format
 msgid "No attachments stored for %(pagename)s"
@@ -1519,7 +1548,7 @@
 msgstr "Last opp"
 
 msgid "Attached Files"
-msgstr "Vedlagte filer"
+msgstr "Vedlegg"
 
 msgid "You are not allowed to attach a file to this page."
 msgstr "Du har ikke tillatelse til å legge ved filer til denne siden."
@@ -1574,7 +1603,7 @@
 msgstr "Vedlegg '%(filename)s' eksisterer ikke!"
 
 msgid "Nothing changed"
-msgstr "Ingenting ble endret"
+msgstr ""
 
 #, python-format
 msgid "Page '%(new_pagename)s' does not exist or you don't have enough rights."
@@ -1603,13 +1632,15 @@
 msgstr "Du kan ikke lagre tomme sider."
 
 msgid "Move"
-msgstr "Flytt"
-
+msgstr ""
+
+#, fuzzy
 msgid "New page name"
-msgstr "Nytt sidenavn"
-
+msgstr "Nytt navn"
+
+#, fuzzy
 msgid "New attachment name"
-msgstr "Nytt vedleggsnavn"
+msgstr "Nytt vedlegg"
 
 msgid "You are not allowed to get attachments from this page."
 msgstr "Du har ikke tillatelse til å hente vedlegg fra denne siden."
@@ -2225,21 +2256,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Du abonnerer nå på denne siden."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Gjenta passord"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Passordet mangler. Oppgi et passord."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Endringer"
 
@@ -2442,22 +2458,23 @@
 msgstr "Kommentar"
 
 msgid "Edit (Text)"
-msgstr "Rediger (Tekst)"
+msgstr ""
 
 msgid "Edit (GUI)"
-msgstr "Rediger (GUI)"
+msgstr ""
 
 msgid "Immutable Page"
 msgstr "Siden kan ikke endres"
 
 msgid "Remove Link"
-msgstr "Fjern lenke"
+msgstr ""
 
 msgid "Add Link"
-msgstr "Legg til lenke"
-
+msgstr ""
+
+#, fuzzy
 msgid "Attachments"
-msgstr "Vedlegg"
+msgstr "Nytt vedlegg"
 
 #, python-format
 msgid "Show %s days."
@@ -2468,7 +2485,7 @@
 
 #, fuzzy
 msgid "DeleteCache"
-msgstr "SlettCache"
+msgstr "SlettSide"
 
 #, python-format
 msgid "(cached %s)"
@@ -2491,10 +2508,10 @@
 
 #, fuzzy
 msgid "Variable name"
-msgstr "Variabelnavn"
+msgstr "Filnavn"
 
 msgid "Description"
-msgstr "Beskrivelse"
+msgstr ""
 
 #, python-format
 msgid "Upload new attachment \"%(filename)s\""
@@ -2525,7 +2542,7 @@
 msgstr "Ta med systemsider"
 
 msgid "Exclude system pages"
-msgstr "Utelat systemsider"
+msgstr "Uten systemsider"
 
 msgid "Go To Page"
 msgstr "Gå til siden"
@@ -2537,7 +2554,7 @@
 msgstr "Vis"
 
 msgid "Wiki configuration"
-msgstr "Wikikonfigurasjon"
+msgstr ""
 
 msgid ""
 "This table shows all settings in this wiki that do not have default values. "
@@ -2547,11 +2564,11 @@
 msgstr ""
 
 msgid "Setting"
-msgstr "Innstilling"
+msgstr ""
 
 #, fuzzy
 msgid "Search for items"
-msgstr "Søk etter elementer"
+msgstr "Søk på tittel"
 
 msgid "containing all the following terms"
 msgstr ""
@@ -2566,22 +2583,25 @@
 msgstr ""
 
 msgid "any category"
-msgstr "enhver kategori"
-
+msgstr ""
+
+#, fuzzy
 msgid "any language"
-msgstr "ethvert språk"
+msgstr "Språkinnstilling"
 
 msgid "any mimetype"
 msgstr ""
 
 msgid "Categories"
-msgstr "Kategorier"
-
+msgstr ""
+
+#, fuzzy
 msgid "File Type"
-msgstr "Filtype"
-
+msgstr "Filnavn"
+
+#, fuzzy
 msgid "Search only in titles"
-msgstr "Søk bare blant titler"
+msgstr "Søk på tittel"
 
 #, fuzzy
 msgid "Case-sensitive search"
@@ -2590,8 +2610,9 @@
 msgid "Exclude underlay"
 msgstr ""
 
+#, fuzzy
 msgid "No system items"
-msgstr "Ingen systemelementer"
+msgstr "Antall systemsider"
 
 msgid "Search in all page revisions"
 msgstr ""
@@ -2601,10 +2622,10 @@
 
 #, fuzzy
 msgid "File attachment browser"
-msgstr "Filvedleggsutforsker"
+msgstr "Nytt vedlegg"
 
 msgid "User account browser"
-msgstr "Brukerkontoutforsker"
+msgstr ""
 
 msgid "No wanted pages in this wiki."
 msgstr "Ingen ønskede sider i denne wikien."
@@ -2631,7 +2652,7 @@
 msgstr "Innhold"
 
 msgid "Search Titles"
-msgstr "Søk blant titler"
+msgstr "Søk på tittel"
 
 msgid "Display context of search results"
 msgstr "Vis søketekst i søkeresultater"
--- a/MoinMoin/i18n/nl.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/nl.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2005-03-13 17:43+0200\n"
 "Last-Translator: Sander Kromwijk <s.kromwijk@gmail.com>\n"
 "Language-Team: Dutch <vertaling@vrijschrift.org>\n"
@@ -2339,21 +2339,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "U moet geabonneerd zijn om uit te schrijven."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Wachtwoord herhalen"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Geen wachtwoord. Geef een gebruikersnaam en wachtwoord op."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Verschillen"
 
--- a/MoinMoin/i18n/pl.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/pl.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -11,12 +11,12 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: 1.8\n"
+"Project-Id-Version: 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2006-02-09 11:25+0100\n"
-"Last-Translator: Sergiusz Pawłowicz <moin@pawlowicz.name>\n"
-"Language-Team: Polish <moin@pawlowicz.name>\n"
+"Last-Translator: Radomir Dopieralski <mondev@sheep.art.pl>\n"
+"Language-Team: Polish <sergiusz-keyword-moinmoin.69c762@pawlowicz.name>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -535,7 +535,7 @@
 msgstr "porównania"
 
 msgid "about"
-msgstr "około"
+msgstr ""
 
 msgid "Language"
 msgstr "Język"
@@ -615,7 +615,7 @@
 
 #, python-format
 msgid "LDAP server %(server)s failed."
-msgstr "Serwer LDAP %(server)s zawiódł."
+msgstr ""
 
 msgid ""
 "Please choose an account name now.\n"
@@ -794,7 +794,7 @@
 msgid "New user account created on %(sitename)s"
 msgstr "Nowe konto czytelnika utworzone na %(sitename)s"
 
-#, python-format
+#, fuzzy, python-format
 msgid ""
 "Dear Superuser, a new user has just been created on %(sitename)s\". Details "
 "follow:\n"
@@ -802,8 +802,7 @@
 "    User name: %(username)s\n"
 "    Email address: %(useremail)s"
 msgstr ""
-"Drogi nadczytelniku, zostało właśnie utworzone nowe konto czytelnika na "
-"stronie %(sitename)s\". Oto szczegóły:\n"
+"Drogi nadczytelniku, zostało właśnie utworzone nowe konto czytelnika.\n"
 "\n"
 "    Identyfikator: %(username)s\n"
 "    Adres e-mail: %(useremail)s"
@@ -1144,14 +1143,16 @@
 msgid "Subscribed wiki pages<<BR>>(one regex per line)"
 msgstr "Zasubskrybowane strony wiki<<BR>>(jedno wyrażenie regularne w linii)"
 
+#, fuzzy
 msgid "OpenID server"
-msgstr "Serwer OpenID"
-
+msgstr "OpenID nie jest serwowany"
+
+#, fuzzy
 msgid "The selected websites have been removed."
-msgstr "Wskazane strony internetowe zostały usunięte."
+msgstr "Wskazane OpenID zostały usunięte."
 
 msgid "Trusted websites"
-msgstr "Zaufane strony internetowe"
+msgstr ""
 
 msgid "Remove selected"
 msgstr "Usuń wskazane"
@@ -1194,7 +1195,7 @@
 "Nie podano stron dla --pages lub --search, zakładam że chodzi o pełen pakiet."
 
 msgid "All attachments included into the package."
-msgstr "Wszystkie załączniki dołączone do pakietu."
+msgstr ""
 
 msgid "Output file already exists! Cowardly refusing to continue!"
 msgstr "Plik wyjściowy już istnieje! Tchórzliwie odmawiam kontynuacji!"
@@ -1431,8 +1432,9 @@
 "odzyskiwania hasła, wprowadź\n"
 "swój identyfikator czytelnika, kod oraz nowe hasło (dwukrotnie)."
 
+#, fuzzy
 msgid "Wiki Backup"
-msgstr "Kopia zapasowa wiki."
+msgstr "Język oznaczeń wiki"
 
 msgid ""
 "= Downloading a backup =\n"
@@ -1448,15 +1450,6 @@
 "\n"
 "To get a backup, just click here:"
 msgstr ""
-"= Pobieranie kopii zapasowej =\n"
-"\n"
-"Uwaga:\n"
-" * Trzymaj kopie zapsowe w bezpiecznym miejscu; zawierają poufne informacje.\n"
-" * Upewnij się, że w konfiguracji wiki parametry backup_* są uzupełnione i poprawne.\n"
-" * Upewnij się, że kopia zapasowa którą uzyskasz zawiera wszystko czego potrzebujesz w razie problemów.\n"
-" * Upewnij się że jest pobrana bez problemów.\n"
-"\n"
-"Aby pobrać kopię zapasową, kliknij tutaj:"
 
 msgid "Backup"
 msgstr "Kopia zapasowa"
@@ -1713,38 +1706,36 @@
 msgid "The file %(filename)s is not a .zip file."
 msgstr "Plik %(filename)s nie jest typu .zip."
 
-#, python-format
+#, fuzzy, python-format
 msgid ""
 "Attachment '%(filename)s' not unzipped because some files in the zip are "
 "either not in the same directory or exceeded the single file size limit (%"
 "(maxsize_file)d kB)."
 msgstr ""
 "Nie rozpakowano załącznika '%(filename)s', ponieważ pliki są zbyt duże, "
-"przekraczają limit wielkości pojedycznego pliku (%(maxsize_file)d kB) albo "
-"też znajdują się w podkatalogach."
-
-#, python-format
+"tylko typu .zip, już istnieją, albo znajdują się w podkatalogach."
+
+#, fuzzy, python-format
 msgid ""
 "Attachment '%(filename)s' not unzipped because it would have exceeded the "
 "per page attachment storage size limit (%(size)d kB)."
 msgstr ""
-"Załącznik '%(filename)s' nie mógł zostać rozpakowany, ponieważ przekroczony "
-"zostałby limit objętości załączników na stronie (%(size)d kB)."
-
-#, python-format
+"Załącznik '%(filename)s' nie mógł zostać rozpakowany, ponieważ powstałe "
+"pliki byłyby zbyt duże (zabrakło %(space)d kB)."
+
+#, fuzzy, python-format
 msgid ""
 "Attachment '%(filename)s' not unzipped because it would have exceeded the "
 "per page attachment count limit (%(count)d)."
 msgstr ""
-"Załącznik '%(filename)s' nie mógł zostać rozpakowany, ponieważ przekroczony "
-"zostałby limit największej ilości plików na stronie (%(count)d)."
-
-#, python-format
+"Załącznik '%(filename)s' nie mógł zostać rozpakowany, ponieważ powstałoby "
+"zbyt wiele plików (zabrakło %(count)d)."
+
+#, fuzzy, python-format
 msgid ""
 "Attachment '%(filename)s' partially unzipped (did not overwrite: %(filelist)"
 "s)."
-msgstr ""
-"Załącznik '%(filename)s' rozpakowano częściowo (nie zamazano: %(filelist)s)."
+msgstr "Załącznik '%(filename)s' rozpakowano."
 
 #, python-format
 msgid "Attachment '%(filename)s' unzipped."
@@ -1850,8 +1841,9 @@
 msgid "Created the package %s containing the pages %s."
 msgstr "Utworzono pakiet %s zawierający strony %s."
 
+#, fuzzy
 msgid "Include all attachments?"
-msgstr "Zawrzeć wszystkie załączniki?"
+msgstr "[%d załączników]"
 
 msgid "Package pages"
 msgstr "Spakuj strony"
@@ -2298,7 +2290,7 @@
 "Your search query {{{\"%s\"}}} didn't return any results. Please change some "
 "terms and refer to HelpOnSearching for more information.%s"
 msgstr ""
-"Twoje zapytanie {{{\"%s\"}}} nie dało żadnych wyników. Zmień niektóre "
+"Twoje zapytanie {{{\"%s\"}}} nie dałoz żadnych wyników. Zmień niektóre "
 "warunki i zobacz HelpOnSearching, by uzyskać więcej informacji.%s"
 
 msgid "(!) Consider performing a"
@@ -2348,19 +2340,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Nie było subskrypcji do tej strony, więc nie można z niej zrezygnować."
 
-msgid "Password is too short."
-msgstr "Hasło jest zbyt krótkie."
-
-msgid "Password has not enough different characters."
-msgstr "Hasło nie ma wystarczająco wiele różnych znaków."
-
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Asło jest zbyt łatwe (hasło zawiera nazwę użytkownika albo odwrotnie)."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr "Hasło jest zbyt łatwe (sekwencja klawiatury)."
-
 msgid "Diffs"
 msgstr "Różnice"
 
@@ -2597,13 +2576,14 @@
 msgstr "Czytelnik"
 
 msgid "[ATTACH]"
-msgstr "[ZAŁĄCZ]"
-
+msgstr ""
+
+#, fuzzy
 msgid "Variable name"
-msgstr "Nazwa zmiennej"
+msgstr "Nazwa pliku"
 
 msgid "Description"
-msgstr "Opis"
+msgstr ""
 
 #, python-format
 msgid "Upload new attachment \"%(filename)s\""
@@ -2652,7 +2632,7 @@
 msgstr "Pokaż"
 
 msgid "Wiki configuration"
-msgstr "Konfiguracja wiki"
+msgstr ""
 
 msgid ""
 "This table shows all settings in this wiki that do not have default values. "
@@ -2660,14 +2640,10 @@
 "''italic'', those may be due to third-party extensions needing configuration "
 "or settings that were removed from Moin."
 msgstr ""
-"Ta tabelka pokazuje wszystkie ustawienia tego wiki które nie mają domyslnych wartości. "
-"Ustawienia nieznane systemowi konfiguracji są wyświetlone ''italikami'', mogą "
-"to być ustawienia dodatkowych rozszerzeń i wtyczek lub ustawienia usunięte z tej "
-"wersji MoinMoin."
-
-
+
+#, fuzzy
 msgid "Setting"
-msgstr "Ustawienie"
+msgstr "Ustawienia"
 
 msgid "Search for items"
 msgstr "Poszukuj obiektów"
--- a/MoinMoin/i18n/pt-br.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/pt-br.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2007-11-20 23:40+0000\n"
 "Last-Translator: Evandro Villa Verde <evandro.villaverde.hackerteen@gmail."
 "com>\n"
@@ -109,7 +109,7 @@
 
 #, python-format
 msgid "Draft of \"%(pagename)s\""
-msgstr "Rascunho de \"%(pagename)s\""
+msgstr "Previsão de \"%(pagename)s\""
 
 #, python-format
 msgid "Edit \"%(pagename)s\""
@@ -153,7 +153,7 @@
 
 #, python-format
 msgid "[Template %s not found]"
-msgstr "[Modelo %s não encontrado]"
+msgstr "[Template %s não encontrado]"
 
 #, python-format
 msgid "[You may not read %s]"
@@ -206,7 +206,7 @@
 msgstr "Visualização Gráfica"
 
 msgid "Load Draft"
-msgstr "Carregar Rascunho"
+msgstr "Carregar Previsão"
 
 msgid "Trivial change"
 msgstr "Alterações superficiais"
@@ -308,7 +308,8 @@
 msgstr "Você já editou esta página! Por favor não use o botão voltar."
 
 msgid "You did not change the page content, not saved!"
-msgstr "Você não alterou o conteúdo da página, a página não foi salva!"
+msgstr ""
+"Você não pode alterar o conteúdo da página, alterações não foram salvas!"
 
 msgid ""
 "You can't change ACLs on this page since you have no admin rights on it!"
@@ -317,7 +318,7 @@
 "administração sobre ela!"
 
 msgid "Notifications sent to:"
-msgstr "Notificação enviada para:"
+msgstr ""
 
 #, python-format
 msgid ""
@@ -400,7 +401,7 @@
 msgstr "Você não tem permissão para ver esta página!"
 
 msgid "The wiki is currently not reachable."
-msgstr "O wiki está atualmente indisponível."
+msgstr "A wiki está atualmente não disponível."
 
 msgid "Invalid username or password."
 msgstr "Usuário ou senha inválida."
@@ -410,8 +411,8 @@
 "The remote wiki uses a different InterWiki name (%(remotename)s) internally "
 "than you specified (%(localname)s)."
 msgstr ""
-"O wiki remoto está usando um nome de InterWiki diferente (%(remotename)s) "
-"internamente que aquele que você especificou (%(localname)s)."
+"O wiki remota está usando um nome de InterWiki diferente (%(remotename)s) "
+"internamente que o especificado (%(localname)s)."
 
 msgid "Text mode"
 msgstr "Modo texto"
@@ -425,8 +426,7 @@
 msgstr "O nome do tema não está definido."
 
 msgid "Installing theme files is only supported for standalone type servers."
-msgstr ""
-"Instalar arquivos de temas só é possível para servidores do tipo standalone."
+msgstr "Instalar arquivos de temas só é suportado por servidores."
 
 #, python-format
 msgid "Installation of '%(filename)s' failed."
@@ -592,10 +592,10 @@
 msgstr "Distribuição dos Tipos de User-Agent"
 
 msgid "Could not contact botbouncer.com."
-msgstr "Não foi possível conectar botbouncer.com"
+msgstr ""
 
 msgid "Failed to connect to database."
-msgstr "Falha em conectar a base de dados"
+msgstr ""
 
 msgid "Missing password. Please enter user name and password."
 msgstr "Senha não foi informada. Por favor, informe o nome do usuário e senha."
@@ -605,16 +605,14 @@
 "If you do not have an account, <a href=\"%(userprefslink)s\">you can create "
 "one now</a>. <a href=\"%(sendmypasswordlink)s\">Forgot your password?</a>"
 msgstr ""
-"Se você não tem uma conta, <a href=\"%(userprefslink)s\">você pode criar uma "
-"agora</a>. <a href=\"%(sendmypasswordlink)s\">Esqueceu sua senha?</a>"
 
 #, fuzzy
 msgid "You need to log in."
-msgstr "Você precisa fazer o login."
+msgstr "Você não está mais logado."
 
 #, python-format
 msgid "LDAP server %(server)s failed."
-msgstr "Servidor LDAP %(server)s falhou"
+msgstr ""
 
 msgid ""
 "Please choose an account name now.\n"
@@ -626,10 +624,10 @@
 msgstr "Nome"
 
 msgid "Choose this name"
-msgstr "Escolha este nome"
+msgstr ""
 
 msgid "This is not a valid username, choose a different one."
-msgstr "Este não é um nome de usuário válido, escolha outro."
+msgstr ""
 
 msgid ""
 "The username you have chosen is already\n"
@@ -642,46 +640,44 @@
 msgstr "Senha"
 
 msgid "Associate this name"
-msgstr "Associe este nome"
+msgstr ""
 
 #, python-format
 msgid "OpenID error: %s."
-msgstr "Erro OpenID: %s."
+msgstr ""
 
 #, fuzzy
 msgid "Verification canceled."
-msgstr "Verificação cancelada."
+msgstr "Operação foi cancelada."
 
 msgid "OpenID failure."
-msgstr "Falha OpenID"
+msgstr ""
 
 msgid "Your account is now associated to your OpenID."
-msgstr "Sua conta está agora associada a sua OpenID"
+msgstr ""
 
 msgid "The password you entered is not valid."
-msgstr "A senha que você informou não é válida."
+msgstr ""
 
 msgid "OpenID verification requires that you click this button:"
-msgstr "A verificação OpenID requer que você clique neste botão:"
+msgstr ""
 
 msgid "Anonymous sessions need to be enabled for OpenID login."
-msgstr "Sessões anônimas necessitam ser habilitadas para login OpenID"
+msgstr ""
 
 msgid "Failed to resolve OpenID."
-msgstr "Falha em resolver OpenID"
+msgstr ""
 
 msgid "OpenID discovery failure, not a valid OpenID."
-msgstr "Falha em recuperar OpenIF, não é uma OpenID válida"
+msgstr ""
 
 msgid "No OpenID."
-msgstr "Nenhuma OpenID."
+msgstr ""
 
 msgid ""
 "If you do not have an account yet, you can still log in with your OpenID and "
 "create one during login."
 msgstr ""
-"Se você ainda não tem uma conta, você ainda assim pode realizar o login com "
-"uma OpenID e criar uma durante o login."
 
 msgid "Page has been modified"
 msgstr ""
@@ -1076,33 +1072,29 @@
 msgstr "Links rápidos"
 
 msgid "Switch user"
-msgstr "Mudar o usuário"
+msgstr ""
 
 msgid "No user selected"
-msgstr "Nenhum usuário selecionado"
+msgstr ""
 
 msgid ""
 "You can now change the settings of the selected user account; log out to get "
 "back to your account."
 msgstr ""
-"Você agora pode alterar as preferências do usuário selecionado; faça o "
-"logout para retornar a sua conta."
 
 msgid "You are the only user."
-msgstr "Você é o único usuário"
+msgstr ""
 
 msgid ""
 "As a superuser, you can temporarily assume the identity of another user."
 msgstr ""
-"Como superusuário, você pode assumir temporariamente a identidade de outro "
-"usuário."
 
 msgid "Select User"
 msgstr "Selecionar Usuário"
 
 #, fuzzy
 msgid "Change password"
-msgstr "Mudar a senha"
+msgstr "Senha"
 
 msgid "Passwords don't match!"
 msgstr "As senhas não conferem!"
@@ -1115,10 +1107,10 @@
 msgstr "Passord não aceitável: %s"
 
 msgid "Your password has been changed."
-msgstr "Sua senha foi alterada"
+msgstr ""
 
 msgid "To change your password, enter a new password twice."
-msgstr "Para alterar sua senha, informe uma nova senha duas vezes."
+msgstr ""
 
 msgid "Password repeat"
 msgstr "Repita a senha"
@@ -1168,19 +1160,19 @@
 msgstr ""
 
 msgid "OpenID settings"
-msgstr "Configurações OpenID"
+msgstr ""
 
 msgid "Cannot remove all OpenIDs."
-msgstr "Não pode remover todas as OpenIDs"
+msgstr ""
 
 msgid "The selected OpenIDs have been removed."
-msgstr "As OpenIDS selecionadas foram removidas."
+msgstr ""
 
 msgid "No OpenID given."
-msgstr "Nenhuma OpenID fornecida."
+msgstr ""
 
 msgid "OpenID is already present."
-msgstr "A OpenID já está presente."
+msgstr ""
 
 #, fuzzy
 msgid "This OpenID is already used for another account."
@@ -1218,22 +1210,22 @@
 
 #, fuzzy
 msgid "Member of Groups"
-msgstr "Membro dos Grupos"
+msgstr "Número de páginas"
 
 msgid "Email"
 msgstr "Email"
 
 msgid "Jabber"
-msgstr "Jabber"
+msgstr ""
 
 msgid "Action"
 msgstr "Ação"
 
 msgid "Disable user"
-msgstr "Desabilitar usuário"
+msgstr "Usuário desabilitado"
 
 msgid "Enable user"
-msgstr "Habilitar usuário"
+msgstr "Usuário habilitado"
 
 msgid "disabled"
 msgstr "desabilitado"
@@ -1242,7 +1234,7 @@
 msgstr "Dados da conta no email"
 
 msgid "OpenID"
-msgstr "OpenID"
+msgstr ""
 
 msgid "Login"
 msgstr "Login"
@@ -2360,21 +2352,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Sua inscrição a esta página foi efetivada."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Senha muito curta"
-
-msgid "Password has not enough different characters."
-msgstr "A senha não tem um número suficiente de caracteres diferentes"
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Senha não foi informada. Por favor, informe o nome do usuário e senha."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr "Senha muito simples (seqüência de teclado)."
-
 msgid "Diffs"
 msgstr "Diffs"
 
@@ -2407,7 +2384,7 @@
 
 msgid "Publish my email (not my wiki homepage) in author info"
 msgstr ""
-"Publique meu e-mail (não minha homepage do wiki) nas informações do autor"
+"Publique meu e-mail (não em minha homepage do wiki) nas informações do autor"
 
 msgid "Open editor on double click"
 msgstr "Abra o editor com um duplo clique"
@@ -2446,7 +2423,7 @@
 msgstr "Apelido"
 
 msgid "Jabber ID"
-msgstr "Identidade Jabber"
+msgstr ""
 
 msgid "User CSS URL"
 msgstr "URL da folha de estilo (CSS) do usuário"
@@ -3000,7 +2977,7 @@
 msgstr "VerificaçãoOrtográfica"
 
 msgid "Discussion"
-msgstr "Discussão"
+msgstr ""
 
 #, python-format
 msgid "Inlined image: %(url)s"
--- a/MoinMoin/i18n/pt.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/pt.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2007-01-05 22:27+0000\n"
 "Last-Translator: Rita Farinha <rita.farinha@intraneia.com>\n"
 "Language-Team: Portuguese <moin-devel@lists.sourceforge.net>\n"
@@ -2350,21 +2350,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Subscreveu esta página."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Repetir senha"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Senha em falta. Por favor, insira o nome de utilizador e a senha."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Diferenças"
 
--- a/MoinMoin/i18n/ro.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/ro.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2005-08-18 14:19+EET\n"
 "Last-Translator: Ovidiu Sabou <ovidiu.sabou@gmail.com>\n"
 "Language-Team: Romanian <ovidiu.sabou@gmail.com>\n"
@@ -2275,21 +2275,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Aţi fost înregistrat(ă) pe această pagină."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Resetare parolă"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Parola lipseşte. Introduceti nume şi parolă"
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Modificări"
 
--- a/MoinMoin/i18n/ru.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/ru.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.7\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2008-09-13 23:53+0200\n"
 "Last-Translator: Mike Rovner <mrovner@hotmail.com>\n"
 "Language-Team: Russian <moin-devel@lists.sourceforge.net>\n"
@@ -874,8 +874,10 @@
 "курсивом'''''<<Verbatim(''''')>>; <<Verbatim('')>>''смешаным ''<<Verbatim"
 "(''')>>'''''жирным'''<<Verbatim(''')>> и курсивом''<<Verbatim('')>>; "
 "<<Verbatim(----)>> горизонтальная черта.\n"
-" Заголовки:: = Уровня 1 =; == Уровня 2 ==; === Уровня 3 ===; ==== Уровня 4 "
-"====; ===== Уровня 5 =====.\n"
+" Заголовки:: <<Verbatim(=)>> Уровня 1 <<Verbatim(=)>>; <<Verbatim(==)>> "
+"Уровня 2 <<Verbatim(==)>>; <<Verbatim(===)>> Уровня 3 <<Verbatim(===)>>; "
+"<<Verbatim(====)>> Уровня 4 <<Verbatim(====)>>; <<Verbatim(=====)>> Уровня 5 "
+"<<Verbatim(=====)>>.\n"
 " Списки:: пробел и одно из: * ненумерованный список; 1., a., A., i., I. "
 "нумерованный список; 1.#n - начать нумерацию с n; пробелы увеличивают "
 "уровень отступа.\n"
@@ -987,8 +989,10 @@
 ">>'''''жирным'''<<Verbatim(**)>> и курсивом''<<Verbatim(//)>>; "
 "Горизонтальная черта:: <<Verbatim(----)>> .\n"
 "Перевод строки:: <<Verbatim(\\\\)>>\n"
-" Заголовки:: = Уровня 1 =; == Уровня 2 ==; === Уровня 3 ===; ==== Уровня 4 "
-"====; ===== Уровня 5 =====.\n"
+" Заголовки:: <<Verbatim(=)>> Уровня 1 <<Verbatim(=)>>; <<Verbatim(==)>> "
+"Уровня 2 <<Verbatim(==)>>; <<Verbatim(===)>> Уровня 3 <<Verbatim(===)>>; "
+"<<Verbatim(====)>> Уровня 4 <<Verbatim(====)>>; <<Verbatim(=====)>> Уровня 5 "
+"<<Verbatim(=====)>>.\n"
 " Списки:: пробел и одно из: * ненумерованный список; ** ненумерованный "
 "подсписок; # нумерованный список ## нумерованный подсписок;\n"
 " Ссылки:: <<Verbatim(ЗаглавныеСловаСлитно)>>;<<Verbatim([[название страницы|"
@@ -2363,23 +2367,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Вы должны быть подписаны, чтобы отписаться."
 
-msgid "Password is too short."
-msgstr "Слишком короткий пароль"
-
-msgid "Password has not enough different characters."
-msgstr ""
-"Слишком простой пароль - в пароле должно присутствовать больше разных "
-"символов"
-
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr ""
-"Слишком простой пароль (в пароле присутствует имя пользователя, либо пароль "
-"содержится в имени)"
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr "Слишком простой пароль (клавиатурная последовательность)"
-
 msgid "Diffs"
 msgstr "Изменения"
 
--- a/MoinMoin/i18n/sk.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/sk.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -319,8 +319,8 @@
 "The lock of %(owner)s timed out %(mins_ago)d minute(s) ago, and you were "
 "granted the lock for this page."
 msgstr ""
-"Zámok užívateľa %(owner)s vypršal pred %(mins_ago)d minútami. Teraz ste "
-"zámok na túto stránku dostali Vy."
+"Zámok užívateľa %(owner)s vypršal pred %(mins_ago)d minútami. Teraz ste zámok "
+"na túto stránku dostali Vy."
 
 #, python-format
 msgid ""
@@ -456,13 +456,13 @@
 "Password recovery token: %s\n"
 "\n"
 "Password reset URL: %s/?action=recoverpass&name=%s&token=%s\n"
-msgstr ""
-"Prihlasovacie meno: %s\n"
+msgstr "Prihlasovacie meno: %s\n"
 "\n"
 "Token pre obnovu hesla: %s\n"
 "\n"
 "URL pre resetovanie hesla: %s/?action=recoverpass&name=%s&token=%s\n"
 
+
 msgid ""
 "Somebody has requested to email you a password recovery token.\n"
 "\n"
@@ -773,8 +773,7 @@
 "Požiadali ste o zasielanie zmien wiki stránky\n"
 "%(sitename)s.\n"
 "\n"
-"Stránka \"%(pagename)s\" bola premenovaná z mena \"%(oldname)s\" redaktorom %"
-"(editor)s\n"
+"Stránka \"%(pagename)s\" bola premenovaná z mena \"%(oldname)s\" redaktorom %(editor)s\n"
 
 #, python-format
 msgid "New user account created on %(sitename)s"
@@ -1005,9 +1004,8 @@
 msgid ""
 "You can now change the settings of the selected user account; log out to get "
 "back to your account."
-msgstr ""
-"Teraz môžete zmeniť nastavenia vybraného užívateľa; odhláste sa aby ste sa "
-"dostali naspäť na svoj účet."
+msgstr "Teraz môžete zmeniť nastavenia vybraného užívateľa; odhláste sa "
+"aby ste sa dostali naspäť na svoj účet."
 
 msgid "You are the only user."
 msgstr "Ste jediný užívateľ"
@@ -1229,8 +1227,8 @@
 "Add your email address or Jabber ID in your user settings to use "
 "subscriptions."
 msgstr ""
-"Uveďte svoju mailovú alebo jabber adresu v NastaveniachUžívateľa a budete "
-"môcť využívať odoberanie."
+"Uveďte svoju mailovú alebo jabber adresu v NastaveniachUžívateľa a budete môcť využívať "
+"odoberanie."
 
 msgid "You are already subscribed to this page."
 msgstr "Na odoberanie tejto stránky ste už prihásený."
@@ -1549,9 +1547,7 @@
 msgid ""
 "Attachment '%(pagename)s/%(filename)s' moved to '%(new_pagename)s/%"
 "(new_filename)s'."
-msgstr ""
-"Príloha „%(pagename)s/%(filename)s“ bola presunutá do „%(new_pagename)s/%"
-"(new_filename)s.“"
+msgstr "Príloha „%(pagename)s/%(filename)s“ bola presunutá do „%(new_pagename)s/%(new_filename)s.“"
 
 msgid "Nothing changed"
 msgstr "Nijaká zmena"
@@ -1612,8 +1608,8 @@
 "(maxsize_file)d kB)."
 msgstr ""
 "Príloha „%(filename)s“ sa nedala rozzipovať, pretože výsledné súbory nie sú "
-"v tom istom adresári alebo prevyšujú limit pre veľkosť jedného súboru (%"
-"(maxsize_file)d kB)."
+"v tom istom adresári alebo prevyšujú limit pre veľkosť jedného súboru "
+"(%(maxsize_file)d kB)."
 
 #, python-format
 msgid ""
@@ -1636,8 +1632,7 @@
 "Attachment '%(filename)s' partially unzipped (did not overwrite: %(filelist)"
 "s)."
 msgstr ""
-"Príloha '%(filename)s' bola čiastočne rozzipovaná (nebolo prepísané: %"
-"(filelist)s)."
+"Príloha '%(filename)s' bola čiastočne rozzipovaná (nebolo prepísané: %(filelist)s)."
 
 #, python-format
 msgid "Attachment '%(filename)s' unzipped."
@@ -1724,7 +1719,8 @@
 #, python-format
 msgid "Exactly one page like \"%s\" found, redirecting to page."
 msgstr ""
-"Našla sa len jedna podobná stránka ako „%s“, presmerovávam na túto stránku."
+"Našla sa len jedna podobná stránka ako „%s“, presmerovávam na túto "
+"stránku."
 
 #, python-format
 msgid "Pages like \"%s\""
@@ -1820,8 +1816,8 @@
 "Got a list of %s local and %s remote pages. This results in %s pages to "
 "process."
 msgstr ""
-"Mám zoznam %s lokálnych stránok a  %s vzdialených stránok. Celkovo je teda "
-"treba spracovať %s stránok."
+"Mám zoznam %s lokálnych stránok a  %s vzdialených stránok. Celkovo je teda treba "
+"spracovať %s stránok."
 
 #, python-format
 msgid "After filtering: %s pages"
--- a/MoinMoin/i18n/sl.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/sl.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.7\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-15 14:30+0200\n"
 "PO-Revision-Date: 2008-05-23 03:00+0200\n"
 "Last-Translator: Mark Martinec <Mark.Martinec@ijs.si>\n"
 "Language-Team: \n"
@@ -1453,8 +1453,8 @@
 "občutljive informacije.\n"
 " * Prepričajte se, da so vrednosti backup_* nastavitev v vaši viki "
 "konfiguraciji pravilne in popolne.\n"
-" * Prepričajte se, da vsebujejo varnostne kopije, ki jih boste dobili, vse "
-"potrebno za primer težav.\n"
+" * Prepričajte se, da vsebujejo varnostne kopije, ki jih boste dobili, "
+"vse potrebno za primer težav.\n"
 " * Preverite, da je bil prenos opravljen brez napak.\n"
 "\n"
 "Izdelaj varostno kopijo:"
@@ -2351,19 +2351,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Če niste naročeni na obvestila jih tudi ne morete odpovedati."
 
-msgid "Password is too short."
-msgstr "Geslo ni dovolj dolgo."
-
-msgid "Password has not enough different characters."
-msgstr "Geslo ne vsebuje dovolj različnih znakov."
-
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Geslo je preveč preprosto (vsebuje ime ali pa je vsebovano v imenu)."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr "Geslo je preveč preprosto (zaporedje s tipkovnice)"
-
 msgid "Diffs"
 msgstr "Razlike"
 
--- a/MoinMoin/i18n/sr.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/sr.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: sr\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2008-05-12 15:58-0400\n"
 "Last-Translator: Igor Miletic <grejigl-gnomeprevod@yahoo.ca>\n"
 "Language-Team: Serbian <fedora-trans-sr@redhat.com>\n"
@@ -2351,21 +2351,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Морате се прво претплатити да би могли укинути претплату."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Понови лозинку"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Недостаје лозинка. Упишите корисничко име и лозинку."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Разлике"
 
--- a/MoinMoin/i18n/sv.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/sv.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,8 +13,8 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.7\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
-"PO-Revision-Date: 2008-09-25 20:00+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
+"PO-Revision-Date: 2008-09-13 11:05+0200\n"
 "Last-Translator: thomas@marquart.se\n"
 "Language-Team: Swedish <moin-user@lists.sourceforge.net>\n"
 "MIME-Version: 1.0\n"
@@ -797,8 +797,8 @@
 "    User name: %(username)s\n"
 "    Email address: %(useremail)s"
 msgstr ""
-"Hej administrator, en ny användare har just skapats på %(sitename)s\". "
-"Detaljer följer:\n"
+"Hej administrator, en ny användare har just skapats på %(sitename)s\". Detaljer "
+"följer:\n"
 "\n"
 "    Användarnamn: %(username)s\n"
 "    Epost-adress: %(useremail)s"
@@ -1685,7 +1685,7 @@
 msgstr "Nytt sidonamn"
 
 msgid "New attachment name"
-msgstr "Nya namnet för bilagan"
+msgstr "Ny bilaga för bilaga"
 
 msgid "You are not allowed to get attachments from this page."
 msgstr "Du får inte hämta bilagor från den här sidan."
@@ -2336,19 +2336,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Du måste prenumera för att kunna sluta prenumera."
 
-msgid "Password is too short."
-msgstr "Lösenordet är för kort."
-
-msgid "Password has not enough different characters."
-msgstr "Lösenordet har inte tillräckligt många olika tecken."
-
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Lösenordet är för enkelt (lösenordet innehåller namnet eller tvärtom)."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr "Lösenordet är för enkelt (tangentbordssekvens)."
-
 msgid "Diffs"
 msgstr "Skillnader"
 
@@ -3129,8 +3116,9 @@
 #~ msgid "File attachments are not allowed in this wiki!"
 #~ msgstr "Bilagor är inte tillåtna i den här wikin!"
 
+#, fuzzy
 #~ msgid "SendMyPassword"
-#~ msgstr "SkickaMittLösenord"
+#~ msgstr "Lösenord"
 
 #~ msgid "Use UserPreferences to change your settings or create an account."
 #~ msgstr ""
--- a/MoinMoin/i18n/tools/mail_i18n-maintainers.txt	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/tools/mail_i18n-maintainers.txt	Thu Jan 29 09:44:57 2009 +0100
@@ -13,10 +13,10 @@
 ============
 
 Please note that we currently have 2 "MoinMaster" wikis:
-    * http://master17.moinmo.in/ (currently same as http://master.moinmo.in/)
-      This wiki is for the "current" 1.7.x releases.
-    * http://master18.moinmo.in/
-      This wiki is for the "upcoming" 1.8.x releases.
+    * http://master18.moinmo.in/ (currently same as http://master.moinmo.in/)
+      This wiki is for the "current" 1.8.x releases.
+    * http://master19.moinmo.in/
+      This wiki is for the "upcoming" 1.9.x releases.
 
 We need your help again for updating the following (high priority and
 most important stuff is on top of the list):
@@ -32,14 +32,14 @@
 [X] "%(lang)s" help pages on the MoinMaster wiki (optional - would be
     nice, if you had the time)
 
-We need that until 2008-10-31 - because MoinMoin 1.8.0 will be released
+We need that until 2009-xx-xx - because MoinMoin 1.9.0 will be released
 then, so we can include that stuff into the distribution archive to make
 people speaking your language happy. ;)
 
 Please, after translating the current stuff, keep an eye on MoinMaster
 wikis - some strings in the PO file may still change or get added/deleted.
 
-See http://moinmo.in/MoinMoinTodo/Release%%201.8 for our planned release schedule.
+See http://moinmo.in/MoinMoinTodo/Release%%201.9 for our planned release schedule.
 
 Please reply immediately
 ========================
--- a/MoinMoin/i18n/tools/mail_i18n-maintainers2.txt	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/tools/mail_i18n-maintainers2.txt	Thu Jan 29 09:44:57 2009 +0100
@@ -3,10 +3,10 @@
 If you are still unfinished with translation - keep in mind that the deadline
 for work on MoinMaster stuff (system texts, system and help pages) is at:
 
-               2008-10-31 16:00 UTC.
+               2009-xx-xx 16:00 UTC.
 
 
-We plan to release MoinMoin 1.8.0 soon. If your translation arrives before last
+We plan to release MoinMoin 1.9.0 soon. If your translation arrives before last
 release steps have begun, it might still get in.
 
 If not, we will include it in development of next version, so it will
--- a/MoinMoin/i18n/tools/po2wiki.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/tools/po2wiki.py	Thu Jan 29 09:44:57 2009 +0100
@@ -5,7 +5,7 @@
     onto moinmaster wiki, letting it get processed by gettext parser
 """
 
-master_url = "http://master18.moinmo.in/?action=xmlrpc2"
+master_url = "http://master19.moinmo.in/?action=xmlrpc2"
 user = "ThomasWaldmann" # must be a known Wiki account
 
 import sys, os
--- a/MoinMoin/i18n/tools/wiki2po.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/tools/wiki2po.py	Thu Jan 29 09:44:57 2009 +0100
@@ -3,7 +3,7 @@
     get latest translation page content from the wiki and write it to *.po
 """
 
-master_url = "http://master18.moinmo.in/?action=xmlrpc2"
+master_url = "http://master19.moinmo.in/?action=xmlrpc2"
 
 DOMAIN = "MoinMoin"
 
--- a/MoinMoin/i18n/tr.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/tr.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin-1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2007-04-25 16:26+0300\n"
 "Last-Translator: Ekrem SEREN <ekrem.seren@parduslinux.org>\n"
 "Language-Team: Türkçe\n"
@@ -2349,21 +2349,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Bu sayfaya üye oldunuz."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Parola (Tekrar)"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Parola eksik. Lütfen kullanıcı adı ve parolayı girin."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Farklar"
 
--- a/MoinMoin/i18n/uk.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/uk.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2007-11-10 16:50+0300\n"
 "Last-Translator: Maxim V. Dziumanenko <dziumanenko@softprom.kiev.ua>\n"
 "Language-Team: Ukrainian <uk@li.org>\n"
@@ -2316,21 +2316,6 @@
 "Щоб припинити стеження за сторінкою, треба щоб спочатку стеження було "
 "встановлено."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Скинути пароль"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Відсутній пароль. Введіть ім'я користувача й пароль."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Зміни"
 
--- a/MoinMoin/i18n/vi.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/vi.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.6\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2004-11-19 21:03+0800\n"
 "Last-Translator: Nam T. Nguyen <nnt@nntsoft.com>\n"
 "Language-Team: Vietnamese <moin-devel@lists.sourceforge.net>\n"
@@ -2266,21 +2266,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "Bạn vừa đăng ký vào trang này."
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "Lập lại mật khẩu"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "Thiếu mật khẩu. Vui lòng nhập tên người dùng và mật khẩu."
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "Các bản diff"
 
--- a/MoinMoin/i18n/zh-tw.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/zh-tw.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.7\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
 "PO-Revision-Date: 2008-06-14 22:44+0800\n"
 "Last-Translator: Rux Li <rux.li3@gmail.com>\n"
 "Language-Team: Chinese/Taiwan <moin-devel@lists.sourceforge.net>\n"
@@ -2227,21 +2227,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "你並未訂閱本頁。"
 
-#, fuzzy
-msgid "Password is too short."
-msgstr "密碼重設"
-
-msgid "Password has not enough different characters."
-msgstr ""
-
-#, fuzzy
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "沒輸入密碼!請輸入名稱及密碼。"
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr ""
-
 msgid "Diffs"
 msgstr "版本比較"
 
--- a/MoinMoin/i18n/zh.MoinMoin.po	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/i18n/zh.MoinMoin.po	Thu Jan 29 09:44:57 2009 +0100
@@ -13,8 +13,8 @@
 msgstr ""
 "Project-Id-Version: MoinMoin 1.7\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-28 20:59+0200\n"
-"PO-Revision-Date: 2008-10-06 11:09+0800\n"
+"POT-Creation-Date: 2008-09-12 23:35+0200\n"
+"PO-Revision-Date: 2008-08-14 09:37+0800\n"
 "Last-Translator: Jiang Xin <worldhello.net@gmail.com>\n"
 "Language-Team: Chinese <moin-devel@lists.sourceforge.net>\n"
 "MIME-Version: 1.0\n"
@@ -764,7 +764,7 @@
 msgid "New user account created on %(sitename)s"
 msgstr "新用户帐号创建于 %(sitename)s"
 
-#, python-format
+#, fuzzy, python-format
 msgid ""
 "Dear Superuser, a new user has just been created on %(sitename)s\". Details "
 "follow:\n"
@@ -772,7 +772,7 @@
 "    User name: %(username)s\n"
 "    Email address: %(useremail)s"
 msgstr ""
-"管理员您好,一个新的用户帐号刚刚在 %(sitename)s 上被创建。详细信息如下:\n"
+"管理员您好,一个新的用户帐号刚刚被创建。详细信息如下:\n"
 "\n"
 "    用户名:%(username)s\n"
 "    邮件地址:%(useremail)s"
@@ -1154,7 +1154,7 @@
 msgstr "使用 --pages 或 --search 时没有指定页面,认为是全部。"
 
 msgid "All attachments included into the package."
-msgstr "所有附件已包含到此包中。"
+msgstr ""
 
 msgid "Output file already exists! Cowardly refusing to continue!"
 msgstr "输出文件已经存在!拒绝执行!"
@@ -1380,8 +1380,9 @@
 "如果您已经收到包含恢复令牌的邮件,输入\n"
 "您的用户名,恢复令牌以及新口令(两次)。"
 
+#, fuzzy
 msgid "Wiki Backup"
-msgstr "维基备份"
+msgstr "维基标记"
 
 msgid ""
 "= Downloading a backup =\n"
@@ -1397,15 +1398,6 @@
 "\n"
 "To get a backup, just click here:"
 msgstr ""
-"= 下载备份 =\n"
-"\n"
-"请注意:\n"
-" * 将备份保存在一个安全和加密之处 —— 因数据包含敏感信息。\n"
-" * 确认您的维基配置中 backup_* 的取值正确和完整。\n"
-" * 确认您获取到的备份包含了一旦出现意外后所需要的所有数据。\n"
-" * 确认下载过程没有问题。\n"
-"\n"
-"获得一个备份,点击这里:"
 
 msgid "Backup"
 msgstr "备份"
@@ -1784,8 +1776,9 @@
 msgid "Created the package %s containing the pages %s."
 msgstr "生成的包%s包含网页%s。"
 
+#, fuzzy
 msgid "Include all attachments?"
-msgstr "包含所有附件?"
+msgstr "[%d个附件]"
 
 msgid "Package pages"
 msgstr "网页打包"
@@ -2256,19 +2249,6 @@
 msgid "You need to be subscribed to unsubscribe."
 msgstr "您需要先订阅才能退订。"
 
-msgid "Password is too short."
-msgstr "口令太短了。"
-
-msgid "Password has not enough different characters."
-msgstr "口令没有足够多的差异字符。"
-
-msgid ""
-"Password is too easy (password contains name or name contains password)."
-msgstr "口令太简单了(口令包含用户名或者用户名包含口令)。"
-
-msgid "Password is too easy (keyboard sequence)."
-msgstr "口令太简单了(键盘序列)。"
-
 msgid "Diffs"
 msgstr "版本比较"
 
@@ -2505,13 +2485,14 @@
 msgstr "用户"
 
 msgid "[ATTACH]"
-msgstr "[附件]"
-
+msgstr ""
+
+#, fuzzy
 msgid "Variable name"
-msgstr "变量名"
+msgstr "打包文件名"
 
 msgid "Description"
-msgstr "描述"
+msgstr ""
 
 #, python-format
 msgid "Upload new attachment \"%(filename)s\""
@@ -2558,7 +2539,7 @@
 msgstr "显示"
 
 msgid "Wiki configuration"
-msgstr "维基配置"
+msgstr ""
 
 msgid ""
 "This table shows all settings in this wiki that do not have default values. "
@@ -2566,9 +2547,8 @@
 "''italic'', those may be due to third-party extensions needing configuration "
 "or settings that were removed from Moin."
 msgstr ""
-"这个表显示本维基上没有缺省值的所有设置。配置系统未知的设置显示为 ''斜体'',这"
-"可能是由第三方扩展所需要的设置或者是从旧版本 Moin 中移除的设置。"
-
+
+#, fuzzy
 msgid "Setting"
 msgstr "设置"
 
@@ -2917,3 +2897,50 @@
 
 msgid "Toggle line numbers"
 msgstr "切换行号显示"
+
+#~ msgid ""
+#~ "Restored Backup: %(filename)s to target dir: %(targetdir)s.\n"
+#~ "Files: %(filecount)d, Directories: %(dircount)d"
+#~ msgstr ""
+#~ "恢复备份:%(filename)s 到目标文件夹:%(targetdir)s。\n"
+#~ "文件:%(filecount)d,目录:%(dircount)d"
+
+#~ msgid "Restoring backup: %(filename)s to target dir: %(targetdir)s failed."
+#~ msgstr "恢复备份 %(filename)s 到目标文件夹:%(targetdir)s 失败。"
+
+#~ msgid "Wiki Backup / Restore"
+#~ msgstr "维基备份/恢复"
+
+#~ msgid ""
+#~ "Some hints:\n"
+#~ " * To restore a backup:\n"
+#~ "  * Restoring a backup will overwrite existing data, so be careful.\n"
+#~ "  * Rename it to <siteid>.tar.<compression> (remove the --date--time--UTC "
+#~ "stuff).\n"
+#~ "  * Put the backup file into the backup_storage_dir (use scp, ftp, ...).\n"
+#~ "  * Hit the <<GetText(Restore)>> button below.\n"
+#~ "\n"
+#~ " * To make a backup, just hit the <<GetText(Backup)>> button and save the "
+#~ "file\n"
+#~ "   you get to a secure place.\n"
+#~ "\n"
+#~ "Please make sure your wiki configuration backup_* values are correct and "
+#~ "complete.\n"
+#~ "\n"
+#~ msgstr ""
+#~ "提示:\n"
+#~ " * 要恢复备份:\n"
+#~ "  * 恢复备份会覆盖已存在的数据,请谨慎操作。\n"
+#~ "  * 重命名到 <siteid>.tar.<compression> (即移除 --date--time--UTC 部"
+#~ "分)。\n"
+#~ "  * 将备份文件放到 backup_storage_dir 中 (使用 scp, ftp, ...)。\n"
+#~ "  * 点击下面的<<GetText(Restore)>>按钮。\n"
+#~ "\n"
+#~ " * 要备份,只需点击<<GetText(Backup)>>按钮并保存文件\n"
+#~ "   到安全的地方。\n"
+#~ "\n"
+#~ "请确保维基配置 backup_* 设定值是正确完整的。\n"
+#~ "\n"
+
+#~ msgid "Restore"
+#~ msgstr "恢复"
--- a/MoinMoin/logfile/editlog.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/logfile/editlog.py	Thu Jan 29 09:44:57 2009 +0100
@@ -170,7 +170,7 @@
         """
         if request.cfg.log_remote_addr:
             if host is None:
-                host = request.remote_addr
+                host = request.remote_addr or ''
 
             if request.cfg.log_reverse_dns_lookups:
                 import socket
--- a/MoinMoin/macro/AdvancedSearch.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/macro/AdvancedSearch.py	Thu Jan 29 09:44:57 2009 +0100
@@ -46,7 +46,7 @@
     @param default: value if not present (default: '')
     @param escaped: if True, escape value so it can be used for html generation (default: False)
     """
-    value = request.form.get(name, [default])[0]
+    value = request.values.get(name, default)
     if escaped:
         value = wikiutil.escape(value, quote=True)
     return value
@@ -166,7 +166,7 @@
 
     # the dialogue
     return f.rawHTML('\n'.join([
-        u'<form method="get" action="%s/%s">' % (macro.request.getScriptname(), wikiutil.quoteWikinameURL(macro.request.formatter.page.page_name)),
+        u'<form method="get" action="%s">' % macro.request.href(macro.request.formatter.page.page_name),
         u'<div>',
         u'<input type="hidden" name="action" value="fullsearch">',
         u'<input type="hidden" name="advancedsearch" value="1">',
--- a/MoinMoin/macro/FullSearch.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/macro/FullSearch.py	Thu Jan 29 09:44:57 2009 +0100
@@ -43,7 +43,7 @@
     """
     _ = macro._
     if 'value' in macro.form:
-        default = wikiutil.escape(macro.form["value"][0], quote=1)
+        default = wikiutil.escape(macro.form["value"], quote=1)
     else:
         default = ''
 
@@ -67,7 +67,7 @@
     # Format
     type = (type == "titlesearch")
     html = [
-        u'<form method="get" action="%s/%s">' % (macro.request.getScriptname(), wikiutil.quoteWikinameURL(macro.request.formatter.page.page_name)),
+        u'<form method="get" action="%s">' % macro.request.href(macro.request.formatter.page.page_name),
         u'<div>',
         u'<input type="hidden" name="action" value="fullsearch">',
         u'<input type="hidden" name="titlesearch" value="%i">' % type,
--- a/MoinMoin/macro/MonthCalendar.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/macro/MonthCalendar.py	Thu Jan 29 09:44:57 2009 +0100
@@ -217,7 +217,7 @@
     # does the url have calendar params (= somebody has clicked on prev/next links in calendar) ?
     if 'calparms' in macro.form:
         has_calparms = 1 # yes!
-        text2 = macro.form['calparms'][0]
+        text2 = macro.form['calparms']
         try:
             cparmpagename, cparmyear, cparmmonth, cparmoffset, cparmoffset2, cparmheight6, cparmanniversary, cparmtemplate = \
                 parseargs(request, text2, thispage, currentyear, currentmonth, 0, 0, False, False, u'')
--- a/MoinMoin/macro/Navigation.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/macro/Navigation.py	Thu Jan 29 09:44:57 2009 +0100
@@ -77,7 +77,7 @@
 
         self.pagename = self.macro.formatter.page.page_name
         self.print_mode = self.macro.request.action == 'print'
-        self.media = self.macro.request.form.get('media', [None])[0]
+        self.media = self.macro.request.values.get('media')
         self.querystr = self.print_mode and self.PROJECTION or {}
 
 
--- a/MoinMoin/macro/NewPage.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/macro/NewPage.py	Thu Jan 29 09:44:57 2009 +0100
@@ -76,7 +76,7 @@
 
         # TODO: better abstract this using the formatter
         html = [
-            u'<form class="macro" method="POST" action="%s/%s"><div>' % (self.request.getScriptname(), wikiutil.quoteWikinameURL(self.formatter.page.page_name)),
+            u'<form class="macro" method="POST" action="%s"><div>' % self.request.href(self.formatter.page.page_name),
             u'<input type="hidden" name="action" value="newpage">',
             u'<input type="hidden" name="parent" value="%s">' % wikiutil.escape(self.parent, 1),
             u'<input type="hidden" name="template" value="%s">' % wikiutil.escape(self.template, 1),
--- a/MoinMoin/macro/RecentChanges.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/macro/RecentChanges.py	Thu Jan 29 09:44:57 2009 +0100
@@ -172,7 +172,7 @@
     last_edits.sort()
 
     # set max size in days
-    max_days = min(int(request.form.get('max_days', [0])[0]), _DAYS_SELECTION[-1])
+    max_days = min(int(request.values.get('max_days', 0)), _DAYS_SELECTION[-1])
     # default to _MAX_DAYS for users without bookmark
     if not max_days:
         max_days = _MAX_DAYS
@@ -269,7 +269,7 @@
         d['rc_update_bookmark'] = page.link_to(request, _("Set bookmark"), querystr={'action': 'bookmark', 'time': '%d' % version}, rel='nofollow')
 
     # set max size in days
-    max_days = min(int(request.form.get('max_days', [0])[0]), _DAYS_SELECTION[-1])
+    max_days = min(int(request.values.get('max_days', 0)), _DAYS_SELECTION[-1])
     # default to _MAX_DAYS for useres without bookmark
     if not max_days and not bookmark_usecs:
         max_days = _MAX_DAYS
--- a/MoinMoin/macro/SystemAdmin.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/macro/SystemAdmin.py	Thu Jan 29 09:44:57 2009 +0100
@@ -25,7 +25,7 @@
         'attachments': (_("File attachment browser"), do_admin_browser),
         'users': (_("User account browser"), do_user_browser),
     }
-    choice = request.form.get('sysadm', [None])[0]
+    choice = request.values.get('sysadm')
 
     # create menu
     menuitems = [(label, fnid) for fnid, (label, handler) in _MENU.items()]
--- a/MoinMoin/macro/TableOfContents.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/macro/TableOfContents.py	Thu Jan 29 09:44:57 2009 +0100
@@ -46,12 +46,12 @@
 
     def startContent(self, *args, **kw):
         res = FormatterBase.startContent(self, *args, **kw)
-        self.collected_headings.append([1, self.request.include_id, None])
+        self.collected_headings.append([1, self.request.uid_generator.include_id, None])
         return res
 
     def endContent(self):
         res = FormatterBase.endContent(self)
-        self.collected_headings.append([0, self.request.include_id, None])
+        self.collected_headings.append([0, self.request.uid_generator.include_id, None])
         return res
 
     def heading(self, on, depth, **kw):
@@ -142,7 +142,7 @@
 
     pname = macro.formatter.page.page_name
 
-    macro.request.push_unique_ids()
+    macro.request.uid_generator.push()
 
     macro.request._tocfm_collected_headings = []
     macro.request._tocfm_orig_formatter = macro.formatter
@@ -224,7 +224,7 @@
         result.append(macro.formatter.number_list(0))
         lastlvl -= 1
 
-    macro.request.pop_unique_ids()
+    macro.request.uid_generator.pop()
 
     result.append(macro.formatter.div(0))
     return ''.join(result)
--- a/MoinMoin/macro/TeudView.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/macro/TeudView.py	Thu Jan 29 09:44:57 2009 +0100
@@ -34,7 +34,7 @@
     pagename = macro.formatter.page.page_name
 
     if 'module' in macro.form:
-        modname = macro.form["module"][0]
+        modname = macro.form["module"]
         try:
             obj = pydoc.locate(modname)
         except pydoc.ErrorDuringImport, value:
--- a/MoinMoin/macro/WantedPages.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/macro/WantedPages.py	Thu Jan 29 09:44:57 2009 +0100
@@ -21,7 +21,7 @@
         return ''
 
     # Get allpages switch from the form
-    allpages = int(request.form.get('allpages', [0])[0]) != 0
+    allpages = int(request.values.get('allpages', 0)) != 0
 
     # Control bar - filter the list of pages
     # TODO: we should make this a widget and use on all page listing pages
--- a/MoinMoin/macro/__init__.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/macro/__init__.py	Thu Jan 29 09:44:57 2009 +0100
@@ -192,7 +192,7 @@
         _ = self._
         request = self.request
         fmt = self.formatter
-        allpages = int(self.form.get('allpages', [0])[0]) != 0
+        allpages = int(request.values.get('allpages', 0)) != 0
         # Get page list readable by current user, filter by isSystemPage if needed
         if allpages:
             pages = request.rootpage.getPageList()
@@ -280,7 +280,7 @@
         """
         _ = self._
         html = [
-            u'<form method="get" action="%s/%s"><div>' % (self.request.getScriptname(), wikiutil.quoteWikinameURL(self.formatter.page.page_name)),
+            u'<form method="get" action="%s"><div>' % self.request.href(self.formatter.page.page_name),
             u'<div>',
             u'<input type="hidden" name="action" value="goto">',
             u'<input type="text" name="target" size="30">',
--- a/MoinMoin/macro/_tests/test_Action.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/macro/_tests/test_Action.py	Thu Jan 29 09:44:57 2009 +0100
@@ -26,7 +26,7 @@
         m = make_macro(self.request, self.page)
         result = Action.macro_Action(m, 'raw')
         nuke_page(request, self.pagename)
-        expected = '<a href="./AutoCreatedMoinMoinTemporaryTestPageForAction?action=raw">raw</a>'
+        expected = '<a href="/AutoCreatedMoinMoinTemporaryTestPageForAction?action=raw">raw</a>'
         assert result == expected
 
 coverage_modules = ['MoinMoin.macro.Action']
--- a/MoinMoin/macro/_tests/test_EmbedObject.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/macro/_tests/test_EmbedObject.py	Thu Jan 29 09:44:57 2009 +0100
@@ -54,7 +54,7 @@
         m = make_macro(self.request, self.page)
         filename = 'test.mpg'
         result = m.execute('EmbedObject', u'%s' % filename)
-        assert '<object data="./AutoCreatedMoinMoinTemporaryTestPageForEmbedObject?action=AttachFile&amp;do=get&amp;target=test.mpg"' in result
+        assert '<object data="/AutoCreatedMoinMoinTemporaryTestPageForEmbedObject?action=AttachFile&amp;do=get&amp;target=test.mpg"' in result
         assert 'align="middle"' in result
         assert 'value="transparent"' in result
 
@@ -64,7 +64,7 @@
         filename = 'test.mpg'
         height = '50 %' # also tests that space is allowed in there
         result = m.execute('EmbedObject', u'target=%s, height=%s' % (filename, height))
-        assert '<object data="./AutoCreatedMoinMoinTemporaryTestPageForEmbedObject?action=AttachFile&amp;do=get&amp;target=test.mpg"' in result
+        assert '<object data="/AutoCreatedMoinMoinTemporaryTestPageForEmbedObject?action=AttachFile&amp;do=get&amp;target=test.mpg"' in result
         assert 'height="50%"' in result
         assert 'align="middle"' in result
 
--- a/MoinMoin/macro/_tests/test_StatsChart.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/macro/_tests/test_StatsChart.py	Thu Jan 29 09:44:57 2009 +0100
@@ -34,19 +34,19 @@
     def testStatsChart_useragents(self):
         """ macro StatsChart useragents test: 'tests useragents' and clean page scope cache """
         result = self._test_macro(u'StatsChart', u'useragents')
-        expected = u'<form action="./AutoCreatedMoinMoinTemporaryTestPageStatsChart" method="GET"'
+        expected = u'<form action="/AutoCreatedMoinMoinTemporaryTestPageStatsChart" method="GET"'
         assert expected in result
 
     def testStatsChart_hitcounts(self):
         """ macro StatsChart hitcounts test: 'tests hitcounts' and clean page scope cache  """
         result = self._test_macro(u'StatsChart', u'hitcounts')
-        expected = u'<form action="./AutoCreatedMoinMoinTemporaryTestPageStatsChart" method="GET"'
+        expected = u'<form action="/AutoCreatedMoinMoinTemporaryTestPageStatsChart" method="GET"'
         assert expected in result
 
     def testStatsChart_languages(self):
         """ macro StatsChart languages test: 'tests languages' and clean page scope cache  """
         result = self._test_macro(u'StatsChart', u'hitcounts')
-        expected = u'<form action="./AutoCreatedMoinMoinTemporaryTestPageStatsChart" method="GET"'
+        expected = u'<form action="/AutoCreatedMoinMoinTemporaryTestPageStatsChart" method="GET"'
         assert expected in result
 
 coverage_modules = ['MoinMoin.stats']
--- a/MoinMoin/mail/mailimport.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/mail/mailimport.py	Thu Jan 29 09:44:57 2009 +0100
@@ -17,7 +17,6 @@
 from MoinMoin.action.AttachFile import add_attachment, AttachmentAlreadyExists
 from MoinMoin.Page import Page
 from MoinMoin.PageEditor import PageEditor
-from MoinMoin.request.request_cli import Request as RequestCLI
 # python, at least up to 2.4, ships a broken parser for headers
 from MoinMoin.support.HeaderFixed import decode_header
 
@@ -184,7 +183,7 @@
         generate_summary = True
         pagename = pagename[1:].lstrip()
 
-    pagename = request.normalizePagename(pagename)
+    pagename = wikiutil.normalize_pagename(pagename, request.cfg)
 
     if choose_html and msg['html']:
         content = "{{{#!html\n%s\n}}}" % msg['html'].replace("}}}", "} } }")
@@ -313,11 +312,12 @@
 
 if __name__ == "__main__":
     if len(sys.argv) > 1:
-        url = sys.argv[1]
+        request_url = sys.argv[1]
     else:
-        url = 'localhost/'
+        request_url = 'localhost/'
 
-    request = RequestCLI(url=url)
+    from MoinMoin.web.contexts import ScriptContext
+    request = ScriptContext(url=request_url)
 
     try:
         import_mail_from_file(request, infile)
--- a/MoinMoin/packages.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/packages.py	Thu Jan 29 09:44:57 2009 +0100
@@ -529,9 +529,8 @@
         request_url = "localhost/"
 
     # Setup MoinMoin environment
-    from MoinMoin.request import request_cli
-    request = request_cli.Request(url=request_url)
-    request.form = request.args = request.setup_args()
+    from MoinMoin.web.contexts import ScriptContext
+    request = ScriptContext(url=request_url)
 
     package = ZipPackage(request, packagefile)
     if not package.isPackage():
--- a/MoinMoin/parser/_ParserBase.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/parser/_ParserBase.py	Thu Jan 29 09:44:57 2009 +0100
@@ -26,6 +26,9 @@
 
 import re
 
+from MoinMoin import log
+logging = log.getLogger(__name__)
+
 from MoinMoin import config, wikiutil
 from MoinMoin.support.python_compatibility import hash_new
 
@@ -152,6 +155,8 @@
 
 
 class ParserBase:
+    """ DEPRECATED highlighting parser - please use/extend pygments library """
+    logging.warning('Using ParserBase is deprecated - please use/extend pygments syntax highlighting library.')
 
     parsername = 'ParserBase'
     tabwidth = 4
--- a/MoinMoin/parser/_tests/test_text_creole.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/parser/_tests/test_text_creole.py	Thu Jan 29 09:44:57 2009 +0100
@@ -302,20 +302,7 @@
 }}}"""
         output = self.parse(raw)
         output = ''.join(output)
-        assert "r'{{{This is some nested text}}}'" in output
-
-    def testColorizedPythonParserAndNestingPreBracketsWithLinebreak(self):
-        """ tests nested {{{ }}} for the python colorized parser
-        """
-
-        raw = """{{{
-#!python
-import re
-pattern = re.compile(r'{{{This is some nested text}}}')
-}}}"""
-        output = self.parse(raw)
-        output = ''.join(output)
-        assert "r'{{{This is some nested text}}}'" in output
+        assert "{{{This is some nested text}}}" in output
 
     def testNestingPreBracketsWithLinebreak(self):
         """ tests nested {{{ }}} for the wiki parser
@@ -369,14 +356,14 @@
     needle = re.compile(text % r'(.+)')
     _tests = [
         # test,           expected
-        ('[[SomeNonExistentPage]]', '<a class="nonexistent" href="./SomeNonExistentPage">SomeNonExistentPage</a>'),
-        ('[[SomeNonExistentPage#anchor]]', '<a class="nonexistent" href="./SomeNonExistentPage#anchor">SomeNonExistentPage#anchor</a>'),
-        ('[[something]]', '<a class="nonexistent" href="./something">something</a>'),
-        ('[[some thing]]', '<a class="nonexistent" href="./some%20thing">some thing</a>'),
-        ('[[something|some text]]', '<a class="nonexistent" href="./something">some text</a>'),
-        ('[[../something]]', '<a class="nonexistent" href="./something">../something</a>'),
-        ('[[/something]]', '<a class="nonexistent" href="./%s/something">/something</a>' % PAGENAME),
-        ('[[something#anchor]]', '<a class="nonexistent" href="./something#anchor">something#anchor</a>'),
+        ('[[SomeNonExistentPage]]', '<a class="nonexistent" href="/SomeNonExistentPage">SomeNonExistentPage</a>'),
+        ('[[SomeNonExistentPage#anchor]]', '<a class="nonexistent" href="/SomeNonExistentPage#anchor">SomeNonExistentPage#anchor</a>'),
+        ('[[something]]', '<a class="nonexistent" href="/something">something</a>'),
+        ('[[some thing]]', '<a class="nonexistent" href="/some%20thing">some thing</a>'),
+        ('[[something|some text]]', '<a class="nonexistent" href="/something">some text</a>'),
+        ('[[../something]]', '<a class="nonexistent" href="/something">../something</a>'),
+        ('[[/something]]', '<a class="nonexistent" href="/%s/something">/something</a>' % PAGENAME),
+        ('[[something#anchor]]', '<a class="nonexistent" href="/something#anchor">something#anchor</a>'),
         ('[[MoinMoin:something]]', '<a class="interwiki" href="http://moinmo.in/something" title="MoinMoin">something</a>'),
         ('[[MoinMoin:something|some text]]', '<a class="interwiki" href="http://moinmo.in/something" title="MoinMoin">some text</a>'),
         ('[[MoinMoin:with space]]', '<a class="interwiki" href="http://moinmo.in/with%20space" title="MoinMoin">with space</a>'),
--- a/MoinMoin/parser/_tests/test_text_moin_wiki.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/parser/_tests/test_text_moin_wiki.py	Thu Jan 29 09:44:57 2009 +0100
@@ -441,7 +441,7 @@
 }}}}"""
         output = self.parse(raw)
         output = ''.join(output)
-        assert "r'{{{This is some nested text}}}'" in output
+        assert "{{{This is some nested text}}}" in output
 
     def testNestingPreBrackets(self):
         """ tests nested {{{ }}} for the wiki parser
@@ -493,20 +493,20 @@
     needle = re.compile(text % r'(.+)')
     _tests = [
         # test,           expected
-        ('SomeNonExistentPage', '<a class="nonexistent" href="./SomeNonExistentPage">SomeNonExistentPage</a>'),
-        ('SomeNonExistentPage#anchor', '<a class="nonexistent" href="./SomeNonExistentPage#anchor">SomeNonExistentPage#anchor</a>'),
-        ('[[something]]', '<a class="nonexistent" href="./something">something</a>'),
-        ('[[some thing]]', '<a class="nonexistent" href="./some%20thing">some thing</a>'),
-        ('[[something|some text]]', '<a class="nonexistent" href="./something">some text</a>'),
-        ('[[../something]]', '<a class="nonexistent" href="./something">../something</a>'),
-        ('[[/something]]', '<a class="nonexistent" href="./%s/something">/something</a>' % PAGENAME),
-        ('[[something#anchor]]', '<a class="nonexistent" href="./something#anchor">something#anchor</a>'),
+        ('SomeNonExistentPage', '<a class="nonexistent" href="/SomeNonExistentPage">SomeNonExistentPage</a>'),
+        ('SomeNonExistentPage#anchor', '<a class="nonexistent" href="/SomeNonExistentPage#anchor">SomeNonExistentPage#anchor</a>'),
+        ('[[something]]', '<a class="nonexistent" href="/something">something</a>'),
+        ('[[some thing]]', '<a class="nonexistent" href="/some%20thing">some thing</a>'),
+        ('[[something|some text]]', '<a class="nonexistent" href="/something">some text</a>'),
+        ('[[../something]]', '<a class="nonexistent" href="/something">../something</a>'),
+        ('[[/something]]', '<a class="nonexistent" href="/%s/something">/something</a>' % PAGENAME),
+        ('[[something#anchor]]', '<a class="nonexistent" href="/something#anchor">something#anchor</a>'),
         ('MoinMoin:something', '<a class="interwiki" href="http://moinmo.in/something" title="MoinMoin">something</a>'),
         ('[[MoinMoin:something|some text]]', '<a class="interwiki" href="http://moinmo.in/something" title="MoinMoin">some text</a>'),
         ('[[MoinMoin:with space]]', '<a class="interwiki" href="http://moinmo.in/with%20space" title="MoinMoin">with space</a>'),
         ('[[MoinMoin:with space|some text]]', '<a class="interwiki" href="http://moinmo.in/with%20space" title="MoinMoin">some text</a>'),
         # no interwiki:
-        ('[[ABC:n]]', '<a class="nonexistent" href="./ABC%3An">ABC:n</a>'), # finnish/swedish abbreviations / possessive
+        ('[[ABC:n]]', '<a class="nonexistent" href="/ABC%3An">ABC:n</a>'), # finnish/swedish abbreviations / possessive
         ('ABC:n', 'ABC:n'), # finnish/swedish abbreviations / possessive
         ('lowercase:nointerwiki', 'lowercase:nointerwiki'),
         ('[[http://google.com/|google]]', '<a class="http" href="http://google.com/">google</a>'),
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/parser/highlight.py	Thu Jan 29 09:44:57 2009 +0100
@@ -0,0 +1,157 @@
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - highlighting parser using the Pygments highlighting library
+
+    @copyright: 2008 Radomir Dopieralski <moindev@sheep.art.pl>
+    @license: GNU GPL, see COPYING for details.
+"""
+
+import re
+
+import pygments
+import pygments.util
+import pygments.lexers
+import pygments.formatter
+from pygments.token import Token
+
+from MoinMoin import config
+from MoinMoin.parser._ParserBase import parse_start_step
+from MoinMoin.support.python_compatibility import hash_new
+
+Dependencies = []
+extensions = []
+extension_re = re.compile(r'^\*(\..*$)')
+for name, short, patterns, mime in pygments.lexers.get_all_lexers():
+    for pattern in patterns:
+        m = extension_re.match(pattern)
+        if m and m.groups(0):
+            extensions.extend(m.groups(0))
+
+
+class PygmentsFormatter(pygments.formatter.Formatter):
+    """ a formatter for Pygments that uses the moin formatter for creating output """
+    line_re = re.compile(r'(\n)')
+
+    def __init__(self, formatter):
+        pygments.formatter.Formatter.__init__(self)
+        self.result = []
+        self.formatter = formatter
+
+    def get_class(self, ttype):
+        if ttype in Token.Text:
+            return None
+        # Reuse existing MoinMoin css class names
+        elif ttype in Token.Operator.Word:
+            return 'ResWord'
+        elif ttype in Token.Comment.Preproc:
+            return 'Preprc'
+        elif ttype in Token.Keyword.Constant:
+            return 'ConsWord'
+        elif ttype in Token.Keyword:
+            return 'ResWord'
+        elif ttype in Token.Name.Builtin:
+            return 'ResWord'
+        elif ttype in Token.Name.Constant:
+            return 'ConsWord'
+        elif ttype in Token.String.Char:
+            return 'Char'
+        elif ttype in Token.String.Escape:
+            return 'SPChar'
+        elif ttype in Token.String:
+            return 'String'
+        elif ttype in Token.Number:
+            return 'Number'
+        elif ttype in Token.Name:
+            return 'ID'
+        elif ttype in Token.Comment:
+            return 'Comment'
+        elif ttype in Token.Generic.Heading:
+            return 'Comment'
+        elif ttype in Token.Generic.Subheading:
+            return 'DiffSeparator'
+        elif ttype in Token.Generic.Inserted:
+            return 'DiffAdded'
+        elif ttype in Token.Generic.Deleted:
+            return 'DiffRemoved'
+        elif ttype in Token.Generic.Strong:
+            return 'DiffChanged'
+        else:
+            # skip tags that have no class defined
+            return None
+            # ... or use the token's name when nothing apropriate
+            # return str(ttype).replace(".", " ")
+
+    def format(self, tokensource, outfile):
+        line_ready = False
+        fmt = self.formatter
+        result = self.result
+        for ttype, value in tokensource:
+            class_ = self.get_class(ttype)
+            if value:
+                for line in self.line_re.split(value):
+                    if not line_ready:
+                        result.append(fmt.code_line(1))
+                        line_ready = True
+                    if line == '\n':
+                        result.append(fmt.code_line(0))
+                        line_ready = False
+                    else:
+                        if class_:
+                            result.append(fmt.code_token(1, class_))
+                        result.append(fmt.text(line))
+                        if class_:
+                            result.append(fmt.code_token(0, class_))
+        result[-2] = ''
+        result[-1] = ''
+#        if line_ready:
+#            result.append(fmt.code_line(0))
+
+
+class Parser:
+    parsername = "highlight"  # compatibility wrappers override this with the pygments lexer name
+    Dependencies = Dependencies
+    extensions = extensions
+
+    def __init__(self, raw, request, filename=None, format_args='', **kw):
+        self.request = request
+        self.raw = raw.strip('\n')
+        self.filename = filename
+        if self.parsername == 'highlight':
+            # user is directly using the highlight parser
+            parts = format_args.split(None)
+            if parts:
+                self.syntax = parts[0]
+            else:
+                self.syntax = ''
+            if len(parts) > 1:
+                params = ' '.join(parts[1:])
+            else:
+                params = ''
+        else:
+            # a compatibility wrapper inherited from this class
+            self.syntax = self.parsername
+            params = format_args
+        self.show_nums, self.num_start, self.num_step, attrs = parse_start_step(request, params)
+
+    def format(self, formatter):
+        fmt = PygmentsFormatter(formatter)
+        fmt.result.append(formatter.div(1, css_class="highlight %s" % self.syntax))
+        self._code_id = hash_new('sha1', self.raw.encode(config.charset)).hexdigest()
+        fmt.result.append(formatter.code_area(1, self._code_id, self.parsername, self.show_nums, self.num_start, self.num_step))
+        if self.filename is not None:
+            try:
+                lexer = pygments.lexers.get_lexer_for_filename(self.filename)
+            except pygments.util.ClassNotFound:
+                fmt.result.append(formatter.text(self.filename))
+                lexer = pygments.lexers.TextLexer()
+        else:
+            try:
+                lexer = pygments.lexers.get_lexer_by_name(self.syntax)
+            except pygments.util.ClassNotFound:
+                fmt.result.append(formatter.text('#!%s\n' % self.syntax))
+                lexer = pygments.lexers.TextLexer()
+        pygments.highlight(self.raw, lexer, fmt)
+        fmt.result.append(formatter.code_area(0, self._code_id))
+        fmt.result.append(formatter.div(0))
+        self.request.write("".join(fmt.result))
+
--- a/MoinMoin/parser/text_cplusplus.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/parser/text_cplusplus.py	Thu Jan 29 09:44:57 2009 +0100
@@ -1,70 +1,26 @@
 # -*- coding: iso-8859-1 -*-
 """
-    MoinMoin - C++ Source Parser
-
-    @copyright: 2002 Taesu Pyo <bigflood@hitel.net>
-    @license: GNU GPL, see COPYING for details.
-
-css:
-
-pre.cpparea     { font-style: sans-serif; color: #000000; }
+    MoinMoin - C/C++ Source Parser
 
-pre.cpparea span.ID       { color: #000000; }
-pre.cpparea span.Char     { color: #004080; }
-pre.cpparea span.Comment  { color: #808080; }
-pre.cpparea span.Number   { color: #008080; font-weight: bold; }
-pre.cpparea span.String   { color: #004080; }
-pre.cpparea span.SPChar   { color: #0000C0; }
-pre.cpparea span.ResWord  { color: #4040ff; font-weight: bold; }
-pre.cpparea span.ConsWord { color: #008080; font-weight: bold; }
-pre.cpparea span.ResWord2 { color: #0080ff; font-weight: bold; }
-pre.cpparea span.Special  { color: #0000ff; }
-pre.cpparea span.Preprc   { color: #804000; }
+    DEPRECATED compatibility wrapper calling the highlight parser.
 
+    This is to support (deprecated) existing syntax like:
+    {{{#!cplusplus ...
+    ...
+    }}}
+
+    It is equivalent to the new way to highlight code:
+    {{{#!highlight cpp ...
+    ...
+    }}}
+
+    @copyright: 2008 MoinMoin:ThomasWaldmann
+    @license: GNU GPL, see COPYING for details.
 """
 
-from MoinMoin.parser._ParserBase import ParserBase
-
-Dependencies = ['user'] # the "Toggle line numbers link" depends on user's language
-
-class Parser(ParserBase):
-
-    parsername = "ColorizedCPlusPlus"
-    extensions = ['.c', '.h', '.cpp', '.c++']
-    Dependencies = Dependencies
-
-    def setupRules(self):
-        ParserBase.setupRules(self)
-
-        self.addRulePair("Comment", r"/[*]", r"[*]/")
-        self.addRule("Comment", r"//.*$")
-        self.addRulePair("String", r'L?"', r'$|[^\\](\\\\)*"')
-        self.addRule("Char", r"'\\.'|'[^\\]'")
-        self.addRule("Number", r"[0-9](\.[0-9]*)?(eE[+-][0-9])?[flFLdD]?|0[xX][0-9a-fA-F]+[Ll]?")
-        self.addRule("Preprc", r"^\s*#(.*\\\n)*(.*(?!\\))$")
-        self.addRule("ID", r"[a-zA-Z_][0-9a-zA-Z_]*")
-        self.addRule("SPChar", r"[~!%^&*()+=|\[\]:;,.<>/?{}-]")
+from MoinMoin.parser.highlight import Parser as HighlightParser
+from MoinMoin.parser.highlight import Dependencies
 
-        reserved_words = ['struct', 'class', 'union', 'enum',
-        'int', 'float', 'double', 'signed', 'unsigned', 'char', 'short', 'void', 'bool',
-        'long', 'register', 'auto', 'operator',
-        'static', 'const', 'private', 'public', 'protected', 'virtual', 'explicit',
-        'new', 'delete', 'this',
-        'if', 'else', 'while', 'for', 'do', 'switch', 'case', 'default', 'sizeof',
-        'dynamic_cast', 'static_cast', 'const_cast', 'reinterpret_cast', 'typeid',
-        'try', 'catch', 'throw', 'throws', 'return', 'continue', 'break', 'goto']
+class Parser(HighlightParser):
+    parsername = 'cpp'  # Lexer name pygments recognizes
 
-        reserved_words2 = ['extern', 'volatile', 'typedef', 'friend',
-                           '__declspec', 'inline', '__asm', 'thread', 'naked',
-                           'dllimport', 'dllexport', 'namespace', 'using',
-                           'template', 'typename', 'goto']
-
-        special_words = ['std', 'string', 'vector', 'map', 'set', 'cout', 'cin', 'cerr', 'endl']
-        constant_words = ['true', 'false', 'NULL']
-
-        self.addReserved(reserved_words)
-        self.addConstant(constant_words)
-
-        self.addWords(reserved_words2, 'ResWord2')
-        self.addWords(special_words, 'Special')
-
--- a/MoinMoin/parser/text_diff.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/parser/text_diff.py	Thu Jan 29 09:44:57 2009 +0100
@@ -1,39 +1,26 @@
 # -*- coding: iso-8859-1 -*-
 """
-    MoinMoin - Diff Parser - highlights diff tool output
+    MoinMoin - diff/patch Parser
 
-    @copyright: 2006 Emilio Lopes, inspired by previous work
-                done by Fabien Ninoles and Juergen Hermann
+    DEPRECATED compatibility wrapper calling the highlight parser.
+
+    This is to support (deprecated) existing syntax like:
+    {{{#!diff ...
+    ...
+    }}}
+
+    It is equivalent to the new way to highlight code:
+    {{{#!highlight diff ...
+    ...
+    }}}
+
+    @copyright: 2008 MoinMoin:ThomasWaldmann
     @license: GNU GPL, see COPYING for details.
 """
 
-from MoinMoin.parser._ParserBase import ParserBase
-
-class Parser(ParserBase):
-    parsername = "ColorizedDiff"
-    extensions = ['.diff', '.patch', ]
-    Dependencies = []
-
-    def setupRules(self):
-        ParserBase.setupRules(self)
+from MoinMoin.parser.highlight import Parser as HighlightParser
+from MoinMoin.parser.highlight import Dependencies
 
-        self.addRule("Comment", r'^(diff .*?)$')
-        self.addRule("Comment", r'^(\*\*\* .*?)$')
-        self.addRule("Comment", r'^(--- .*?)$')
-        self.addRule("Comment", r'^(\+\+\+ .*?)$')
-        self.addRule("Comment", r'^\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* *$')
-
-        self.addRule("DiffSeparator", r'^(@@ .*?)$')
-        self.addRule("DiffSeparator", r'^--- *$')
+class Parser(HighlightParser):
+    parsername = 'diff'  # Lexer name pygments recognizes
 
-        self.addRule("DiffAdded", r'^(\+.*?)$')
-        self.addRule("DiffRemoved", r'^(-.*?)$')
-        self.addRule("DiffAdded", r'^(>.*?)$')
-        self.addRule("DiffRemoved", r'^(<.*?)$')
-        self.addRule("DiffChanged", r'^(!.*?)$')
-
-        self.addRuleFormat("DiffAdded")
-        self.addRuleFormat("DiffRemoved")
-        self.addRuleFormat("DiffChanged")
-        self.addRuleFormat("DiffSeparator")
-
--- a/MoinMoin/parser/text_java.py	Wed Jan 28 17:06:22 2009 +0100
+++ b/MoinMoin/parser/text_java.py	Thu Jan 29 09:44:57 2009 +0100
@@ -2,42 +2,25 @@
 """
     MoinMoin - Java Source Parser
 
-    @copyright: 2002 Taesu Pyo <bigflood@hitel.net>
+    DEPRECATED compatibility wrapper calling the highlight parser.
+
+    This is to support (deprecated) existing syntax like:
+    {{{#!java ...
+    ...
+    }}}
+
+    It is equivalent to the new way to highlight code:
+    {{{#!highlight java ...
+    ...
+    }}}
+
+    @copyright: 2008 MoinMoin:ThomasWaldmann
     @license: GNU GPL, see COPYING for details.
-
 """
 
-from MoinMoin.parser._ParserBase import ParserBase
-
-Dependencies = ['user'] # the "Toggle line numbers link" depends on user's language
-
-class Parser(ParserBase):
-
-    parsername = "ColorizedJava"
-    extensions = ['.java']
-    Dependencies = Dependencies
-
-    def setupRules(self):
-        ParserBase.setupRules(self)
+from MoinMoin.parser.highlight import Parser as HighlightParser
+from MoinMoin.parser.highlight import Dependencies
 
-        self.addRulePair("Comment", r"/[*]", r"[*]/")
-        self.addRule("Comment", r"//.*$")
-        self.addRulePair("String", r'"', r'$|[^\\](\\\\)*"')
-        self.addRule("Char", r"'\\.'|'[^\\]'")
-        self.addRule("Number", r"[0-9](\.[0-9]*)?(eE[+-][0-9])?[flFLdD]?|0[xX][0-9a-fA-F]+[Ll]?")