diff --git a/modules/webaccess/lib/webaccessadmin_lib.py b/modules/webaccess/lib/webaccessadmin_lib.py
index 9df771022..c0701d09a 100644
--- a/modules/webaccess/lib/webaccessadmin_lib.py
+++ b/modules/webaccess/lib/webaccessadmin_lib.py
@@ -1,3430 +1,3430 @@
 ## $Id$
 ## Administrator interface for WebAccess
 
 ## This file is part of CDS Invenio.
 ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
 ##
 ## CDS Invenio is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License as
 ## published by the Free Software Foundation; either version 2 of the
 ## License, or (at your option) any later version.
 ##
 ## CDS Invenio is distributed in the hope that it will be useful, but
 ## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ## General Public License for more details.  
 ##
 ## You should have received a copy of the GNU General Public License
 ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc.,
 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
 """CDS Invenio WebAccess Administrator Interface."""
 
 __lastupdated__ = """$Date$"""
 
 ## fill config variables:
 
 import cgi
 import re
 import random
 import string
 import smtplib
 from mod_python import apache
 
 import invenio.access_control_engine as acce
 import invenio.access_control_admin as acca
 from invenio.bibrankadminlib import adderrorbox,addadminbox,tupletotable,tupletotable_onlyselected,addcheckboxes,createhiddenform
 from invenio.access_control_config import * 
 from invenio.dbquery import run_sql, escape_string
 from invenio.config import *
 from invenio.webpage import page, pageheaderonly, pagefooteronly
 from invenio.webuser import getUid, get_email, page_not_authorized
 from invenio.search_engine import print_record
-from invenio.webuser import checkemail, get_user_preferences, set_user_preferences
+from invenio.webuser import email_valid_p, get_user_preferences, set_user_preferences
 
 __version__ = "$Id$"
 
 
 def index(req, title='', body='', subtitle='', adminarea=2, authorized=0):
     """main function to show pages for webaccessadmin.
 
     1. if user not logged in and administrator, show the mustlogin page
 
     2. if used without body argument, show the startpage
 
     3. show admin page with title, body, subtitle and navtrail.
 
     adminarea - number codes that tell what extra info to put in the navtrail
                 0 - nothing extra
                 1 - add Delegate Rights
                 2 - add Manage WebAccess
                 maybe add:
                 3: role admin
                 4: action admin
                 5: user area
                 6: reset area
 
     authorized - if 1, don't check if the user is allowed to be webadmin """
     
     navtrail_previous_links = """<a class=navtrail href="%s/admin/">Admin Area</a> &gt; <a class=navtrail href="%s/admin/webaccess/">WebAccess Admin</a> """ % (weburl, weburl)
     
     if body:
         if adminarea == 1: navtrail_previous_links += '&gt; <a class=navtrail href=%s/admin/webaccess/webaccessadmin.py/delegate_startarea>Delegate Rights</a> ' % (weburl, )
         if adminarea >= 2 and adminarea < 7: navtrail_previous_links += '&gt; <a class=navtrail href=%s/admin/webaccess/webaccessadmin.py>Manage WebAccess</a> ' % (weburl, )
         if adminarea == 3: navtrail_previous_links += '&gt; <a class=navtrail href=%s/admin/webaccess/webaccessadmin.py/rolearea>Role Administration</a> ' % (weburl, )
         elif adminarea == 4: navtrail_previous_links += '&gt; <a class=navtrail href=%s/admin/webaccess/webaccessadmin.py/actionarea>Action Administration</a> ' % (weburl, )
         elif adminarea == 5: navtrail_previous_links += '&gt; <a class=navtrail href=%s/admin/webaccess/webaccessadmin.py/userarea>User Administration</a> ' % (weburl, )
         elif adminarea == 6: navtrail_previous_links += '&gt; <a class=navtrail href=%s/admin/webaccess/webaccessadmin.py/resetarea>Reset Authorizations</a> ' % (weburl, )
         elif adminarea == 7: navtrail_previous_links += '&gt; <a class=navtrail href=%s/admin/webaccess/webaccessadmin.py/manageaccounts>Manage Accounts</a> ' % (weburl, )
     
     id_user = getUid(req)
     (auth_code, auth_message) = is_adminuser(req)
     if not authorized and auth_code != 0: return mustloginpage(req, auth_message)
 
     elif not body:
         title = 'Manage WebAccess'
         body = startpage()
     elif type(body) != str: body = addadminbox(subtitle, datalist=body)
 
     return page(title=title,
                 uid=id_user,
                 req=req,
                 body=body,
                 navtrail=navtrail_previous_links,
                 lastupdated=__lastupdated__)                
 
 def mustloginpage(req, message):
     """show a page asking the user to login."""
     
     navtrail_previous_links = """<a class=navtrail href="%s/admin/">Admin Area</a> &gt; <a class=navtrail href="%s/admin/webaccess/">WebAccess Admin</a> """ % (weburl, weburl)
 
     return page_not_authorized(req=req, text=message, navtrail=navtrail_previous_links)
                 
 def is_adminuser(req):
     """check if user is a registered administrator. """
 
     id_user = getUid(req)
     return acce.acc_authorize_action(id_user, WEBACCESSACTION)
 
 def perform_rolearea(req):
     """create the role area menu page."""
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     header = ['id', 'name', 'description', 'users', 'authorizations / actions', 'role', '']
     roles = acca.acc_getAllRoles()
 
     roles2 = []
     for (id, name, desc) in roles:
         if len(desc) > 30: desc = desc[:30] + '...'
         roles2.append([id, name, desc])
         for col in [(('add', 'adduserrole'),
                      ('remove', 'deleteuserrole')),
                     (('add', 'addauthorization'),
                      ('modify', 'modifyauthorizations'),
                      ('remove', 'deleteroleaction')),
                     (('delete', 'deleterole'), ),
                     (('show details', 'showroledetails'), )]:
             roles2[-1].append('<a href="%s?id_role=%s">%s</a>' % (col[0][1], id, col[0][0]))
             for (str, function) in col[1:]:
                 roles2[-1][-1] += ' / <a href="%s?id_role=%s">%s</a>' % (function, id, str)
 
     output  = """
     <dl>
      <dt>Users:</dt>
      <dd>add or remove users from the access to a role and its priviliges.</dd>
      <dt>Authorizations/Actions:</dt>
      <dd>these terms means almost the same, but an authorization is a <br>
          connection between a role and an action (possibly) containing arguments.</dd>
      <dt>Roles:</dt>
      <dd>see all the information attached to a role and decide if you want to<br>delete it.</dd>
     </dl>
     """
     
     output += tupletotable(header=header, tuple=roles2)
 
     extra = """
     <dl>
      <dt><a href="addrole">Create new role</a></dt>
      <dd>go here to add a new role.</dd>
      <dt><a href="addaction">Create new action</a></dt>
      <dd>go here to add a new action.</dd>
     </dl>
     """
 
     return index(req=req,
                  title='Role Administration',
                  subtitle='administration with roles as access point',
                  body=[output, extra],
                  adminarea=2)
 
 
 def perform_actionarea(req):
     """create the action area menu page."""
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     header = ['id', 'name', 'authorizations/roles', 'action', '']
     actions = acca.acc_getAllActions()
 
     actions2 = []
     roles2 = []
     for (id, name, dontcare) in actions:
         actions2.append([id, name])
         for col in [(('add', 'addauthorization'),
                      ('modify', 'modifyauthorizations'),
                      ('remove', 'deleteroleaction')),
                     (('delete', 'deleteaction'), ),
                     (('show details', 'showactiondetails'), )]:
             actions2[-1].append('<a href="%s?id_action=%s&amp;reverse=1">%s</a>' % (col[0][1], id, col[0][0]))
             for (str, function) in col[1:]:
                 actions2[-1][-1] += ' / <a href="%s?id_action=%s&amp;reverse=1">%s</a>' % (function, id, str)
 
     output  = """
     <dl>
      <dt>Authorizations/Roles:</dt>
      <dd>these terms means almost the same, but an authorization is a <br>
          connection between a role and an action (possibly) containing arguments.</dd>
      <dt>Actions:</dt>
      <dd>see all the information attached to an action and decide if you want to<br>delete it.</dd>
     </dl>
     """
     
     output += tupletotable(header=header, tuple=actions2)
 
     extra = """
     <dl>
      <dt><a href="addrole">Create new role</a>
      <dd>go here to add a new role.
      <dt><a href="addaction">Create new action</a>
      <dd>go here to add a new action.
     </dl>
     """
 
     return index(req=req,
                  title='Action Administration',
                  subtitle='administration with actions as access point',
                  body=[output, extra],
                  adminarea=2)
 
 
 def perform_userarea(req, email_user_pattern=''):
     """create area to show info about users. """
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     subtitle = 'step 1 - search for users'
 
     output = """
     <p>
      search for users to display. 
     </p> """
 
     # remove letters not allowed in an email
     email_user_pattern = cleanstring_email(email_user_pattern)
         
     text  = ' <span class="adminlabel">1. search for user</span>\n'
     text += ' <input class="admin_wvar" type="text" name="email_user_pattern" value="%s" />\n' % (email_user_pattern, )
 
     output += createhiddenform(action="userarea",
                                text=text,
                                button="search for users")
 
     if email_user_pattern:
         users1 = run_sql("""SELECT id, email FROM user WHERE email RLIKE '%s' ORDER BY email LIMIT %s""" % (email_user_pattern, MAXPAGEUSERS+1))
 
         if not users1:
             output += '<p>no matching users</p>'
         else: 
             subtitle = 'step 2 - select what to do with user'
 
             users = []
             for (id, email) in users1[:MAXPAGEUSERS]:
                 users.append([id, email])
                 for col in [(('add', 'addroleuser'),
                              ('remove', 'deleteuserrole')),
                             (('show details', 'showuserdetails'), )]:
                     users[-1].append('<a href="%s?email_user_pattern=%s&amp;id_user=%s">%s</a>' % (col[0][1], email_user_pattern, id, col[0][0]))
                     for (str, function) in col[1:]:
                         users[-1][-1] += ' / <a href="%s?email_user_pattern=%s&amp;id_user=%s&amp;reverse=1">%s</a>' % (function, email_user_pattern, id, str)
     
             output += '<p>found <strong>%s</strong> matching users:</p>' % (len(users1), )
             output += tupletotable(header=['id', 'email', 'roles', ''], tuple=users)
 
             if len(users1) > MAXPAGEUSERS:
                 output += '<p><strong>only showing the first %s users, narrow your search...</strong></p>' % (MAXPAGEUSERS, )
 
     return index(req=req,
                  title='User Administration',
                  subtitle=subtitle,
                  body=[output],
                  adminarea=2)
 
 
 def perform_resetarea(req):
     """create the reset area menu page."""
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     output = """
     <dl>
      <dt><a href="resetdefaultsettings">Reset to Default Authorizations</a>
      <dd>remove all changes that has been done to the roles and <br>
      add only the default authorization settings.
      <dt><a href="adddefaultsettings">Add Default Authorizations</a>
      <dd>keep all changes and add the default authorization settings.
     </dl>
     """
 
     return index(req=req,
                  title='Reset Authorizations',
                  subtitle='reseting to or adding default authorizations',
                  body=[output],
                  adminarea=2)
 
 
 def perform_resetdefaultsettings(req, superusers=[], confirm=0):
     """delete all roles, actions and authorizations presently in the database
     and add only the default roles.
     only selected users will be added to superadmin, rest is blank """
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     # cleaning input
     if type(superusers) == str: superusers = [superusers]
 
     # remove not valid e-mails
     for email in superusers:
         if not check_email(email): superusers.remove(email)
     
     # instructions
     output  = """
     <p>
      before you reset the settings, we need some users<br>
      to connect to <strong>%s</strong>.<br>
      enter as many e-mail addresses you want and press <strong>reset</strong>.<br>
      <strong>confirm reset settings</strong> when you have added enough e-mails.<br>
      <strong>%s</strong> is added as default.
     </p>""" % (SUPERADMINROLE, supportemail)
 
     # add more superusers
     output += """
     <p>enter user e-mail addresses: </p>
     <form action="resetdefaultsettings" method="POST">"""
 
     for email in superusers:
         output += '      <input type="hidden" name="superusers" value="%s" />' % (email, )
 
     output += """
      <span class="adminlabel">e-mail</span>
      <input class="admin_wvar" type="text" name="superusers" />
      <input class="adminbutton" type="submit" value="add e-mail" />
     </form>"""
 
 
     if superusers:
         # remove emails
         output += """
         <form action="resetdefaultsettings" method="POST">
          have you entered wrong data? 
          <input class="adminbutton" type="submit" value="remove all e-mails" />
         </form>
         """
         
         # superusers confirm table
         start = '<form action="resetdefaultsettings" method="POST">'
     
         extra  = ' <input type="hidden" name="confirm" value="1" />'
         for email in superusers:
             extra += '<input type="hidden" name="superusers" value="%s" />' % (email, )
         extra += ' <input class="adminbutton" type="submit" value="confirm to reset settings" />'
     
         end    = '</form>'
     
         output += '<p><strong>reset default settings</strong> with the users below? </p>'
         output += tupletotable(header=['e-mail address'],
                                tuple=superusers,
                                start=start,
                                extracolumn=extra,
                                end=end)
         
         if confirm in [1, "1"]:
             res = acca.acc_reset_default_settings(superusers)
             if res:
                   output += '<p>successfully reset default settings</p>'
             else:
                   output += '<p>sorry, could not reset default settings</p>'
     
     return index(req=req,
                  title='Reset Default Settings',
                  subtitle='reset settings',
                  body=[output],
                  adminarea=6)
 
 
 def perform_adddefaultsettings(req, superusers=[], confirm=0):
     """add the default settings, and keep everything else.
     probably nothing will be deleted, except if there has been made changes to the defaults."""
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     # cleaning input
     if type(superusers) == str: superusers = [superusers]
     
     # remove not valid e-mails
     for email in superusers:
         if not check_email(email): superusers.remove(email)
     
     # instructions
     output  = """
     <p>
      before you add the settings, we need some users<br>
      to connect to <strong>%s</strong>.<br>
      enter as many e-mail addresses you want and press <strong>add</strong>.<br>
      <strong>confirm add settings</strong> when you have added enough e-mails.<br>
      <strong>%s</strong> is added as default.
     </p>""" % (SUPERADMINROLE, supportemail)
 
     # add more superusers
     output += """
     <p>enter user e-mail addresses: </p>
     <form action="adddefaultsettings" method="POST">"""
 
     for email in superusers:
         output += '      <input type="hidden" name="superusers" value="%s" />' % (email, )
 
     output += """
      <span class="adminlabel">e-mail</span>
      <input class="admin_wvar" type="text" name="superusers" />
      <input class="adminbutton" type="submit" value="add e-mail" />
     </form>
     """
 
     if superusers:
         # remove emails
         output += """
         <form action="adddefaultsettings" method="POST">
          have you entered wrong data? 
          <input class="adminbutton" type="submit" value="remove all e-mails" />
         </form>
         """
         
         # superusers confirm table
         start = '<form action="adddefaultsettings" method="POST">'
     
         extra  = ' <input type="hidden" name="confirm" value="1" />'
         for email in superusers:
             extra += '<input type="hidden" name="superusers" value="%s" />' % (email, )
         extra += ' <input class="adminbutton" type="submit" value="confirm to add settings" />'
     
         end    = '</form>'
     
         output += '<p><strong>add default settings</strong> with the users below? </p>'
         output += tupletotable(header=['e-mail address'],
                                tuple=superusers,
                                start=start,
                                extracolumn=extra,
                                end=end)
 
         if confirm in [1, "1"]:
             res = acca.acc_add_default_settings(superusers)
             if res:
                   output += '<p>successfully added default settings</p>'
             else:
                   output += '<p>sorry, could not add default settings</p>'
     
     return index(req=req,
                  title='Add Default Settings',
                  subtitle='add settings',
                  body=[output],
                  adminarea=6)
 
 def perform_manageaccounts(req, mtype='', content='', confirm=0):
     """start area for managing accounts."""
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     subtitle = 'Overview'
 
     fin_output = ''
 
     fin_output += """
     <table>
     <tr>
     <td><b>Menu</b></td>
     </tr>
     <tr>
     <td>0.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/manageaccounts?mtype=perform_showall">Show all</a></small></td>
     <td>1.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/manageaccounts?mtype=perform_accesspolicy#1">Access policy</a></
 small></td>
     <td>2.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/manageaccounts?mtype=perform_accountoverview#2">Account overview</a></
 small></td>
     <td>3.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/manageaccounts?mtype=perform_createaccount#3">Create account</a></
 small></td>
     <td>4.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/manageaccounts?mtype=perform_modifyaccounts#4">Edit accounts</a></small></
 td>
     </tr>
     </table>
     """ % (weburl, weburl, weburl, weburl, weburl)
 
     if mtype == "perform_accesspolicy" and content:
         fin_output += content
     elif mtype == "perform_accesspolicy" or mtype == "perform_showall":
         fin_output += perform_accesspolicy(req, callback='')
         fin_output += "<br>"
 
     if mtype == "perform_accountoverview" and content:
         fin_output += content
     elif mtype == "perform_accountoverview" or mtype == "perform_showall":
         fin_output += perform_accountoverview(req, callback='')
         fin_output += "<br>"
 
     if mtype == "perform_createaccount" and content:
         fin_output += content
     elif mtype == "perform_createaccount" or mtype == "perform_showall":
         fin_output += perform_createaccount(req, callback='')
         fin_output += "<br>"
 
     if mtype == "perform_modifyaccounts" and content:
         fin_output += content
     elif mtype == "perform_modifyaccounts" or mtype == "perform_showall":
         fin_output += perform_modifyaccounts(req, callback='')
         fin_output += "<br>"
 
     return index(req=req,
                  title='Manage Accounts',
                  subtitle=subtitle, 
                  body=[fin_output],
                  adminarea=0,
                  authorized=1)
 
 def perform_accesspolicy(req, callback='yes', confirm=0):
     """Modify default behaviour of a guest user or if new accounts should automatically/manually be modified."""
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     subtitle = """<a name="1"></a>1. Access policy.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/webaccess/guide.html#4">?</a>]</small>""" % weburl
 
     account_policy = {}
     account_policy[0] = "Users can register new accounts. New accounts automatically activated." 
     account_policy[1] = "Users can register new accounts. Admin users must activate the accounts."
     account_policy[2] = "Only admin can register new accounts. User cannot edit email address."
     account_policy[3] = "Only admin can register new accounts. User cannot edit email address or password."
     account_policy[4] = "Only admin can register new accounts. User cannot edit email address,password or login method."
     site_policy = {}
     site_policy[0] = "Normal operation of the site."
     site_policy[1] = "Read-only site, all write operations temporarily closed."
     site_policy[2] = "Site fully closed."
 
     output = "(Modifications must be done in access_control_config.py)<br>"
     output += "<br><b>Current settings:</b><br>"
     output += "Site status: %s<br>" % (site_policy[CFG_ACCESS_CONTROL_LEVEL_SITE])
     output += "Guest accounts allowed: %s<br>" % (CFG_ACCESS_CONTROL_LEVEL_GUESTS == 0 and "Yes" or "No")
     output += "Account policy: %s<br>" % (account_policy[CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS])
     output += "Allowed email addresses limited: %s<br>" % (CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN and CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN or "Not limited")
     output += "Send email to admin when new account: %s<br>" % (CFG_ACCESS_CONTROL_NOTIFY_ADMIN_ABOUT_NEW_ACCOUNTS == 1 and "Yes" or "No")
     output += "Send email to user after creating new account: %s<br>" % (CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT == 1 and "Yes" or "No")
     output += "Send email to user when account is activated: %s<br>" % (CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_ACTIVATION == 1 and "Yes" or "No")
     output += "Send email to user when account is deleted/rejected: %s<br>" % (CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_DELETION == 1 and "Yes" or "No")
 
     output += "<br>"
     output += "<b>Available 'login via' methods:</b><br>"
     methods = CFG_EXTERNAL_AUTHENTICATION.keys()
     methods.sort()
     for system in methods:
         output += """%s %s<br>""" % (system, (CFG_EXTERNAL_AUTHENTICATION[system][1] and "(Default)" or ""))
  
     output += "<br><b>Changing the settings:</b><br>"
     output += "Currently, all changes must be done using your favourite editor, and the webserver restarted for changes to take effect. For the settings to change, either look in the guide or in access_control_config.py ."
 
     try:
         body = [output, extra]
     except NameError:
         body = [output]
 
     if callback:
         return perform_manageaccounts(req, "perform_accesspolicy", addadminbox(subtitle, body))
     else:
         return addadminbox(subtitle, body)
 
 def perform_accountoverview(req, callback='yes', confirm=0):
     """Modify default behaviour of a guest user or if new accounts should automatically/manually be modified."""
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     subtitle = """<a name="2"></a>2. Account overview.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/webaccess/guide.html#4">?</a>]</small>""" % weburl
     output = ""
     res = run_sql("SELECT COUNT(*) FROM user WHERE email=''")
     output += "Guest accounts: %s<br>" % res[0][0]
     res = run_sql("SELECT COUNT(*) FROM user WHERE email!=''")
     output += "Registered accounts: %s<br>" % res[0][0]
     res = run_sql("SELECT COUNT(*) FROM user WHERE email!='' AND note='0' OR note IS NULL")
     output += "Inactive accounts: %s " % res[0][0]
     if res[0][0] > 0:
         output += ' [<a href="modifyaccounts?email_user_pattern=&amp;limit_to=disabled&amp;maxpage=25&amp;page=1">Activate/Reject accounts</a>]'
     res = run_sql("SELECT COUNT(*) FROM user")
     output += "<br>Total nr of accounts: %s<br>" % res[0][0]
 
     try:
         body = [output, extra]
     except NameError:
         body = [output]
 
     if callback:
         return perform_manageaccounts(req, "perform_accountoverview", addadminbox(subtitle, body))
     else:
         return addadminbox(subtitle, body)
 
 def perform_createaccount(req, email='', password='', callback='yes', confirm=0):
     """Modify default behaviour of a guest user or if new accounts should automatically/manually be modified."""
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     subtitle = """<a name="3"></a>3. Create account.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/webaccess/guide.html#4">?</a>]</small>""" % weburl
 
     output = ""
 
     text = ' <span class="adminlabel">Email:</span>\n'
     text += ' <input class="admin_wvar" type="text" name="email" value="%s" /><br>' % (email, )
     text += ' <span class="adminlabel">Password:</span>\n'
     text += ' <input class="admin_wvar" type="text" name="password" value="%s" /><br>' % (password, )
 
     output += createhiddenform(action="createaccount",
                                	text=text,
                                 confirm=1,
                                 button="Create")
 
-    if confirm in [1, "1"] and email and checkemail(email):
+    if confirm in [1, "1"] and email and email_valid_p(email):
         res = run_sql("SELECT * FROM user WHERE email='%s'" % escape_string(email))
         if not res:
             res = run_sql("INSERT INTO user (email,password, note) values('%s','%s', '1')" % (escape_string(email), escape_string(password)))
             if CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT == 1:
                 emailsent = sendNewUserAccountWarning(email, email, password)
             if password:
                 output += '<b><span class="info">Account created with password and activated.</span></b>'  
             else: 
                 output += '<b><span class="info">Account created without password and activated.</span></b>' 
             if CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT == 1:
                 if emailsent:
                     output += '<br><b><span class="info">An email has been sent to the owner of the account.</span></b>' 
                 else:
                     output += '<br><b><span class="important">Could not send an email to the owner of the account.</span></b>' 
             
         else:
             output += '<b><span class="info">An account with the same email already exists.</span></b>' 
        
     elif confirm in [1, "1"]:
         output += '<b><span class="info">Please specify an valid email-address.</span></b>'
         
     try:
         body = [output, extra]
     except NameError:
         body = [output]
 
     if callback:
         return perform_manageaccounts(req, "perform_createaccount", addadminbox(subtitle, body))
     else:
         return addadminbox(subtitle, body)
 
 
 def perform_modifyaccountstatus(req, userID, email_user_pattern, limit_to, maxpage, page, callback='yes', confirm=0):
     """set a disabled account to enabled and opposite"""
     
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     res = run_sql("SELECT id, email, note, password FROM user WHERE id=%s" % userID)
     output = ""
     if res:
         if res[0][2] in [0, "0", None]:
             res2 = run_sql("UPDATE user SET note=1 WHERE id=%s" % userID)
             output += """<b><span class="info">The account '%s' has been activated.</span></b>""" % res[0][1]
             if CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_ACTIVATION == 1:
                 emailsent = sendAccountActivatedMessage(res[0][1], res[0][1], res[0][3])
                 if emailsent: 
                     output += """<br><b><span class="info">An email has been sent to the owner of the account.</span></b>"""
                 else:
                     output += """<br><b><span class="info">Could not send an email to the owner of the account.</span></b>"""
  
         elif res[0][2] in [1, "1"]:
             res2 = run_sql("UPDATE user SET note=0 WHERE id=%s" % userID)
             output += """<b><span class="info">The account '%s' has been set inactive.</span></b>""" % res[0][1]
     else:
         output += '<b><span class="info">The account id given does not exist.</span></b>'
   
     try:
         body = [output, extra]
     except NameError:
         body = [output]
 
     if callback:
         return perform_modifyaccounts(req, email_user_pattern, limit_to, maxpage, page, content=output, callback='yes')
     else:
         return addadminbox(subtitle, body)
 
 def perform_editaccount(req, userID, mtype='', content='', callback='yes', confirm=-1):
     """form to modify an account. this method is calling other methods which again is calling this and sending back the output of the method.
     if callback, the method will call perform_editcollection, if not, it will just return its output.
     userID - id of the user
     mtype - the method that called this method.
     content - the output from that method."""
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     res = run_sql("SELECT id, email FROM user WHERE id=%s" % userID)
     if not res:
         if mtype == "perform_deleteaccount":
             text = """<b><span class="info">The selected account has been deleted, to continue editing, go back to 'Manage Accounts'.</span></b>"""
             if CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_DELETION == 1:
                 text += """<br><b><span class="info">An email has been sent to the owner of the account.</span></b>"""
         else:
             text = """<b><span class="info">The selected accounts does not exist, please go back and select an account to edit.</span></b>"""
           
         return index(req=req, 
                  title='Edit Account',
                  subtitle="Edit account", 
                  body=[text],
                  adminarea=7,
                  authorized=1)
         
     fin_output = """
     <table>
     <tr>
     <td><b>Menu</b></td>
     </tr>
     <tr>
     <td>0.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/editaccount?userID=%s">Show all</a></small></td>
     <td>1.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/editaccount?userID=%s&amp;mtype=perform_modifylogindata">Modify login-data</a></small></td>
     <td>2.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/editaccount?userID=%s&amp;mtype=perform_modifybasket">Modify baskets</a></small></td>
     <td>3.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/editaccount?userID=%s&amp;mtype=perform_modifyalerts">Modify alerts</a></small></td>
     <td>4.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/editaccount?userID=%s&amp;mtype=perform_modifypreferences">Modify preferences</a></small></td>
     </tr><tr>
     <td>5.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/editaccount?userID=%s&amp;mtype=perform_deleteaccount">Delete account</a></small></td>
     </tr>
     </table>
     """ % (weburl, userID, weburl, userID, weburl, userID, weburl, userID, weburl, userID, weburl, userID)
 
     if mtype == "perform_modifylogindata" and content:
         fin_output += content
     elif mtype == "perform_modifylogindata" or not mtype:
         fin_output += perform_modifylogindata(req, userID, callback='')
 
     if mtype == "perform_modifybasket" and content:
         fin_output += content
     elif mtype == "perform_modifybasket" or not mtype:
         fin_output += perform_modifybasket(req, userID, callback='')
 
     if mtype == "perform_modifypreferences" and content:
         fin_output += content
     elif mtype == "perform_modifypreferences" or not mtype:
         fin_output += perform_modifypreferences(req, userID, callback='')
 
     if mtype == "perform_modifyalerts" and content:
         fin_output += content
     elif mtype == "perform_modifyalerts" or not mtype:
         fin_output += perform_modifyalerts(req, userID, callback='')
 
     if mtype == "perform_deleteaccount" and content:
         fin_output += content
     elif mtype == "perform_deleteaccount" or not mtype:
         fin_output += perform_deleteaccount(req, userID, callback='')
         
     return index(req=req,
                  title='Edit Account',
                  subtitle="Edit account '%s'" % res[0][1], 
                  body=[fin_output],
                  adminarea=7,
                  authorized=1)
 
 def perform_modifybasket(req, userID, callback='yes', confirm=0):
     """modify email and password of an account"""
     
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     subtitle = """<a name="2"></a>2. Modify baskets.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/webaccess/guide.html#4">?</a>]</small>""" % weburl
 
     res = run_sql("SELECT id, email, password FROM user WHERE id=%s" % userID)
     output = ""
     if res:
         text = """To modify the baskets for this account, you have to login as the user."""
         output += createhiddenform(action="%s/youraccount/login?" % sweburl,
                                    text=text,
                                    p_email=res[0][1],
                                    p_pw=res[0][2],
                                    referer="%s/yourbaskets/display" % weburl,
                                    button="Login")
         output += "Remember that you will be logged out as the current user."
 
         #baskets = run_sql("SELECT basket.id, basket.name, basket.public FROM basket, user_basket WHERE id_user=%s and user_basket.id_basket=basket.id" % userID)
         #output += "<table><tr>"
         #for (id, name, public) in baskets:
         #    output += "<tr><td>%s<br>Public: %s</td></tr>" % (name, (public=="y" and "Yes" or "No"))
         #    basket_records = run_sql("SELECT id_record, nb_order FROM basket_record WHERE id_basket=%s" % id)
         #    for (id_record, nb_order) in basket_records:
         #        output += "<tr><td></td><td>"
         #        output += print_record(id_record)
         #        output += "</td></tr>"
         #    
         #output += "</tr></table>"
     else:
         output += '<b><span class="info">The account id given does not exist.</span></b>'
   
     try:
         body = [output, extra]
     except NameError:
         body = [output]
 
     if callback:
         return perform_editaccount(req, userID, mtype='perform_modifybasket', content=addadminbox(subtitle, body), callback='yes')
     else:
         return addadminbox(subtitle, body)
 
 def perform_modifylogindata(req, userID, email='', password='', callback='yes', confirm=0):
     """modify email and password of an account"""
     
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     subtitle = """<a name="1"></a>1. Edit login-data.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/webaccess/guide.html#4">?</a>]</small>""" % weburl
 
     res = run_sql("SELECT id, email, password FROM user WHERE id=%s" % userID)
     output = ""
     if res:
         if not email and not password:
             email = res[0][1]
             password = res[0][2]
         text =  ' <span class="adminlabel">Account id:</span>%s<br>\n' % userID
         text += ' <span class="adminlabel">Email:</span>\n'
         text += ' <input class="admin_wvar" type="text" name="email" value="%s" /><br>' % (email, )
         text += ' <span class="adminlabel">Password:</span>\n'
         text += ' <input class="admin_wvar" type="text" name="password" value="%s" /><br>' % (password, )
 
         output += createhiddenform(action="modifylogindata",
                                    text=text,
 				   userID=userID,
                                    confirm=1,
                                    button="Modify")
-        if confirm in [1, "1"] and email and checkemail(email):
+        if confirm in [1, "1"] and email and email_valid_p(email):
             res = run_sql("UPDATE user SET email='%s' WHERE id=%s" % (escape_string(email), userID))
             res = run_sql("UPDATE user SET password='%s' WHERE id=%s" % (escape_string(password), userID))
             output += '<b><span class="info">Email and/or password modified.</span></b>'
         elif confirm in [1, "1"]:
             output += '<b><span class="info">Please specify an valid email-address.</span></b>'
     else:
         output += '<b><span class="info">The account id given does not exist.</span></b>'
   
     try:
         body = [output, extra]
     except NameError:
         body = [output]
 
     if callback:
         return perform_editaccount(req, userID, mtype='perform_modifylogindata', content=addadminbox(subtitle, body), callback='yes')
     else:
         return addadminbox(subtitle, body)
 
 
 def perform_modifyalerts(req, userID, callback='yes', confirm=0):
     """modify email and password of an account"""
     
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     subtitle = """<a name="3"></a>3. Modify alerts.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/webaccess/guide.html#4">?</a>]</small>""" % weburl
 
     res = run_sql("SELECT id, email, password FROM user WHERE id=%s" % userID)
     output = ""
     if res:
         text = """To modify the alerts for this account, you have to login as the user."""
         output += createhiddenform(action="%s/youraccount/login?" % sweburl,
                                    text=text,
                                    p_email=res[0][1],
                                    p_pw=res[0][2],
                                    referer="%s/youralerts/display" % weburl,
                                    button="Login")
         output += "Remember that you will be logged out as the current user."
 
         res= """ SELECT q.id, q.urlargs, a.id_basket, 
                  a.alert_name, a.frequency, a.notification, 
                  DATE_FORMAT(a.date_creation,'%%d %%b %%Y'), 
                  DATE_FORMAT(a.date_lastrun,'%%d %%b %%Y')
                  FROM query q, user_query_basket a
                  WHERE a.id_user='%s' AND a.id_query=q.id
                  ORDER BY a.alert_name ASC """ % userID
         #res = run_sql(res)
         #for (qID, qurlargs,  id_basket, alertname, frequency, notification, date_creation, date_lastrun) in res:
         #    output += "%s - %s - %s - %s - %s - %s - %s<br>" % (qID,  id_basket, alertname, frequency, notification, date_creation, date_lastrun)
     else:
         output += '<b><span class="info">The account id given does not exist.</span></b>'
   
     try:
         body = [output, extra]
     except NameError:
         body = [output]
 
     if callback:
         return perform_editaccount(req, userID, mtype='perform_modifyalerts', content=addadminbox(subtitle, body), callback='yes')
     else:
         return addadminbox(subtitle, body)
 
 def perform_modifypreferences(req, userID, login_method='', callback='yes', confirm=0):
     """modify email and password of an account"""
     
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     subtitle = """<a name="4"></a>4. Modify preferences.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/webaccess/guide.html#4">?</a>]</small>""" % weburl
 
     res = run_sql("SELECT id, email, password FROM user WHERE id=%s" % userID)
     output = ""
     if res:
         user_pref = get_user_preferences(userID)
         if confirm in [1, "1"]:
             if login_method:
                 user_pref['login_method'] = login_method 
                 set_user_preferences(userID, user_pref)
 
         output += "Select default login method:<br>"
         text = ""
         methods = CFG_EXTERNAL_AUTHENTICATION.keys()
         methods.sort()
         for system in methods:
             text += """<input type="radio" name="login_method" value="%s" %s>%s<br>""" % (system, (user_pref['login_method'] == system and "checked" or ""), system)
 
 
         output += createhiddenform(action="modifypreferences",
                                    text=text,
                                    confirm=1,
                                    userID=userID,
                                    button="Select")
 
         if confirm in [1, "1"]:
             if login_method:
                 output += """<b><span class="info">The login method has been changed</span></b>"""
             else:
                  output += """<b><span class="info">Nothing to update</span></b>"""
     else:
         output += '<b><span class="info">The account id given does not exist.</span></b>'
   
     try:
         body = [output, extra]
     except NameError:
         body = [output]
 
     if callback:
         return perform_editaccount(req, userID, mtype='perform_modifypreferences', content=addadminbox(subtitle, body), callback='yes')
     else:
         return addadminbox(subtitle, body)
 
 def perform_deleteaccount(req, userID, callback='yes', confirm=0):
     """delete account"""
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
     
     subtitle = """<a name="5"></a>5. Delete account.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/webaccess/guide.html#4">?</a>]</small>""" % weburl
 
     res = run_sql("SELECT id, email, password FROM user WHERE id=%s" % userID)
     output = ""
     if res:
         if confirm in [0, "0"]:
             text = '<b><span class="important">Are you sure you want to delete the account with email: "%s"?</span></b>' % res[0][1]
             output += createhiddenform(action="deleteaccount",
                                        text=text,
 				       userID=userID,
                                        confirm=1,
                                        button="Delete")
         
         elif confirm in [1, "1"]:
             res2 = run_sql("DELETE FROM user WHERE id=%s" % userID)
             output += '<b><span class="info">Account deleted.</span></b>'
             if CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_DELETION == 1:
                 emailsent = sendAccountDeletedMessage(res[0][1], res[0][1])
     else:
         output += '<b><span class="info">The account id given does not exist.</span></b>'
   
     try:
         body = [output, extra]
     except NameError:
         body = [output]
 
     if callback:
         return perform_editaccount(req, userID, mtype='perform_deleteaccount', content=addadminbox(subtitle, body), callback='yes')
     else:
         return addadminbox(subtitle, body)
 
 def perform_rejectaccount(req, userID, email_user_pattern, limit_to, maxpage, page, callback='yes', confirm=0):
     """Delete account and send an email to the owner."""
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
     
     res = run_sql("SELECT id, email, password, note FROM user WHERE id=%s" % userID)
     output = ""
     if res:
         res2 = run_sql("DELETE FROM user WHERE id=%s" % userID)
         output += '<b><span class="info">Account rejected and deleted.</span></b>'
         if CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_DELETION == 1:
             if not res[0][3] or res[0][3] == "0":
                 emailsent = sendAccountRejectedMessage(res[0][1], res[0][1])
             elif res[0][3] == "1":
                 emailsent = sendAccountDeletedMessage(res[0][1], res[0][1])
             if emailsent: 
                 output += """<br><b><span class="info">An email has been sent to the owner of the account.</span></b>"""
             else:
                 output += """<br><b><span class="info">Could not send an email to the owner of the account.</span></b>"""
     else:
         output += '<b><span class="info">The account id given does not exist.</span></b>'
 
     try:
         body = [output, extra]
     except NameError:
         body = [output]
 
     if callback:
         return perform_modifyaccounts(req, email_user_pattern, limit_to, maxpage, page, content=output, callback='yes')
     else:
         return addadminbox(subtitle, body)
         
 def perform_modifyaccounts(req, email_user_pattern='', limit_to=-1, maxpage=MAXPAGEUSERS, page=1, content='', callback='yes', confirm=0):
     """Modify default behaviour of a guest user or if new accounts should automatically/manually be modified."""
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     subtitle = """<a name="4"></a>4. Edit accounts.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/webaccess/guide.html#4">?</a>]</small>""" % weburl
 
     output = ""
 
     # remove letters not allowed in an email
     email_user_pattern = cleanstring_email(email_user_pattern)
     try:
         maxpage = int(maxpage)
     except:
         maxpage = MAXPAGEUSERS
     try:
         page = int(page)
         if page < 1:
             page = 1
     except:
         page = 1
         
     text  = ' <span class="adminlabel">Email (part of):</span>\n'
     text += ' <input class="admin_wvar" type="text" name="email_user_pattern" value="%s" /><br>' % (email_user_pattern, )
     
     text += """<span class="adminlabel">Limit to:</span>
     <select name="limit_to" class="admin_w200">
     <option value="all" %s>All accounts</option>
     <option value="enabled" %s>Active accounts</option>
     <option value="disabled" %s>Inactive accounts</option>
     </select><br>""" % ((limit_to=="all" and "selected" or ""), (limit_to=="enabled" and "selected" or ""), (limit_to=="disabled" and "selected" or ""))
 
     text += """<span class="adminlabel">Accounts per page:</span>
     <select name="maxpage" class="admin_wvar">
     <option value="25" %s>25</option>
     <option value="50" %s>50</option>
     <option value="100" %s>100</option>
     <option value="250" %s>250</option>
     <option value="500" %s>500</option>
     <option value="1000" %s>1000</option>
     </select><br>""" % ((maxpage==25 and "selected" or ""), (maxpage==50 and "selected" or ""), (maxpage==100 and "selected" or ""), (maxpage==250 and "selected" or ""), (maxpage==500 and "selected" or ""), (maxpage==1000 and "selected" or ""))
 
     output += createhiddenform(action="modifyaccounts",
                                text=text,
                                button="search for accounts")
 
     if limit_to not in [-1, "-1"] and maxpage:
         users1 = "SELECT id,email,note FROM user WHERE "
         if limit_to == "enabled":
             users1 += " email!='' AND note=1"
         elif limit_to == "disabled":
             users1 += " email!='' AND note=0 OR note IS NULL"
         elif limit_to == "guest":
             users1 += " email=''"
         else:
             users1 += " email!=''"
         if email_user_pattern:
             users1 += " AND email RLIKE '%s'" % (email_user_pattern)
         users1 += " ORDER BY email LIMIT %s" % (maxpage * page + 1)
         users1 = run_sql(users1)
         if not users1:
             output += '<b><span class="info">There are no accounts matching the email given.</span></b>'
         else: 
             users = []
             if maxpage * (page  - 1) > len(users1):
                 page = len(users1) / maxpage + 1  
             for (id, email, note) in users1[maxpage * (page  - 1):(maxpage * page)]:
                 users.append(['', id, email, (note=="1" and '<strong class="info">Active</strong>' or '<strong class="important">Inactive</strong>')])
                 for col in [(((note=="1" and 'Inactivate' or 'Activate'), 'modifyaccountstatus'), ((note == "0" and 'Reject' or 'Delete'), 'rejectaccount'), ),   
                             (('Edit account', 'editaccount'), ),]:
                     users[-1].append('<a href="%s?userID=%s&amp;email_user_pattern=%s&amp;limit_to=%s&amp;maxpage=%s&amp;page=%s&amp;rand=%s">%s</a>' % (col[0][1], id, email_user_pattern, limit_to, maxpage, page, random.randint(0,1000), col[0][0]))
                     for (str, function) in col[1:]:
                         users[-1][-1] += ' / <a href="%s?userID=%s&amp;email_user_pattern=%s&amp;limit_to=%s&amp;maxpage=%s&amp;page=%s&amp;rand=%s">%s</a>' % (function, id, email_user_pattern, limit_to, maxpage, page, random.randint(0,1000), str)
  
             last = ""
             next = ""
             if len(users1) > maxpage:
                 if page > 1:
                     last += '<b><span class="info"><a href="modifyaccounts?email_user_pattern=%s&amp;limit_to=%s&amp;maxpage=%s&amp;page=%s">Last Page</a></span></b>' % (email_user_pattern, limit_to, maxpage, (page - 1))
                 if len(users1[maxpage * (page  - 1):(maxpage * page)]) == maxpage:
                     next += '<b><span class="info"><a href="modifyaccounts?email_user_pattern=%s&amp;limit_to=%s&amp;maxpage=%s&amp;page=%s">Next page</a></span></b>' % (email_user_pattern, limit_to, maxpage, (page + 1))
                 output += '<b><span class="info">Showing accounts %s-%s:</span></b>' % (1 + maxpage * (page - 1), maxpage * page)
             else:
                 output += '<b><span class="info">%s matching account(s):</span></b>' % len(users1)
             output += tupletotable(header=[last, 'id', 'email', 'Status', '', '',next], tuple=users)
 
     else:
         output += '<b><span class="info">Please select which accounts to find and how many to show per page.</span></b>'
     
     if content:
         output += "<br>%s" % content
     
     try:
         body = [output, extra]
     except NameError:
         body = [output]
 
     if callback:
         return perform_manageaccounts(req, "perform_modifyaccounts", addadminbox(subtitle, body))
     else:
         return addadminbox(subtitle, body)
 
 def perform_delegate_startarea(req):
     """start area for lower level delegation of rights."""
 
     subtitle = 'select what to do'
 
     output = ''
     
     if is_adminuser(req)[0] == 0:
         output += """
         <p>
          You are also allowed to be in the <a href="../webaccessadmin.py">Main Admin Area</a> which gives you<br>
          the access to the full functionality of WebAccess.
         </p>
         """
 
     output += """
     <dl>
      <dt><a href="delegate_adduserrole">Connect users to roles</a></dt>
      <dd>add users to the roles you have delegation rights to.</dd>
      <dt><a href="delegate_deleteuserrole">Remove users from roles</a></dt>
      <dd>remove users from the roles you have delegation rights to.</dd>
     </dl>
     <dl>
      <dt><a href="delegate_adminsetup">Set up delegation rights</a></dt>
      <dd>spesialized area to set up the delegation rights used in the areas above. <br>
          you need to be a web administrator to access the area.</dd>
     </dl>
     """
         
     return index(req=req,
                  title='Delegate Rights',
                  subtitle=subtitle, 
                  body=[output],
                  adminarea=0,
                  authorized=1)
 
 
 def perform_delegate_adminsetup(req, id_role_admin=0, id_role_delegate=0, confirm=0):
     """lets the webadmins set up the delegation rights for the other roles
 
        id_role_admin - the role to be given delegation rights
 
     id_role_delegate - the role over which the delegation rights are given
 
              confirm - make the connection happen """
 
     subtitle = 'step 1 - select admin role'
 
     admin_roles = acca.acc_getAllRoles()
 
     output = """
     <p>
      This is a specialized area to handle a task that also can be handled<br>
      from the &quot;add authorization&quot; interface.
     </p>
     <p>
      By handling the delegation rights here you get the advantage of<br>
      not having to select the correct action <i>(%s)</i> or<br>
      remembering the names of available roles.
     </p>
     """ % (DELEGATEADDUSERROLE, )
     
     output += createroleselect(id_role=id_role_admin,
                               step=1,
                               button='select admin role',
                               name='id_role_admin',
                               action='delegate_adminsetup',
                               roles=admin_roles)
 
     if str(id_role_admin) != '0':
         subtitle = 'step 2 - select delegate role'
 
         name_role_admin = acca.acc_getRoleName(id_role=id_role_admin)
 
         delegate_roles_old = acca.acc_find_delegated_roles(id_role_admin=id_role_admin)
         
         delegate_roles = []
         delegate_roles_old_names = []
         for role in admin_roles:
             if (role,) not in delegate_roles_old:
                 delegate_roles.append(role)
             else:
                 delegate_roles_old_names.append(role[1])
 
         if delegate_roles_old_names:
             delegate_roles_old_names.sort()
             names_str = ''
             for name in delegate_roles_old_names:
                 if names_str: names_str += ', '
                 names_str += name
             output += '<p>previously selected roles: <strong>%s</strong>.</p>' % (names_str, )
 
             extra = """
             <dl>
              <dt><a href="modifyauthorizations?id_role=%s&amp;id_action=%s">Remove delegated roles</a></dt>
              <dd>use the standard administration area to remove delegation rights
                  you no longer want to be available.</dd>
             </dl>
             """ % (id_role_admin, acca.acc_getActionId(name_action=DELEGATEADDUSERROLE))
 
         else:
             output += '<p>no previously selected roles.</p>'
 
         output += createroleselect(id_role=id_role_delegate,
                                    step=2,
                                    button='select delegate role',
                                    name='id_role_delegate',
                                    action='delegate_adminsetup',
                                    roles=delegate_roles,
                                    id_role_admin=id_role_admin)
 
         if str(id_role_delegate) != '0':
             subtitle = 'step 3 - confirm to add delegation right'
             
             name_role_delegate = acca.acc_getRoleName(id_role=id_role_delegate)
 
             output += """
             <p>
              <span class="warning"><strong>Warning:</strong> don't hand out delegation rights that can harm the system (e.g. delegating superrole).</span>
             </p> """
 
             output += createhiddenform(action="delegate_adminsetup",
                                        text='let role <strong>%s</strong> delegate rights over role <strong>%s</strong>?' % (name_role_admin, name_role_delegate),
                                        id_role_admin=id_role_admin,
                                        id_role_delegate=id_role_delegate,
                                        confirm=1)
 
             if int(confirm):
                 subtitle = 'step 4 - confirm delegation right added'
                 # res1 = acca.acc_addRoleActionArguments_names(name_role=name_role_admin,
                 #                                              name_action=DELEGATEADDUSERROLE,
                 #                                              arglistid=-1,
                 #                                              optional=0,
                 #                                              role=name_role_delegate)
                 res1 = acca.acc_addAuthorization(name_role=name_role_admin,
                                                  name_action=DELEGATEADDUSERROLE,
                                                  optional=0,
                                                  role=name_role_delegate)
 
                 if res1:
                     output += '<p>confirm: role <strong>%s</strong> delegates role <strong>%s</strong>.' % (name_role_admin, name_role_delegate)
         
                 else: output += '<p>sorry, delegation right could not be added,<br>it probably already exists.</p>'
 
     # see if right hand menu is available
     try: body = [output, extra]
     except NameError: body = [output]
     
     return index(req=req,
                  title='Delegate Rights',
                  subtitle=subtitle, 
                  body=body,
                  adminarea=1)
 
 
 def perform_delegate_adduserrole(req, id_role=0, email_user_pattern='', id_user=0, confirm=0):
     """let a lower level web admin add users to a limited set of roles.
 
     id_role - the role to connect to a user
 
     id_user - the user to connect to a role
 
     confirm - make the connection happen """
 
     # finding the allowed roles for this user
     id_admin = getUid(req)
     id_action = acca.acc_getActionId(name_action=DELEGATEADDUSERROLE) 
     actions = acca.acc_findPossibleActionsUser(id_user=id_admin, id_action=id_action)
 
     allowed_roles = []
     allowed_id_roles = []
     for (id, arglistid, name_role_help) in actions[1:]:
         id_role_help = acca.acc_getRoleId(name_role=name_role_help)
         if id_role_help and [id_role_help, name_role_help, ''] not in allowed_roles:
             allowed_roles.append([id_role_help, name_role_help, ''])
             allowed_id_roles.append(str(id_role_help))
         
     output = ''
 
     if not allowed_roles:
         subtitle = 'no delegation rights'
         output += """
         <p>
          You do not have the delegation rights over any roles.<br>
          If you think you should have such rights, contact a WebAccess Administrator.
         </p>"""
         extra = ''
     else:
         subtitle = 'step 1 - select role'
 
         output += """
         <p>
          Lower level delegation of access rights to roles.<br>
          An administrator with all rights have to give you these rights.
         </p>"""
 
         email_out = acca.acc_getUserEmail(id_user=id_user)
         name_role = acca.acc_getRoleName(id_role=id_role)
 
         output += createroleselect(id_role=id_role, step=1, name='id_role',
                                    action='delegate_adduserrole', roles=allowed_roles)
 
         if str(id_role) != '0' and str(id_role) in allowed_id_roles:
             subtitle = 'step 2 - search for users'
 
             # remove letters not allowed in an email
             email_user_pattern = cleanstring_email(email_user_pattern)
                 
             text  = ' <span class="adminlabel">2. search for user </span>\n'
             text += ' <input class="admin_wvar" type="text" name="email_user_pattern" value="%s" />\n' % (email_user_pattern, )
     
             output += createhiddenform(action="delegate_adduserrole",
                                        text=text,
                                        button="search for users",
                                        id_role=id_role)
     
             # pattern is entered
             if email_user_pattern:
                 # users with matching email-address
                 users1 = run_sql("""SELECT id, email FROM user WHERE email RLIKE '%s' ORDER BY email """ % (email_user_pattern, ))
                 # users that are connected
                 users2 = run_sql("""SELECT DISTINCT u.id, u.email
                 FROM user u LEFT JOIN user_accROLE ur ON u.id = ur.id_user
                 WHERE ur.id_accROLE = '%s' AND u.email RLIKE '%s'
                 ORDER BY u.email """ % (id_role, email_user_pattern))
     
                 # no users that match the pattern
                 if not (users1 or users2):
                     output += '<p>no qualified users, try new search.</p>'
                 # too many matching users
                 elif len(users1) > MAXSELECTUSERS:
                     output += '<p><strong>%s hits</strong>, too many qualified users, specify more narrow search. (limit %s)</p>' % (len(users1), MAXSELECTUSERS)
 
                 # show matching users
                 else:
                     subtitle = 'step 3 - select a user'
                     
                     users = []
                     extrausers = []
                     for (id, email) in users1:
                         if (id, email) not in users2: users.append([id,email,''])
                     for (id, email) in users2:
                         extrausers.append([-id, email,''])
 
                     output += createuserselect(id_user=id_user,
                                                action="delegate_adduserrole",
                                                step=3,
                                                users=users,
                                                extrausers=extrausers,
                                                button="add this user",
                                                id_role=id_role,
                                                email_user_pattern=email_user_pattern)
     
                     try: id_user = int(id_user)
                     except ValueError: pass
                     # user selected already connected to role
                     if id_user < 0:
                         output += '<p>users in brackets are already attached to the role, try another one...</p>'
                     # a user is selected
                     elif email_out:
                         subtitle = "step 4 - confirm to add user"
     
                         output += createhiddenform(action="delegate_adduserrole",
                                                    text='add user <strong>%s</strong> to role <strong>%s</strong>?' % (email_out, name_role),
                                                    id_role=id_role,
                                                    email_user_pattern=email_user_pattern,
                                                    id_user=id_user,
                                                    confirm=1)
     
                         # it is confirmed that this user should be added
                         if confirm:
                             # add user
                             result = acca.acc_addUserRole(id_user=id_user, id_role=id_role)
             
                             if result and result[2]: 
                                 subtitle = 'step 5 - confirm user added'
                                 output  += '<p>confirm: user <strong>%s</strong> added to role <strong>%s</strong>.</p>' % (email_out, name_role)
                             else:
                                 subtitle = 'step 5 - user could not be added'
                                 output += '<p>sorry, but user could not be added.</p>'
 
         extra = """
         <dl>
          <dt><a href="delegate_deleteuserrole?id_role=%s">Remove users from role</a></dt>
          <dd>remove users from the roles you have delegating rights to.</dd>
         </dl>
         """ % (id_role, )
 
     return index(req=req,
                  title='Connect users to roles',
                  subtitle=subtitle, 
                  body=[output, extra],
                  adminarea=1,
                  authorized=1)
 
 
 def perform_delegate_deleteuserrole(req, id_role=0, id_user=0, confirm=0):
     """let a lower level web admin remove users from a limited set of roles.
 
     id_role - the role to connect to a user
 
     id_user - the user to connect to a role
 
     confirm - make the connection happen """
 
     subtitle = 'in progress...'
 
     output = '<p>in progress...</p>'
 
     # finding the allowed roles for this user
     id_admin = getUid(req)
     id_action = acca.acc_getActionId(name_action=DELEGATEADDUSERROLE)
     actions = acca.acc_findPossibleActionsUser(id_user=id_admin, id_action=id_action)
 
     output = ''
 
     if not actions:
         subtitle = 'no delegation rights'
         output += """
         <p>
          You do not have the delegation rights over any roles.<br>
          If you think you should have such rights, contact a WebAccess Administrator.
         </p>"""
         extra = ''
     else:
         subtitle = 'step 1 - select role'
 
         output += """
         <p>
          Lower level delegation of access rights to roles.<br>
          An administrator with all rights have to give you these rights.
         </p>"""
 
         email_out = acca.acc_getUserEmail(id_user=id_user)
         name_role = acca.acc_getRoleName(id_role=id_role)
 
         # create list of allowed roles
         allowed_roles = []
         allowed_id_roles = []
         for (id, arglistid, name_role_help) in actions[1:]:
             id_role_help = acca.acc_getRoleId(name_role=name_role_help)
             if id_role_help and [id_role_help, name_role_help, ''] not in allowed_roles:
                 allowed_roles.append([id_role_help, name_role_help, ''])
                 allowed_id_roles.append(str(id_role_help))
         
         output += createroleselect(id_role=id_role, step=1,
                                    action='delegate_deleteuserrole', roles=allowed_roles)
 
         if str(id_role) != '0' and str(id_role) in allowed_id_roles:
             subtitle = 'step 2 - select user'
 
             users = acca.acc_getRoleUsers(id_role)
 
             output += createuserselect(id_user=id_user,
                                        step=2,
                                        action='delegate_deleteuserrole',
                                        users=users,
                                        id_role=id_role)
 
             if str(id_user) != '0':
                 subtitle = 'step 3 - confirm delete of user'
                 email_user = acca.acc_getUserEmail(id_user=id_user)
                 
                 output += createhiddenform(action="delegate_deleteuserrole",
                                            text='delete user %s from %s?'
                                            % (headerstrong(user=id_user), headerstrong(role=id_role)),
                                            id_role=id_role,
                                            id_user=id_user,
                                            confirm=1)
         
                 if confirm:
                     res = acca.acc_deleteUserRole(id_user=id_user, id_role=id_role)
                     if res:
                         subtitle = 'step 4 - confirm user deleted from role'
                         output += '<p>confirm: deleted user <strong>%s</strong> from role <strong>%s</strong>.</p>' % (email_user, name_role)
                     else:
                         subtitle = 'step 4 - user could not be deleted'
                         output += 'sorry, but user could not be deleted<br>user is probably already deleted.'
 
         extra = """
         <dl>
          <dt><a href="delegate_adduserrole?id_role=%s">Connect users to role</a></dt>
          <dd>add users to the roles you have delegating rights to.</dd>
         </dl>
         """ % (id_role, )
 
     return index(req=req,
                  title='Remove users from roles',
                  subtitle=subtitle, 
                  body=[output, extra],
                  adminarea=1,
                  authorized=1)
 
 
 def perform_addaction(req, name_action='', arguments='', optional='no', description='put description here.', confirm=0):
     """form to add a new action with these values:
 
     name_action - name of the new action
 
       arguments - allowedkeywords, separated by whitespace
 
     description - optional description of the action"""
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     name_action = cleanstring(name_action)
     arguments = cleanstring(arguments, comma=1)
 
     title = 'Add Action'
     subtitle = 'step 1 - give values to the requested fields'
 
     output  = """
     <form action="addaction" method="POST">
      <span class="adminlabel">action name </span>
      <input class="admin_wvar" type="text" name="name_action" value="%s" /> <br> 
      <span class="adminlabel">arguments </span>
      <input class="admin_wvar" type="text" name="arguments" value="%s" /> 
      <small>keywords for arguments, separate with comma, no whitespace.</small> <br>
      <span class="adminlabel">optional arguments</span>
      <select name="optional" class="admin_w200">
       <option value="no" selected="selected">no, not allowed</option>
       <option value="yes" %s>yes, allowed</option>
      </select><br>
      <span class="adminlabel">description </span>
      <textarea class="admin_wvar" rows="6" cols="30" name="description">%s</textarea> 
      <input class="adminbutton" type="submit" value="add action" />
     </form>
     """ % (name_action, arguments, optional == 'yes' and 'selected="selected"' or '', description)
 
     if name_action:
         # description must be changed before it is submitted
         if description == 'put description here.': internaldesc = ''
         else: internaldesc = description
         
         if arguments:
             subtitle = 'step 2 - confirm to add action with %s arguments' % (optional == 'yes' and 'optional' or '', )
             arguments = arguments.replace(' ', '')
             text  = 'add action with: <br>\n'
             text += 'name: <strong>%s</strong><br>\n' % (name_action, )
             if internaldesc:
                 text += 'description: <strong>%s</strong><br>\n' % (description, )
             text += '%sarguments: <strong>%s</strong><br>' % (optional == 'yes' and 'optional ' or '', arguments)
             text += 'optional: <strong>%s</strong>?' % (optional, )
         
         else:
             optional = 'no'
             subtitle = 'step 2 - confirm to add action without arguments'
             text = 'add action <strong>%s</strong> without arguments' % (name_action, )
             if internaldesc: text += '<br>\nand description: <strong>%s</strong>?\n' % (description, )
             else: text += '?\n'
             
         output += createhiddenform(action="addaction",
                                    text=text,
                                    name_action=name_action,
                                    arguments=arguments,
                                    optional=optional, 
                                    description=description,
                                    confirm=1)
 
         if confirm not in ["0", 0]:
             arguments = arguments.split(',')
             result = acca.acc_addAction(name_action,
                                         internaldesc,
                                         optional,
                                         *arguments)
 
             if result:
                 subtitle = 'step 3 - action added'
                 output += '<p>action added:</p>'
                 output += tupletotable(header=['id', 'action name', 'description', 'allowedkeywords', 'optional'],
                                       tuple=[result])
             else:
                 subtitle = 'step 3 - action could not be added'
                 output += '<p>sorry, could not add action, <br>action with the same name probably exists.</p>'
                 
             extra = """
             <dl>
              <dt><a href="addauthorization?id_action=%s&amp;reverse=1">Add authorization</a></dt>
              <dd>start adding new authorizations to action %s.</dd>
             </dl> """ % (acca.acc_getActionId(name_action=name_action), name_action)
 
     try: body = [output, extra]
     except NameError: body = [output]
 
     return index(req=req,
                  title=title,
                  body=body,
                  subtitle=subtitle,
                  adminarea=4)
 
 
 def perform_deleteaction(req, id_action="0", confirm=0):
     """show all roles connected, and ask for confirmation.
 
     id_action - id of action to delete """
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     title='Delete action'
     subtitle='step 1 - select action to delete'
     name_action = acca.acc_getActionName(id_action=id_action)
 
     output = createactionselect(id_action=id_action,
                                 action="deleteaction",
                                 step=1,
                                 actions=acca.acc_getAllActions(),
                                 button="delete action")
 
     if id_action != "0" and name_action:
         subtitle = 'step 2 - confirm the delete'
 
         output += actiondetails(id_action=id_action)
 
         if acca.acc_getActionRoles(id_action=id_action):
             output += createhiddenform(action="deleteroleaction",
                                        text="""rather delete only connection between action %s
                                        and a selected role?""" % (name_action, ),
                                        id_action=id_action,
                                        reverse=1,
                                        button='go there')
         
         output += createhiddenform(action="deleteaction",
                                    text=' delete action <strong>%s</strong> and all connections?' % (name_action, ),
                                    confirm=1,
                                    id_action=id_action)
         
         if confirm:
             subtitle = 'step 3 - confirm delete of action'
             res = acca.acc_deleteAction(id_action=id_action)
             if res:
                 output += '<p>confirm: action <strong>%s</strong> deleted.<br>\n' % (name_action, )
                 output += '%s entries deleted all in all.</p>\n' % (res, )
             else:
                 output += '<p>sorry, action could not be deleted.</p>\n'
     elif id_action != "0":
         output += '<p>the action has been deleted...</p>'
     
     return index(req=req,
                  title=title,
                  subtitle=subtitle,
                  body=[output],
                  adminarea=4)
 
 
 def perform_showactiondetails(req, id_action):
     """show the details of an action. """
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     output = createactionselect(id_action=id_action,
                                 action="showactiondetails",
                                 step=1,
                                 actions=acca.acc_getAllActions(),
                                 button="select action")
 
     if id_action not in [0, '0']:
         output += actiondetails(id_action=id_action)
 
         extra = """
         <dl>
          <dt><a href="addauthorization?id_action=%s&amp;reverse=1">Add new authorization</a></dt>
          <dd>add an authorization.</dd>
          <dt><a href="modifyauthorizations?id_action=%s&amp;reverse=1">Modify authorizations</a></dt>
          <dd>modify existing authorizations.</dd>
          <dt><a href="deleteroleaction?id_action=%s&amp;reverse=1">Remove role</a></dt>
          <dd>remove all authorizations from action and a role.</dd>
         </dl>
         """ % (id_action, id_action, id_action)
         body = [output, extra]
         
     else:
         output += '<p>no details to show</p>'
         body = [output]
 
     return index(req=req,
                  title='Show Action Details',
                  subtitle='show action details',
                  body=body,
                  adminarea=4)
 
 
 def actiondetails(id_action=0):
     """show details of given action. """
 
     output = ''
 
     if id_action not in [0, '0']:
         name_action = acca.acc_getActionName(id_action=id_action)
 
         output += '<p>action details:</p>'
         output += tupletotable(header=['id', 'name', 'description', 'allowedkeywords', 'optional'],
                                tuple=[acca.acc_getActionDetails(id_action=id_action)])
     
         roleshlp = acca.acc_getActionRoles(id_action=id_action)
         if roleshlp: 
             roles = []
             for (id, name, dontcare) in roleshlp:
                 roles.append([id, name,
                               '<a href="simpleauthorization?id_role=%s&amp;id_action=%s">show authorization details</a>'
                               % (id, id_action),
                               '<a href="showroleusers?id_role=%s">show connected users</a>' % (id, )])
             roletable = tupletotable(header=['id', 'name', '', ''], tuple=roles)
             
             output += '<p>roles connected to %s:</p>\n' % (headerstrong(action=name_action, query=0), )
             output += roletable
     
         else:
             output += '<p>no roles connected to %s.</p>\n' % (headerstrong(action=name_action, query=0), )
 
     else:
         output += '<p>no details to show</p>'
     
     return output
 
 
 def perform_addrole(req, name_role='', description='put description here.', confirm=0):
     """form to add a new role with these values:
     
       name_role - name of the new role
 
     description - optional description of the role """
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     name_role = cleanstring(name_role)
 
     title='Add Role'
     subtitle = 'step 1 - give values to the requested fields'
 
     output = """
     <form action="addrole" method="POST">
      <span class="adminlabel">role name </span>
      <input class="admin_wvar" type="text" name="name_role" value="%s" /> <br>
      <span class="adminlabel">description </span>
      <textarea class="admin_wvar" rows="6" cols="30" name="description">%s</textarea>
      <input class="adminbutton" type="submit" value="add role" />
     </form>
     """ % (name_role, description)
     
     if name_role:
         # description must be changed before submitting
         subtitle = 'step 2 - confirm to add role'
         internaldesc = ''
         if description != 'put description here.':
             internaldesc = description
             
         text = """
         add role with: <br>\n
         name: <strong>%s</strong> <br>""" % (name_role, )
         if internaldesc:
             text += 'description: <strong>%s</strong>?\n' % (description, )
             
         output += createhiddenform(action="addrole",
                                    text=text,
                                    name_role=name_role,
                                    description=description,
                                    confirm=1)
         
         if confirm not in ["0", 0]:
             result = acca.acc_addRole(name_role=name_role,
                                       description=internaldesc)
             
             if result:
                 subtitle = 'step 3 - role added'
                 output += '<p>role added: </p>'
                 output += tupletotable(header=['id', 'action name', 'description', 'allowedkeywords'],
                                        tuple=[result])
             else:
                 subtitle = 'step 3 - role could not be added'
                 output += '<p>sorry, could not add role, <br>role with the same name probably exists.</p>'
 
             id_role = acca.acc_getRoleId(name_role=name_role)
             extra = """
             <dl>
              <dt><a href="addauthorization?id_role=%s">Add authorization</a></dt>
              <dd>start adding new authorizations to role %s.</dd>
             </dl>
              <dt><a href="adduserrole?id_role=%s">Connect user</a></dt>
              <dd>connect a user to role %s.</dd>
             <dl>
             </dl>""" % (id_role, name_role, id_role, name_role)
 
     try: body = [output, extra]
     except NameError: body = [output]
 
     return index(req=req,
                  title=title,
                  body=body,
                  subtitle=subtitle,
                  adminarea=3)
 
 
 def perform_deleterole(req, id_role="0", confirm=0):
     """select a role and show all connected information,
 
       users - users that can access the role.
 
     actions - actions with possible authorizations."""
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     title = 'Delete role'
     subtitle = 'step 1 - select role to delete'
 
     name_role = acca.acc_getRoleName(id_role=id_role)
     output = createroleselect(id_role=id_role,
                               action="deleterole",
                               step=1,
                               roles=acca.acc_getAllRoles(),
                               button="delete role")
 
     if id_role != "0" and name_role:
         subtitle = 'step 2 - confirm delete of role'
 
         output += roledetails(id_role=id_role)
 
         output += createhiddenform(action="deleterole",
                                    text='delete role <strong>%s</strong> and all connections?' % (name_role, ),
                                    id_role=id_role,
                                    confirm=1)
 
         if confirm:
             res = acca.acc_deleteRole(id_role=id_role)
             subtitle = 'step 3 - confirm role deleted'
             if res:
                 output += "<p>confirm: role <strong>%s</strong> deleted.<br>" % (name_role, )
                 output += "<strong>%s</strong> entries were removed.</p>" % (res, )
             else:
                 output += "<p>sorry, the role could not be deleted.</p>"
     elif id_role != "0":
         output += '<p>the role has been deleted...</p>'
 
     return index(req=req,
                  title=title,
                  subtitle=subtitle,                 
                  body=[output],
                  adminarea=3)
 
 
 def perform_showroledetails(req, id_role):
     """show the details of a role."""
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     output = createroleselect(id_role=id_role,
                               action="showroledetails",
                               step=1,
                               roles=acca.acc_getAllRoles(),
                               button="select role")
 
     if id_role not in [0, '0']:
         name_role = acca.acc_getRoleName(id_role=id_role)
         
         output += roledetails(id_role=id_role)
             
         extra = """
         <dl>
          <dt><a href="addauthorization?id_role=%s">Add new authorization</a></dt>
          <dd>add an authorization.</dd>
          <dt><a href="modifyauthorizations?id_role=%s">Modify authorizations</a></dt>
          <dd>modify existing authorizations.</dd>
         </dl>
         <dl>
          <dt><a href="adduserrole?id_role=%s">Connect user</a></dt>
          <dd>connect a user to role %s.</dd>
          <dt><a href="deleteuserrole?id_role=%s">Remove user</a></dt>
          <dd>remove a user from role %s.</dd>
         </dl>
         """ % (id_role, id_role, id_role, name_role, id_role, name_role)
         body = [output, extra]
     
     else:
         output += '<p>no details to show</p>'
         body = [output]
     
     return index(req=req,
                  title='Show Role Details',
                  subtitle='show role details',
                  body=body,
                  adminarea=3)
 
 
 def roledetails(id_role=0):
     """create the string to show details about a role. """
 
     name_role = acca.acc_getRoleName(id_role=id_role)
 
     usershlp = acca.acc_getRoleUsers(id_role)
     users = []
     for (id, email, dontcare) in usershlp:
         users.append([id, email, '<a href="showuserdetails?id_user=%s">show user details</a>' % (id, )])
     usertable = tupletotable(header=['id', 'email'], tuple=users)
     
     actionshlp = acca.acc_getRoleActions(id_role)
     actions = []
     for (id, name, dontcare) in actionshlp:
         actions.append([id, name,
                         '<a href="showactiondetails?id_role=%s&amp;id_action=%s">show action details</a>' % (id_role, id),
                         '<a href="simpleauthorization?id_role=%s&amp;id_action=%s">show authorization details</a>' % (id_role, id)])
         
     actiontable = tupletotable(header=['id', 'name', '', ''], tuple=actions)
 
     # show role details
     details  = '<p>role details:</p>'
     details += tupletotable(header=['id', 'name', 'description'],
                             tuple=[acca.acc_getRoleDetails(id_role=id_role)])
 
     # show connected users
     details += '<p>users connected to %s:</p>' % (headerstrong(role=name_role, query=0), )
     if users: 
         details += usertable
     else:
         details += '<p>no users connected.</p>'
     # show connected authorizations
     details += '<p>authorizations for %s:</p>' % (headerstrong(role=name_role, query=0), )
     if actions: 
         details += actiontable
     else:
         details += '<p>no authorizations connected</p>'
 
     return details 
 
 
 
 def perform_adduserrole(req, id_role='0', email_user_pattern='', id_user='0', confirm=0):
     """create connection between user and role.
 
                id_role - id of the role to add user to
 
     email_user_pattern - search for users using this pattern
 
                id_user - id of user to add to the role. """
     
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     email_out = acca.acc_getUserEmail(id_user=id_user)
     name_role = acca.acc_getRoleName(id_role=id_role)
     
     title = 'Connect user to role '
     subtitle = 'step 1 - select a role'
 
     output = createroleselect(id_role=id_role,
                               action="adduserrole",
                               step=1,
                               roles=acca.acc_getAllRoles())
 
     # role is selected
     if id_role != "0":
         title += name_role
         
         subtitle = 'step 2 - search for users'
 
         # remove letters not allowed in an email
         email_user_pattern = cleanstring_email(email_user_pattern)
             
         text  = ' <span class="adminlabel">2. search for user </span>\n'
         text += ' <input class="admin_wvar" type="text" name="email_user_pattern" value="%s" />\n' % (email_user_pattern, )
 
         output += createhiddenform(action="adduserrole",
                                    text=text,
                                    button="search for users",
                                    id_role=id_role)
 
         # pattern is entered
         if email_user_pattern:
             # users with matching email-address
             users1 = run_sql("""SELECT id, email FROM user WHERE email RLIKE '%s' ORDER BY email """ % (email_user_pattern, ))
             # users that are connected
             users2 = run_sql("""SELECT DISTINCT u.id, u.email
             FROM user u LEFT JOIN user_accROLE ur ON u.id = ur.id_user
             WHERE ur.id_accROLE = '%s' AND u.email RLIKE '%s'
             ORDER BY u.email """ % (id_role, email_user_pattern))
 
             # no users that match the pattern
             if not (users1 or users2):
                 output += '<p>no qualified users, try new search.</p>'
             elif len(users1) > MAXSELECTUSERS:
                 output += '<p><strong>%s hits</strong>, too many qualified users, specify more narrow search. (limit %s)</p>' % (len(users1), MAXSELECTUSERS)
                 
             # show matching users
             else:
                 subtitle = 'step 3 - select a user'
                 
                 users = []
                 extrausers = []
                 for (id, email) in users1:
                     if (id, email) not in users2: users.append([id,email,''])
                 for (id, email) in users2:
                     extrausers.append([-id, email,''])
 
                 output += createuserselect(id_user=id_user,
                                            action="adduserrole",
                                            step=3,
                                            users=users,
                                            extrausers=extrausers,
                                            button="add this user",
                                            id_role=id_role,
                                            email_user_pattern=email_user_pattern)
 
                 try: id_user = int(id_user)
                 except ValueError: pass
                 # user selected already connected to role
                 if id_user < 0:
                     output += '<p>users in brackets are already attached to the role, try another one...</p>'
                 # a user is selected
                 elif email_out:
                     subtitle = "step 4 - confirm to add user"
 
                     output += createhiddenform(action="adduserrole",
                                                text='add user <strong>%s</strong> to role <strong>%s</strong>?' % (email_out, name_role),
                                                id_role=id_role,
                                                email_user_pattern=email_user_pattern,
                                                id_user=id_user,
                                                confirm=1)
 
                     # it is confirmed that this user should be added
                     if confirm:
                         # add user
                         result = acca.acc_addUserRole(id_user=id_user, id_role=id_role)
         
                         if result and result[2]: 
                             subtitle = 'step 5 - confirm user added'
                             output  += '<p>confirm: user <strong>%s</strong> added to role <strong>%s</strong>.</p>' % (email_out, name_role)
                         else:
                             subtitle = 'step 5 - user could not be added'
                             output += '<p>sorry, but user could not be added.</p>'
             
     extra = """
     <dl>
      <dt><a href="addrole">Create new role</a></dt>
      <dd>go here to add a new role.</dd>
     </dl>
     """
     if str(id_role) != "0":
         extra += """
     <dl>
      <dt><a href="deleteuserrole?id_role=%s">Remove users</a></dt>
      <dd>remove users from role %s.</dd>
      <dt><a href="showroleusers?id_role=%s">Connected users</a></dt>
      <dd>show all users connected to role %s.</dd>
     </dl>
     <dl>
      <dt><a href="addauthorization?id_role=%s">Add authorization</a></dt>
      <dd>start adding new authorizations to role %s.</dd>
     </dl>
     """ % (id_role, name_role, id_role, name_role, id_role, name_role)
 
     return index(req=req,
                  title=title,
                  subtitle=subtitle,
                  body=[output, extra],
                  adminarea=3)
 
 
 def perform_addroleuser(req, email_user_pattern='', id_user='0', id_role='0', confirm=0):
     """delete connection between role and user.
 
     id_role - id of role to disconnect
 
     id_user - id of user to disconnect. """
     
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     email_out = acca.acc_getUserEmail(id_user=id_user)
     name_role = acca.acc_getRoleName(id_role=id_role)
     # used to sort roles, and also to determine right side links
     con_roles = []
     not_roles = []
 
     title = 'Connect user to roles'
     subtitle = 'step 1 - search for users'
 
     # clean email search string
     email_user_pattern = cleanstring_email(email_user_pattern)
         
     text  = ' <span class="adminlabel">1. search for user </span>\n'
     text += ' <input class="admin_wvar" type="text" name="email_user_pattern" value="%s" />\n' % (email_user_pattern, )
 
     output = createhiddenform(action='addroleuser',
                                text=text,
                                button='search for users',
                                id_role=id_role)
     
     if email_user_pattern:
         subtitle = 'step 2 - select user'
 
         users1 = run_sql("""SELECT id, email FROM user WHERE email RLIKE '%s' ORDER BY email """ % (email_user_pattern, ))
         users = []
         for (id, email) in users1: users.append([id, email, ''])
 
         # no users 
         if not users:
             output += '<p>no qualified users, try new search.</p>'
         # too many users
         elif len(users) > MAXSELECTUSERS:
             output += '<p><strong>%s hits</strong>, too many qualified users, specify more narrow search. (limit %s)</p>' % (len(users), MAXSELECTUSERS)
         # ok number of users
         else:
             output += createuserselect(id_user=id_user,
                                        action='addroleuser',
                                        step=2,
                                        users=users,
                                        button='select user',
                                        email_user_pattern=email_user_pattern)
 
             if int(id_user):
                 subtitle = 'step 3 - select role'
 
                 # roles the user is connected to
                 role_ids = acca.acc_getUserRoles(id_user=id_user)
                 # all the roles, lists are sorted on the background of these...
                 all_roles = acca.acc_getAllRoles()
 
                 # sort the roles in connected and not connected roles
                 for (id, name, description) in all_roles:
                     if (id, ) in role_ids: con_roles.append([-id, name, description])
                     else: not_roles.append([id, name, description])
 
                 # create roleselect
                 output += createroleselect(id_role=id_role,
                                            action='addroleuser',
                                            step=3,
                                            roles=not_roles,
                                            extraroles=con_roles,
                                            extrastamp='(connected)', 
                                            button='add this role',
                                            email_user_pattern=email_user_pattern,
                                            id_user=id_user)
 
                 if int(id_role) < 0:
                     name_role = acca.acc_getRoleName(id_role=-int(id_role))
                     output += '<p>role %s already connected to the user, try another one...<p>' % (name_role, )
                 elif int(id_role):
                     subtitle = 'step 4 - confirm to add role to user'
 
                     output += createhiddenform(action='addroleuser',
                                                text='add role <strong>%s</strong> to user <strong>%s</strong>?' % (name_role, email_out),
                                                email_user_pattern=email_user_pattern,
                                                id_user=id_user,
                                                id_role=id_role,
                                                confirm=1)
 
                     if confirm:
                         # add role
                         result = acca.acc_addUserRole(id_user=id_user, id_role=id_role)
 
                         if result and result[2]:
                             subtitle = 'step 5 - confirm role added'
                             output  += '<p>confirm: role <strong>%s</strong> added to user <strong>%s</strong>.</p>' % (name_role, email_out)
                         else:
                             subtitle = 'step 5 - role could not be added'
                             output += '<p>sorry, but role could not be added</p>'
 
     extra = """
     <dl>
      <dt><a href="addrole">Create new role</a></dt>
      <dd>go here to add a new role.</dd>
     """
     if int(id_user) and con_roles:
         extra += """
     </dl>
     <dl>
      <dt><a href="deleteuserrole?id_user=%s&amp;reverse=1">Remove roles</a></dt>
      <dd>disconnect roles from user %s.</dd>
     </dl>
     """ % (id_user, email_out)
         if int(id_role):
             if int(id_role) < 0: id_role = -int(id_role)
             extra += """
             <dl>
              <dt><a href="deleteuserrole?id_role=%s">Remove users</a></dt>
              <dd>disconnect users from role %s.<dd>
             </dl>
             """ % (id_role, name_role)
     
     return index(req=req,
                  title=title,
                  subtitle=subtitle,
                  body=[output, extra],
                  adminarea=5)
 
 
 def perform_deleteuserrole(req, id_role='0', id_user='0', reverse=0, confirm=0):
     """delete connection between role and user.
 
     id_role - id of role to disconnect
 
     id_user - id of user to disconnect. """
     
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     title = 'Remove user from role'
     email_user = acca.acc_getUserEmail(id_user=id_user)
     name_role = acca.acc_getRoleName(id_role=id_role)
 
     output = ''
 
     if reverse in [0, '0']:
         adminarea = 3
         subtitle = 'step 1 - select the role'
         output += createroleselect(id_role=id_role,
                                    action="deleteuserrole",
                                    step=1,
                                    roles=acca.acc_getAllRoles())
             
         if id_role != "0":
             subtitle = 'step 2 - select the user'
             output += createuserselect(id_user=id_user,
                                        action="deleteuserrole",
                                        step=2,
                                        users=acca.acc_getRoleUsers(id_role=id_role),
                                        id_role=id_role)
 
     else:
         adminarea = 5
         # show only if user is connected to a role, get users connected to roles
         users = run_sql("""SELECT DISTINCT(u.id), u.email, u.note
         FROM user u LEFT JOIN user_accROLE ur
         ON u.id = ur.id_user
         WHERE ur.id_accROLE != 'NULL' AND u.email != ''
         ORDER BY u.email """)
 
         has_roles = 1
         
         # check if the user is connected to any roles
         for (id, email, note) in users:
             if str(id) == str(id_user): break
         # user not connected to a role
         else:
             subtitle = 'step 1 - user not connected'
             output += '<p>no need to remove roles from user <strong>%s</strong>,<br>user is not connected to any roles.</p>' % (email_user, )
             has_roles, id_user = 0, '0' # stop the rest of the output below...
             
         # user connected to roles
         if has_roles:
             output += createuserselect(id_user=id_user,
                                        action="deleteuserrole",
                                        step=1,
                                        users=users,
                                        reverse=reverse)
         
             if id_user != "0":
                 subtitle = 'step 2 - select the role'
     
                 role_ids = acca.acc_getUserRoles(id_user=id_user)
                 all_roles = acca.acc_getAllRoles()
                 roles = []
                 for (id, name, desc) in all_roles:
                     if (id, ) in role_ids: roles.append([id, name, desc])
                 
                 output += createroleselect(id_role=id_role,
                                            action="deleteuserrole",
                                            step=2,
                                            roles=roles,
                                            id_user=id_user,
                                            reverse=reverse)
     
     if id_role != '0' and id_user != '0':
         subtitle = 'step 3 - confirm delete of user'
         output += createhiddenform(action="deleteuserrole",
                                    text='delete user %s from %s?' % (headerstrong(user=id_user), headerstrong(role=id_role)),
                                    id_role=id_role,
                                    id_user=id_user,
                                    reverse=reverse,
                                    confirm=1)
 
         if confirm:
             res = acca.acc_deleteUserRole(id_user=id_user, id_role=id_role)
             if res:
                 subtitle = 'step 4 - confirm delete of user'
                 output += '<p>confirm: deleted user <strong>%s</strong> from role <strong>%s</strong>.</p>' % (email_user, name_role)
             else:
                 subtitle = 'step 4 - user could not be deleted'
                 output += 'sorry, but user could not be deleted<br>user is probably already deleted.'
 
     extra = ''
     if str(id_role) != "0":
         extra += """
         <dl>
          <dt><a href="adduserrole?id_role=%s">Connect user</a></dt>
          <dd>add users to role %s.</dd>
         """ % (id_role, name_role)
         if int(reverse):
             extra += """
              <dt><a href="deleteuserrole?id_role=%s">Remove user</a></dt>
              <dd>remove users from role %s.</dd> """ % (id_role, name_role)
         extra += '</dl>'
     if str(id_user) != "0":
         extra += """
         <dl>
          <dt><a href="addroleuser?email_user_pattern=%s&amp;id_user=%s">Connect role</a></dt>
          <dd>add roles to user %s.</dd>
         """ % (email_user, id_user, email_user)
         if not int(reverse):
             extra += """
              <dt><a href="deleteuserrole?id_user=%s&amp;email_user_pattern=%s&amp;reverse=1">Remove role</a></dt>
              <dd>remove roles from user %s.</dd> """ % (id_user, email_user, email_user)
         extra += '</dl>'
 
     if extra: body = [output, extra]
     else: body = [output]
 
     return index(req=req,
                  title=title,
                  subtitle=subtitle,
                  body=body,
                  adminarea=adminarea)
 
 
 def perform_showuserdetails(req, id_user=0):
     """show the details of a user. """
     
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     if id_user not in [0, '0']:
         output = userdetails(id_user=id_user)
         email_user = acca.acc_getUserEmail(id_user=id_user)
 
         extra = """
         <dl>
          <dt><a href="addroleuser?id_user=%s&amp;email_user_pattern=%s">Connect role</a></dt>
          <dd>connect a role to user %s.</dd>
          <dt><a href="deleteuserrole?id_user=%s&amp;reverse=1">Remove role</a></dt>
          <dd>remove a role from user %s.</dd>
         </dl>
         """ % (id_user, email_user, email_user, id_user, email_user)
 
         body = [output, extra]
     else:
         body = ['<p>no details to show</p>']
 
     return index(req=req,
                  title='Show User Details',
                  subtitle='show user details',
                  body=body,
                  adminarea=5)
 
 
 def userdetails(id_user=0):
     """create the string to show details about a user. """
 
     # find necessary details
     email_user = acca.acc_getUserEmail(id_user=id_user)
 
     userroles = acca.acc_getUserRoles(id_user=id_user)
     conn_roles = []
 
     # find connected roles
     for (id, name, desc) in acca.acc_getAllRoles():
         if (id, ) in userroles:
             conn_roles.append([id, name, desc])
             conn_roles[-1].append('<a href="showroledetails?id_role=%s">show details</a>' % (id, ))
 
     if conn_roles: 
         # print details
         details  = '<p>roles connected to user <strong>%s</strong></p>' % (email_user, )
         details += tupletotable(header=['id', 'name', 'description', ''], tuple=conn_roles)
     else:
         details  = '<p>no roles connected to user <strong>%s</strong>.</p>' % (email_user, )
 
     return details
 
 def perform_addauthorization(req, id_role="0", id_action="0", optional=0, reverse="0", confirm=0, **keywords):
     """ form to add new connection between user and role:
 
       id_role - role to connect 
 
     id_action - action to connect
 
       reverse - role or action first? """
     
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     # values that might get used
     name_role = acca.acc_getRoleName(id_role=id_role) or id_role
     name_action = acca.acc_getActionName(id_action=id_action) or id_action
 
     optional = optional == 'on' and 1 or int(optional)
     
     extra = """
     <dl>
      <dt><a href="addrole">Create new role</a></dt>
      <dd>go here to add a new role.</dd>
      <dt><a href="addaction">Create new action</a></dt>
      <dd>go here to add a new action.</dd>
     </dl>
     """
 
     # create the page according to which step the user is on
     # role -> action -> arguments
     if reverse in ["0", 0]:
         adminarea = 3
         subtitle = 'step 1 - select role'
         output = createroleselect(id_role=id_role,
                                   action="addauthorization",
                                   step=1,
                                   roles=acca.acc_getAllRoles(),
                                   reverse=reverse)
 
         if str(id_role) != "0":
             subtitle = 'step 2 - select action'
             rolacts = acca.acc_getRoleActions(id_role)
             allhelp = acca.acc_getAllActions()
             allacts = []
             for r in allhelp:
                 if r not in rolacts: allacts.append(r)
             output += createactionselect(id_action=id_action,
                                          action="addauthorization",
                                          step=2,
                                          actions=rolacts,
                                          extraactions=allacts,
                                          id_role=id_role,
                                          reverse=reverse)
             
     # action -> role -> arguments
     else:
         adminarea = 4
         subtitle = 'step 1 - select action'
         output = createactionselect(id_action=id_action,
                                     action="addauthorization",
                                     step=1,
                                     actions=acca.acc_getAllActions(),
                                     reverse=reverse)
         if str(id_action) != "0":
             subtitle = 'step 2 - select role'
             actroles = acca.acc_getActionRoles(id_action)
             allhelp = acca.acc_getAllRoles()
             allroles = []
             for r in allhelp:
                 if r not in actroles: allroles.append(r)
             output += createroleselect(id_role=id_role,
                                        action="addauthorization",
                                        step=2,
                                        roles=actroles,
                                        extraroles=allroles,
                                        id_action=id_action,
                                        reverse=reverse)
 
     # ready for step 3 no matter which direction we took to get here
     if id_action != "0" and id_role != "0":
         # links to adding authorizations in the other direction
         if str(reverse) == "0":
             extra += """
             <dl>
              <dt><a href="addauthorization?id_action=%s&amp;reverse=1">Add authorization</a></dt>
              <dd>add authorizations to action %s.</dd>
             </dl> """ % (id_action, name_action)
         else:
             extra += """
             <dl>
              <dt><a href="addauthorization?id_role=%s">Add authorization</a></dt>
              <dd>add authorizations to role %s.</dd>
             </dl> """ % (id_role, name_role)
 
         subtitle = 'step 3 - enter values for the keywords\n'
 
         output += """
         <form action="addauthorization" method="POST">
          <input type="hidden" name="id_role" value="%s">
          <input type="hidden" name="id_action" value="%s">
          <input type="hidden" name="reverse" value="%s">
         """  % (id_role, id_action, reverse)
 
         # the actions argument keywords
         res_keys = acca.acc_getActionKeywords(id_action=id_action)
         
         # res used to display existing authorizations
         # res used to determine if showing "create connection without arguments"
         res_auths = acca.acc_findPossibleActions(id_role, id_action)
         
         if not res_keys:
             # action without arguments
             if not res_auths:
                 output += """
                  <input type="hidden" name="confirm" value="1">
                   create connection between %s?
                  <input class="adminbutton" type="submit" value="confirm">
                 </form>
                 """ % (headerstrong(role=name_role, action=name_action, query=0), )
             else:
                 output += '<p><strong>connection without arguments is already created.</strong></p>'
                    
         else:
             # action with arguments
             optionalargs = acca.acc_getActionIsOptional(id_action=id_action)
 
             output += '<span class="adminlabel">3. authorized arguments</span><br>'
             if optionalargs:
                 # optional arguments
                 output += """
                 <p>
                  <input type="radio" name="optional" value="1" %s />
                  connect %s to %s for any arguments <br>
                  <input type="radio" name="optional" value="0" %s />
                  connect %s to %s for only these argument cases:
                 </p>
                 """ % (optional and 'checked="checked"' or '', name_role, name_action, not optional and 'checked="checked"' or '', name_role, name_action)
 
             # list the arguments
             allkeys = 1
             for key in res_keys:
                 output += '<span class="adminlabel" style="margin-left: 30px;">%s </span>\n <input class="admin_wvar" type="text" name="%s"' % (key, key)
                 try:
                     val = keywords[key] = cleanstring_argumentvalue(keywords[key])
                     if val: output += 'value="%s" ' % (val, )
                     else: allkeys = 0
                 except KeyError: allkeys = 0
                 output += ' /> <br>\n'
             output = output[:-5] + ' <input class="adminbutton" type="submit" value="create authorization -->" />\n'
             output += '</form>\n'
 
             # ask for confirmation
             if str(allkeys) != "0" or optional:
                 keys = keywords.keys()
                 keys.reverse()
                 subtitle = 'step 4 - confirm add of authorization\n'
 
                 text = """
                 create connection between <br>
                 %s <br>
                 """ % (headerstrong(role=name_role, action=name_action, query=0), )
 
                 if optional:
                     text += 'withouth arguments'
                     keywords = {}
                 else:
                     for key in keys:
                         text += '<strong>%s</strong>: %s \n' % (key, keywords[key])
                 
                 output += createhiddenform(action="addauthorization",
                                            text=text,
                                            id_role=id_role,
                                            id_action=id_action,
                                            reverse=reverse,
                                            confirm=1,
                                            optional=optional,
                                            **keywords)
 
         # show existing authorizations, found authorizations further up in the code...
         # res_auths = acca.acc_findPossibleActions(id_role, id_action)
         output += '<p>existing authorizations:</p>'
         if res_auths:
             output += tupletotable(header=res_auths[0], tuple=res_auths[1:])
             # shortcut to modifying authorizations
             extra += """
             <dl>
              <dt><a href="modifyauthorizations?id_role=%s&amp;id_action=%s&amp;reverse=%s">Modify authorizations</a></dt>
              <dd>modify the existing authorizations.</dd>
             </dl> """ % (id_role, id_action, reverse)
 
         else:   output += '<p>no details to show</p>'
 
 
     # user confirmed to add entries
     if confirm: 
         subtitle = 'step 5 - confirm authorization added'
         res1 = acca.acc_addAuthorization(name_role=name_role,
                                          name_action=name_action,
                                          optional=optional,
                                          **keywords)
 
         if res1:
             res2 = acca.acc_findPossibleActions(id_role, id_action)
             arg = res1[0][3] # the arglistid
             new = [res2[0]]
             for row in res2[1:]:
                 if int(row[0]) == int(arg): new.append(row)
     
             newauths = tupletotable(header=new[0], tuple=new[1:])
             newentries = tupletotable(header=['role id', 'action id', 'argument id', '#'], tuple=res1)
 
             st = 'style="vertical-align: top"'
             output += """
             <p>new authorization and entries:</p>
             <table><tr>
              <td class="admintd" %s>%s</td>
              <td class="admintd" %s>%s</td>
             </tr></table> """ % (st, newauths, st, newentries)
 
         else: output += '<p>sorry, authorization could not be added,<br>it probably already exists</p>'
 
     # trying to put extra link on the right side
     try: body = [output, extra]
     except NameError: body = [output]
 
     return index(req=req,
                  title = 'Create entry for new authorization',
                  subtitle=subtitle,
                  body=body,
                  adminarea=adminarea)
 
 
 def perform_deleteroleaction(req, id_role="0", id_action="0", reverse=0, confirm=0):
     """delete all connections between a role and an action.
 
       id_role - id of the role
 
     id_action - id of the action
 
       reverse - 0: ask for role first
                 1: ask for action first"""
     
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     title = 'Remove action from role '
     
     if reverse in ["0", 0]:
         # select role -> action
         adminarea = 3
         subtitle = 'step 1 - select a role'
         output  = createroleselect(id_role=id_role,
                                    action="deleteroleaction",
                                    step=1,
                                    roles=acca.acc_getAllRoles(),
                                    reverse=reverse)
         
         if id_role != "0":
             rolacts = acca.acc_getRoleActions(id_role=id_role)
             subtitle = 'step 2 - select the action'
             output += createactionselect(id_action=id_action,
                                          action="deleteroleaction",
                                          step=2,
                                          actions=rolacts,
                                          reverse=reverse,
                                          id_role=id_role,
                                          button="remove connection and all authorizations")
     else:
         # select action -> role
         adminarea = 4
         subtitle = 'step 1 - select an action'
         output = createactionselect(id_action=id_action,
                                     action="deleteroleaction",
                                     step=1,
                                     actions=acca.acc_getAllActions(),
                                     reverse=reverse)
         
         if id_action != "0":
             actroles = acca.acc_getActionRoles(id_action=id_action)
             subtitle = 'step 2 - select the role'
             output += createroleselect(id_role=id_role,
                                        action="deleteroleaction",
                                        step=2,
                                        roles=actroles,
                                        button="remove connection and all authorizations", 
                                        id_action=id_action,
                                        reverse=reverse)
 
     if id_action != "0" and id_role != "0":
         subtitle = 'step 3 - confirm to remove authorizations'
         # ask for confirmation
 
         res = acca.acc_findPossibleActions(id_role, id_action)
 
         if res:
             output += '<p>authorizations that will be deleted:</p>'
             output += tupletotable(header=res[0], tuple=res[1:])
 
             output += createhiddenform(action="deleteroleaction",
                                        text='remove %s from %s' % (headerstrong(action=id_action), headerstrong(role=id_role)),
                                        confirm=1,
                                        id_role=id_role,
                                        id_action=id_action,
                                        reverse=reverse)
         else:
             output += 'no authorizations'
 
         # confirmation is given
         if confirm: 
             subtitle = 'step 4 - confirm authorizations removed '
             res = acca.acc_deleteRoleAction(id_role=id_role, id_action=id_action)
             if res:
                 output += '<p>confirm: removed %s from %s<br>' % (headerstrong(action=id_action), headerstrong(role=id_role))
                 output += '<strong>%s</strong> entries were removed.</p>' % (res, )
             else:
                 output += '<p>sorry, no entries could be removed.</p>'
     
     return index(req=req,
                  title=title,
                  subtitle=subtitle,
                  body=[output],
                  adminarea=adminarea)
         
 
 def perform_modifyauthorizations(req, id_role="0", id_action="0", reverse=0, confirm=0, errortext='', sel='', authids=[]):
     """given ids of a role and an action, show all possible action combinations
     with checkboxes and allow user to access other functions.    
 
       id_role - id of the role
 
     id_action - id of the action
 
       reverse - 0: ask for role first
                 1: ask for action first
 
           sel - which button and modification that is selected
     
     errortext - text to print when no connection exist between role and action
     
       authids - ids of checked checkboxes """
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     name_role = acca.acc_getRoleName(id_role)
     name_action = acca.acc_getActionName(id_action)
 
     output = ''
     
     try: id_role, id_action, reverse = int(id_role), int(id_action), int(reverse)
     except ValueError: pass
 
     extra = """
     <dl>
      <dt><a href="addrole">Create new role</a></dt>
      <dd>go here to add a new role.</dd>
      <dt><a href="addaction">Create new action</a></dt>
      <dd>go here to add a new action.</dd>
     </dl>
     """
     if id_role or id_action:
         extra += '\n<dl>\n'
         if id_role and id_action:
             extra += """
              <dt><a href="addauthorization?id_role=%s&amp;id_action=%s&amp;reverse=%s">Add authorizations</a></dt>
              <dd>add an authorization to the existing ones.</dd> """ % (id_role, id_action, reverse)
         if id_role:
             extra += """
              <dt><a href="addauthorization?id_role=%s">Add authorizations</a></dt>
              <dd>add to role %s.</dd> """ % (id_role, name_role)
         if id_action:
             extra += """
              <dt><a href="addauthorization?id_action=%s&amp;reverse=1">Add authorizations</a></dt>
              <dd>add to action %s.</dd> """ % (id_action, name_action)
         extra += '\n</dl>\n'
 
         
     if not reverse:
         # role -> action
         adminarea = 3
         subtitle = 'step 1 - select the role'
         output += createroleselect(id_role=str(id_role),
                                    action="modifyauthorizations",
                                    step=1,
                                    roles=acca.acc_getAllRoles(),
                                    reverse=reverse)
 
         if id_role:
             rolacts = acca.acc_getRoleActions(id_role=id_role)
             subtitle = 'step 2 - select the action'
             output += createactionselect(id_action=str(id_action),
                                          action="modifyauthorizations",
                                          step=2,
                                          actions=rolacts,
                                          id_role=id_role,
                                          reverse=reverse)
     else:
         adminarea = 4
         # action -> role
         subtitle = 'step 1 - select the action'
         output += createactionselect(id_action=str(id_action),
                                      action="modifyauthorizations",
                                      step=1,
                                      actions=acca.acc_getAllActions(),
                                      reverse=reverse)
         if id_action:
             actroles = acca.acc_getActionRoles(id_action=id_action)
             subtitle = 'step 2 - select the role'
             output += createroleselect(id_role=str(id_role),
                                        action="modifyauthorizations",
                                        step=2,
                                        roles=actroles,
                                        id_action=id_action,
                                        reverse=reverse)
 
     if errortext: output += '<p>%s</p>' % (errortext, )
 
     if id_role and id_action:
         # adding to main area
         if type(authids) is not list: authids = [authids]
         subtitle = 'step 3 - select groups and modification'
 
         # get info 
         res = acca.acc_findPossibleActions(id_role, id_action)
 
         # clean the authids
         hiddenids = []
         if sel in ['delete selected']:
             hiddenids = authids[:]
         elif sel in ['split groups', 'merge groups']:
             for authid in authids:
                 arghlp = res[int(authid)][0]
                 if authid not in hiddenids and arghlp not in [-1, '-1', 0, '0']: hiddenids.append(authid)
             authids = hiddenids[:]
         
         if confirm:
             # do selected modification and output with new authorizations
             if sel == 'split groups':
                 res = splitgroups(id_role, id_action, authids)
             elif sel == 'merge groups':
                 res = mergegroups(id_role, id_action, authids)
             elif sel == 'delete selected':
                 res = deleteselected(id_role, id_action, authids)
             authids = []
             res = acca.acc_findPossibleActions(id_role, id_action)
             output += 'authorizations after <strong>%s</strong>.<br>\n' % (sel, )
 
         elif sel and authids:
             output += 'confirm choice of authorizations and modification.<br>\n'
         else:
             output += 'select authorizations and perform modification.<br>\n'
             
         if not res:
             errortext='all connections deleted, try different '
             if reverse in ["0", 0]:
                 return perform_modifyauthorizations(req=req, id_role=id_role, errortext=errortext + 'action.')
             else:
                 return perform_modifyauthorizations(req=req, id_action=id_action, reverse=reverse, errortext=errortext + 'role.')
         
         # display 
         output += modifyauthorizationsmenu(id_role, id_action, header=res[0], tuple=res[1:], checked=authids, reverse=reverse)
         
         if sel and authids:
             subtitle = 'step 4 - confirm to perform modification'
             # form with hidden authids
             output += '<form action="%s" method="POST">\n' % ('modifyauthorizations', )
 
             for hiddenid in hiddenids: 
                 output += '<input type="hidden" name="authids" value="%s" />\n' % (hiddenid, )
 
             # choose what to do
             if sel == 'split groups':
                 output += '<p>split groups containing:</p>'
             elif sel == 'merge groups':               
                 output += '<p>merge groups containing:</p>'
             elif sel == 'delete selected':            
                 output += '<p>delete selected entries:</p>'
 
             extracolumn  = '<input type="checkbox" name="confirm" value="1" />\n'
             extracolumn += '<input class="adminbutton" type="submit" value="confirm" />\n'
 
             # show the entries here...
             output += tupletotable_onlyselected(header=res[0],
                                                 tuple=res[1:],
                                                 selected=hiddenids,
                                                 extracolumn=extracolumn)
             
             output += '<input type="hidden" name="id_role" value="%s" />\n' % (id_role, )
             output += '<input type="hidden" name="id_action" value="%s" />\n' % (id_action, )
             output += '<input type="hidden" name="sel" value="%s" />\n' % (sel, )
             output += '<input type="hidden" name="reverse" value="%s" />\n' % (reverse, )
             output += '</form>'
 
         # tried to perform modification without something selected
         elif sel and not authids and not confirm: 
             output += '<p>no valid groups selected</p>'
 
     # trying to put extra link on the right side
     try: body = [output, extra]
     except NameError: body = [output]
 
     # Display the page
     return index(req=req,
                  title='Modify Authorizations',
                  subtitle=subtitle,
                  body=body,
                  adminarea=adminarea)
 
 
 def modifyauthorizationsmenu(id_role, id_action, tuple=[], header=[], checked=[], reverse=0):
     """create table with header and checkboxes, used for multiple choice.
     makes use of tupletotable to add the actual table
 
       id_role - selected role, hidden value in the form
 
     id_action - selected action, hidden value in the form
 
         tuple - all rows to be put in the table (with checkboxes)
 
        header - column headers, empty strings added at start and end
 
       checked - ids of rows to be checked """
 
     if not tuple:
         return 'no authorisations...'
 
     argnum = len(acca.acc_getActionKeywords(id_action=id_action))
     
     tuple2 = []
     for t in tuple: tuple2.append(t[:])
     
     tuple2 = addcheckboxes(datalist=tuple2, name='authids', startindex=1, checked=checked)
 
     hidden  = '<input type="hidden" name="id_role" value="%s" /> \n' % (id_role, )
     hidden += '<input type="hidden" name="id_action" value="%s" /> \n' % (id_action, )
     hidden += '<input type="hidden" name="reverse" value="%s" /> \n' % (reverse, )
 
     
     button = '<input type="submit" class="adminbutton" value="delete selected" name="sel" />\n'
     if argnum > 1: 
         button += '<input type="submit" class="adminbutton" value="split groups" name="sel" />\n'
         button += '<input type="submit" class="adminbutton" value="merge groups" name="sel" />\n'
     
     hdrstr = ''
     for h in [''] + header + ['']: hdrstr += '  <th class="adminheader">%s</th>\n' % (h, )
     if hdrstr: hdrstr = ' <tr>\n%s\n </tr>\n' % (hdrstr, )
     
     output  = '<form action="modifyauthorizations" method="POST">\n'
     output += '<table class="admin_wvar_nomargin"> \n'
     output += hdrstr
     output += '<tr><td>%s</td></tr>\n' % (hidden, )
 
     align = ['admintdleft'] * len(tuple2[0])
     try: align[1] = 'admintdright'
     except IndexError: pass
 
     output += '<tr>'
     for i in range(len(tuple2[0])): output += '<td class="%s">%s</td>\n' % (align[i], tuple2[0][i])
     output += '<td rowspan="%s" style="vertical-align: bottom">\n%s\n</td>\n' % (len(tuple2), button)
     
     output += '</tr>\n'
     for row in tuple2[1:]:
         output += ' <tr>\n'
         for i in range(len(row)): output += '<td class="%s">%s</td>\n' % (align[i], row[i])
         output += ' </tr>\n'
 
     output += '</table>\n</form>\n'
 
     return output
 
 
 def splitgroups(id_role=0, id_action=0, authids=[]):
     """get all the old ones, gather up the arglistids find a list of
     arglistidgroups to be split, unique get all actions in groups outside
     of the old ones, (old arglistid is allowed).
     
     show them like in showselect. """
 
     if not id_role or not id_action or not authids:
         return 0
     
     # find all the actions
     datalist = acca.acc_findPossibleActions(id_role, id_action)
 
     if type(authids) is str: authids = [authids]
     for i in range(len(authids)): authids[i] = int(authids[i])
     
     # argumentlistids of groups to be split
     splitgrps = []
     for authid in authids:
         hlp = datalist[authid][0]
         if hlp not in splitgrps and authid in range(1,len(datalist)):
             splitgrps.append(hlp)
 
     # split groups and return success or failure
     result = 1
     for splitgroup in splitgrps:
         result = 1 and acca.acc_splitArgumentGroup(id_role, id_action, splitgroup)
 
     return result
 
 
 def mergegroups(id_role=0, id_action=0, authids=[]):
     """get all the old ones, gather up the argauthids find a list
     of arglistidgroups to be split, unique get all actions in groups
     outside of the old ones, (old arglistid is allowed).
 
     show them like in showselect."""
 
     if not id_role or not id_action or not authids:
         return 0
     
     datalist = acca.acc_findPossibleActions(id_role, id_action)
 
     if type(authids) is str: authids = [authids]
     for i in range(len(authids)): authids[i] = int(authids[i])
     
     # argumentlistids of groups to be merged
     mergegroups = []
     for authid in authids:
         hlp = datalist[authid][0]
         if hlp not in mergegroups and authid in range(1, len(datalist)):
             mergegroups.append(hlp)
 
     # merge groups and return success or failure
     if acca.acc_mergeArgumentGroups(id_role, id_action, mergegroups):
         return 1
     else:
         return 0
 
 
 
 def deleteselected(id_role=0, id_action=0,  authids=[]):
     """delete checked authorizations/possible actions, ids in authids.
 
     id_role - role to delete from
 
     id_action - action to delete from
 
     authids - listids for which possible actions to delete."""
     
     if not id_role or not id_action or not authids:
         return 0
 
     if type(authids) in [str, int]: authids = [authids]
     for i in range(len(authids)): authids[i] = int(authids[i])
     
     result = acca.acc_deletePossibleActions(id_role=id_role,
                                             id_action=id_action,
                                             authids=authids)
 
     return result
 
 def headeritalic(**ids):
     """transform keyword=value pairs to string with value in italics.
 
     **ids - a dictionary of pairs to create string from """
     
     output = ''
     value = ''
     table = ''
 
     for key in ids.keys():
         if key in ['User', 'user']:
             value, table = 'email', 'user'
         elif key in ['Role', 'role']:
             value, table = 'name', 'accROLE'
         elif key in ['Action', 'action']:
             value, table = 'name', 'accACTION'
         else:
             if output: output += ' and '
             output += ' %s <i>%s</i>' % (key, ids[key])
             continue
                 
         res = run_sql("""SELECT %s FROM %s WHERE id = %s""" % (value, table, ids[key]))
         
         if res:
             if output: output += ' and '
             output += ' %s <i>%s</i>' % (key, res[0][0])
 
     return output
 
 
 def headerstrong(query=1, **ids):
     """transform keyword=value pairs to string with value in strong text.
 
     **ids - a dictionary of pairs to create string from
     
     query - 1 -> try to find names to ids of role, user and action.
             0 -> do not try to find names, use the value passed on """
 
     output = ''
     value = ''
     table = ''
 
     for key in ids.keys():
         if key in ['User', 'user']:
             value, table = 'email', 'user'
         elif key in ['Role', 'role']:
             value, table = 'name', 'accROLE'
         elif key in ['Action', 'action']:
             value, table = 'name', 'accACTION'
         else:
             if output: output += ' and '
             output += ' %s <strong>%s</strong>' % (key, ids[key])
             continue
 
         if query:
             res = run_sql("""SELECT %s FROM %s WHERE id = %s""" % (value, table, ids[key]))
             if res:
                 if output: output += ' and '
                 output += ' %s <strong>%s</strong>' % (key, res[0][0])
         else:
             if output: output += ' and '
             output += ' %s <strong>%s</strong>' % (key, ids[key])
 
     return output
 
 
 def startpage():
     """create the menu for the startpage"""
     
     body = """
     <table class="admin_wvar" width="100%" summary="">
      <thead>
       <tr>
        <th class="adminheaderleft">selection for WebAccess Admin</th>
       </tr>
      </thead>
      <tbody>
       <tr>
        <td>
         <dl>
          <dt><a href="webaccessadmin.py/rolearea">Role Area</a>
          <dd>main area to configure administration rights and authorization rules.
          <dt><a href="webaccessadmin.py/actionarea">Action Area</a>
          <dd>configure administration rights with the actions as starting point.
          <dt><a href="webaccessadmin.py/userarea">User Area</a>
          <dd>configure administration rights with the users as starting point.
          <dt><a href="webaccessadmin.py/resetarea">Reset Area</a>
          <dd>reset roles, actions and authorizations.
         </dl>
        </td>
       </tr>
      </tbody>
     </table>""" 
 
     return body
 
 def rankarea():
     return "Rankmethod area"
 
 def perform_simpleauthorization(req, id_role=0, id_action=0):
     """show a page with simple overview of authorizations between a
     connected role and action. """
     
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     res = acca.acc_findPossibleActions(id_role, id_action)
     if res:
         extra = createhiddenform(action='modifyauthorizations',
                                  button='modify authorizations',
                                  id_role=id_role,
                                  id_action=id_action)
         
         output  = '<p>authorizations for %s:</p>' % (headerstrong(action=id_action, role=id_role), )
         output += tupletotable(header=res[0], tuple=res[1:], extracolumn=extra)
     else:
         output = 'no details to show'
 
     return index(req=req,
                  title='Simple authorization details',
                  subtitle='simple authorization details', 
                  body=[output],
                  adminarea=3)
 
 
 def perform_showroleusers(req, id_role=0):
     """show a page with simple overview of a role and connected users. """
 
     (auth_code, auth_message) = is_adminuser(req)
     if auth_code != 0: return mustloginpage(req, auth_message)
 
     res = acca.acc_getRoleUsers(id_role=id_role)
     name_role = acca.acc_getRoleName(id_role=id_role)
     
     if res:
         users = []
         for (id, name, dontcare) in res: users.append([id, name, '<a href="showuserdetails?id_user=%s">show user details</a>'
                                                        % (id, )])
         output  = '<p>users connected to %s:</p>' % (headerstrong(role=id_role), )
         output += tupletotable(header=['id', 'name', ''], tuple=users)
     else:
         output = 'no users connected to role <strong>%s</strong>' % (name_role, )
 
     extra = """
     <dl>
      <dt><a href="adduserrole?id_role=%s">Connect user</a></dt>
      <dd>connect users to the role.</dd>
     </dl>
     """ % (id_role, )
 
     return index(req=req,
                  title='Users connected to role %s' % (name_role, ),
                  subtitle='simple details', 
                  body=[output, extra],
                  adminarea=3)
                
 
 
 
 
 def createselect(id_input="0", label="", step=0, name="",
                  action="", list=[], extralist=[], extrastamp='',
                  button="", **hidden):
     """create form with select and hidden values
 
             id - the one to choose as selected if exists
  
          label - label shown to the left of the select
  
           name - the name of the select on which to reference it
  
           list - primary list to select from
  
      extralist - list of options to be put in paranthesis
  
     extrastamp - stamp extralist entries with this if not ''
                  usually paranthesis around the entry
  
         button - the value/text to be put on the button
  
       **hidden - name=value pairs to be put as hidden in the form. """
 
     step = step and '%s. ' % step or ''
     
     output  = '<form action="%s" method="POST">\n' % (action, )
     output += ' <span class="adminlabel">%s</span>\n' % (step + label, )
     output += ' <select name="%s" class="admin_w200">\n' % (name, )
     if not list and not extralist:
         output += '  <option value="0">*** no %ss to select from ***</option>\n' % (label.split()[-1], )
     else:
         output += '  <option value="0">*** %s ***</option>\n' % (label, )
         for (id, email, dontcare) in list:
             if str(id) == id_input: output += '  <option value="%s" selected="selected">%s</option>\n' % (id, email)
             else: output += '  <option value="%s">%s</option>\n' % (id, email)
         for (id, email, dontcare) in extralist:
             if str(id) == id_input:
                 if not extrastamp: output += '  <option value="%s" selected="selected">(%s)</option>\n' % (id, email)
                 else: output += '  <option value="%s">%s %s</option>\n' % (id, email, extrastamp)
             elif not extrastamp: output += '  <option value="%s">(%s)</option>\n' % (id, email)
             else: output += '  <option value="%s">%s %s</option>\n' % (id, email, extrastamp)
             
     output += ' </select>\n'
     for key in hidden.keys():
         output += ' <input type="hidden" name="%s" value="%s" />\n' % (key, hidden[key])
     output += ' <input class="adminbutton" type="submit" value="%s" />\n' % (button, )
     output += '</form>\n'
 
     return output
 
 
 def createactionselect(id_action="0", label="select action", step=0, name="id_action",
                        action="", actions=[], extraactions=[], extrastamp='',
                        button="select action", **hidden):
     """create a select for roles in a form. see createselect."""
 
     return createselect(id_input=id_action, label=label, step=step, name=name,
                         action=action, list=actions, extralist=extraactions, extrastamp=extrastamp, 
                         button=button, **hidden)
 
 
 def createroleselect(id_role="0", label="select role", step=0, name="id_role",
                      action="", roles=[], extraroles=[], extrastamp='',
                      button="select role", **hidden):
     """create a select for roles in a form. see createselect."""
 
     return createselect(id_input=id_role, label=label, step=step, name=name,
                         action=action, list=roles, extralist=extraroles, extrastamp=extrastamp,
                         button=button, **hidden)
 
 
 def createuserselect(id_user="0", label="select user", step=0, name="id_user",
                      action="", users=[], extrausers=[], extrastamp='(connected)', 
                      button="select user", **hidden):
     """create a select for users in a form.see createselect."""
     
     return createselect(id_input=id_user, label=label, step=step, name=name,
                         action=action, list=users, extralist=extrausers, extrastamp=extrastamp,
                         button=button, **hidden)
 
 
 def cleanstring(str='', comma=0):
     """clean all the strings before submitting to access control admin.
     remove characters not letter, number or underscore, also remove leading
     underscores and numbers. return cleaned string.
 
       str - string to be cleaned
 
     comma - 1 -> allow the comma to divide multiple arguments
             0 -> wash commas as well """
 
     # remove not allowed characters
     str = re.sub(r'[^a-zA-Z0-9_,]', '', str)
 
     # split string on commas
     items = str.split(',')
     str = ''
     for item in items:
         if not item: continue
         if comma and str: str += ','
         # create valid variable names
         str += re.sub(r'^([0-9_])*', '', item)
 
     return str
 
 
 def cleanstring_argumentvalue(str=''):
     """clean the value of an argument before submitting it.
     allowed characters: a-z A-Z 0-9 _ and space 
 
       str - string to be cleaned """
 
     # remove not allowed characters
     str = re.sub(r'[^a-zA-Z0-9_ .]', '', str)
     # trim leading and ending spaces
     str = re.sub(r'^ *| *$', '', str)
 
     return str
 
 
 def cleanstring_email(str=''):
     """clean the string and return a valid email address.
     
       str - string to be cleaned """
 
     # remove not allowed characters
     str = re.sub(r'[^a-zA-Z0-9_.@-]', '', str)
 
     return str
 
 
 def check_email(str=''):
     """control that submitted emails are correct.
     this little check is not very good, but better than nothing. """
 
     r = re.compile(r'(.)+\@(.)+\.(.)+')
     return r.match(str) and 1 or 0
 
 def sendAccountActivatedMessage(AccountEmail, sendTo, password, ln=cdslang):
     """Send an email to the address given by sendTo about the new activated account."""
 
     fromaddr = "From: %s" % supportemail
     toaddrs  = "To: %s" % sendTo
     to = toaddrs + "\n"
     sub = "Subject: Your account on '%s' has been activated\n\n" % cdsname
     body = "Your account earlier created on '%s' has been activated:\n\n" % cdsname
     body += "   Username/Email: %s\n" % AccountEmail
     body += "   Password: %s\n" % ("*" * len(password))
     body += "\n---------------------------------"
     body += "\n%s" % cdsname
     body += "\nContact: %s" % supportemail
     msg = to + sub + body
 
     server = smtplib.SMTP('localhost')
     server.set_debuglevel(1)
 
     try:
         server.sendmail(fromaddr, toaddrs, msg)
     except smtplib.SMTPRecipientsRefused,e:
         return 0
 
     server.quit()
     return 1
 
 def sendNewUserAccountWarning(newAccountEmail, sendTo, password, ln=cdslang):
     """Send an email to the address given by sendTo about the new account newAccountEmail."""
 
     fromaddr = "From: %s" % supportemail
     toaddrs  = "To: %s" % sendTo
     to = toaddrs + "\n"
     sub = "Subject: Account created on '%s'\n\n" % cdsname
     body = "An account has been created for you on '%s':\n\n" % cdsname
     body += "   Username/Email: %s\n" % newAccountEmail
     body += "   Password: %s\n" % ("*" * len(password))
     body += "\n---------------------------------"
     body += "\n%s" % cdsname
     body += "\nContact: %s" % supportemail
     msg = to + sub + body
 
     server = smtplib.SMTP('localhost')
     server.set_debuglevel(1)
 
     try:
         server.sendmail(fromaddr, toaddrs, msg)
     except smtplib.SMTPRecipientsRefused,e:
         return 0
 
     server.quit()
     return 1
 
 def sendAccountRejectedMessage(newAccountEmail, sendTo, ln=cdslang):
     """Send an email to the address given by sendTo about the new account newAccountEmail."""
 
     fromaddr = "From: %s" % supportemail
     toaddrs  = "To: %s" % sendTo
     to = toaddrs + "\n"
     sub = "Subject: Account rejected on '%s'\n\n" % cdsname
     body = "Your request for an account has been rejected on '%s':\n\n" % cdsname
     body += "   Username/Email: %s\n" % newAccountEmail
     body += "\n---------------------------------"
     body += "\n%s" % cdsname
     body += "\nContact: %s" % supportemail
     msg = to + sub + body
 
     server = smtplib.SMTP('localhost')
     server.set_debuglevel(1)
 
     try:
         server.sendmail(fromaddr, toaddrs, msg)
     except smtplib.SMTPRecipientsRefused,e:
         return 0
 
     server.quit()
     return 1
 
 def sendAccountDeletedMessage(newAccountEmail, sendTo, ln=cdslang):
     """Send an email to the address given by sendTo about the new account newAccountEmail."""
 
     fromaddr = "From: %s" % supportemail
     toaddrs  = "To: %s" % sendTo
     to = toaddrs + "\n"
     sub = "Subject: Account deleted on '%s'\n\n" % cdsname
     body = "Your account on '%s' has been deleted:\n\n" % cdsname
     body += "   Username/Email: %s\n" % newAccountEmail
     body += "\n---------------------------------"
     body += "\n%s" % cdsname
     body += "\nContact: %s" % supportemail
     msg = to + sub + body
 
     server = smtplib.SMTP('localhost')
     server.set_debuglevel(1)
 
     try:
         server.sendmail(fromaddr, toaddrs, msg)
     except smtplib.SMTPRecipientsRefused,e:
         return 0
 
     server.quit()
     return 1
 
 
 
 
 
diff --git a/modules/websession/lib/webaccount.py b/modules/websession/lib/webaccount.py
index 053182ebd..a4f302b35 100644
--- a/modules/websession/lib/webaccount.py
+++ b/modules/websession/lib/webaccount.py
@@ -1,244 +1,247 @@
 ## $Id$
 
 ## This file is part of CDS Invenio.
 ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
 ##
 ## CDS Invenio is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License as
 ## published by the Free Software Foundation; either version 2 of the
 ## License, or (at your option) any later version.
 ##
 ## CDS Invenio is distributed in the hope that it will be useful, but
 ## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ## General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
 ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc.,
 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
 import sys
 import string
 import cgi
 
 from invenio.config import *
 from invenio.webpage import page
 from invenio.dbquery import run_sql
 from invenio.webuser import getUid,isGuestUser, get_user_preferences, set_user_preferences
 from invenio.access_control_admin import acc_findUserRoleActions
 from invenio.access_control_config import CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS, CFG_EXTERNAL_AUTHENTICATION
 
 from invenio.messages import gettext_set_language
 
 import invenio.template
 websession_templates = invenio.template.load('websession')
 
 # perform_info(): display the main features of CDS personalize
 def perform_info(req, ln):
     out = ""
     uid = getUid(req)
 
     return websession_templates.tmpl_account_info(
             ln = ln,
             uid = uid,
             guest = isGuestUser(uid),
             cfg_cern_site = cfg_cern_site,
            );
 
 
 def perform_youradminactivities(uid, ln):
     """Return text for the `Your Admin Activities' box.  Analyze
        whether user UID has some admin roles, and if yes, then print
        suitable links for the actions he can do.  If he's not admin,
        print a simple non-authorized message."""
     your_role_actions = acc_findUserRoleActions(uid)
     your_roles = []
     your_admin_activities = []
     guest = isGuestUser(uid)
     for (role, action) in your_role_actions:
         if role not in your_roles:
             your_roles.append(role)
         if action not in your_admin_activities:
             your_admin_activities.append(action)
 
     if "superadmin" in your_roles:
         for action in ["runbibedit", "cfgbibformat", "cfgbibharvest", "cfgbibrank", "cfgbibindex", "cfgwebaccess", "cfgwebcomment", "cfgwebsearch", "cfgwebsubmit"]:
             if action not in your_admin_activities:
                 your_admin_activities.append(action)
 
     return websession_templates.tmpl_account_adminactivities(
              ln = ln,
              uid = uid,
              guest = guest,
              roles = your_roles,
              activities = your_admin_activities,
              weburl = weburl,
            )
 
 # perform_display_account(): display a dynamic page that shows the user's account
-def perform_display_account(req,data,bask,aler,sear,msgs,ln):
+def perform_display_account(req,username,bask,aler,sear,msgs,ln):
 
     # load the right message language
     _ = gettext_set_language(ln)
 
     uid = getUid(req)
     #your account
     if isGuestUser(uid):
         user = "guest"
         login = "%s/youraccount/login?ln=%s" % (sweburl, ln)
         accBody = _("""You are logged in as guest. You may want to <A href="%s">login</A> as a regular user""") % login + "<BR><BR>"
         bask=aler=msgs= _("""The <strong class="headline">guest</strong> users need to <A href="%s">register</A> first""") % login
         sear= _("No queries found")
     else:
-        user = data[0]
+        user = username
         accBody = websession_templates.tmpl_account_body(
                     ln = ln,
                     user = user,
                   )
 
     return websession_templates.tmpl_account_page(
              ln = ln,
              weburl = weburl,
              accBody = accBody,
              baskets = bask,
              alerts = aler,
              searches = sear,
              messages = msgs,
              administrative = perform_youradminactivities(uid, ln)
            )
 
 # template_account() : it is a template for print each of the options from the user's account
 def template_account(title, body, ln):
     return websession_templates.tmpl_account_template(
              ln = ln,
              title = title,
              body = body
            )
 
 # warning_guest_user(): It returns an alert message,showing that the user is a guest user and should log into the system
 def warning_guest_user(type, ln=cdslang):
 
     # load the right message language
     _ = gettext_set_language(ln)
 
     return websession_templates.tmpl_warning_guest_user(
              ln = ln,
              type = type,
            )
 
 ## perform_delete():delete  the account of the user, not implement yet
 def perform_delete(ln):
     return websession_templates.tmpl_account_delete(ln = ln)
 
 ## perform_set(email,password): edit your account parameters, email and password.
 def perform_set(email,password, ln):
 
     try:
-        uid = run_sql("SELECT id FROM user where email=%s", (email,))
-        uid = uid[0][0]
+        res = run_sql("SELECT id, nickname FROM user WHERE email=%s", (email,))
+        uid = res[0][0]
+        nickname = res[0][1]
     except:
         uid = 0
+        nickname = ""
 
     CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS_LOCAL = CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS
     prefs = get_user_preferences(uid)
     if CFG_EXTERNAL_AUTHENTICATION.has_key(prefs['login_method']) and  CFG_EXTERNAL_AUTHENTICATION[prefs['login_method']][1] != True:
         CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS_LOCAL = 3
 
     out = websession_templates.tmpl_user_preferences(
              ln = ln,
              email = email,
              email_disabled = (CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS_LOCAL >= 2),
              password = password,
-             password_disabled = (CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS_LOCAL >= 3)
+             password_disabled = (CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS_LOCAL >= 3),
+             nickname = nickname,
            )
 
     if len(CFG_EXTERNAL_AUTHENTICATION) >= 1:
         try:
             uid = run_sql("SELECT id FROM user where email=%s", (email,))
             uid = uid[0][0]
         except:
             uid = 0
         prefs = get_user_preferences(uid)
         current_login_method = prefs['login_method']
         methods = CFG_EXTERNAL_AUTHENTICATION.keys()
         methods.sort()
 
         out += websession_templates.tmpl_user_external_auth(
                  ln = ln,
                  methods = methods,
                  current = current_login_method,
                  method_disabled = (CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 4)
                )
     return out
 
 ##  create_register_page_box(): register a new account
 def create_register_page_box(referer='', ln=cdslang):
 
     return websession_templates.tmpl_register_page(
              referer = referer,
              ln = ln,
              level = CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS,
              supportemail = supportemail,
              cdsname = cdsname
            )
 
 ##  create_login_page_box(): ask for the user's email and password, for login into the system
 def create_login_page_box(referer='', ln=cdslang):
 
     internal = None
     for system in CFG_EXTERNAL_AUTHENTICATION.keys():
         if not CFG_EXTERNAL_AUTHENTICATION[system][0]:
             internal = system
             break
     register_available = CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS <= 1 and internal
     methods = CFG_EXTERNAL_AUTHENTICATION.keys()
     methods.sort()
     selected = ''
     for method in methods:
         if CFG_EXTERNAL_AUTHENTICATION[method][1] == True:
             selected = method
             break
 
     return websession_templates.tmpl_login_form(
              ln = ln,
              referer = referer,
              internal = internal,
              register_available = register_available,
              methods = methods,
              selected_method = selected,
              supportemail = supportemail,
            )
 
 
 # perform_logout: display the message of not longer authorized,
 def perform_logout(req, ln):
     return websession_templates.tmpl_account_logout(ln = ln)
 
 #def perform_lost: ask the user for his email, in order to send him the lost password
 def perform_lost(ln):
     return websession_templates.tmpl_lost_password_form(
              ln = ln,
              msg = websession_templates.tmpl_lost_password_message(ln = ln, supportemail = supportemail),
            )
 
 # perform_emailSent(email): confirm that the password has been emailed to 'email' address
 def perform_emailSent(email, ln):
     return websession_templates.tmpl_account_emailSent(ln = ln, email = email)
 
 # peform_emailMessage : display a error message when the email introduced is not correct, and sugest to try again
 def perform_emailMessage(eMsg, ln):
     return websession_templates.tmpl_account_emailMessage( ln = ln,
                                            msg = eMsg
                                          )
 
 # perform_back(): template for return to a previous page, used for login,register and setting
 def perform_back(mess,act,linkname='', ln='en'):
     if not linkname:
         linkname = act
 
     return websession_templates.tmpl_back_form(
              ln = ln,
              message = mess,
              act = act,
              link = linkname,
            )
diff --git a/modules/websession/lib/websession_templates.py b/modules/websession/lib/websession_templates.py
index 580491819..6ceae483b 100644
--- a/modules/websession/lib/websession_templates.py
+++ b/modules/websession/lib/websession_templates.py
@@ -1,818 +1,856 @@
 ## $Id$
 
 ## This file is part of CDS Invenio.
 ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
 ##
 ## CDS Invenio is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License as
 ## published by the Free Software Foundation; either version 2 of the
 ## License, or (at your option) any later version.
 ##
 ## CDS Invenio is distributed in the hope that it will be useful, but
 ## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ## General Public License for more details.  
 ##
 ## You should have received a copy of the GNU General Public License
 ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc.,
 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
 import urllib
 import time
 import cgi
 import gettext
 import string
 import locale
 
 from invenio.config import *
 from invenio.messages import gettext_set_language
 
 class Template:
     def tmpl_lost_password_message(self, ln, supportemail):
         """
         Defines the text that will be displayed on the 'lost password' page
 
         Parameters:
 
           - 'ln' *string* - The language to display the interface in
 
           - 'supportemail' *string* - The email of the support team
         """
 
         # load the right message language
         _ = gettext_set_language(ln)
 
         return _("If you have lost password for your CDS Invenio internal account, then please enter your email address below and the lost password will be emailed to you.") +\
                "<br /><br />" +\
                _("Note that if you have been using an external login system (such as CERN NICE), then we cannot do anything and you have to ask there.") +\
                _("Alternatively, you can ask %s to change your login system from external to internal.") % ("""<a href="mailto:%(email)s">%(email)s</a>""" % { 'email' : supportemail }) +\
                "<br><br>"
 
     def tmpl_back_form(self, ln, message, act, link):
         """
         A standard one-message-go-back-link page.
 
         Parameters:
 
           - 'ln' *string* - The language to display the interface in
 
           - 'message' *string* - The message to display
 
           - 'act' *string* - The action to accomplish when going back
 
           - 'link' *string* - The link text
         """
         out = """
                  <table>
                     <tr>
                       <td align=center>%(message)s
                        <A href="./%(act)s">%(link)s</A></td>
                     </tr>
                  </table>
              """% {
                'message' : message,
                'act'     : act,
                'link'    : link
              }
 
         return out
 
-    def tmpl_user_preferences(self, ln, email, email_disabled, password, password_disabled):
+    def tmpl_user_preferences(self, ln, email, email_disabled, password, password_disabled, nickname):
         """
         Displays a form for the user to change his email/password.
 
         Parameters:
 
           - 'ln' *string* - The language to display the interface in
 
           - 'email' *string* - The email of the user
 
           - 'email_disabled' *boolean* - If the user has the right to edit his email
 
           - 'password' *string* - The password of the user
 
           - 'password_disabled' *boolean* - If the user has the right to edit his password
 
+          - 'nickname' *string* - The nickname of the user (empty string if user does not have it)
+
         """
 
         # load the right message language
         _ = gettext_set_language(ln)
 
         out = """
-                <p><big><strong class="headline">Edit parameters</strong></big></p>
+                <p><big><strong class="headline">%(edit_params)s</strong></big></p>
                 <form method="post" action="%(sweburl)s/youraccount/change">
                 <p>%(change_user_pass)s</p>
                 <table>
+                  <tr><td align="right"><strong>
+                      %(nickname_label)s:</strong><br/>
+                      <small class="important">(%(mandatory)s)</small>
+                    </td><td>
+                      %(nickname_prefix)s%(nickname)s%(nickname_suffix)s
+                    </td>
+                    <td></td>
+                  </tr>
                   <tr><td align="right"><strong>
                       %(new_email)s:</strong><br/>
                       <small class="important">(%(mandatory)s)</small>
                     </td><td>
                       <input type="text" size="25" name="email" %(email_disabled)s value="%(email)s"><br>
                       <small><span class="quicknote">%(example)s:</span>
-                        <span class="example">johndoe@example.com</span>
+                        <span class="example">john.doe@example.com</span>
                       </small>
                     </td>
                     <td></td>
                   </tr>
                   <tr>
                     <td align="right"><strong>%(new_password)s:</strong><br>
                       <small class="quicknote">(%(optional)s)</small>
                     </td><td align="left">
                       <input type="password" size="25" name="password" %(password_disabled)s value="%(password)s"><br>
                       <small><span class=quicknote>%(note)s:</span>
                        %(password_note)s
                       </small>
                     </td>
                   </tr>
                   <tr>
                     <td align="right"><strong>%(retype_password)s:</strong></td>
                     <td align="left">
                       <input type="password" size="25" name="password2" %(password_disabled)s value="">
                     </td>
                     <td><input type="hidden" name="action" value="edit"></td>
                   </tr>
                   <tr><td align="center" colspan="3">
                     <code class="blocknote"><input class="formbutton" type="submit" value="%(set_values)s"></code>&nbsp;&nbsp;&nbsp;
                   </td></tr>
                 </table>
               </form>
         """ % {
           'change_user_pass' : _("If you want to change your email address or password, please set new values in the form below."),
+          'edit_params' : _("Edit parameters"),
+          'nickname_label' : _("Nickname"),
+          'nickname' : nickname,
+          'nickname_prefix' : nickname=='' and '<input type="text" size="25" name="nickname" value=""' or '',
+          'nickname_suffix' : nickname=='' and '"><br><small><span class="quicknote">'+_("Example")+':</span><span class="example">johnd</span></small>' or '',
           'new_email' : _("New email address"),
           'mandatory' : _("mandatory"),
           'example' : _("Example"),
           'new_password' : _("New password"),
           'optional' : _("optional"),
           'note' : _("Note"),
           'password_note' : _("The password phrase may contain punctuation, spaces, etc."),
           'retype_password' : _("Retype password"),
           'set_values' : _("Set new values"),
 
           'email' : email,
           'email_disabled' : email_disabled and "disabled" or "",
           'password' : password,
           'password_disabled' : password_disabled and "disabled" or "",
           'sweburl': sweburl,
         }
         return out
 
     def tmpl_user_external_auth(self, ln, methods, current, method_disabled):
         """
         Displays a form for the user to change his authentication method.
 
         Parameters:
 
           - 'ln' *string* - The language to display the interface in
 
           - 'methods' *array* - The methods of authentication
 
           - 'method_disabled' *boolean* - If the user has the right to change this
 
           - 'current' *string* - The currently selected method
         """
 
         # load the right message language
         _ = gettext_set_language(ln)
 
         out = """
                  <form method="post" action="%(sweburl)s/youraccount/change">
                    <big><strong class="headline">%(edit_method)s</strong></big>
                    <p>%(explain_method)s:</p>
                    <table>
                      <tr><td valign="top"><b>%(select_method)s:</b></td><td>
                """ % {
                  'edit_method' : _("Edit login method"),
                  'explain_method' : _("Please select which login method you would like to use to authenticate yourself"),
                  'select_method' : _("Select method"),
                  'sweburl': sweburl,
                }
         for system in methods:
             out += """<input type="radio" name="login_method" value="%(system)s" %(disabled)s %(selected)s>%(system)s<br>""" % {
                      'system' : system,
                      'disabled' : method_disabled and "disabled" or "",
                      'selected' : current == system and "disabled" or "",
                    }
         out += """  </td><td></td></tr>
                    <tr><td></td>
                      <td><input class="formbutton" type="submit" value="%(select_method)s"></td></tr></table>
                     </form>""" % {
                      'select_method' : _("Select method"),
                    }
 
         return out
 
     def tmpl_lost_password_form(self, ln, msg):
         """
         Displays a form for the user to ask for his password sent by email.
 
         Parameters:
 
           - 'ln' *string* - The language to display the interface in
 
           - 'msg' *string* - Explicative message on top of the form.
         """
 
         # load the right message language
         _ = gettext_set_language(ln)
 
         out = """
           <form  method="post" action="../youraccount/send_email">
             %(msg)s
           <table>
                 <tr>
               <td align="right"><strong>%(email)s:</strong></td>
               <td><input type="text" size="25" name="p_email" value=""></td>
               <td><input type="hidden" name="action" value="lost"></td>
             </tr>
             <tr><td></td>
               <td><code class="blocknote"><input class="formbutton" type="submit" value="%(send)s"></code></td>
             </tr>
           </table>
 
           </form>
           """ % {
             'msg' : msg,
             'email' : _("Email address"),
             'send' : _("Send lost password"),
           }
         return out
 
     def tmpl_account_info(self, ln, uid, guest, cfg_cern_site):
         """
         Displays the account information
 
         Parameters:
 
           - 'ln' *string* - The language to display the interface in
 
           - 'uid' *string* - The user id
 
           - 'guest' *boolean* - If the user is guest
 
           - 'cfg_cern_site' *boolean* - If the site is a CERN site
         """
 
         # load the right message language
         _ = gettext_set_language(ln)
 
         out = """<P>%(account_offer)s</P>
                  <blockquote>
                  <dl>
               """ % {
                 'account_offer' : _("The CDS Search offers you a possibility to personalize the interface, to set up your own personal library of documents, or to set up an automatic alert query that would run periodically and would notify you of search results by email."),
               }
 
         if not guest:
             out += """
                    <dt>
                    <A href="./edit?ln=%(ln)s">%(your_settings)s</A>
                    <dd>%(change_account)s""" % {
                      'ln' : ln,
                      'your_settings' : _("Your Settings"),
                      'change_account' : _("Set or change your account Email address or password. Specify your preferences about the way the interface looks like.")
                    }
 
         out += """
         <dt><A href="../youralerts/display?ln=%(ln)s">%(your_searches)s</A>
         <dd>%(search_explain)s
 
         <dt><A href="../yourbaskets/display?ln=%(ln)s">%(your_baskets)s</A>
         <dd>%(basket_explain)s""" % {
           'ln' : ln,
           'your_searches' : _("Your Searches"),
           'search_explain' : _("View all the searches you performed during the last 30 days."),
           'your_baskets' : _("Your Baskets"),
           'basket_explain' : _("With baskets you can define specific collections of items, store interesting records you want to access later or share with others."),
         }
         if guest:
             out += self.tmpl_warning_guest_user(ln = ln, type = "baskets")
         out += """
         <dt><A href="../youralerts/list?ln=%s">%(your_alerts)s</A>
         <dd>%(explain_alerts)s""" % {
           'ln' : ln,
           'your_alerts' : _("Your Alerts"),
           'explain_alerts' : _("Subscribe to a search which will be run periodically by our service.  The result can be sent to you via Email or stored in one of your baskets."),
         }
         if guest:
             out += self.tmpl_warning_guest_user(type="alerts", ln = ln)
 
         if cfg_cern_site:
             out += """
             <dt><A href="http://weblib.cern.ch/cgi-bin/checkloan?uid=&version=2">%(your_loans)s</A>
             <dd>%(explain_loans)s""" % {
               'your_loans' : _("Your Loans"),
               'explain_loans' : _("Check out book you have on load, submit borrowing requests, etc.  Requires CERN ID."),
             }
 
         out += """
         </dl>
         </blockquote>"""
 
         return out
 
     def tmpl_warning_guest_user(self, ln, type):
         """
         Displays a warning message about the specified type
 
         Parameters:
 
           - 'ln' *string* - The language to display the interface in
 
           - 'type' *string* - The type of data that will get lost in case of guest account
         """
 
         # load the right message language
         _ = gettext_set_language(ln)
 
         msg= _("""You are logged in as a guest user, so your %s will disappear at the end of the current session. If you wish you can
                <a href="%s/youraccount/login?ln=%s">login or register here</a>.""") % (type, sweburl, ln)
         return """<table class="errorbox" summary="">
                            <thead>
                             <tr>
                              <th class="errorboxheader">%s</th>
                             </tr>
                            </thead>
                           </table>""" % msg
 
     def tmpl_account_body(self, ln, user):
         """
         Displays the body of the actions of the user
 
         Parameters:
 
           - 'ln' *string* - The language to display the interface in
 
-          - 'user' *string* - The user name
+          - 'user' *string* - The username (nickname or email)
         """
 
         # load the right message language
         _ = gettext_set_language(ln)
 
         return _("""You are logged in as %(user)s. You may want to a) <A href="%(logout)s">logout</A>; b) edit your <A href="%(edit)s">account settings</a>.""") % {
             'user': user,
             'logout': '%s/youraccount/logout?ln=%s' % (sweburl, ln),
             'edit': '%s/youraccount/edit?ln=%s' % (sweburl, ln)
             } + "<BR><BR>"
 
     def tmpl_account_template(self, title, body, ln):
         """
         Displays a block of the your account page
 
         Parameters:
 
           - 'ln' *string* - The language to display the interface in
 
           - 'title' *string* - The title of the block
 
           - 'body' *string* - The body of the block
         """
 
         out =""
         out +="""
               <table class="searchbox" width="90%%" summary=""  >
                            <thead>
                             <tr>
                              <th class="searchboxheader">%s</th>
                             </tr>
                            </thead>
                            <tbody>
                             <tr>
                              <td class="searchboxbody">%s</td>
                             </tr>
                            </tbody>
                           </table>""" % (title, body)
         return out
 
     def tmpl_account_page(self, ln, weburl, accBody, baskets, alerts, searches, messages, administrative):
         """
         Displays the your account page
 
         Parameters:
 
           - 'ln' *string* - The language to display the interface in
 
           - 'weburl' *string* - The URL of CDS Invenio
 
           - 'accBody' *string* - The body of the heading block
 
           - 'baskets' *string* - The body of the baskets block
 
           - 'alerts' *string* - The body of the alerts block
 
           - 'searches' *string* - The body of the searches block
 
           - 'messages' *string* - The body of the messages block
 
           - 'administrative' *string* - The body of the administrative block
         """
 
         # load the right message language
         _ = gettext_set_language(ln)
 
         out = ""
         out += self.tmpl_account_template(_("Your Account"), accBody, ln)
         out += self.tmpl_account_template(_("Your Messages"), messages, ln)
         out += self.tmpl_account_template(_("Your Baskets"), baskets, ln)
         out += self.tmpl_account_template(_("Your Alert Searches"), alerts, ln)
         out += self.tmpl_account_template(_("Your Searches"), searches, ln)
         out += self.tmpl_account_template(_("Your Submissions"),
                                _("You can consult the list of %(your_submissions)s and inquire about their status.") % {
                                  'your_submissions' :
                                     """<a href="%(weburl)s/yoursubmissions.py?ln=%(ln)s">%(your_sub)s</a>""" % {
                                       'ln' : ln,
                                       'weburl' : weburl,
                                       'your_sub' : _("your submissions")
                                     }
                                }, ln)
         out += self.tmpl_account_template(_("Your Approvals"),
                                _("You can consult the list of %(your_approvals)s with the documents you approved or refereed.") % {
                                  'your_approvals' :
                                     """ <a href="%(weburl)s/yourapprovals.py?ln=%(ln)s">%(your_app)s</a>""" % {
                                       'ln' : ln,
                                       'weburl' : weburl,
                                       'your_app' : _("your approvals"),
                                     }
                                }, ln)
         out += self.tmpl_account_template(_("Your Administrative Activities"), administrative, ln)
         return out
 
     def tmpl_account_emailMessage(self, ln, msg):
         """
         Displays a link to retrieve the lost password
 
         Parameters:
 
           - 'ln' *string* - The language to display the interface in
 
           - 'msg' *string* - Explicative message on top of the form.
         """
 
         # load the right message language
         _ = gettext_set_language(ln)
 
         out =""
         out +="""
         <body>
            %(msg)s <A href="../youraccount/lost?ln=%(ln)s">%(try_again)s</A>
 
               </body>
 
           """ % {
             'ln' : ln,
             'msg' : msg,
             'try_again' : _("Try again")
           }
         return out
 
     def tmpl_account_emailSent(self, ln, email):
         """
         Displays a confirmation message for an email sent
 
         Parameters:
 
           - 'ln' *string* - The language to display the interface in
 
           - 'email' *string* - The email to which the message has been sent
         """
 
         # load the right message language
         _ = gettext_set_language(ln)
 
         out =""
         out += _("Okay, password has been emailed to %s") % email
         return out
 
     def tmpl_account_delete(self, ln):
         """
         Displays a confirmation message about deleting the account
 
         Parameters:
 
           - 'ln' *string* - The language to display the interface in
         """
 
         # load the right message language
         _ = gettext_set_language(ln)
 
         out = "<p>" + _("""Deleting your account""")
         return out
 
     def tmpl_account_logout(self, ln):
         """
         Displays a confirmation message about logging out
 
         Parameters:
 
           - 'ln' *string* - The language to display the interface in
         """
 
         # load the right message language
         _ = gettext_set_language(ln)
 
         out = ""
         out += _("""You are no longer recognized.  If you wish you can <A href="./login?ln=%s">login here</A>.""") % ln
         return out
 
     def tmpl_login_form(self, ln, referer, internal, register_available, methods, selected_method, supportemail):
         """
         Displays a login form
 
         Parameters:
 
           - 'ln' *string* - The language to display the interface in
 
           - 'referer' *string* - The referer URL - will be redirected upon after login
 
           - 'internal' *boolean* - If we are producing an internal authentication
 
           - 'register_available' *boolean* - If users can register freely in the system
 
           - 'methods' *array* - The available authentication methods
 
           - 'selected_method' *string* - The default authentication method
 
           - 'supportemail' *string* - The email of the support team
         """
 
         # load the right message language
         _ = gettext_set_language(ln)
 
         out = "<p>%(please_login)s<br>" % {
                 'please_login' : _("If you already have an account, please login using the form below.")
               }
 
         if register_available:
             out += _("""If you don't own an account yet, please <a href="../youraccount/register?ln=%s">register</a> an internal account.""") % ln
         else:
             out += _("""It is not possible to create an account yourself. Contact %s if you want an account.""") % (
                       """<a href="mailto:%(email)s">%(email)s</a>""" % { 'email' : supportemail }
                     )
         out += """<form method="post" action="../youraccount/login">
                   <table>
 
                """
         if len(methods) > 1:
             # more than one method, must make a select
             login_select = """<select name="login_method">"""
             for method in methods:
                 login_select += """<option value="%(method)s" %(selected)s>%(method)s</option>""" % {
                                   'method' : method,
                                   'selected' : (method == selected_method and "selected" or "")
                                 }
             login_select += "</select>"
             out += """
                    <tr>
                       <td align="right">%(login_title)s</td>
                       <td>%(login_select)s</td>
                       <td></td>
                    </tr>""" % {
                      'login_title' : _("Login via:"),
                      'login_select' : login_select,
                    }
         else:
             # only one login method available
             out += """<input type="hidden" name="login_method" value="%s">""" % (methods[0])
 
         out += """<tr>
                    <td align="right">
                      <input type="hidden" name="ln" value="%(ln)s">
                      <input type="hidden" name="referer" value="%(referer)s">
                      <strong>%(username)s:</strong>
                    </td>
-                   <td><input type="text" size="25" name="p_email" value=""></td>
+                   <td><input type="text" size="25" name="p_un" value=""></td>
                    <td></td>
                   </tr>
                   <tr>
                    <td align="right"><strong>%(password)s:</strong></td>
                    <td align="left"><input type="password" size="25" name="p_pw" value=""></td>
                    <td></td>
                   </tr>
                   <tr>
                    <td></td>
                    <td align="center" colspan="3"><code class="blocknote"><input class="formbutton" type="submit" name="action" value="%(login)s"></code>""" % {
                        'ln': ln,
                        'referer' : cgi.escape(referer),
                        'username' : _("Username"),
                        'password' : _("Password"),
                        'login' : _("login"),
                        }
         if internal:
             out += """&nbsp;&nbsp;&nbsp;(<a href="./lost?ln=%(ln)s">%(lost_pass)s</a>)""" % {
                      'ln' : ln,
                      'lost_pass' : _("Lost your password?")
                    }
         out += """</td><td></td>
                     </tr>
                   </table></form>"""
         return out
 
+    def tmpl_lost_your_password_teaser(self, ln=cdslang):
+        """Displays a short sentence to attract user to the fact that
+        maybe he lost his password.  Used by the registration page.
+        """
+
+        _ = gettext_set_language(ln)
+
+        out = ""
+        out += """<a href="./lost?ln=%(ln)s">%(maybe_lost_pass)s</a>""" % {
+                     'ln' : ln,
+                     'maybe_lost_pass': ("Maybe you have lost your password?") 
+                     }
+        return out
+
     def tmpl_register_page(self, ln, referer, level, supportemail, cdsname):
         """
         Displays a login form
 
         Parameters:
 
           - 'ln' *string* - The language to display the interface in
 
           - 'referer' *string* - The referer URL - will be redirected upon after login
 
           - 'level' *int* - Login level (0 - all access, 1 - accounts activated, 2+ - no self-registration)
 
           - 'supportemail' *string* - The email of the support team
 
           - 'cdsname' *string* - The name of the installation
         """
 
         # load the right message language
         _ = gettext_set_language(ln)
 
         out = ""
         if level <= 1:
-            out += _("""Please enter your email address and desired password:""")
+            out += _("""Please enter your email address and desired nickname and password:""")
             if level == 1:
                 out += _("The account will not be possible to use before it has been verified and activated.")
             out += """
               <form method="post" action="../youraccount/register">
               <input type="hidden" name="referer" value="%(referer)s">
               <table>
                 <tr>
                  <td align="right"><strong>%(email_address)s:</strong><br><small class="important">(%(mandatory)s)</small></td>
                  <td><input type="text" size="25" name="p_email" value=""><br>
                      <small><span class="quicknote">%(example)s:</span>
-                     <span class="example">johndoe@example.com</span></small>
+                     <span class="example">john.doe@example.com</span></small>
+                 </td>
+                 <td></td>
+                </tr>
+                <tr>
+                 <td align="right"><strong>%(nickname)s:</strong><br><small class="important">(%(mandatory)s)</small></td>
+                 <td><input type="text" size="25" name="p_nickname" value=""><br>
+                     <small><span class="quicknote">%(example)s:</span>
+                     <span class="example">johnd</span></small>
                  </td>
                  <td></td>
                 </tr>
                 <tr>
                  <td align="right"><strong>%(password)s:</strong><br><small class="quicknote">(%(optional)s)</small></td>
                  <td align="left"><input type="password" size="25" name="p_pw" value=""><br>
                     <small><span class="quicknote">%(note)s:</span> %(password_contain)s</small>
                  </td>
                  <td></td>
                 </tr>
                 <tr>
                  <td align="right"><strong>%(retype)s:</strong></td>
                  <td align="left"><input type="password" size="25" name="p_pw2" value=""></td>
                  <td></td>
                 </tr>
                 <tr>
                  <td></td>
                  <td align="left" colspan="3"><code class="blocknote"><input class="formbutton" type="submit" name="action" value="%(register)s"></code></td>
                 </tr>
               </table>
               <p><strong>%(note)s:</strong> %(explain_acc)s""" % {
                 'referer' : cgi.escape(referer),
                 'email_address' : _("Email address"),
+                'nickname' : _("Nickname"),
                 'password' : _("Password"),
                 'mandatory' : _("mandatory"),
                 'optional' : _("optional"),
                 'example' : _("Example"),
                 'note' : _("Note"),
                 'password_contain' : _("The password phrase may contain punctuation, spaces, etc."),
                 'retype' : _("Retype Password"),
                 'register' : _("register"),
                 'explain_acc' : _("Please do not use valuable passwords such as your Unix, AFS or NICE passwords with this service. Your email address will stay strictly confidential and will not be disclosed to any third party. It will be used to identify you for personal services of %s. For example, you may set up an automatic alert search that will look for new preprints and will notify you daily of new arrivals by email.") % cdsname,
               }
         return out
 
     def tmpl_account_adminactivities(self, ln, weburl, uid, guest, roles, activities):
         """
         Displays the admin activities block for this user
 
         Parameters:
 
           - 'ln' *string* - The language to display the interface in
 
           - 'weburl' *string* - The address of the site
 
           - 'uid' *string* - The used id
 
           - 'guest' *boolean* - If the user is guest
 
           - 'roles' *array* - The current user roles
 
           - 'activities' *array* - The user allowed activities
         """
 
         # load the right message language
         _ = gettext_set_language(ln)
 
         out = ""
         # guest condition
         if guest:
             return _("""You seem to be the guest user.  You have to <a href="../youraccount/login?ln=%s">login</a> first.""") % ln
 
         # no rights condition
         if not roles:
             return "<p>" + _("You are not authorized to access administrative functions.") + "</p>"
 
         # displaying form
         out += "<p>" + _("You seem to be <em>%s</em>.") % string.join(roles, ", ") + " "
         out += _("Here are some interesting web admin links for you:")
 
         # print proposed links:
         activities.sort(lambda x, y: cmp(string.lower(x), string.lower(y)))
         for action in activities:
             if action == "runbibedit":
                 out += """<br>&nbsp;&nbsp;&nbsp; <a href="%s/admin/bibedit/bibeditadmin.py?ln=%s">%s</a>""" % (weburl, ln, _("Run BibEdit"))
             if action == "cfgbibformat":
                 out += """<br>&nbsp;&nbsp;&nbsp; <a href="%s/admin/bibformat/?ln=%s">%s</a>""" % (weburl, ln, _("Configure BibFormat"))
             if action == "cfgbibharvest":
                 out += """<br>&nbsp;&nbsp;&nbsp; <a href="%s/admin/bibharvest/bibharvestadmin.py?ln=%s">%s</a>""" % (weburl, ln, _("Configure BibHarvest"))
             if action == "cfgbibindex":
                 out += """<br>&nbsp;&nbsp;&nbsp; <a href="%s/admin/bibindex/bibindexadmin.py?ln=%s">%s</a>""" % (weburl, ln, _("Configure BibIndex"))
             if action == "cfgbibrank":
                 out += """<br>&nbsp;&nbsp;&nbsp; <a href="%s/admin/bibrank/bibrankadmin.py?ln=%s">%s</a>""" % (weburl, ln, _("Configure BibRank"))
             if action == "cfgwebaccess":
                 out += """<br>&nbsp;&nbsp;&nbsp; <a href="%s/admin/webaccess/?ln=%s">%s</a>""" % (weburl, ln, _("Configure WebAccess"))
             if action == "cfgwebcomment":
                 out += """<br>&nbsp;&nbsp;&nbsp; <a href="%s/admin/webcomment/webcommentadmin.py?ln=%s">%s</a>""" % (weburl, ln, _("Configure WebComment"))
             if action == "cfgwebsearch":
                 out += """<br>&nbsp;&nbsp;&nbsp; <a href="%s/admin/websearch/websearchadmin.py?ln=%s">%s</a>""" % (weburl, ln, _("Configure WebSearch"))
             if action == "cfgwebsubmit":
                 out += """<br>&nbsp;&nbsp;&nbsp; <a href="%s/admin/websubmit/?ln=%s">%s</a>""" % (weburl, ln, _("Configure WebSubmit"))
         out += "<br>" + _("""For more admin-level activities, see the complete %(admin_area)s""") % {
                            'admin_area' : """<a href="%s/admin/index.%s.html">%s</a>.""" % (weburl, ln, _("Admin Area"))
                          }
 
         return out
 
-    def tmpl_create_userinfobox(self, ln, url_referer, guest, email, submitter, referee, admin):
+    def tmpl_create_userinfobox(self, ln, url_referer, guest, username, submitter, referee, admin):
         """
         Displays the user block
 
         Parameters:
 
           - 'ln' *string* - The language to display the interface in
 
           - 'url_referer' *string* - URL of the page being displayed
 
           - 'guest' *boolean* - If the user is guest
 
-          - 'email' *string* - The user email (if known)
+          - 'username' *string* - The username (nickname or email)
 
           - 'submitter' *boolean* - If the user is submitter
 
           - 'referee' *boolean* - If the user is referee
 
           - 'admin' *boolean* - If the user is admin
         """
 
         # load the right message language
         _ = gettext_set_language(ln)
 
         out = """<img src="%s/img/head.gif" border="0" alt="">""" % weburl
         if guest:
             out += """%(guest_msg)s ::
     	       <a class="userinfo" href="%(sweburl)s/youraccount/display?ln=%(ln)s">%(session)s</a> ::
                    <a class="userinfo" href="%(weburl)s/yourbaskets/display?ln=%(ln)s">%(baskets)s</a> ::
                    <a class="userinfo" href="%(weburl)s/youralerts/list?ln=%(ln)s">%(alerts)s</a> ::
                    <a class="userinfo" href="%(sweburl)s/youraccount/login?ln=%(ln)s">%(login)s</a>""" % {
                      'weburl' : weburl,
                      'sweburl': sweburl,
                      'ln' : ln,
                      'guest_msg' : _("guest"),
                      'session' : _("session"),
                      'alerts' : _("alerts"),
                      'baskets' : _("baskets"),
                      'login' : _("login"),
                    }
         else:
-            out += """%(email)s ::
+            out += """%(username)s ::
     	       <a class="userinfo" href="%(sweburl)s/youraccount/display?ln=%(ln)s">%(account)s</a> ::
                    <a class="userinfo" href="%(weburl)s/yourmessages/display?ln=%(ln)s">%(messages)s</a> ::
                    <a class="userinfo" href="%(weburl)s/yourbaskets/display?ln=%(ln)s">%(baskets)s</a> ::
                    <a class="userinfo" href="%(weburl)s/youralerts/list?ln=%(ln)s">%(alerts)s</a> :: """ % {
-                     'email' : email,
+                     'username' : username,
                      'weburl' : weburl,
                      'sweburl' : sweburl,
                      'ln' : ln,
                      'account' : _("account"),
                      'alerts' : _("alerts"),
 		     'messages': _("messages"),
                      'baskets' : _("baskets"),
                    }
             if submitter:
                 out += """<a class="userinfo" href="%(weburl)s/yoursubmissions?ln=%(ln)s">%(submission)s</a> :: """ % {
                          'weburl' : weburl,
                          'ln' : ln,
                          'submission' : _("submissions"),
                        }
             if referee:
                 out += """<a class="userinfo" href="%(weburl)s/yourapprovals?ln=%(ln)s">%(approvals)s</a> :: """ % {
                          'weburl' : weburl,
                          'ln' : ln,
                          'approvals' : _("approvals"),
                        }
             if admin:
                 out += """<a class="userinfo" href="%(sweburl)s/youraccount/youradminactivities?ln=%(ln)s">%(administration)s</a> :: """ % {
                          'sweburl' : sweburl,
                          'ln' : ln,
                          'administration' : _("administration"),
                        }
             out += """<a class="userinfo" href="%(sweburl)s/youraccount/logout?ln=%(ln)s">%(logout)s</a>""" % {
                      'sweburl' : sweburl,
                      'ln' : ln,
                      'logout' : _("logout"),
                    }
         return out
diff --git a/modules/websession/lib/websession_webinterface.py b/modules/websession/lib/websession_webinterface.py
index b731775ed..4767789d5 100644
--- a/modules/websession/lib/websession_webinterface.py
+++ b/modules/websession/lib/websession_webinterface.py
@@ -1,484 +1,530 @@
 # -*- coding: utf-8 -*-
 ## $Id$
 
 ## This file is part of CDS Invenio.
 ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
 ##
 ## CDS Invenio is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License as
 ## published by the Free Software Foundation; either version 2 of the
 ## License, or (at your option) any later version.
 ##
 ## CDS Invenio is distributed in the hope that it will be useful, but
 ## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ## General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
 ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc.,
 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
 """CDS Invenio ACCOUNT HANDLING"""
 
 __lastupdated__ = """$Date$"""
 
 import sys
 from mod_python import apache
 import smtplib
 
 from invenio import webuser
 from invenio.config import weburl, sweburl, cdsname, cdslang, supportemail
 from invenio.webpage import page
 from invenio import webaccount
 from invenio import webbasket
 from invenio import webalert
 from invenio import webuser
 from invenio.webmessage import account_new_mail
 from invenio.access_control_config import *
 from invenio.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE, cfg_webaccess_warning_msgs, CFG_EXTERNAL_AUTHENTICATION
 from invenio.webinterface_handler import wash_urlargd, WebInterfaceDirectory
 from invenio.urlutils import redirect_to_url, make_canonical_urlargd
 
 from invenio.messages import gettext_set_language
 import invenio.template
 websession_templates = invenio.template.load('websession')
 
 
 class WebInterfaceYourAccountPages(WebInterfaceDirectory):
 
     _exports = ['', 'edit', 'change', 'lost', 'display',
                 'send_email', 'youradminactivities',
                 'delete', 'logout', 'login', 'register']
 
     _force_https = True
 
     def index(self, req, form):
         redirect_to_url(req, '%s/youraccount/display' % sweburl)
         
     def display(self, req, form):
         args = wash_urlargd(form, {})
         uid = webuser.getUid(req)
 
         # load the right message language
         _ = gettext_set_language(args['ln'])
 
         if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
             return webuser.page_not_authorized(req, "../youraccount/display")
 
         if webuser.isGuestUser(uid):
             return page(title=_("Your Account"),
                         body=webaccount.perform_info(req, args['ln']),
                         description="CDS Personalize, Main page",
                         keywords="CDS, personalize",
                         uid=uid,
                         req=req,
                         secure_page_p = 1,
                         language=args['ln'],
                         lastupdated=__lastupdated__)
 
-        data = webuser.getDataUid(req,uid)
+        username = webuser.get_nickname_or_email(uid)
         bask = webbasket.account_list_baskets(uid, ln=args['ln'])
         aler = webalert.account_list_alerts(uid, ln=args['ln'])
         sear = webalert.account_list_searches(uid, ln=args['ln'])
         msgs = account_new_mail(uid, ln=args['ln'])
         
         return page(title=_("Your Account"),
-                    body=webaccount.perform_display_account(req,data,bask,aler,sear,msgs,args['ln']),
+                    body=webaccount.perform_display_account(req,username,bask,aler,sear,msgs,args['ln']),
                     description="CDS Personalize, Main page",
                     keywords="CDS, personalize",
                     uid=uid,
                     req=req,
                     secure_page_p = 1,
                     language=args['ln'],
                     lastupdated=__lastupdated__)
 
 
     def edit(self, req, form):
         args = wash_urlargd(form, {})
         uid = webuser.getUid(req)
 
         # load the right message language
         _ = gettext_set_language(args['ln'])
 
         if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
             return webuser.page_not_authorized(req, "../youraccount/edit")
 
-        data = webuser.getDataUid(req,uid)
-        email = data[0]
-        passw = data[1]
         return page(title= _("Your Settings"),
-                    body=webaccount.perform_set(email,passw, args['ln']),
+                    body=webaccount.perform_set(webuser.get_email(uid),
+                                                webuser.get_password(uid),
+                                                args['ln']),
                     navtrail="""<a class="navtrail" href="%s/youraccount/display?ln=%s">""" % (sweburl, args['ln']) + _("Your Account") + """</a>""",
                     description="CDS Personalize, Your Settings",
                     keywords="CDS, personalize",
                     uid=uid,
                     req=req,
                     secure_page_p = 1,
                     language=args['ln'],
                     lastupdated=__lastupdated__)
 
     def change(self, req, form):
         args = wash_urlargd(form, {
+            'nickname': (str, None),
             'email': (str, None),
             'password': (str, None),
             'password2': (str, None),
             'login_method': (str, "")
             })
         
         uid = webuser.getUid(req)
 
         # load the right message language
         _ = gettext_set_language(args['ln'])
 
         if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
             return webuser.page_not_authorized(req, "../youraccount/change")
 
         if args['login_method'] and CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS < 4:
             title = _("Settings edited")
             act = "display"
             linkname = _("Show account")
             prefs = webuser.get_user_preferences(uid)
             prefs['login_method'] = args['login_method']
             webuser.set_user_preferences(uid, prefs)
             mess = _("Login method successfully selected.")
         elif args['login_method'] and CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 4:
             return webuser.page_not_authorized(req, "../youraccount/change")
         elif args['email']:
             uid2 = webuser.emailUnique(args['email'])
-            if (CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 2 or (CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS <= 1 and webuser.checkemail(args['email']))) and uid2 != -1 and (uid2 == uid or uid2 == 0) and args['password'] == args['password2']:
+            uid_with_the_same_nickname = webuser.nicknameUnique(args['nickname']) 
+            if (CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 2 or (CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS <= 1 and \
+                                                           webuser.email_valid_p(args['email']))) \
+               and (args['nickname'] is None or webuser.nickname_valid_p(args['nickname'])) \
+               and uid2 != -1 and (uid2 == uid or uid2 == 0) \
+               and uid_with_the_same_nickname != -1 and (uid_with_the_same_nickname == uid or uid_with_the_same_nickname == 0) \
+               and args['password'] == args['password2']:
                 if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS < 3:
-                    change = webuser.updateDataUser(req,uid,args['email'],args['password'])
+                    change = webuser.updateDataUser(req,uid,args['email'],args['password'],args['nickname'],)
                 else:
                     return webuser.page_not_authorized(req, "../youraccount/change")
                 if change and CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 2:
                     mess = _("Password successfully edited.")
                 elif change:
                     mess = _("Settings successfully edited.")
                 act = "display"
                 linkname = _("Show account")
                 title = _("Settings edited")
+            elif not webuser.nickname_valid_p(args['nickname']):
+                mess = _("Desired nickname %s is invalid.") % args['nickname']
+                mess += " " + _("Please try again.")
+                act = "edit"
+                linkname = _("Edit settings")
+                title = _("Editing settings failed")
+            elif not webuser.email_valid_p(args['email']):
+                mess = _("Supplied email address %s is invalid.") % args['email']
+                mess += " " + _("Please try again.")
+                act = "edit"
+                linkname = _("Edit settings")
+                title = _("Editing settings failed")
             elif uid2 == -1 or uid2 != uid and not uid2 == 0:
-                mess = _("The email address is already in use, please try again.")
+                mess = _("Supplied email address %s already exists in the database.") % args['p_email']
+                mess += " " + websession_templates.tmpl_lost_your_password_teaser(args['ln'])
+                mess += " " + _("Or please try again.")
                 act = "edit"
                 linkname = _("Edit settings")
                 title = _("Editing settings failed")
-            elif not webuser.checkemail(args['email']):
-                mess = _("The email address is not valid, please try again.")
+            elif uid_with_the_same_nickname == -1 or uid_with_the_same_nickname != uid and not uid_with_the_same_nickname == 0:
+                mess = _("Desired nickname %s is already in use.") % args['nickname']
+                mess += " " + _("Please try again.")
                 act = "edit"
                 linkname = _("Edit settings")
                 title = _("Editing settings failed")
             elif args['password'] != args['password2']:
-                mess = _("The passwords do not match, please try again.")
+                mess = _("Both passwords must match.")
+                mess += " " + _("Please try again.")
                 act = "edit"
                 linkname = _("Edit settings")
                 title = _("Editing settings failed")
         else:
             mess = _("Could not update settings.")
             act = "edit"
             linkname = _("Edit settings")
             title = _("Editing settings failed")
 
         return page(title=title,
                     body=webaccount.perform_back(mess,act, linkname, args['ln']),
                     navtrail="""<a class="navtrail" href="%s/youraccount/display?ln=%s">""" % (sweburl, args['ln']) + _("Your Account") + """</a>""",
                     description="CDS Personalize, Main page",
                     keywords="CDS, personalize",
                     uid=uid,
                     req=req,
                     secure_page_p = 1,
                     language=args['ln'],
                     lastupdated=__lastupdated__)
 
     def lost(self, req, form):
         args = wash_urlargd(form, {})
         uid = webuser.getUid(req)
 
         # load the right message language
         _ = gettext_set_language(args['ln'])
 
         if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
             return webuser.page_not_authorized(req, "../youraccount/lost")
 
         return page(title=_("Lost your password?"),
                     body=webaccount.perform_lost(args['ln']),
                     navtrail="""<a class="navtrail" href="%s/youraccount/display?ln=%s">""" % (sweburl, args['ln']) + _("Your Account") + """</a>""",
                     description="CDS Personalize, Main page",
                     keywords="CDS, personalize",
                     uid=uid,
                     req=req,
                     secure_page_p = 1,
                     language=args['ln'],
                     lastupdated=__lastupdated__)
 
 
     def send_email(self, req, form):
         # set all the declared query fields as local variables
         args = wash_urlargd(form, {'p_email': (str, None)})
         uid = webuser.getUid(req)
 
         # load the right message language
         _ = gettext_set_language(args['ln'])
 
         if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
             return webuser.page_not_authorized(req, "../youraccount/send_email")
 
         user_prefs = webuser.get_user_preferences(webuser.emailUnique(args['p_email']))
         if user_prefs:
             if CFG_EXTERNAL_AUTHENTICATION.has_key(user_prefs['login_method']) or CFG_EXTERNAL_AUTHENTICATION.has_key(user_prefs['login_method']) and CFG_EXTERNAL_AUTHENTICATION[user_prefs['login_method']][0] != None:
                 Msg = websession_templates.tmpl_lost_password_message(ln=args['ln'], supportemail = supportemail)
 
                 return page(title=_("Your Account"),
                             body=Msg,
                             description="CDS Personalize, Main page",
                             keywords="CDS, personalize",
                             uid=uid,
                             req=req,
                             secure_page_p = 1,
                             language=args['ln'],
                             lastupdated=__lastupdated__)
 
         passw = webuser.givePassword(args['p_email'])
         if passw == -999:
             eMsg = _("The entered e-mail address doesn't exist in the database")
             return page(title=_("Your Account"),
                         body=webaccount.perform_emailMessage(eMsg, args['ln']),
                         description="CDS Personalize, Main page",
                         keywords="CDS, personalize",
                         uid=uid, req=req,
                         secure_page_p = 1,
                         language=args['ln'],
                         lastupdated=__lastupdated__)
 
         fromaddr = "From: %s" % supportemail
         toaddrs  = "To: " + args['p_email']
         to = toaddrs + "\n"
         sub = "Subject: %s %s\n\n" % (_("Credentials for"), cdsname)
         body = "%s %s:\n\n" % (_("Here are your user credentials for"), cdsname)
         body += "   %s: %s\n   %s: %s\n\n" % (_("username"), args['p_email'], _("password"), passw)
         body += "%s %s/youraccount/login?ln=%s" % (_("You can login at"), sweburl, args['ln'])
         msg = to + sub + body
 
         server = smtplib.SMTP('localhost')
         server.set_debuglevel(1)
 
         try:
             server.sendmail(fromaddr, toaddrs, msg)
 
         except smtplib.SMTPRecipientsRefused,e:
             eMsg = _("The entered email address is incorrect, please check that it is written correctly (e.g. johndoe@example.com).")
             return page(title=_("Incorrect email address"),
                         body=webaccount.perform_emailMessage(eMsg, args['ln']),
                         description="CDS Personalize, Main page",
                         keywords="CDS, personalize",
                         uid=uid,
                         req=req,
                         secure_page_p = 1,
                         language=args['ln'],
                         lastupdated=__lastupdated__)
 
         server.quit()
         return page(title=_("Lost password sent"),
                     body=webaccount.perform_emailSent(args['p_email'], args['ln']),
                     description="CDS Personalize, Main page",
                     keywords="CDS, personalize",
                     uid=uid, req=req,
                     secure_page_p = 1,
                     language=args['ln'],
                     lastupdated=__lastupdated__)
 
     def youradminactivities(self, req, form):
         args = wash_urlargd(form, {})
         uid = webuser.getUid(req)
 
         # load the right message language
         _ = gettext_set_language(args['ln'])
 
         if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
             return webuser.page_not_authorized(req, "../youraccount/youradminactivities")
 
         return page(title=_("Your Administrative Activities"),
                     body=webaccount.perform_youradminactivities(uid, args['ln']),
                     navtrail="""<a class="navtrail" href="%s/youraccount/display?ln=%s">""" % (sweburl, args['ln']) + _("Your Account") + """</a>""",
                     description="CDS Personalize, Main page",
                     keywords="CDS, personalize",
                     uid=uid,
                     req=req,
                     secure_page_p = 1,
                     language=args['ln'],
                     lastupdated=__lastupdated__)
 
     def delete(self, req, form):
         args = wash_urlargd(form, {})
         uid = webuser.getUid(req)
 
         # load the right message language
         _ = gettext_set_language(args['ln'])
 
         if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
             return webuser.page_not_authorized(req, "../youraccount/delete")
 
         return page(title=_("Delete Account"),
                     body=webaccount.perform_delete(args['ln']),
                     navtrail="""<a class="navtrail" href="%s/youraccount/display?ln=%s">""" % (sweburl, args['ln']) + _("Your Account") + """</a>""",
                     description="CDS Personalize, Main page",
                     keywords="CDS, personalize",
                     uid=uid,
                     req=req,
                     secure_page_p = 1,
                     language=args['ln'],
                     lastupdated=__lastupdated__)
 
     def logout(self, req, form):
         args = wash_urlargd(form, {})
         uid = webuser.logoutUser(req)
 
         # load the right message language
         _ = gettext_set_language(args['ln'])
 
         if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
             return webuser.page_not_authorized(req, "../youraccount/logout")
 
         return page(title=_("Logout"),
                     body=webaccount.perform_logout(req, args['ln']),
                     navtrail="""<a class="navtrail" href="%s/youraccount/display?ln=%s">""" % (sweburl, args['ln']) + _("Your Account") + """</a>""",
                     description="CDS Personalize, Main page",
                     keywords="CDS, personalize",
                     uid=uid,
                     req=req,
                     secure_page_p = 1,
                     language=args['ln'],
                     lastupdated=__lastupdated__)
 
     def login(self, req, form):
         args = wash_urlargd(form, {
-            'p_email': (str, None),
+            'p_un': (str, None),
             'p_pw': (str, None),
             'login_method': (str, None),
             'action': (str, 'login'),
             'referer': (str, '')})
 
         locals().update(args)
 
         if CFG_ACCESS_CONTROL_LEVEL_SITE > 0:
             return webuser.page_not_authorized(req, "../youraccount/login?ln=%s" % args['ln'])
 
         uid = webuser.getUid(req)
 
         # load the right message language
         _ = gettext_set_language(args['ln'])
 
         #return action+_("login")
         if args['action'] == "login" or args['action'] == _("login"):
-            if args['p_email']==None or not args['login_method']:
+            if args['p_un']==None or not args['login_method']:
                 return page(title=_("Login"),
                             body=webaccount.create_login_page_box(args['referer'], args['ln']),
                             navtrail="""<a class="navtrail" href="%s/youraccount/display?ln=%s">""" % (sweburl, args['ln']) + _("Your Account") + """</a>""",
                             description="CDS Personalize, Main page",
                             keywords="CDS, personalize",
                             uid=uid,
                             req=req,
                             secure_page_p = 1,
                             language=args['ln'],
                             lastupdated=__lastupdated__)
-            (iden, args['p_email'], args['p_pw'], msgcode) = webuser.loginUser(req,args['p_email'],args['p_pw'], args['login_method'])
+            (iden, args['p_un'], args['p_pw'], msgcode) = webuser.loginUser(req, args['p_un'], args['p_pw'], args['login_method'])
             if len(iden)>0:
 
-                uid = webuser.update_Uid(req,args['p_email'],args['p_pw'])
+                uid = webuser.update_Uid(req,args['p_un'], args['p_pw'])
                 uid2 = webuser.getUid(req)
                 if uid2 == -1:
                     webuser.logoutUser(req)
                     return webuser.page_not_authorized(req, "../youraccount/login?ln=%s" % args['ln'], uid=uid)
 
                 # login successful!
                 if args['referer']:
                     req.err_headers_out.add("Location", args['referer'])
                     raise apache.SERVER_RETURN, apache.HTTP_MOVED_PERMANENTLY
                 else:
                     return self.display(req, form)
             else:
                 mess = cfg_webaccess_warning_msgs[msgcode] % args['login_method']
                 if msgcode == 14:
-                    if not webuser.userNotExist(args['p_email'],args['p_pw']) or args['p_email']=='' or args['p_email']==' ':
+                    if webuser.username_exists_p(args['p_un']):
                         mess = cfg_webaccess_warning_msgs[15] % args['login_method']
                 act = "login"
                 return page(title=_("Login"),
-                            body=webaccount.perform_back(mess,act, _("login"), args['ln']),
+                            body=webaccount.perform_back(mess, act, _("login"), args['ln']),
                             navtrail="""<a class="navtrail" href="%s/youraccount/display?ln=%s">""" % (sweburl, args['ln']) + _("Your Account") + """</a>""",
                             description="CDS Personalize, Main page",
                             keywords="CDS, personalize",
                             uid=uid,
                             req=req,
                             secure_page_p = 1,
                             language=args['ln'],
                             lastupdated=__lastupdated__)
         else:
             return "This should have never happened.  Please contact %s." % supportemail
 
     def register(self, req, form):
         args = wash_urlargd(form, {
+            'p_nickname': (str, None),
             'p_email': (str, None),
             'p_pw': (str, None),
             'p_pw2': (str, None),
-            'action': (str, 'login'),
-            'referer': (str, '')})
+            'action': (str, "login"),
+            'referer': (str, "")})
 
         if CFG_ACCESS_CONTROL_LEVEL_SITE > 0:
             return webuser.page_not_authorized(req, "../youraccount/register?ln=%s" % args['ln'])
 
         uid = webuser.getUid(req)
 
         # load the right message language
         _ = gettext_set_language(args['ln'])
 
-        if args['p_email']==None:
+        if args['p_nickname']==None or args['p_email']==None:
             return  page(title=_("Register"),
                          body=webaccount.create_register_page_box(args['referer'], args['ln']),
                          navtrail="""<a class="navtrail" href="%s/youraccount/display?ln=%s">""" % (sweburl, args['ln']) + _("Your Account") + """</a>""",
                          description="CDS Personalize, Main page",
                          keywords="CDS, personalize",
                          uid=uid,
                          req=req,
                          secure_page_p = 1,
                          language=args['ln'],
                          lastupdated=__lastupdated__)
 
         mess=""
         act=""
         if args['p_pw'] == args['p_pw2']:
-            ruid = webuser.registerUser(req,args['p_email'],args['p_pw'])
+            ruid = webuser.registerUser(req, args['p_email'], args['p_pw'], args['p_nickname'])
         else:
             ruid = -2
-        if ruid == 1:
+        if ruid == 0:
             uid = webuser.update_Uid(req,args['p_email'],args['p_pw'])
             mess = _("Your account has been successfully created.")
             title = _("Account created")
             if CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT == 1:
                 mess += _(" An email has been sent to the given address with the account information.")
             if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 1:
                 mess += _(" A second email will be sent when the account has been activated and can be used.")
             else:
                 mess += _(""" You can now access your <a href="%s">account</a>.""") % (
                           "%s/youraccount/display?ln=%s" % (sweburl, args['ln']))
-        elif ruid == -1:
-            mess = _("The user already exists in the database, please try again.")
+        elif ruid == -2:
+            mess = _("Both passwords must match.")
+            mess += " " + _("Please try again.")
             act = "register"
             title = _("Register failure")
-        elif ruid == -2:
-            mess = _("Both passwords must match, please try again.")
+        elif ruid == 1:
+            mess = _("Supplied email address %s is invalid.") % args['p_email']
+            mess += " " + _("Please try again.")
+            act = "register"
+            title = _("Register failure")
+        elif ruid == 2:
+            mess = _("Desired nickname %s is invalid.") % args['p_nickname']
+            mess += " " + _("Please try again.")
+            act = "register"
+            title = _("Register failure")
+        elif ruid == 3:
+            mess = _("Supplied email address %s already exists in the database.") % args['p_email']
+            mess += " " + websession_templates.tmpl_lost_your_password_teaser(args['ln'])
+            mess += " " + _("Or please try again.")
+            act = "register"
+            title = _("Register failure")
+        elif ruid == 4:
+            mess = _("Desired nickname %s already exists in the database.") % args['p_nickname']
+            mess += " " + _("Please try again.")
+            act = "register"
+            title = _("Register failure")
+        elif ruid == 5:
+            mess = _("Users cannot register themselves, only admin can register them.")
             act = "register"
             title = _("Register failure")
         else:
-            mess = _("The email address given is not valid, please try again.")
+            # this should never happen
+            mess = _("Internal Error")
             act = "register"
             title = _("Register failure")
 
         return page(title=title,
                     body=webaccount.perform_back(mess,act, (act == 'register' and _("register") or ""), args['ln']),
                     navtrail="""<a class="navtrail" href="%s/youraccount/display?ln=%s">""" % (sweburl, args['ln']) + _("Your Account") + """</a>""",
                     description="CDS Personalize, Main page",
                     keywords="CDS, personalize",
                     uid=uid,
                     req=req,
                     secure_page_p = 1,
                     language=args['ln'],
                     lastupdated=__lastupdated__)
diff --git a/modules/websession/lib/webuser.py b/modules/websession/lib/webuser.py
index 1d1653221..59b3f6dcf 100644
--- a/modules/websession/lib/webuser.py
+++ b/modules/websession/lib/webuser.py
@@ -1,647 +1,694 @@
 ## $Id$
 ## CDS Invenio User related utilities.
 
 ## This file is part of CDS Invenio.
 ## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
 ##
 ## CDS Invenio is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License as
 ## published by the Free Software Foundation; either version 2 of the
 ## License, or (at your option) any later version.
 ##
 ## CDS Invenio is distributed in the hope that it will be useful, but
 ## WITHOUT ANY WARRANTY; without even the implied warranty of
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ## General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
 ## along with CDS Invenio; if not, write to the Free Software Foundation, Inc.,
 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
 """
 This file implements all methods necessary for working with users and sessions in invenio.
 Contains methods for logging/registration when a user log/register into the system, checking if it
 is a guest user or not.
 
 At the same time this presents all the stuff it could need with sessions managements, working with websession.
 
 It also contains Apache-related user authentication stuff.
 """
 
 from marshal import loads,dumps
 from zlib import compress,decompress
 import sys
 import time
 import os
 import crypt
 import string
 import smtplib
 
 from invenio import session, websession
 from invenio.dbquery import run_sql, escape_string, OperationalError
 from invenio.websession import pSession, pSessionMapping
 from invenio.session import SessionError
 from invenio.config import *
 from invenio.access_control_engine import acc_authorize_action
 from invenio.access_control_admin import acc_findUserRoleActions
 from invenio.access_control_config import *
 
 from invenio.messages import gettext_set_language
 import invenio.template
 tmpl = invenio.template.load('websession')
 
 def createGuestUser():
     """Create a guest user , insert into user null values in all fields
 
        createGuestUser() -> GuestUserID
     """
     if CFG_ACCESS_CONTROL_LEVEL_GUESTS == 0:
         try:
             return run_sql("insert into user (email, note) values ('', '1')")
         except OperationalError:
             return None
             
     elif CFG_ACCESS_CONTROL_LEVEL_GUESTS >= 1:
         try:
             return run_sql("insert into user (email, note) values ('', '0')")
         except OperationalError:
             return None
 
 def page_not_authorized(req, referer='', uid='', text='', navtrail='', ln=cdslang):
     """Show error message when account is not activated"""
 
     from invenio.webpage import page
 
     _ = gettext_set_language(ln)
 
     if not CFG_ACCESS_CONTROL_LEVEL_SITE:
         title = cfg_webaccess_msgs[5]
         if not uid:
             uid = getUid(req)
         try:
             res = run_sql("SELECT email FROM user WHERE id=%s" % uid)
 
             if res and res[0][0]:
                 if text:
                     body = text
                 else:
                     body = "%s %s" % (cfg_webaccess_warning_msgs[9] % res[0][0],
                                       ("%s %s" % (cfg_webaccess_msgs[0] % referer, cfg_webaccess_msgs[1])))
             else:
                 if text:
                     body = text
                 else:
                     if CFG_ACCESS_CONTROL_LEVEL_GUESTS == 1:
                         body = cfg_webaccess_msgs[3]
                     else:
                         body = cfg_webaccess_warning_msgs[4] + cfg_webaccess_msgs[2]
 
         except OperationalError, e:
             body = _("Database problem: %s") % str(e)
 
 
     elif CFG_ACCESS_CONTROL_LEVEL_SITE == 1:
         title = cfg_webaccess_msgs[8]
         body = "%s %s" % (cfg_webaccess_msgs[7], cfg_webaccess_msgs[2])
 
     elif CFG_ACCESS_CONTROL_LEVEL_SITE == 2:
         title = cfg_webaccess_msgs[6]
         body = "%s %s" % (cfg_webaccess_msgs[4], cfg_webaccess_msgs[2])
 
     return page(title=title,
                 uid=getUid(req),
                 body=body,
                 navtrail=navtrail,
                 req=req)
 
 def getUid (req):
     """Return user ID taking it from the cookie of the request.
        Includes control mechanism for the guest users, inserting in
        the database table when need be, raising the cookie back to the
        client.
 
        User ID is set to 0 when client refuses cookie or we are in the
        read-only site operation mode.
 
        User ID is set to -1 when we are in the permission denied site
        operation mode.
 
        getUid(req) -> userId
     """
 
     if CFG_ACCESS_CONTROL_LEVEL_SITE == 1: return 0
     if CFG_ACCESS_CONTROL_LEVEL_SITE == 2: return -1
 
     guest = 0
     sm = session.MPSessionManager(pSession, pSessionMapping())
     try:
 	s = sm.get_session(req)
     except SessionError,e:
 	sm.revoke_session_cookie (req)
 	s = sm.get_session(req)
     userId = s.getUid()
     if userId == -1: # first time, so create a guest user
         s.setUid(createGuestUser())
         userId = s.getUid()
         guest = 1
     sm.maintain_session(req,s)
 
     if guest == 0:
         guest = isGuestUser(userId)
 
     if guest:
         if CFG_ACCESS_CONTROL_LEVEL_GUESTS == 0:
             return userId
         elif CFG_ACCESS_CONTROL_LEVEL_GUESTS >= 1:
             return -1
     else:
         res = run_sql("SELECT note FROM user WHERE id=%s" % userId)
         if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS == 0:
             return userId
         elif CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 1 and res and res[0][0] in [1, "1"]:
             return userId
         else:
             return -1
 
 def setUid(req,uid):
     """It sets the userId into the session, and raise the cookie to the client.
     """
     sm = session.MPSessionManager(pSession, pSessionMapping())
     try:
 	s = sm.get_session(req)
     except SessionError,e:
 	sm.revoke_session_cookie (req)
 	s = sm.get_session(req)
     s.setUid(uid)
     sm.maintain_session(req,s)
     return uid
 
 def get_user_info(uid, ln=cdslang):
     """Get infos for a given user.
     @param uid: user id (int)
     @return tuple: (uid, nickname, display_name)
     """
     _ = gettext_set_language(ln)
     query = """SELECT id, nickname
                FROM user
                WHERE id=%i"""
     res = run_sql(query%uid)
     if res:
         if res[0]:
             user = list(res[0])
             if user[1]:
                 user.append(user[1])
             else:
                 user[1] = str(user[0])
                 user.append(_("user #%i")% user[0])
             return tuple(user)
     return (uid, '', _("N/A"))
 
 def isGuestUser(uid):
     """It Checks if the userId corresponds to a guestUser or not
 
        isGuestUser(uid) -> boolean
     """
     out = 1
     try:
         res = run_sql("select email from user where id=%s", (uid,))
         if res:
             if res[0][0]:
                 out = 0
     except OperationalError:
         pass
     return out
 
 def isUserSubmitter(uid):
     u_email = get_email(uid)
     res = run_sql("select * from sbmSUBMISSIONS where email=%s",(u_email,))
     if len(res) > 0:
         return 1
     else:
         return 0
 
 def isUserReferee(uid):
     res = run_sql("select sdocname from sbmDOCTYPE")
     for row in res:
         doctype = row[0]
         categ = "*"
         (auth_code, auth_message) = acc_authorize_action(uid, "referee",doctype=doctype, categ=categ)
         if auth_code == 0:
             return 1
         res2 = run_sql("select sname from sbmCATEGORIES where doctype=%s",(doctype,))
         for row2 in res2:
             categ = row2[0]
             (auth_code, auth_message) = acc_authorize_action(uid, "referee",doctype=doctype, categ=categ)
             if auth_code == 0:
                 return 1
     return 0
 
 def isUserAdmin(uid):
     "Return 1 if the user UID has some admin rights; 0 otherwise."
     out = 0
     if acc_findUserRoleActions(uid):
         out = 1
     return out
 
-def checkRegister(user,passw):
-    """It checks if the user is register with the correct password
+def nickname_valid_p(nickname):
+    """Check whether wanted NICKNAME supplied by the user is valid.
+       At the moment we just check whether it is not empty, does not
+       contain blanks or @, is not equal to `guest', etc.
 
-       checkRegister(user,passw) -> boolean
+       Return 1 if nickname is okay, return 0 if it is not.
     """
-
-    query_result = run_sql("select * from user where email=%s and password=%s", (user,passw))
-    if len(query_result)> 0 :
+    if not nickname \
+       or len(nickname) < 1 \
+       or string.find(nickname, " ") > 0 \
+       or string.find(nickname, "@") > 0 \
+       or nickname == "guest":
         return 0
     return 1
 
-def userOnSystem(user):
-    """It checks if the user is registered already on the system
-    """
-    query_register = run_sql("select * from user where email=%s", (user,))
-    if len(query_register)>0:
-	return 1
-    return 0
-
-def checkemail(email):
-    """Check whether the EMAIL address supplied by the user is valid.
-       At the moment we just check whether it contains '@' and
-       whether it doesn't contain blanks.
+def email_valid_p(email):
+    """Check whether wanted EMAIL address supplied by the user is valid.
+       At the moment we just check whether it contains '@' and whether
+       it doesn't contain blanks.  We also check the email domain if
+       CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN is set.
 
-       checkemail(email) -> boolean
+       Return 1 if email is okay, return 0 if it is not.
     """
-
     if (string.find(email, "@") <= 0) or (string.find(email, " ") > 0):
-       return 0
+        return 0
     elif CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN:
         if not email.endswith(CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN):
             return 0
     return 1
 
-def getDataUid(req,uid):
-    """It takes the email and password from a given userId, from the database, if don't exist it just returns
-       guest values for email and password
-
-       getDataUid(req,uid) -> [email,password]
-
-    """
-
-    email = 'guest'
-    password = 'none'
-
-    query_result = run_sql("select email, password from user where id=%s", (uid,))
+def registerUser(req, email, passw, nickname=""):
+    """Register user with used-wished values of NICKNAME, EMAIL and
+       PASSW.
+       
+       Return 0 if the registration is successful, 1 if email is not
+       valid, 2 if nickname is not valid, 3 if email is already in the
+       database, 4 if nickname is already in the database, 5 when
+       users cannot register themselves because of the site policy.
+       """
+
+    # is email valid?
+    if not email_valid_p(email):
+        return 1
 
-    if len(query_result)>0:
+    # is nickname valid?
+    if not nickname_valid_p(nickname):
+        return 2
 
-        email = query_result[0][0]
-        password = query_result[0][1]
+    # is email already taken?
+    res = run_sql("SELECT * FROM user WHERE email=%s", (email,))
+    if len(res) > 0:
+	return 3
 
-    if password == None or  email =='':
-        email = 'guest'
-    list = [email] +[password]
-    return list
+    # is nickname already taken?
+    res = run_sql("SELECT * FROM user WHERE nickname=%s", (nickname,))
+    if len(res) > 0:
+	return 4
 
+    # okay, go on and register the user:
+    if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS == 0:
+        activated = 1
+    elif CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS == 1:
+        activated = 0
+    elif CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 2:
+        return 5
 
-def registerUser(req,user,passw):
-    """It registers the user, inserting into the user table of database, the email and the pasword
-	of the user. It returns 1 if the insertion is done, 0 if there is any failure with the email
-	and -1 if the user is already on the data base
+    user_preference = get_default_user_preferences()
 
-       registerUser(req,user,passw) -> int
-    """
-    if userOnSystem(user) and  user !='':
-	return -1
-    if checkRegister(user,passw) and checkemail(user):
-        if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS == 0:
-            activated = 1
-        elif CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS == 1:
-            activated = 0
-        elif CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 2:
-            return 0
+    setUid(req, run_sql("INSERT INTO user (nickname, email, password, note, settings) VALUES (%s,%s,%s,%s,%s)",
+                        (nickname, email, passw, activated, serialize_via_marshal(user_preference),)))
 
-        user_preference = get_default_user_preferences()
-
-	setUid(req, run_sql("INSERT INTO user (email, password, note, settings) VALUES (%s,%s,%s,%s)",
-                                (user,passw,activated,serialize_via_marshal(user_preference),)))
-
-        if CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT:
-            sendNewUserAccountWarning(user, user, passw)
-        if CFG_ACCESS_CONTROL_NOTIFY_ADMIN_ABOUT_NEW_ACCOUNTS:
-            sendNewAdminAccountWarning(user, adminemail)
-	return 1
+    if CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT:
+        sendNewUserAccountWarning(email, email, passw)
+    if CFG_ACCESS_CONTROL_NOTIFY_ADMIN_ABOUT_NEW_ACCOUNTS:
+        sendNewAdminAccountWarning(email, adminemail)
     return 0
 
-def updateDataUser(req,uid,email,password):
-    """It updates the data from the user. It is used when a user set his email and password
+def updateDataUser(req,uid,email,password,nickname):
+    """Update user data.  Used when a user changed his email or password or nickname.
     """
-    if email =='guest':
+    if email == 'guest':
         return 0
 
     if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 2:
         query_result = run_sql("update user set password=%s where id=%s", (password,uid))
     else:
         query_result = run_sql("update user set email=%s,password=%s where id=%s", (email,password,uid))
+    if nickname and nickname != '':
+        query_result = run_sql("update user set nickname=%s where id=%s", (nickname,uid))
     return 1
 
-def loginUser(req, p_email,p_pw, login_method):
+def loginUser(req, p_un, p_pw, login_method):
     """It is a first simple version for the authentication of user. It returns the id of the user,
        for checking afterwards if the login is correct
     """
 
+    # p_un passed may be an email or a nickname:
+    p_email = get_email_from_username(p_un)
+
+    # go on with the old stuff based on p_email:
     user_prefs = get_user_preferences(emailUnique(p_email))
     if user_prefs and login_method != user_prefs["login_method"]:
         if CFG_EXTERNAL_AUTHENTICATION.has_key(user_prefs["login_method"]):
             return ([], p_email, p_pw, 11)
 
     if not CFG_EXTERNAL_AUTHENTICATION.has_key(login_method):
         return ([], p_email, p_pw, 12)
 
     if CFG_EXTERNAL_AUTHENTICATION[login_method][0]:
         p_email = CFG_EXTERNAL_AUTHENTICATION[login_method][0].auth_user(p_email, p_pw)
         if p_email:
             p_pw = givePassword(p_email)
             if not p_pw or p_pw < 0:
                 import random
                 p_pw = int(random.random() * 1000000)
-                if not registerUser(req,p_email,p_pw):
+                if registerUser(req, p_email, p_pw) != 0:
                     return ([], p_email, p_pw, 13)
                 else:
-                    query_result = run_sql("SELECT id from user where email=%s and password=%s", (p_email,p_pw,))
+                    query_result = run_sql("SELECT id from user where email=%s and password=%s", (p_email, p_pw,))
                     user_prefs = get_user_preferences(query_result[0][0])
                     user_prefs["login_method"] = login_method
                     set_user_preferences(query_result[0][0], user_prefs)
         else:
             return ([], p_email, p_pw, 10)
 
-    query_result = run_sql("SELECT id from user where email=%s and password=%s", (p_email,p_pw,))
+    query_result = run_sql("SELECT id from user where email=%s and password=%s", (p_email, p_pw,))
     if query_result:
         prefered_login_method = get_user_preferences(query_result[0][0])['login_method']
     else:
         return ([], p_email, p_pw, 14)
 
     if login_method != prefered_login_method:
         if CFG_EXTERNAL_AUTHENTICATION.has_key(prefered_login_method):
             return ([], p_email, p_pw, 11)
 
     return (query_result, p_email, p_pw, 0)
 
 def logoutUser(req):
     """It logout the user of the system, creating a guest user.
     """
     uid = getUid(req)
 
     sm = session.MPSessionManager(pSession, pSessionMapping())
     try:
 	s = sm.get_session(req)
     except SessionError,e:
 	sm.revoke_session_cookie (req)
 	s = sm.get_session(req)
     id1 = createGuestUser()
     s.setUid(id1)
     sm.maintain_session(req,s)
     return id1
 
-def userNotExist(p_email,p_pw):
-    """Check if the user exists or not in the system
+def username_exists_p(username):
+    """Check if USERNAME exists in the system.  Username may be either
+    nickname or email.
+    
+    Return 1 if it does exist, 0 if it does not. 
     """
 
-    query_result = run_sql("select email from user where email=%s", (p_email,))
-    if len(query_result)>0 and query_result[0]!='':
+    if username == "":
+        # return not exists if asked for guest users
         return 0
-    return 1
+    res = run_sql("SELECT email FROM user WHERE nickname=%s OR email=%s",
+                  (username, username,))
+    if len(res) > 0:
+        return 1
+    return 0
 
 def emailUnique(p_email):
     """Check if the email address only exists once. If yes, return userid, if not, -1
     """
 
     query_result = run_sql("select id, email from user where email=%s", (p_email,))
     if len(query_result) == 1:
         return query_result[0][0]
     elif len(query_result) == 0:
         return 0
     return -1
 
+def nicknameUnique(p_nickname):
+    """Check if the nickname only exists once. If yes, return userid, if not, -1
+    """
+
+    query_result = run_sql("select id, nickname from user where nickname=%s", (p_nickname,))
+    if len(query_result) == 1:
+        return query_result[0][0]
+    elif len(query_result) == 0:
+        return 0
+    return -1
+
 def update_Uid(req,p_email,p_pw):
     """It updates the userId of the session. It is used when a guest user is logged in succesfully in the system
     with a given email and password
     """
     query_ID = int(run_sql("select id from user where email=%s and password=%s",
                            (p_email,p_pw))[0][0])
     setUid(req,query_ID)
     return query_ID
 
 def givePassword(email):
     """ It checks in the database the password for a given email. It is used to send the password to the email of the user.It returns
 	the password if the user exists, otherwise it returns -999
     """
 
     query_pass = run_sql("select password from user where email =%s",(email,))
     if len(query_pass)>0:
         return query_pass[0][0]
     return -999
 
 def sendNewAdminAccountWarning(newAccountEmail, sendTo, ln=cdslang):
     """Send an email to the address given by sendTo about the new account newAccountEmail."""
 
     fromaddr = "From: %s" % supportemail
     toaddrs  = "To: %s" % sendTo
     to = toaddrs + "\n"
     sub = "Subject: New account on '%s'" % cdsname
     if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS == 1:
         sub += " - PLEASE ACTIVATE"
     sub += "\n\n"
     body = "A new account has been created on '%s'" % cdsname
     if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS == 1:
         body += " and is awaiting activation"
     body += ":\n\n"
     body += "   Username/Email: %s\n\n" % newAccountEmail
     body += "You can approve or reject this account request at: %s/admin/webaccess/webaccessadmin.py/manageaccounts\n" % weburl
     body += "\n---------------------------------"
     body += "\n%s" % cdsname
     body += "\nContact: %s" % supportemail
     msg = to + sub + body
 
     server = smtplib.SMTP('localhost')
     server.set_debuglevel(1)
 
     try:
         server.sendmail(fromaddr, toaddrs, msg)
     except smtplib.SMTPRecipientsRefused,e:
         return 0
 
     server.quit()
     return 1
 
 def sendNewUserAccountWarning(newAccountEmail, sendTo, password, ln=cdslang):
     """Send an email to the address given by sendTo about the new account newAccountEmail."""
 
     fromaddr = "From: %s" % supportemail
     toaddrs  = "To: %s" % sendTo
     to = toaddrs + "\n"
     sub = "Subject: Your account created on '%s'\n\n" % cdsname
     body = "You have created a new account on '%s':\n\n" % cdsname
     body += "   Username/Email: %s\n" % newAccountEmail
     body += "   Password: %s\n\n" % ("*" * len(password))
     if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 1:
         body += "This account is awaiting approval by the site administrators and therefore cannot be used as of yet.\nYou will receive an email notification as soon as your account request has been processed.\n"
     body += "\n---------------------------------"
     body += "\n%s" % cdsname
     body += "\nContact: %s" % supportemail
     msg = to + sub + body
 
     server = smtplib.SMTP('localhost')
     server.set_debuglevel(1)
 
     try:
         server.sendmail(fromaddr, toaddrs, msg)
     except smtplib.SMTPRecipientsRefused,e:
         return 0
 
     server.quit()
     return 1
 
 def get_email(uid):
     """Return email address of the user uid.  Return string 'guest' in case
     the user is not found."""
     out = "guest"
     res = run_sql("SELECT email FROM user WHERE id=%s", (uid,), 1)
     if res and res[0][0]:
         out = res[0][0]
     return out
 
+def get_email_from_username(username):
+    """Return email address of the user corresponding to USERNAME.
+    The username may be either nickname or email.  Return USERNAME
+    untouched if not found in the database or if found several
+    matching entries.
+    """
+    out = username
+    res = run_sql("SELECT email FROM user WHERE email=%s OR nickname=%s", (username, username,), 1)
+    if res and len(res) == 1:
+        out = res[0][0]
+    return out
+
+def get_password(uid):
+    """Return password of the user uid.  Return None in case
+    the user is not found."""
+    out = None
+    res = run_sql("SELECT password FROM user WHERE id=%s", (uid,), 1)
+    if res and res[0][0]:
+        out = res[0][0]
+    return out
+
+def get_nickname_or_email(uid):
+    """Return nickname (preferred) or the email address of the user uid.
+    Return string 'guest' in case the user is not found."""
+    out = "guest"
+    res = run_sql("SELECT nickname, email FROM user WHERE id=%s", (uid,), 1)
+    if res and res[0]:
+        if res[0][0]:
+            out = res[0][0]
+        elif res[0][1]:
+            out = res[0][1]
+    return out
+
 def create_userinfobox_body(req, uid, language="en"):
     """Create user info box body for user UID in language LANGUAGE."""
 
     if req:
         if req.subprocess_env.has_key('HTTPS') \
            and req.subprocess_env['HTTPS'] == 'on':
             url_referer = sweburl + req.unparsed_uri
         else:
             url_referer = weburl + req.unparsed_uri
     else:
         url_referer = weburl
         
     try:
         return tmpl.tmpl_create_userinfobox(ln=language,
                                             url_referer=url_referer,
                                             guest = isGuestUser(uid),
-                                            email = get_email(uid),
+                                            username = get_nickname_or_email(uid),
                                             submitter = isUserSubmitter(uid),
                                             referee = isUserReferee(uid),
                                             admin = isUserAdmin(uid),
                                             )
     except OperationalError:
         return ""
 
 def list_registered_users():
     """List all registered users."""
     return run_sql("SELECT id,email FROM user where email!=''")
 
 def list_users_in_role(role):
     """List all users of a given role (see table accROLE)
     @param role: role of user (string)
     @return list of uids
     """
     query = """SELECT uacc.id_user
                FROM user_accROLE uacc JOIN accROLE acc
                     ON uacc.id_accROLE=acc.id
                WHERE acc.name='%s'"""
     res = run_sql(query% escape_string(role))
     if res:
         return map(lambda x: int(x[0]), res)
     return []
 
 def list_users_in_roles(role_list):
     """List all users of given roles (see table accROLE)
     @param role_list: list of roles [string]
     @return list of uids
     """
     if not(type(role_list) is list or type(role_list) is tuple):
         role_list = [role_list]
     params=''
     query = """SELECT distinct(uacc.id_user)
                FROM user_accROLE uacc JOIN accROLE acc
                     ON uacc.id_accROLE=acc.id
                %s"""
     if len(role_list) > 0:
         params = 'WHERE '
         for role in role_list[:-1]:
             params += "acc.name='%s' OR " % escape_string(role)
         params += "acc.name='%s'" % escape_string(role_list[-1])
     res = run_sql(query% params)
     if res:
         return map(lambda x: int(x[0]), res)
     return []
 
 ## --- follow some functions for Apache user/group authentication
 
 def auth_apache_user_p(user, password):
     """Check whether user-supplied credentials correspond to valid
     Apache password data file.  Return 0 in case of failure, 1 in case
     of success."""
     try:
         pipe_input, pipe_output = os.popen2(["grep", "^" + user + ":", cfg_apache_password_file], 'r')
         line =  pipe_output.readlines()[0]
         password_apache = string.split(string.strip(line),":")[1]
     except: # no pw found, so return not-allowed status
         return 0
     salt = password_apache[:2]
     if crypt.crypt(password, salt) == password_apache:
         return 1
     else:
         return 0
 
 def auth_apache_user_in_groups(user):
     """Return list of Apache groups to which Apache user belong."""
     out = []
     try:
         pipe_input,pipe_output = os.popen2(["grep", user, cfg_apache_group_file], 'r')
         for line in pipe_output.readlines():
             out.append(string.split(string.strip(line),":")[0])
     except: # no groups found, so return empty list
         pass
     return out
 
 def auth_apache_user_collection_p(user, password, coll):
     """Check whether user-supplied credentials correspond to valid
     Apache password data file, and whether this user is authorized to
     see the given collections.  Return 0 in case of failure, 1 in case
     of success."""
     from invenio.search_engine import coll_restricted_p, coll_restricted_group
     if not auth_apache_user_p(user, password):
         return 0
     if not coll_restricted_p(coll):
         return 1
     if coll_restricted_group(coll) in auth_apache_user_in_groups(user):
         return 1
     else:
         return 0
 
 def get_user_preferences(uid):
     pref = run_sql("SELECT id, settings FROM user WHERE id=%s", (uid,))
     if pref:
         try:
             return deserialize_via_marshal(pref[0][1])
         except:
             return get_default_user_preferences()
 
     return None
 
 def set_user_preferences(uid, pref):
     res = run_sql("UPDATE user SET settings='%s' WHERE id=%s" % (serialize_via_marshal(pref),uid))
 
 def get_default_user_preferences():
     user_preference = {
         'login_method': ''}
 
     for system in CFG_EXTERNAL_AUTHENTICATION.keys():
         if CFG_EXTERNAL_AUTHENTICATION[system][1]:
             user_preference['login_method'] = system
             break
     return user_preference
 
 def serialize_via_marshal(obj):
     """Serialize Python object via marshal into a compressed string."""
     return escape_string(compress(dumps(obj)))
 def deserialize_via_marshal(string):
     """Decompress and deserialize string into a Python object via marshal."""
     return loads(decompress(string))